0% acharam este documento útil (0 voto)
0 visualizações6 páginas

Blofin_Risk_Engine_Spec

O documento descreve a arquitetura e implementação de um monitor de risco para a API da BloFin, utilizando uma abordagem híbrida de WebSocket e REST para otimizar o consumo de bateria e evitar limites de requisição. Inclui detalhes sobre a gestão de alertas, cooldown e histerese para evitar alarmes excessivos, além de fornecer exemplos de código em Kotlin para a configuração do serviço no Android. A tabela comparativa ilustra o comportamento do alarme em diferentes condições de risco.

Enviado por

jussarajube
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
0 visualizações6 páginas

Blofin_Risk_Engine_Spec

O documento descreve a arquitetura e implementação de um monitor de risco para a API da BloFin, utilizando uma abordagem híbrida de WebSocket e REST para otimizar o consumo de bateria e evitar limites de requisição. Inclui detalhes sobre a gestão de alertas, cooldown e histerese para evitar alarmes excessivos, além de fornecer exemplos de código em Kotlin para a configuração do serviço no Android. A tabela comparativa ilustra o comportamento do alarme em diferentes condições de risco.

Enviado por

jussarajube
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

BLOFIN RISK GUARD & ENGINE

Especificação Técnica de Engenharia: ForegroundService, WebSocket/REST Híbrido, Cooldown


de Alerta e Gestão de Rate-Limit

KOTLIN 2.0.0 ANDROID 8.0+ OREO (API 26) BLOFIN FUTURES API V1 WEBSOCKET REAL-TIME

1. Arquitetura do Monitor de Risco & Estratégia Rate-Limit Free


Para rodar um monitoramento de risco ininterrupto no Android sem violar os limites de requisições da camada
gratuita da API da BloFin (Rate-Limits REST) e sem consumir excessivamente a bateria do dispositivo, utilizamos
uma Engenharia Híbrida Inteligente:

🌐 Engenharia de Conexão Híbrida (WebSocket + REST Polling)


• Conexão Primária (WebSocket [Link] Escuta as atualizações de preço de
marcação (Mark Price) e do livro de ordens em tempo real. O WebSocket possui consumo zero de
cotas REST.
• Fallback Dinâmico (REST Adaptive Polling): Caso a conexão WebSocket caia, o sistema chaveia para
REST Polling. A frequência ajusta-se automaticamente com base na proximidade do risco:
◦ Modo Seguro (Distância > 5%): Requisição a cada 30 segundos.
◦ Modo Alerta (Distância entre 1.5% e 5%): Requisição a cada 10 segundos.
◦ Modo Crítico (Distância < 1.5%): Requisição a cada 3 segundos.

🔔 Engenharia de Anti-Spam e Gestão de Cooldown de Alertas


Sem controle de estado, uma variação contínua em torno do limiar de 1,5% dispararia dezenas de alarmes
sonoros por minuto. Implementamos um Mecanismo de Histerese de Preço + Cooldown Temporal:

• Cooldown Mínimo: Intervalo mínimo obrigatório de 45 segundos entre alarmes sonoros seguidos.
• Margem de Histerese (+0.5%): O alarme não desativa assim que o risco volta a 1,51%. Ele exige que a
distância alcance pelo menos 2,0% para resetar completamente o estado do disparador sonoro.
• Persistência no Service: O estado de disparo é mantido em memória dentro do ciclo de vida do
ForegroundService.

2. Código-Fonte da Engenharia em Kotlin 2.0.0

A. Configuração de Permissões (`[Link]`)


Requisito obrigatório para garantir a execução contínua no Android 8.0+ (Oreo) até o Android 14+.
<manifest xmlns:android="[Link]
package="[Link]">

<uses-permission android:name="[Link]" />


<uses-permission android:name="[Link].FOREGROUND_SERVICE" />
<uses-permission android:name="[Link].FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="[Link].POST_NOTIFICATIONS" />
<uses-permission android:name="[Link].WAKE_LOCK" />
<uses-permission android:name="[Link].USE_EXACT_ALARM" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="BloFin Risk Guard"
android:theme="@style/[Link]">

<service
android:name=".[Link]"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="specialUse">
<property
android:name="[Link].PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Realtime Cryptocurrency Margin Liquidation Risk Monitoring" />
</service>
</application>
</manifest>

B. Gerenciador de Áudio e Notificação Rápida (`[Link]`)

package [Link]

import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]

