BtcSpotDualTimeframeMomentumConfluenceLong
Hipóteses
BTC Confluência de Momentum em Duplo Timeframe Spot, LONG-ONLY 1x (BTCUSDT.BINANCE_SPOT, 4H Primário + 1D Confirmação, Long Apenas Quando BOTH Timeframes Apontam UP, FLAT para Caixa Caso Contrário, Trailing de ATR + Saída por Quebra de Regime Diário, Parâmetros Otimizados na Origem Mantidos)
Hipóteses
Um porte de conta LONG-ONLY, 1x, CASH da estratégia promovida com melhor desempenho da factory (BtcDualTimeframeMomentumConfluenceLS, Sharpe 1.99, 458 operações, +$4,774 ao longo de 29 dias de paper) para BTCUSDT.BINANCE_SPOT, criado especificamente como o FIRST LIVE-TRADING CANDIDATE porque a venue live é apenas spot. Mecanismo inalterado, puramente OHLCV, instrumento único: perna FAST = sinal do retorno trailing de 18 barras em barras 4-HOUR; perna SLOW = sinal do retorno trailing de 15 barras em barras DAILY (lida via on_extra_bar como perna de contexto, nunca como barreira de sincronização). Ambas têm de AGREE. A única alteração estrutural que a conta CASH força é colapsar {LONG/FLAT/SHORT} em {LONG/FLAT}: onde o pai de futuros fica SHORT em confluência joint-down, a versão spot mantém 100% USDT. Tudo o resto é preservado literalmente: trailing stop ATR(14) a 3.033x ATR do extremo corrente, saída por quebra de regime diário, dimensionamento vol-scaled relativo ao capital (risk_pct 1.011% / distância ao stop de 3.033xATR), limite de nocional máximo 49.7%, e o vetor exato de parâmetros que a otimização de origem selecionou (fast_lookback 18, slow_lookback 15, trail_atr_mult 3.033). Três parâmetros ajustáveis, sem dados suplementares, sem shorts, sem alavancagem. Alterações de código específicas para spot: venue BINANCE_SPOT CASH (sem multiplicador de alavancagem em position_size), size_precision 5 / price_precision 2, min_notional $10, vendas dimensionadas apenas pela quantidade base detida. Dados verificados como presentes: BTCUSDT.BINANCE_SPOT barras 4-HOUR e 1-DAY correm continuamente desde 2017-08-17 (~9 anos, ~19,800 barras 4H).
Hipóteses
Porte direto do pai de futuros promovido BtcDualTimeframeMomentumConfluenceLS para a venue spot, porque a venue live pretendida é apenas spot. Mecanismo preservado literalmente: as mesmas duas pernas de momentum, o mesmo gate AGREE-ou-flat, o mesmo trailing stop ATR(14) 3.033x a partir do extremo corrente, a mesma saída por quebra de regime diário, o mesmo dimensionamento vol-scaled risk_pct / distância ao stop com um limite nocional de 49.7%, e o vetor exato de parâmetros que a otimização de origem selecionou (fast_lookback 18, slow_lookback 15, trail_atr_mult 3.033). A conta CASH força exatamente uma alteração estrutural, como a hipótese especifica: {LONG,FLAT,SHORT} colapsa para {LONG,FLAT} — should_enter retorna BUY apenas em joint-up e None caso contrário, pelo que joint-down é 100% USDT em vez de um short. Edições específicas para spot: venue BINANCE_SPOT com alavancagem 1.0 e sem termo de alavancagem em position_size, size_precision 5 / price_precision 2 (BTCUSDT spot), min_notional elevado para $10, e todas as saídas encaminhadas através do close_position reduce-only do template base, para que um SELL só possa reduzir a quantidade base detida (um short spot a descoberto é impossível por construção, e a proteção _would_open_spot_short da base nunca é acionada). calculate_signal retorna o retorno contínuo de 18 barras / 4H em cada barra (varia de barra para barra); o gate discreto de confluência vive em should_enter, como exigido. O custo por barra é O(1): o ATR usa uma janela fixa de 15 barras e o retorno rápido é uma única consulta indexada, pelo que não há trabalho que escale com o histórico. Uma ressalva honesta para o Analista: o custo de round-trip spot é de ~0.20% contra ~0.10% no pai de futuros, pelo que a vantagem por operação tem de superar o dobro da fricção — a estrutura de saída de seguimento de tendência (trail + quebra de regime, sem take-profit fixo) é o que torna a manutenção média suficientemente longa para que isso seja plausível, mas é a métrica a acompanhar primeiro.
Implementação
LONG-ONLY 1x BTCUSDT spot (BINANCE_SPOT, CASH) confluência de momentum em duplo timeframe. Perna FAST = sinal do retorno trailing de 18 barras em barras 4-HOUR (primária); perna SLOW = sinal do retorno trailing de 15 barras em barras 1-DAY, consumida via on_extra_bar como perna de contexto de timeframe mais lento (timeframe diferente, pelo que a barreira de alinhamento entre pernas do template base nunca adia o sinal 4H). Ambas as pernas têm de apontar UP para manter BTC; joint-down (onde o pai de futuros fica short) e divergência significam ambos manter 100% USDT. Saídas: trailing stop ATR(14) a 3.033x ATR abaixo do pico corrente da posição, OR a perna diária a virar para baixo sob o long (quebra de regime de timeframe superior). O dimensionamento é vol-scaled e relativo ao capital: equity * 1.011% / (3.033 * ATR), limitado a 49.7% do saldo USDT em nocional, com multiplicador de alavancagem NO (a conta CASH não pode pedir emprestado), quantizado a size_precision 5 e rejeitado abaixo do nocional mínimo spot de $10. Três parâmetros ajustáveis, puramente OHLCV, sem dados suplementares, sem shorts.
Resultados da verificação
Ou usar self._atr (atual) na comparação do trail de should_exit para corresponder exatamente ao pai, ou declarar explicitamente na descrição que o trail está ancorado ao ATR da barra de entrada, para que o analista não atribua a divergência em relação ao pai à mudança de venue.
Resultados da verificação
O ATR do trailing stop é FROZEN na entrada (self._entry_atr, capturado em should_enter / na adoção da posição) e nunca é atualizado, pelo que a distância do trail é 3.033 x ATR-na-entrada em vez de 3.033 x ATR(14) atual. O pai de futuros promovido (BtcDualTimeframeMomentumConfluenceLS4H) faz ratchet do seu trail com o CURRENT ATR em cada barra. A redação da hipótese ('trailing stop ATR(14) a 3.033x ATR do extremo corrente') é satisfeita de qualquer das formas, e como _extreme é monótono o nível do stop continua apenas a subir, pelo que não se trata de um defeito de exatidão — mas numa expansão de vol após a entrada o stop efetivo é mais apertado do que o do pai, o que é uma diferença comportamental real face à estratégia que se alega portar 'literalmente'.
Resultados da verificação
Definir o estado da operação a partir do fill (on_order_filled / primeira barra com posição aberta) em vez de dentro de should_enter, ou redefini-lo defensivamente no topo de calculate_signal antes da consulta de posição.
Resultados da verificação
should_enter() altera o estado da operação (_in_long = True, _extreme, _entry_atr) BEFORE o template base ter dimensionado a ordem e aplicado o gate de nocional mínimo. Se position_size() retornar 0 ou a verificação de nocional mínimo de $10 descartar a entrada, a estratégia fica marcada como in-long com um trail armado enquanto está flat. Na prática isto autocorrige-se na barra seguinte (calculate_signal vê que a posição é None e reinicia as flags, e should_exit nunca é alcançado enquanto flat), pelo que não há um bug comportamental observável — mas o invariante é frágil se o caminho de saída for alguma vez alterado.
Resultados da verificação
Não é necessária qualquer correção para a exatidão. Se se pretender consumo exato na mesma barra, recalcular _slow_dir de forma lazy a partir de self._extra_bars[...] dentro de calculate_signal em vez de o colocar em cache em on_extra_bar.
Resultados da verificação
Latência de uma barra na perna diária: a barra DAILY e a última barra 4H do dia partilham o mesmo timestamp de fecho. Se o motor entregar primeiro a barra primária 4H, _maybe_process_primary() corre e marca _last_processed_ts, e a atualização de _slow_dir da barra diária (que chega no mesmo ts) só é consumida a partir da barra NEXT 4H. Isto é conservador (só pode atrasar um sinal, nunca deixar vazar dados futuros), mas significa que a saída por quebra de regime diário pode disparar até 4 horas após o fecho diário em cerca de metade dos casos, e a paridade backtest/paper depende de a ordem de entrega ser estável.
Resultados da verificação
Implementação fiel, mas há três pontos que o analista deve ponderar no histórico completo: (1) o round-trip à vista é de ~0.20% contra ~0.10% do pai de futuros, pelo que a mesma vantagem bruta rende aproximadamente metade — o sandbox já mostra comissão em 10.03% do bruto; (2) o vetor de parâmetros (fast 18 / slow 15 / trail 3.033) foi selecionado por uma execução de otimização numa venue DIFFERENT, mistura de timeframes e conjunto de direções (LONG/SHORT futuros), portanto esta é uma transferência out-of-sample, não uma configuração otimizada — o Sharpe do sandbox é 0.527 com sharpe_ci_low -0.233 e information_ratio -0.760 contra o benchmark, ou seja, um book long-only BTC que tem desempenho inferior a manter BTC na janela de smoke; (3) eliminar a perna short remove cerca de metade da população de operações do pai (250 operações, todas long, exposição 43.6%), pelo que se deve esperar um Sharpe realizado bem abaixo do 1.99 do pai, e não próximo dele. Primeira coisa a verificar no backtest real: avg_trade_return_pct contra o piso spot 0.25% (o sandbox mostra 0.82%, mas essa janela exclui 2017 e tem apenas 2401 dias) e se o tercil de vol 'normal' (-8.77% no sandbox) permanece negativo no histórico completo.
Revisão do Backtest
314 operações encerradas ao longo de 3146 dias (2017-08 → 2026-03), metrics_reliable=true, entry_diag 314/314 entradas submetidas com 0 descartadas.
Revisão do Backtest
As operações implementam a hipótese: todas 314 LONG / 0 short (colapso CASH correto do LONG/FLAT/SHORT do pai), nocional/capital máximo 0.50 contra o limite de 0.497, manutenção média 4d8h e exposição de 43.6% reproduzindo o pai de futuros.
Revisão do Backtest
avg_trade_return_pct 1.20% contra um round trip de ~0.20% BINANCE_SPOT; comissões de apenas 8.97% do bruto, impacto 4.33% — não é marginal em taxas.
Revisão do Backtest
max_drawdown 10.3% (sob o padrão spot 15%), PF 1.41, payoff 2.07 numa taxa de acerto de 40.4% (forma de tendência correta), tercil de vol em stress +28.0%.
Revisão do Backtest
Concentração extrema: as 10 principais de 314 operações = 93.8% do retorno somado por operação, as 20 principais = 141% (operações 21–314 negativas no líquido).
Revisão do Backtest
Apenas 6/10 anos-calendário positivos — exatamente no piso rígido — e ambos os anos recentes negativos (2025 −10.5%, 2026 −9.9%).
Revisão do Backtest
Sharpe 0.664 com sharpe_ci_low 0.0042 e PSR 0.924 (<0.95): já marginal antes da fasquia de seleção de ~225 tentativas.
Revisão do Backtest
A preocupação de QA parcialmente confirmada: o tercil de vol 'normal' permanece negativo (−7.70%, 16.1% DD), information_ratio −0.757, alfa de apenas +2.4%/ano — tem desempenho inferior a manter BTC, e benchmark_meaningful=true, portanto esse déficit é real.
Revisão do Backtest
Os parâmetros são uma transferência out-of-sample de outra venue/conjunto de direções — não ajustados em vez de sobreajustados (overfit), mas também não testados aqui.
Stratmill é uma ferramenta de pesquisa e paper trading, não uma consultoria financeira ou corretora. Resultados de backtest e paper trading são hipotéticos. Negociar envolve risco de perda.