Saltar para o conteúdo

Ver original

BtcSpotDualTimeframeMomentumConfluenceLong

Hipóteses

BTC Spot Dual-Timeframe Momentum Confluence, LONG-ONLY 1x (BTCUSDT.BINANCE_SPOT, 4H Primário + 1D Confirmação, Apenas Long Quando BOTH Timeframes Apontam UP, FLAT para Cash Caso Contrário, Saída ATR-Trailing + Rutura de Regime Diário, Parâmetros Otimizados na Origem Mantidos)

Hipóteses

Uma portagem LONG-ONLY, 1x, CASH da estratégia com melhor desempenho promovida pela fábrica (BtcDualTimeframeMomentumConfluenceLS, Sharpe 1.99, 458 trades, +$4,774 ao longo de 29 dias de paper) para BTCUSDT.BINANCE_SPOT, criada especificamente como a FIRST LIVE-TRADING CANDIDATE porque o venue de produção é apenas spot. Mecanismo inalterado, puro-OHLCV, instrumento único: a perna FAST = sinal do retorno trailing de 18 barras em barras 4-HOUR; a 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 obriga é colapsar {LONG/FLAT/SHORT} em {LONG/FLAT}: onde o parent em futuros entra SHORT em confluência joint-down, a versão spot mantém-se 100% USDT. Tudo o resto é preservado verbatim: stop trailing ATR(14) a 3.033x ATR a partir do extremo em curso, saída por rutura de regime diário, dimensionamento ajustado à volatilidade e relativo ao capital (risk_pct 1.011% / distância de stop 3.033xATR), limite máximo de nocional 49.7%, e o vetor de parâmetros exato selecionado pela otimização de origem (fast_lookback 18, slow_lookback 15, trail_atr_mult 3.033). Três parâmetros ajustáveis, sem dados suplementares, sem shorts, sem leverage. Alterações de código específicas do spot: venue BINANCE_SPOT CASH (sem multiplicador de leverage em position_size), size_precision 5 / price_precision 2, min_notional $10, vendas dimensionadas apenas para a quantidade base detida. Dados verificados como presentes: BTCUSDT.BINANCE_SPOT 4-HOUR e 1-DAY barras correm continuamente desde 2017-08-17 (~9 anos, ~19,800 barras 4H).

Hipóteses

Portagem direta do parent em futuros promovido BtcDualTimeframeMomentumConfluenceLS para o venue spot, uma vez que o venue de produção pretendido é apenas spot. Mecanismo preservado verbatim: as mesmas duas pernas de momentum, o mesmo gate AGREE-ou-flat, o mesmo stop trailing ATR(14) 3.033x a partir do extremo em curso, a mesma saída de rutura de regime diário, o mesmo dimensionamento ajustado à volatilidade risk_pct / distância de stop com um limite de 49.7% de nocional, e o vetor de parâmetros exato selecionado pela otimização de origem (fast_lookback 18, slow_lookback 15, trail_atr_mult 3.033). A conta CASH obriga a exatamente uma alteração estrutural, tal como a hipótese especifica: {LONG,FLAT,SHORT} colapsa em {LONG,FLAT} — should_enter devolve BUY apenas em joint-up e None nos restantes casos, pelo que joint-down é 100% USDT em vez de um short. Alterações específicas do spot: venue BINANCE_SPOT com leverage 1.0 e sem termo de leverage 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 reduce-only close_position do template base, pelo que uma SELL apenas pode reduzir a quantidade base detida (um short spot descoberto é impossível por construção, e o guard _would_open_spot_short do base nunca é acionado). calculate_signal devolve o retorno contínuo de 18 barras 4H em cada barra (varia de barra para barra); o gate de confluência discreto reside em should_enter, conforme exigido. O custo por barra é O(1): o ATR usa uma janela fixa de 15 barras e o retorno rápido é uma única leitura indexada, pelo que não há trabalho que escale com o histórico. Uma ressalva honesta para o Analyst: o custo de round-trip em spot é ~0.20% face a ~0.10% no parent em futuros, pelo que a vantagem por trade tem de superar o dobro da fricção — a estrutura de saída de seguimento de tendência (trail + rutura de regime, sem take-profit fixo) é o que torna a duração média suficientemente longa para que isso seja plausível, mas é a métrica a observar em primeiro lugar.

Implementação

LONG-ONLY 1x BTCUSDT spot (BINANCE_SPOT, CASH) confluência de momentum em dois timeframes. 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 de 4H). Ambas as pernas têm de apontar UP para manter BTC; joint-down (onde o parent em futuros vende short) e desacordo significam ambos manter-se 100% USDT. Saídas: stop trailing ATR(14) a 3.033x ATR abaixo do pico em curso da posição, OR a perna diária a inverter para baixo sob o long (rutura de regime de timeframe superior). O dimensionamento é ajustado à volatilidade e relativo ao capital: equity * 1.011% / (3.033 * ATR), limitado a 49.7% do saldo de USDT em nocional, com multiplicador de leverage 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, OHLCV puro, sem dados suplementares, sem shorts.