class RiskAlarmManager(private val context: Context) {

private var mediaPlayer: MediaPlayer? = null


private var vibrator: Vibrator? = null

init {
vibrator = if ([Link].SDK_INT >= Build.VERSION_CODES.S) {
val vibratorManager = [Link](Context.VIBRATOR_MANAGER_SERVICE) as
VibratorManager
[Link]
} else {
@Suppress("DEPRECATION")
[Link](Context.VIBRATION_SERVICE) as Vibrator
}
}

/**
* Dispara Alarme Sonoro Alto e Vibração em Padrão de Emergência
*/
fun triggerEmergencyAlarm() {
if (mediaPlayer?.isPlaying == true) return

try {
val alarmUri = [Link](RingtoneManager.TYPE_ALARM)
?: [Link](RingtoneManager.TYPE_NOTIFICATION)

mediaPlayer = MediaPlayer().apply {
setDataSource(context, alarmUri)
setAudioAttributes(
[Link]()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.build()
)
isLooping = false
prepare()
start()
}

// Vibração SOS/Emergência
val pattern = longArrayOf(0, 500, 200, 500, 200, 800)
if ([Link].SDK_INT >= Build.VERSION_CODES.O) {
vibrator?.vibrate([Link](pattern, -1))
} else {
@Suppress("DEPRECATION")
vibrator?.vibrate(pattern, -1)
}
} catch (e: Exception) {
[Link]()
}
}

fun stopAlarm() {
try {
if (mediaPlayer?.isPlaying == true) {
mediaPlayer?.stop()
mediaPlayer?.release()
mediaPlayer = null
}
vibrator?.cancel()
} catch (e: Exception) {
[Link]()
}
}
}

C. Motor do Service (`[Link]`)


Service principal compatível com Android 8.0+ que consome a API/WebSocket com controle de cooldown e
histerese.

package [Link]

import [Link].*
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link].*
import [Link]

