BtcSpotDualTimeframeMomentumConfluenceLong
Hipotezy
BTC Spot Dual-Timeframe Momentum Confluence, LONG-ONLY 1x (BTCUSDT.BINANCE_SPOT, 4H Primary + 1D Confirm, tylko Long, gdy BOTH interwały wskazują UP, w przeciwnym razie FLAT do gotówki, wyjście ATR-Trailing + złamanie dziennego reżimu, zachowane parametry zoptymalizowane u źródła)
Hipotezy
Port najlepiej działającej promowanej strategii z fabryki (BtcDualTimeframeMomentumConfluenceLS, Sharpe 1.99, 458 transakcji, +$4,774 w ciągu 29 dni papierowego handlu) na BTCUSDT.BINANCE_SPOT — LONG-ONLY, 1x, konto CASH — stworzony specjalnie jako FIRST LIVE-TRADING CANDIDATE, ponieważ środowisko live jest wyłącznie spotowe. Mechanizm niezmieniony, czysty OHLCV, pojedynczy instrument: noga FAST = znak zwrotu 18-świecowego na świecach 4-HOUR; noga SLOW = znak zwrotu 15-świecowego na świecach DAILY, odczytywana przez on_extra_bar jako noga kontekstowa, nigdy jako bariera synchronizacji. Obie muszą AGREE. Jedyną zmianą strukturalną wymuszoną przez konto CASH jest zwinięcie {LONG/FLAT/SHORT} do {LONG/FLAT}: tam gdzie rodzic na kontraktach terminowych idzie SHORT przy wspólnej konfluencji spadkowej, wersja spot pozostaje 100% USDT. Wszystko inne zachowane dosłownie: trailing stop ATR(14) na poziomie 3.033x ATR od bieżącego ekstremum, wyjście przy złamaniu dziennego reżimu, skalowana zmiennością wielkość pozycji relatywna do kapitału (risk_pct 1.011% / odległość stopu 3.033xATR), limit maksymalnego nominału 49.7%, oraz dokładnie ten sam wektor parametrów wybrany przez optymalizację źródłową (fast_lookback 18, slow_lookback 15, trail_atr_mult 3.033). Trzy parametry strojone, brak danych dodatkowych, brak krótkich pozycji, brak dźwigni. Zmiany kodu specyficzne dla spotu: giełda BINANCE_SPOT CASH (brak mnożnika dźwigni w position_size), size_precision 5 / price_precision 2, min_notional $10, sprzedaże skalowane wyłącznie do posiadanej ilości bazowej. Zweryfikowano obecność danych: BTCUSDT.BINANCE_SPOT świece 4-HOUR i 1-DAY działają nieprzerwanie od 2017-08-17 (~9 lata, ~19,800 świec 4H).
Hipotezy
Bezpośredni port promowanego rodzica na kontraktach terminowych BtcDualTimeframeMomentumConfluenceLS na giełdę spot, ponieważ docelowe środowisko live jest wyłącznie spotowe. Mechanizm zachowany dosłownie: te same dwie nogi momentum, ta sama bramka AGREE-lub-płasko, ten sam trailing stop ATR(14) 3.033x od bieżącego ekstremum, to samo wyjście przy złamaniu dziennego reżimu, ta sama skalowana zmiennością wielkość pozycji risk_pct / odległość stopu z limitem nominału 49.7%, oraz dokładnie ten sam wektor parametrów wybrany przez optymalizację źródłową (fast_lookback 18, slow_lookback 15, trail_atr_mult 3.033). Konto CASH wymusza dokładnie jedną zmianę strukturalną, zgodnie z hipotezą: {LONG,FLAT,SHORT} zwija się do {LONG,FLAT} — should_enter zwraca BUY tylko przy wspólnym wzroście, a w pozostałych przypadkach None, więc wspólny spadek oznacza 100% USDT, a nie pozycję krótką. Zmiany specyficzne dla spotu: giełda BINANCE_SPOT z dźwignią 1.0 i bez członu dźwigni w position_size, size_precision 5 / price_precision 2 (BTCUSDT spot), min_notional podniesiony do $10, a wszystkie wyjścia przekierowane przez mechanizm reduce-only close_position bazowego szablonu, więc SELL może wyłącznie redukować posiadaną ilość bazową (naga krótka pozycja spot jest niemożliwa z konstrukcji, a zabezpieczenie _would_open_spot_short bazowego szablonu nigdy nie jest uruchamiane). calculate_signal zwraca ciągły zwrot 18-świecowy 4H w każdej świecy (zmienia się świeca po świecy); dyskretna bramka konfluencji znajduje się w should_enter, zgodnie z wymogiem. Koszt na świecę wynosi O(1): ATR używa stałego okna 15-świecowego, a szybki zwrot to pojedyncze wyszukanie indeksowane, więc nie ma pracy skalującej się z historią. Jedno szczere zastrzeżenie dla Analityka: koszt round-trip na spocie wynosi ~0.20% wobec ~0.10% na rodzicu kontraktów terminowych, więc przewaga na transakcję musi pokryć dwukrotnie wyższe tarcie — struktura wyjścia typu trend-following (trailing + złamanie reżimu, brak stałego take-profit) sprawia, że średni czas utrzymania pozycji jest na tyle długi, by to było prawdopodobne, ale to jest metryka, którą należy obserwować w pierwszej kolejności.
Implementacja
LONG-ONLY 1x BTCUSDT spot (BINANCE_SPOT, CASH) — konfluencja momentum na dwóch interwałach czasowych. Noga FAST = znak zwrotu 18-świecowego na świecach 4-HOUR (główny interwał); noga SLOW = znak zwrotu 15-świecowego na świecach 1-DAY, odczytywana przez on_extra_bar jako noga kontekstowa wolniejszego interwału (inny interwał czasowy, więc bariera wyrównania nóg bazowego szablonu nigdy nie opóźnia sygnału 4H). Obie nogi muszą wskazywać UP, aby utrzymać BTC; wspólny spadek (gdzie rodzic na kontraktach terminowych idzie krótko) oraz brak zgodności oznaczają utrzymanie 100% USDT. Wyjścia: trailing stop ATR(14) na poziomie 3.033x ATR poniżej bieżącego szczytu pozycji, OR złamanie w dół nogi dziennej pod pozycją długą (złamanie reżimu wyższego interwału). Wielkość pozycji jest skalowana zmiennością i relatywna do kapitału: equity * 1.011% / (3.033 * ATR), z limitem 49.7% salda USDT w nominale, bez mnożnika dźwigni NO (konto CASH nie może pożyczać), kwantyzowana do size_precision 5 i odrzucana poniżej minimalnego nominału spot $10. Trzy parametry strojone, czysty OHLCV, brak danych dodatkowych, brak krótkich pozycji.
Wyniki weryfikacji
Albo użyć self._atr (bieżącego) w porównaniu trailingu should_exit, aby dokładnie odpowiadało rodzicowi, albo wyraźnie zaznaczyć w opisie, że trailing jest zakotwiczony w ATR ze świecy wejścia, tak by analityk nie przypisał rozbieżności z rodzicem zmianie giełdy.
Wyniki weryfikacji
ATR trailing stopu jest FROZEN przy wejściu (self._entry_atr, zapisywane w should_enter / przy przejęciu pozycji) i nigdy nie odświeżane, więc odległość trailingu jest 3.033 x ATR-przy-wejściu, a nie 3.033 x bieżącym ATR(14). Promowany rodzic na kontraktach terminowych (BtcDualTimeframeMomentumConfluenceLS4H) podciąga swój trailing wraz z CURRENT ATR co świecę. Sformułowanie hipotezy ('trailing stop ATR(14) na poziomie 3.033x ATR od bieżącego ekstremum') jest spełnione w obu przypadkach, a ponieważ _extreme jest monotoniczne, poziom stopu nadal wyłącznie rośnie, więc nie jest to defekt poprawności — ale przy ekspansji zmienności po wejściu efektywny stop jest ciaśniejszy niż u rodzica, co stanowi realną różnicę behawioralną wobec strategii, która ma być portowana 'dosłownie'.
Wyniki weryfikacji
Ustawić stan transakcji na podstawie wykonania (on_order_filled / pierwsza świeca z otwartą pozycją), a nie wewnątrz should_enter, lub zresetować go zapobiegawczo na początku calculate_signal przed sprawdzeniem pozycji.
Wyniki weryfikacji
should_enter() zmienia stan transakcji (_in_long = True, _extreme, _entry_atr) BEFORE bazowy szablon wyznaczy wielkość zlecenia i zastosuje bramkę minimalnego nominału. Jeśli position_size() zwróci 0 lub kontrola minimalnego nominału $10 odrzuci wejście, strategia pozostaje oznaczona jako in-long z uzbrojonym trailingiem, będąc jednocześnie płaska. W praktyce samo się naprawia na kolejnej świecy (calculate_signal widzi, że pozycja to None, i resetuje flagi, a should_exit nigdy nie jest osiągane, gdy jest się płaskim), więc nie ma obserwowalnego błędu behawioralnego — jednak ten niezmiennik jest kruchy, jeśli ścieżka wyjścia zostanie kiedykolwiek zmieniona.
Wyniki weryfikacji
Poprawka nie jest wymagana dla poprawności. Jeśli pożądane jest dokładnie takie samo zużycie w ramach tej samej świecy, należy przeliczać _slow_dir leniwie z self._extra_bars[...] wewnątrz calculate_signal zamiast buforować go w on_extra_bar.
Wyniki weryfikacji
Opóźnienie jednej świecy na nodze dziennej: świeca DAILY i ostatnia świeca 4H dnia mają ten sam znacznik czasu zamknięcia. Jeśli silnik dostarczy najpierw główną świecę 4H, uruchamia się _maybe_process_primary() i zapisuje _last_processed_ts, a aktualizacja _slow_dir świecy dziennej (przychodząca z tym samym ts) jest uwzględniana dopiero z NEXT świecy 4H. Jest to podejście konserwatywne (może jedynie opóźnić sygnał, nigdy nie ujawnić przyszłych danych), ale oznacza, że wyjście przy złamaniu dziennego reżimu może zadziałać nawet do 4 godzin po dziennym zamknięciu w około połowie przypadków, a zgodność między backtestem a handlem papierowym zależy od stabilności kolejności dostarczania danych.
Wyniki weryfikacji
Wierna implementacja, ale trzy kwestie, które analityk powinien rozważyć na pełnej historii: (1) koszt round-trip na spocie wynosi ~0.20% wobec ~0.10% rodzica na kontraktach terminowych, więc ta sama przewaga brutto netto daje mniej więcej połowę — sandbox pokazuje już prowizję na poziomie 10.03% brutto; (2) wektor parametrów (szybki 18 / wolny 15 / trailing 3.033) został wybrany przez proces optymalizacji na DIFFERENT giełdzie, mieszance interwałów czasowych i zestawie kierunków (LONG/SHORT kontrakty terminowe), więc jest to transfer out-of-sample, a nie zoptymalizowana konfiguracja — Sharpe w sandboxie wynosi 0.527 przy sharpe_ci_low -0.233 i information_ratio -0.760 wobec benchmarku, tj. book wyłącznie długi na BTC, który osiąga gorsze wyniki niż utrzymywanie BTC w oknie testowym; (3) usunięcie nogi krótkiej eliminuje mniej więcej połowę populacji transakcji rodzica (250 transakcji, wszystkie długie, ekspozycja 43.6%), więc zrealizowany Sharpe powinien być wyraźnie niższy od 1.99 rodzica, a nie zbliżony do niego. Pierwsza rzecz do sprawdzenia w rzeczywistym backteście: avg_trade_return_pct wobec progu spot 0.25% (sandbox pokazuje 0.82%, ale to okno wyklucza 2017 i liczy jedynie 2401 dni) oraz czy tercyl 'normalnej' zmienności (-8.77% w sandboxie) pozostaje ujemny na pełnej historii.
Przegląd backtestu
314 zamkniętych transakcji na przestrzeni 3146 dni (2017-08 → 2026-03), metrics_reliable=true, entry_diag 314/314 zleceń złożonych, 0 odrzuconych.
Przegląd backtestu
Transakcje realizują hipotezę: wszystkie 314 LONG / 0 krótkie (poprawne zwinięcie CASH LONG/FLAT/SHORT rodzica), maksymalny nominał/kapitał 0.50 wobec limitu 0.497, średni czas utrzymania 4d8h oraz ekspozycja 43.6% odwzorowująca rodzica na kontraktach terminowych.
Przegląd backtestu
avg_trade_return_pct 1.20% wobec round trip ~0.20% BINANCE_SPOT; prowizje to zaledwie 8.97% brutto, wpływ 4.33% — nie jest marginalny opłatowo.
Przegląd backtestu
max_drawdown 10.3% (poniżej domyślnego spot 15%), PF 1.41, wypłata 2.07 przy współczynniku trafień 40.4% (poprawny kształt trendu), tercyl zmienności podwyższonej +28.0%.
Przegląd backtestu
Ekstremalna koncentracja: górne 10 z 314 transakcji = 93.8% sumy zwrotów na transakcję, górne 20 = 141% (transakcje 21–314 netto ujemne).
Przegląd backtestu
Tylko 6/10 lata kalendarzowe dodatnie — dokładnie na twardym progu minimalnym — a oba ostatnie lata ujemne (2025 −10.5%, 2026 −9.9%).
Przegląd backtestu
Sharpe 0.664 przy sharpe_ci_low 0.0042 i PSR 0.924 (<0.95): już marginalny przed progiem selekcji obejmującym ~225 prób.
Przegląd backtestu
Obawa QA częściowo potwierdzona: tercyl 'normalnej' zmienności pozostaje ujemny (−7.70%, 16.1% DD), information_ratio −0.757, alfa wynosi zaledwie +2.4%/rok — strategia osiąga gorsze wyniki niż utrzymywanie BTC, a ponieważ benchmark_meaningful=true, ten niedobór jest realny.
Przegląd backtestu
Parametry są transferem out-of-sample z innej giełdy/zestawu kierunków — nie są dostrojone, a nie przeoptymalizowane, ale też nie zostały tu przetestowane.
Stratmill to narzędzie do badań i handlu na papierze (paper trading), a nie doradztwo finansowe ani broker. Wyniki backtestów i paper tradingu mają charakter hipotetyczny. Handel wiąże się z ryzykiem straty.