O Trade Heart é um “motor de decisão e gestão” que opera em cima de dados de mercado (preço/volume/notícias via VOLT)
e do estado da sua conta (posições/ordens/execuções). Ele faz duas coisas:
- Decide entradas (quando entrar e com qual confiança)
- Gerencia saídas (stop, take profit parcial, trailing, cooldown e guardrails)
Regra de segurança (fail-closed)
Tudo é configurável por usuário/conta no ClickHouse. Quando falta configuração, o sistema falha fechado (fail-closed): não executa ordens.
Fluxo de ponta a ponta (sequência de decisões)
-
Gate de segurança (antes de qualquer coisa)
O Heart só roda se:
- existe configuração válida para o usuário/conta;
- existe bridge configurado (Gateway local para usuários; TWS/VM para admin);
- o mercado está em sessão permitida (regular e/ou after-market, conforme config);
- o modo de execução permite (dry-run vs execute).
Se algum gate falhar → não executa e registra o motivo (blockedReasons).
-
Seleção do universo (o que ele analisa)
- favoritos / watchlist / universo definido, com limites (runner_max_symbols etc.).
- por símbolo, pode haver override (kill switch, cooldown, etc.).
-
Timeframes: decisão vs gestão
O Heart separa “pensar” de “gerenciar”:
- Decision TF (min): frequência de decidir entrada (ex.: a cada 5 min).
- Manage TF (min): frequência de atualizar stop/trailing (ex.: a cada 1 min).
- Exec TF (min): timeframe usado para emitir ações e consolidar regras de execução.
Isso evita ruído: entrar é mais criterioso; gerenciar pode ser mais frequente.
-
Entradas: como o Heart usa o VOLT
O VOLT gera sinais por ativo com:
- RVOL (volume relativo no minuto vs baseline histórico)
- sentimento de notícias
- variação do preço
- um score de confidence e should_act
O Heart usa isso como “gatilho” e “filtro”:
- Só considera entrada se o sinal está vivo (TTL) e com confiança mínima.
- Pode aplicar regras adicionais de risco/cooldown e limites de trades.
Termos importantes do VOLT:
- VOLT min confidence: confiança mínima (0–1) para considerar o sinal.
- VOLT TTL (s): tempo que um sinal continua válido.
-
Cálculo de risco: o que é “R”
R é a unidade de risco da operação:
- Stop inicial define o risco por ação: R = |entry_price − stop_price|
- Alvos e decisões são expressos em múltiplos de R (TP1, TP2…)
Por isso você configura:
- TP1 (R) e TP2 (R): distância em R.
- TP1 (%) e TP2 (%): quanto da posição vende em cada alvo.
-
Stop Loss e Trailing: lógica baseada em ATR
O stop não é um % fixo: ele é dinâmico e usa ATR.
ATR (Average True Range) mede a volatilidade recente:
- ATR alto → ativo “anda muito” → stop precisa ser mais folgado.
- ATR baixo → stop pode ser mais apertado.
Definição: atrPctNow
atrPctNow é o ATR “normalizado” em % do preço atual. No script debug-heart-atr-trailing-once.ts ele é calculado exatamente assim:
atrPctNow = atrNow / lastPrice
Se lastPrice <= 0, então atrPctNow = null.
Por que estava null antes? Porque o lastPrice estava vindo 0 ou inválido. A origem típica é o market_price do snapshot em ibkr_sim_positions_v2_latest (às vezes vem 0, NULL ou desatualizado). Como atrPctNow precisa de um preço válido no denominador, o debug faz early-exit e evita seguir com conta quebrada.
De onde vem atrNow
atrNow é o ATR (Average True Range) em unidades de preço, calculado a partir de candles agregados.
O debug busca barras intraday (1m) e agrega para tfMinutes=5 (5 minutos) com OHLC. Para cada candle de 5m ele calcula o True Range (TR):
TR_t = max(High_t − Low_t, |High_t − Close_{t-1}|, |Low_t − Close_{t-1}|)
A partir da série de TR, ele calcula o Wilder ATR com period=14:
ATR_0 = mean(TR_1..TR_p)
ATR_t = (ATR_{t-1} * (p−1) + TR_t) / p
Exemplo real do output do debug: lastPrice=71.15 e atrNow=0.563843 ⇒ atrPctNow ≈ 0.563843 / 71.15 ≈ 0.0079247 (0,792%).
Você configura:
- ATR TF (min): timeframe do ATR (ex.: 5 min).
- ATR period: número de candles usados no ATR (ex.: 14).
- ATR lookback (days): janela de dias para calcular baseline/percentis.
O Heart calcula percentis do ATR (p20/p50/p80) e define um regime (Range/Trend).
-
k_trend / k_range: agressividade do trailing
O trailing usa multiplicadores:
- k_trend: agressividade quando o regime parece tendência.
- k_range: agressividade quando o regime parece lateral.
Regra prática:
- k maior → stop mais longe → menos stop prematuro, mais risco de devolver lucro.
- k menor → stop mais perto → protege lucro, mas stopa mais fácil.
Alpha (0..1) → interpolação de k
O Heart calcula um alpha que representa quão “TREND” (agressivo) o trailing deve ser. Um jeito (usado no debug) é pelo ATR-percent:
alphaAtr = clamp01((atrPctNow − p20_atr_pct) / (p80_atr_pct − p20_atr_pct))
Em paralelo existe alphaRvol (por RVOL). O script usa:
alpha = max(alphaAtr, alphaRvol)
Com alpha em mãos, ele interpola k:
k = kRange + alpha * (kTrend − kRange)
Exemplo: se atrPctNow > p80_atr_pct ⇒ alphaAtr=1; se rvolNow=0 ⇒ alphaRvol=0; então alpha=1 e o trailing usa k=kTrend.
-
Anti-churn: Min Step e Debounce
Para evitar “spam de updates”:
- Min step (bps): só move stop se melhorar pelo menos X bps.
- Trail min ATR step: só move stop se melhorar pelo menos X * ATR.
- Debounce base (ms): janela mínima entre updates de stop.
- Extra debounce (extreme): aumenta debounce quando RVOL/extremo.
-
Guardrails: limites que impedem “robot pirado”
Exemplos de guardrails configuráveis:
- Max updates pos/1h e pos/24h
- Max updates conta/1h
- Cooldown pós-stop (min)
- Max trades/símbolo/dia
- Min tick (arredondamento seguro)
-
Both-hit policy: quando TP e SL batem no mesmo candle
Resolve ambiguidades de candle com uma regra fixa e auditável (ex.: KEEP_STOP).
-
Decision ledger: auditoria do motor
Quando Decision ledger = 1, o Heart grava:
- inputs (ATR, RVOL, regime, price_used…)
- outputs (intent gerado ou bloqueado)
- motivos (blockedReasons, warnings)
Serve para explicar “por que não entrou?”, calibrar config e investigar bugs.
Execução: dry-run vs execute (e por que é seguro)
- dry-run: calcula tudo, mas não manda ordem. Ideal para testar.
- execute: manda ordens, mas só se config está completa, bridge está configurado e execução está eligible (com gates explícitos).
Kill switch (por símbolo)
No override por símbolo, você pode desabilitar um símbolo (enabled=0), bloquear até um horário (block_until) e aplicar overrides.
Glossário rápido
- TF: timeframe em minutos (cadência de decisão/gestão/execução).
- ATR: medida de volatilidade.
- R: unidade de risco baseada no stop inicial.
- Debounce: espera mínima entre mudanças (anti-spam).
- Min step (bps): mudança mínima em pontos-base (0.01%).
- Range mode: regime de mercado (lateral vs tendência).
- Decision ledger: trilha auditável das decisões.
- Both-hit policy: regra quando candle sugere TP e SL no mesmo período.
- VOLT: detector de oportunidade (volume relativo + notícia + preço) com score.
Diagrama mental (resumo)
Gates (config+bridge+sessão+mode)
↓
Seleciona universo (favoritos/posições/universe)
↓
VOLT sinal (RVOL+news+price) → filtro (TTL+min_conf)
↓
Risco (R) + ATR regime → stops/trailing
↓
Guardrails/cooldowns → intent
↓
dry-run (simula) | execute (envia ordem se eligible)