Resultados da Verificação

Usar self._atr (atual) na comparação do trail de should_exit para corresponder exatamente ao parent, ou indicar 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 face ao parent à mudança de venue.

Resultados da Verificação

O ATR do stop trailing é 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 parent em futuros promovido (BtcDualTimeframeMomentumConfluenceLS4H) ajusta o seu trail com o CURRENT ATR a cada barra. A formulação da hipótese ('stop trailing ATR(14) a 3.033x ATR a partir do extremo em curso') é satisfeita de qualquer forma, e como _extreme é monótono o nível de stop continua apenas a subir, pelo que isto não é um defeito de correção funcional — mas numa expansão de volatilidade após a entrada, o stop efetivo é mais apertado do que o do parent, o que constitui uma diferença comportamental real face à estratégia que se afirma estar a ser portada 'verbatim'.

Resultados da Verificação

Definir o estado do trade a partir do fill (on_order_filled / primeira barra com uma posição aberta) em vez de dentro de should_enter, ou reiniciá-lo defensivamente no topo de calculate_signal antes da consulta da posição.

Resultados da Verificação

should_enter() altera o estado do trade (_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() devolver 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á 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 correção para a correção funcional. 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 guardar 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 de 4H do dia partilham o mesmo timestamp de fecho. Se o motor entregar primeiro a barra primária de 4H, _maybe_process_primary() é executado e regista _last_processed_ts, e a atualização _slow_dir da barra diária (que chega com o mesmo ts) só é consumida a partir da NEXT barra de 4H. Isto é conservador (só pode atrasar um sinal, nunca vazar dados futuros), mas significa que a saída por rutura de regime diário pode disparar até 4 horas depois do 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 aspetos que o analista deve ponderar no histórico completo: (1) o custo de round-trip em spot é de ~0.20% face a ~0.10% do parent em futuros, pelo que a mesma vantagem bruta rende aproximadamente metade — a sandbox já mostra a comissão em 10.03% do bruto; (2) o vetor de parâmetros (fast 18 / slow 15 / trail 3.033) foi selecionado por uma otimização executada num conjunto DIFFERENT de venue, combinação de timeframes e conjunto de direções (LONG/SHORT futuros), pelo que se trata de uma transferência out-of-sample, e não de uma configuração otimizada — o Sharpe da sandbox é 0.527 com sharpe_ci_low -0.233 e information_ratio -0.760 face ao benchmark, ou seja, uma carteira BTC apenas long que tem desempenho inferior a manter BTC na janela de smoke; (3) eliminar a perna short remove aproximadamente metade da população de trades do parent (250 trades, todos long, exposição 43.6%), pelo que o Sharpe realizado deve ficar bem abaixo do 1.99 do parent, em vez de próximo dele. Primeira coisa a verificar no backtest real: avg_trade_return_pct contra o piso spot de 0.25% (a sandbox mostra 0.82%, mas essa janela exclui 2017 e tem apenas 2401 dias) e se o tercil de volatilidade 'normal' (-8.77% na sandbox) se mantém negativo ao longo do histórico completo.

Revisão do Backtest

314 trades fechados 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

Os trades implementam a hipótese: todos 314 LONG / 0 short (colapso CASH correto do LONG/FLAT/SHORT do parent), nocional máximo/equity 0.50 face ao limite 0.497, duração média de posse 4d8h e 43.6% de exposição a reproduzir o parent em futuros.

Revisão do Backtest

avg_trade_return_pct 1.20% face a um round trip de ~0.20% BINANCE_SPOT; comissões apenas 8.97% do bruto, impacto 4.33% — não é marginal em termos de taxas.

Revisão do Backtest

max_drawdown 10.3% (abaixo do default 15% do spot), PF 1.41, payoff 2.07 com uma taxa de acerto de 40.4% (forma de tendência correta), tercil de volatilidade sob stress +28.0%.

Revisão do Backtest

Concentração extrema: o top 10 de 314 trades = 93.8% do retorno somado por trade, top 20 = 141% (trades 21–314 líquido negativo).

Revisão do Backtest

Apenas 6/10 anos civis positivos — exatamente no limiar mínimo — 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 barreira de seleção de ~225 ensaios.

Revisão do Backtest

A preocupação de QA é parcialmente confirmada: o tercil de volatilidade 'normal' mantém-se negativo (−7.70%, 16.1% DD), information_ratio −0.757, alfa apenas +2.4%/ano — tem um desempenho inferior a manter BTC, e benchmark_meaningful=true, pelo que esse défice é real.

Revisão do Backtest

Os parâmetros são uma transferência out-of-sample de outro venue/conjunto de direções — não estão sobreajustados, mas também não foram testados aqui.
Relatório da estratégia

O Stratmill é uma ferramenta de investigação e paper trading, não constitui aconselhamento financeiro nem é uma corretora. Os resultados de backtest e paper trading são hipotéticos. Negociar envolve risco de perda.