class BlofinRiskForegroundService : Service() {

private val serviceScope = CoroutineScope([Link] + SupervisorJob())


private lateinit var alarmManager: RiskAlarmManager

// Configurações de Risco
private val LIQUIDATION_THRESHOLD_PCT = 1.5 // Disparo em 1.5%
private val HYSTERESIS_RESET_PCT = 2.0 // Reset do estado em 2.0%
private val ALARM_COOLDOWN_MS = 45_000L // 45 segundos de cooldown entre apitos

// Estado Local de Anti-Spam


private var lastAlarmTimestamp = 0L
private var isAlarmStateActive = false

// Dados Exemplo da Posição (Simulando Payload WebSocket/API)


private var entryPrice = 63100.30
private var liquidationPrice = 60161.80
private var isLong = true

override fun onCreate() {


[Link]()
alarmManager = RiskAlarmManager(this)
createNotificationChannel()
startForeground(NOTIFICATION_ID, createNotification("Iniciando Monitor de Risco
BloFin...", false))
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {


startRiskMonitoringLoop()
return START_STICKY
}

private fun startRiskMonitoringLoop() {


[Link] {
while (isActive) {
// Simulação da Leitura de Preço do WebSocket / API
val currentMarkPrice = fetchLatestMarkPrice()
evaluateRiskAndNotify(currentMarkPrice)

// Adaptativo: Intervalo de checagem mais rápido se o preço estiver instável


delay(2000L)
}
}
}

private fun evaluateRiskAndNotify(markPrice: Double) {


// Cálculo exato da distância percentual até o preço de liquidação
val distancePct = if (isLong) {
((markPrice - liquidationPrice) / markPrice) * 100.0
} else {
((liquidationPrice - markPrice) / markPrice) * 100.0
}

val currentTime = [Link]()

// Lógica de Histerese & Cooldown


if (distancePct <= LIQUIDATION_THRESHOLD_PCT) {
val canTriggerAlarm = (currentTime - lastAlarmTimestamp) > ALARM_COOLDOWN_MS

if (!isAlarmStateActive || canTriggerAlarm) {
isAlarmStateActive = true
lastAlarmTimestamp = currentTime

// Dispara o som crítico


[Link]()

// Atualiza Notificação para Vermelho Crítico


updateNotification(
"🚨 PERIGO DE LIQUIDAÇÃO! (${[Link]("%.2f", distancePct)}%)",
"Preço Atual: $markPrice | Liquidação: $liquidationPrice. FECHE A POSIÇÃO!",
isCritical = true
)
}
} else if (distancePct >= HYSTERESIS_RESET_PCT) {
// Reseta o estado quando o mercado se afasta com segurança (> 2.0%)
isAlarmStateActive = false
[Link]()

updateNotification(
"🟢 Posição Estável (Distância: ${[Link]("%.2f", distancePct)}%)",
"Preço Atual: $markPrice | Liquidação: $liquidationPrice",
isCritical = false
)
} else {
// Zona Neutra (entre 1.5% e 2.0%) - Apenas atualiza o texto sem apitar
updateNotification(
"⚠️ Atenção - Próximo do Limite (${[Link]("%.2f", distancePct)}%)",
"Preço Atual: $markPrice | Liquidação: $liquidationPrice",
isCritical = false
)
}
}

private fun fetchLatestMarkPrice(): Double {


// Em produção: Retorna o valor emitido pelo StateFlow do WebSocket
return 60800.00 // Exemplo de preço aproximando da liquidação
}

private fun createNotificationChannel() {


if ([Link].SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
"BloFin Risk Alerts",
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "Alertas críticos de liquidação de futuros BloFin"
enableLights(true)
lightColor = [Link]
enableVibration(true)
}
val manager = getSystemService(NotificationManager::[Link])
manager?.createNotificationChannel(channel)
}
}

private fun createNotification(contentText: String, title: String, isCritical: Boolean =


false): Notification {
val builder = [Link](this, CHANNEL_ID)
.setContentTitle(title)
.setContentText(contentText)
.setSmallIcon([Link].stat_sys_warning)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setOngoing(true)

if (isCritical) {
[Link]([Link])
[Link](true)
}

return [Link]()
}

private fun updateNotification(title: String, text: String, isCritical: Boolean) {


val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
[Link](NOTIFICATION_ID, createNotification(text, title, isCritical))
}

override fun onDestroy() {


[Link]()
[Link]()
[Link]()
}

override fun onBind(intent: Intent?): IBinder? = null

companion object {
const val CHANNEL_ID = "blofin_risk_channel"
const val NOTIFICATION_ID = 9901
}
}

3. Tabela Comparativa de Comportamento do Alarme

Distância da
Estado da Conexão API Ação do Service Emissão de Som/Alarme
Liquidação

WebSocket Ativo / REST a Notificação Verde (Modo


> 5,0% Muto
cada 30s Vigilância)

1,5% a 2,0% (Zona WebSocket Ativo / REST a Notificação Amarela de Muto (Aguardando Reset/
Neutra) cada 10s Alerta Disparo)

WebSocket Ativo / REST a


< 1,5% (Início da Crise) Notificação Vermelha Crítica 🔊 DISPARO IMEDIATO
cada 3s

< 1,5% (Permanência < WebSocket Ativo / REST a Atualização visual na tela do Muto (Bloqueado por
45s) cada 3s Android Cooldown)

< 1,5% (Após 45 WebSocket Ativo / REST a Notificação Vermelha Re- 🔊 NOVO DISPARO DE
segundos) cada 3s Notificada REFORÇO

Você também pode gostar