Backtesting i forward testing — metodologia i pułapki testowania
Backtest, na którym strategia zarabia 280% rocznie, jest najczęściej zmyśleniem — nie z premedytacją, lecz przez błędy metodologiczne, których tester sam nie widzi. Look-ahead bias, survivorship, curve fitting, niedomodelowane koszty, dobór okna danych, optymalizacja parametrów na całym zbiorze, ignorowanie reżimu rynkowego — każdy z tych grzechów potrafi sam jeden zamienić tracącą strategię w pozornego zwycięzcę. W profesjonalnych procesach walidacyjnych pojedynczy backtest nigdy nie wystarcza — strategia przechodzi walk-forward, Monte Carlo bootstrap, out-of-sample i 30–90 dniowy forward test na demo z realnym strumieniem ticków, zanim dotknie kapitału. Detal powinien skopiować zasadę, nie skalę infrastruktury. W tym artykule rozkładamy całą metodologię — z konkretnymi progami statystycznymi, przykładowym kodem Pythona do bootstrapu (z instrukcją odpalenia w Google Colab), modelem kosztów dla MT4/MT5, regułą reconciliation backtest vs forward i listą 8 pułapek, które najczęściej zamieniają dobry backtest w stratny live w pierwszym kwartale po wdrożeniu.
- Backtest odpowiada na pytanie „czy strategia mogła zarabiać w przeszłości", forward test odpowiada na pytanie „czy zarabia teraz". To dwa różne testy z dwoma różnymi pułapkami — żaden nie zastąpi drugiego
- Sześć pułapek metodologicznych: look-ahead bias, survivorship, curve fitting / overfitting, cherry picking instancji, niedomodelowane koszty i data snooping. Każda potrafi sama zamienić tracący system w pozornego zwycięzcę
- Walk-forward analysis to standard branżowy: in-sample 70% danych do kalibracji, out-of-sample 30% do walidacji, okno przesuwane krokiem. Bez tego optymalizujesz na szumie historycznym
- Próg statystyczny: N = 30 transakcji to za mało (przedział ufności WR ±15 pp), N = 200 daje ±5 pp, N = 500 daje ±3 pp. Strategia z 24 trade'ami w backteście to nadzieja, nie dowód
- Forward test minimum 30 dni demo przed mikrokontem live i 90 dni mikrokonta przed pełnym sizingiem. To nie są liczby do pełnej walidacji statystycznej — to minimum operacyjne, żeby wykryć największe dziury: rozjazd sygnałów, koszty egzekucji, awarie alertów i błędy człowieka pod realnym ryzykiem
1. Backtest vs forward test — różne pytania, różne odpowiedzi
Większość początkujących robi jeden błąd: po dobrym backteście uznaje, że strategia jest gotowa. Nie jest. Backtest sprawdza historię, forward sprawdza wykonanie tu i teraz. W praktyce to są dwa różne filtry: backtest łapie statystykę, forward łapie realną egzekucję, opóźnienia, poślizg i to, czy trader faktycznie klika zgodnie z regułami. Pomylenie ról oznacza, że jeden test próbujesz zastąpić drugim — i tracisz informację, którą tylko ten drugi potrafiłby ci dać.
Backtest — pytanie historyczne
Backtest pyta: „Gdyby strategia działała przez ostatnie 3–10 lat, jak by się zachowała?". Odpowiedź jest tak dobra, jak jakość danych i jakość modelu kosztów. Backtest jest retrospektywny — patrzy w przeszłość, więc:
- Jest szybki — możesz przetestować 5 lat danych w 10 minut
- Daje dużą próbę — kilkaset, kilka tysięcy transakcji
- Pozwala porównać warianty parametrów — ale to jednocześnie jego największa pułapka (overfitting)
- Jest wrażliwy na jakość danych — błędne ticki, brakujące świece, wadliwy model kosztów = wynik bezwartościowy
Backtest nie odpowiada na pytanie, czy strategia działa teraz. Reżim rynkowy z 2018–2022 może nie istnieć w 2024–2026. Strategia, która świetnie zarabiała na trendach JPY z lat 2012–2015, nie zarabia w środowisku QE plus interwencji BOJ.
Forward test — pytanie prospektywne
Forward test pyta: „Czy strategia zarabia teraz, w obecnym reżimie, na realnych warunkach egzekucji?". Jest prospektywny — patrzy w przyszłość, dane spływają w czasie rzeczywistym, więc:
- Jest powolny — żeby zebrać 100 transakcji przy 5 trade'ach tygodniowo, potrzebujesz 5 miesięcy
- Daje mniejszą próbę — większość forward testów detalu kończy się na 30–80 transakcjach
- Eliminuje look-ahead bias z definicji — danych z przyszłości fizycznie nie ma
- Mierzy realne warunki egzekucji — spread w stresie, slippage, requote, opóźnienia mostka
- Mierzy poślizg ludzki — fat-finger, paraliż decyzyjny, manualne interwencje na otwartej pozycji w warunkach stresu rynkowego
Forward test nie odpowiada na pytanie, czy strategia ma długoterminową przewagę — próba jest za mała. Odpowiada na pytanie, czy nie ma fundamentalnej dziury między backtestem a realem.
Czego nie wykryje backtest, czego nie wykryje forward
| Klasa błędu | Wykrywa backtest? | Wykrywa forward? |
|---|---|---|
| Look-ahead bias (dane z przyszłości w decyzji) | Nie — to jest źródło iluzji | Tak — dane z przyszłości fizycznie niedostępne |
| Curve fitting parametrów | Częściowo — tylko walk-forward | Częściowo — ujawnia się dopiero po wystarczającym N lub zmianie reżimu (krótki forward sam może trafić w korzystną wariancję) |
| Niedomodelowane koszty (slippage, requote) | Częściowo — zależy od jakości modelu | Tak — koszty realne są mierzone bezpośrednio |
| Zmiana reżimu rynkowego od czasu danych historycznych | Nie — operuje na starych danych | Tak — operuje na obecnym reżimie |
| Niewykonalność reguł przez tradera (dyscyplina) | Nie — backtest zakłada idealne wykonanie | Tak — realny człowiek przy klawiaturze |
| Statystyczna zdarzeniowość edge'u (jakieś N=300+ wymagane) | Tak — backtest dostarcza dużej próby | Nie — forward przy 5 trade'ach tygodniowo daje N=80 w pół roku |
| Drawdown w długim horyzoncie (3+ lata, kilka cykli) | Tak — backtest na 5 lat to kilka cykli | Nie — forward to zwykle 1 cykl rynkowy |
Bez backtestu nie masz próby. Bez forwardu nie wiesz, czy twój backtest nie był fikcją kosztową albo efektem repaintującego wskaźnika. W praktyce traderzy pomijają forward test częściej niż backtest — bo forward to 90 dni czekania, a backtest daje wyniki w 10 minut. To jest dokładnie ten moment, w którym tracą kapitał, który backtest „zaoszczędził".
Reconciliation backtest vs forward — procedura kontrolna
Najmocniejszy detektor look-ahead bias i błędów feedu danych: porównanie sygnał po sygnale. Eksport z backtestu i z forwardu w jednolitym formacie CSV:
timestamp_utc, broker_server_time, pair, setup_id, direction, entry_rule_hash,
entry_price, sl_price, tp_price, trigger_bar_close, source
Pierwsze 30–60 dni forwardu generuje sygnały na realnych świecach. W tym samym oknie odpalasz backtest na archiwalnych danych z tych dni. Porównujesz oba pliki: rozjazd > 5–10% sygnałów = alarm. Możliwe przyczyny: look-ahead w indykatorze, repaint, inny feed danych, błąd w kodzie strategii (np. dostęp do Close[0] intrabar). Strategia, która produkuje 50 sygnałów w backteście i 12 w forwardzie na tych samych dniach, ma fundamentalną dziurę i nie idzie dalej, dopóki diagnoza nie jest jednoznaczna.
timestamp_utc, jak i broker_server_time. Część brokerów MT4/MT5 używa czasu serwera GMT+2/GMT+3 z przesunięciem DST (zwykle dopasowanym do New York close, czyli 5 PM ET). Jeśli porównasz sygnały bez normalizacji czasu, wykryjesz „look-ahead", którego nie ma — bo testujesz inne świece niż te, na których działa twój EA. Zawsze najpierw normalizuj do UTC, potem porównuj.2. Pułapki testowania — look-ahead, survivorship, curve fit, overfitting
Te pułapki są metodologiczne, nie poznawcze. Oznacza to, że nie chodzi o to, że tester jest naiwny lub leniwy — chodzi o to, że narzędzia testowe (MT4 Strategy Tester, MT5, własne skrypty) same wpuszczają błędy, jeśli tester nie wie, czego szukać. Pułapki poznawcze (confirmation bias, hindsight) opisujemy w dziale 10; tu skupiamy się na technicznych dziurach metody.
Pułapka 1: Look-ahead bias
Strategia w trakcie świecy używa danych, które stałyby się znane dopiero po jej zamknięciu. Najczęstsze warianty:
- Decyzja w trakcie świecy na podstawie close. Strategia oblicza SMA-20 z 20 ostatnich świec łącznie z bieżącą i wchodzi „gdy świeca M5 zamknie się powyżej". W realu: w sekundzie 240 świecy M5 nie wiesz jeszcze, jak się zamknie. W backteście MT4 z modelem „Open prices only" — wiesz, bo silnik daje ci close jako fakt
- Indykator z look-back rounding. ZigZag, Fractals, Andrews Pitchfork, niektóre warianty Donchiana — odświeżają się retrospektywnie. Świeca, która 10 dni temu była zaznaczona jako swing high, może dziś nie być nim, gdy zaszły nowe dane. Tester widzi w danych „swing high" w t = -10 i zakłada, że trader też go widział — nie widział, bo wtedy nie był on jeszcze swing highem
- Dane fundamentalne z opóźnieniem publikacji. CPI za marzec publikowane jest 12 kwietnia, ale w bazie danych ma datę „marzec". Strategia, która używa „CPI z marca w decyzjach z 1 kwietnia", używa danych, których wtedy nie było
Detekcja: uruchom strategię na realtime data feed (forward test) i porównaj wygenerowane sygnały z tymi, które backtest wskazałby na tych samych świecach (procedura reconciliation z sekcji 1). Jeśli backtest generuje więcej sygnałów lub generuje je w innych miejscach — masz look-ahead.
Lista konstrukcji wymagających testu antyrepaint w MT4/MT5:
- ZigZag, Fractals, Andrews Pitchfork — z definicji odświeżają się retrospektywnie, wpisane w architekturę narzędzia
- Heikin-Ashi, SuperTrend, Hull MA i customowe kanały nie są z definicji oszustwem — ale każda implementacja z MQL Market albo TradingView musi przejść test antyrepaint przed użyciem w backteście. Problemem nie jest nazwa wskaźnika, tylko to, czy jego sygnał na zamkniętej świecy pozostaje niezmienny po dopłynięciu kolejnych świec
- Custom indicators z MQL Market bez kodu źródłowego — czarna skrzynka, której nie można zwalidować, automatyczne odrzucenie
iCustom()bez kontroli bufora — czytanie wartości z bufora wskaźnika, który mógł zostać przeliczony- Decyzje intrabar na
Close[0]w MT4 — w realuClose[0]w trakcie świecy to bieżąca cena bid, nie cena zamknięcia, której nie ma jeszcze w naturze - Dane makro z datą okresu zamiast datą publikacji — CPI „za marzec" w bazie z datą 2024-03-01 zamiast 2024-04-12
Test antyrepaint w 60 sekund (do wykonania w MT4): uruchom indykator na żywo, zapisz wartość dla bary t = -10 (np. wartość ZigZag 10 świec wstecz). Poczekaj 5 nowych świec. Sprawdź wartość bary t = -15 (ta sama świeca, teraz przesunięta o 5). Jeśli wartość się zmieniła — wskaźnik repaintuje i każdy backtest na nim jest fikcją. Test trwa minutę, oszczędza miesiące pracy nad strategią opartą na fałszywym sygnale.
Close[0] w trakcie świecy. Repaintujący kod „wiedział" o odwróceniu trendu, zanim to nastąpiło. Sam koncept Heikin-Ashi nie jest patologiczny — patologiczna była ta konkretna implementacja, której nie zwalidowano testem antyrepaint przed backtestem. Wypalił połowę kapitału testowego w tydzień przez jedną wadę kodu, której test antyrepaint by wykrył w minutę. Procedura reconciliation backtest vs forward zatrzymałaby live'a po pierwszych 5 sygnałach z rozjazdu > 50%.Pułapka 2: Survivorship bias
Testujesz strategię na koszyku par walutowych z 2024 r. — EUR/USD, USD/TRY, GBP/JPY, USD/RUB itp. Backtest pokazuje świetne wyniki na USD/RUB w 2018 r. Problem: USD/RUB jako para handlowalna w retail praktycznie zniknął po 2022 r. Strategia, która „działa" głównie na danych historycznych USD/RUB, ma dziś ograniczoną wartość operacyjną — bo dostępność handlu, płynność i warunki egzekucji po 2022 r. są zupełnie inne.
Drugi wariant: testujesz EA z marketplace'u, który ma 5 gwiazdek i 200 pozytywnych opinii. Survivorship bias: setki EA z 1 gwiazdką, które przegrały konta swoich klientów, zniknęły z marketplace'u. Widzisz tylko tych, którzy przeżyli pierwsze 3 miesiące — ale kupujesz strategię, która ma średnio taką samą szansę przeżycia jak każda inna na starcie.
Detekcja: w testach koszyka par używaj listy par aktywnych dziś, nie listy historycznej. W ocenie EA z marketplace'u sprawdzaj jego datę publikacji i wymagaj minimum 3 lat historii produktu z aktywną sprzedażą.
Pułapka 3: Curve fitting (dopasowanie do krzywej)
Testujesz strategię z parametrami SMA-20 vs SMA-22 vs SMA-25 vs SMA-30, RSI(11) vs RSI(14) vs RSI(17), próg ATR od 0,8 do 1,5 z krokiem 0,1. Łącznie 4 × 3 × 8 = 96 kombinacji. Z czystego przypadku jakaś kombinacja wygeneruje świetne wyniki w backteście — to jest matematyka, nie talent strategii.
Klasyczny przykład: trader testuje 96 kombinacji parametrów, wybiera najlepszą (SMA-22, RSI-14, ATR 1,1), backtest pokazuje +180% w 3 lata. Forward test 60 dni: −8%. Co się stało? Strategia była dopasowana do szumu historycznego, nie do edge'u. Każda kombinacja parametrów to 96-elementowa loteria, w której pojedyncza wygrana w backteście nie świadczy o przewadze — świadczy o tym, że losowałeś 96 razy.
Detekcja: wykres heatmapy parametrów. Jeśli optymalne parametry to izolowany szczyt, otoczony słabymi wynikami — strategia jest curve-fittowana. Jeśli optimum to plateau (wiele kombinacji okolicznych daje podobnie dobre wyniki) — strategia ma robust edge.
Pułapka 4: Overfitting (przeuczenie)
Curve fitting to overfitting na poziomie parametrów. Pełen overfitting to dodawanie reguł i filtrów do strategii w odpowiedzi na konkretne stratne trade'y w backteście. „Dodaję filtr: nie wchodzę we wtorki po 14:00 PL" — bo dwa stratne trade'y w backteście były we wtorki po 14:00. Z perspektywy backtestu wynik się poprawia. Z perspektywy realu ten filtr nie ma sensu — to dopasowanie do dwóch instancji szumu.
Nie wolno dodawać filtra tylko dlatego, że trzy stratne transakcje w historii były w piątek. Filtr musi istnieć przed testem i mieć logiczny powód poza tym, że poprawia equity curve. Reguły dodawane ex post w odpowiedzi na konkretne stratne trade'y są overfittingiem na szumie.
Twarda zasada ilościowa: jeśli optymalizujesz więcej niż 4 niezależne parametry na próbie mniejszej niż 200 trade'ów, overfitting jest bazowym założeniem audytowym — traktujesz strategię jako przeuczoną, dopóki OOS, walk-forward i stabilna heatmapa nie udowodnią inaczej. Reguła robocza dla detalu: liczba optymalizowanych parametrów × 30 ≤ liczba trade'ów w próbie. Strategia z 4 parametrami wymaga minimum 120 trade'ów. Z 8 parametrami — 240+. Poniżej tego nie testujesz strategii, tylko ją rzeźbisz.
Pułapka 5: Niedomodelowane koszty
MT4 Strategy Tester domyślnie używa fixed spreadu (np. 1,0 pipsa na EUR/USD przez całe 5 lat). Realność: spread na EUR/USD oscyluje od 0,3 pipsa w pełnej płynności LON+NY do 4–8 pipsów w godzinach rolloveru i 8–25 pipsów w pierwszej minucie po publikacjach makro. Strategia, która działa intraday w godzinach 21:00–06:00 (rollover, niska płynność), w fixed spread teście pokazuje zysk; w realnym środowisku z variable spreadem traci.
Drugi wymiar: slippage. Backtest zakłada egzekucję dokładnie po cenie z bazy danych. Real: slippage 0,2–0,5 pipsa w normalnych warunkach, 1–3 pipsy na breakoutach, 5–15 pipsów po publikacjach. Strategia z expectancy +0,3R brutto może mieć w realu +0,1R netto — i nie wiesz tego z backtestu, jeśli nie modelowałeś slippage'u.
Trzeci: swap (cost of carry). Strategia swing trzymająca pozycje 3–8 dni płaci swap codziennie. Long EUR/USD ma zwykle ujemny swap (płacisz różnicę stóp). Strategia z expectancy +0,4R za trade, gdzie typowy trade trwa 5 dni, traci 5 × 0,15R kosztu swapu = 0,75R, czyli więcej niż jej brutto edge.
Czwarty: prowizja. Konta ECN (zwykle wymagane dla strategii skalpujących) mają komisję 5–7 USD per lot per RT. Przy 0,1 lota i 200 trade'ach miesięcznie: 200 × 0,1 × 6 = 120 USD komisji miesięcznie, czyli 12% od kapitału 1000 USD. Backtest bez modelowania prowizji jest bezwartościowy dla skalperów.
Pułapka 6: Data snooping (przeszukiwanie danych)
Bardziej subtelna wersja curve fittingu. Tester przegląda 30 strategii, odrzuca 28, które nie działają, publikuje 2, które działają w backteście. Z czystego przypadku przy 30 testach jakieś 2–3 strategie wyjdą dobrze. Tester nie kłamie — jego backtest tych 2 strategii jest poprawny. Ale prawdopodobieństwo, że któraś działa w realu, jest niemal zerowe — bo prawdopodobnie wybrał statystyczne anomalie z 30 prób.
Akademicka korekta: Bonferroni — przy 30 testach próg p-value powinien być 0,05/30 = 0,00167 zamiast 0,05. Detal o tym nie myśli, bo nie liczy ile strategii odrzucił przed tą jedną.
Detekcja: prowadź dziennik wszystkich testowanych strategii z wynikami. Jeśli z 30 testowanych 2 wyszły dobrze, traktuj te 2 z większym sceptycyzmem niż gdyby były 1. lub 2. testem.
3. Walk-forward analysis — jak walidować z małą próbką
Walk-forward analysis (WFA) to standard branżowy walidacji strategii — opisany m.in. przez Roberta Pardo w The Evaluation and Optimization of Trading Strategies[2]. Idea: zamiast optymalizować parametry na całych danych historycznych, dzielimy je na okno in-sample (IS) i out-of-sample (OOS), optymalizujemy na IS, walidujemy na OOS, a następnie przesuwamy okno do przodu i powtarzamy.
Standardowy schemat 70/30
Najprostsza wersja:
- Dane łączne: 5 lat (2020-01-01 do 2024-12-31)
- In-sample: 70% = 3,5 roku (2020-01-01 do 2023-06-30) — kalibrujesz parametry tutaj
- Out-of-sample: 30% = 1,5 roku (2023-07-01 do 2024-12-31) — testujesz raz na tych danych z parametrami z IS
Reguła żelazna: parametrów nie wolno dotykać po teście OOS. Jeśli OOS daje słabe wyniki i wracasz do IS żeby „doszlifować", po czym retestujesz OOS — właśnie zmieniłeś OOS w drugi IS, czyli zoptymalizowałeś na całym zbiorze danych. Pełen overfitting.
Walk-forward kroczący — wersja zaawansowana
Pojedynczy podział 70/30 ma wadę — jeden konkretny okres OOS może być niereprezentatywny (akurat trafił w wyjątkowo trudny lub łatwy reżim). Walk-forward kroczący naprawia to przesuwając okno:
| Krok | In-sample (kalibracja) | Out-of-sample (test) |
|---|---|---|
| 1 | 2020-01 do 2022-12 (3 lata) | 2023-01 do 2023-06 (6 miesięcy) |
| 2 | 2020-07 do 2023-06 (3 lata) | 2023-07 do 2023-12 (6 miesięcy) |
| 3 | 2021-01 do 2023-12 (3 lata) | 2024-01 do 2024-06 (6 miesięcy) |
| 4 | 2021-07 do 2024-06 (3 lata) | 2024-07 do 2024-12 (6 miesięcy) |
Każdy krok ma własne IS i OOS. Sumarycznie testujesz strategię na 4 niezależnych oknach OOS pokrywających 2 lata. Statystyka: jeśli strategia działa w 3–4 z 4 okien, masz kandydata na przewagę odporną na zmianę próbki (robust edge) — pod warunkiem, że każde okno ma sensowne N i dodatnią expectancy po kosztach. Jeśli działa w 1–2 — strategia jest reżimowo wrażliwa, może działać w przyszłości tylko w niektórych warunkach. Jeśli działa w 0–1 — strategia jest fikcją.
Walk-forward dla swing tradera z małą próbką
Swing trader z 5–10 trade'ami miesięcznie ma w 5 latach 300–600 trade'ów. Przy podziale 70/30 OOS ma 90–180 trade'ów — wystarczająco do statystycznej wypowiedzi. Day trader z 50–100 trade'ami miesięcznie ma 3000–6000 trade'ów w 5 lat — luksus statystyczny.
Position trader z 1–2 trade'ami miesięcznie ma 60–120 trade'ów w 5 lat. Przy 70/30 OOS ma 18–36 trade'ów — to za mało na poważną walidację. Rozwiązania:
- Dłuższy zakres danych (10–15 lat zamiast 5) — daje 120–360 trade'ów łącznie, OOS 36–108
- Multi-asset — testowanie na 6–10 par walutowych jednocześnie zwielokrotnia próbę
- Block bootstrap (Monte Carlo na blokach trade'ów) — sztuczne mnożenie próby z zachowaniem korelacji czasowych — patrz sekcja 4
Zamrożenie OOS — folder structure i hash konfiguracji
Najczęstsze samosabotowanie WFA: trader testuje OOS, widzi słaby wynik, „dostosowuje" parametry na IS i retestuje OOS. To nie jest walk-forward — to optymalizacja na całym zbiorze danych. Praktyka, która eliminuje ten błąd na poziomie procesu:
- Folder projektu ma trzy katalogi:
01_raw_data,02_IS_optimization,03_OOS_locked - Po pierwszym uruchomieniu OOS zapisujesz hash konfiguracji strategii (parametry, kod, model kosztów, zakres dat) w pliku
03_OOS_locked/run_001.lock - Każda kolejna zmiana parametrów wymaga nowego pliku
run_002.locki oznacza poprzedni test jakotainted(skażony) - Liczba czystych uruchomień na tym samym oknie OOS = 1. Kolejne uruchomienie po zmianie parametrów oznacza, że to okno przestaje być dziewiczym OOS — staje się drugim IS. Walk-forward windows planujesz z góry, każde traktujesz jako osobne OOS
Co zrobić, gdy OOS wypada słabo
Po słabym OOS nie wolno dopisywać filtra, bo boli wynik. To najprostszy sposób, żeby zamienić walidację w dekorowanie trupa. Sekwencja decyzyjna:
- Zaakceptuj wynik — strategia w obecnej formie nie ma walidacji
- Wróć do koncepcji — przejrzyj sekcję 1 (hipoteza), 2 (logika), 3 (edge) z artykułu 15.3 (Budowanie strategii). Sprawdź, czy hipoteza nadal jest sensowna w obecnym reżimie
- Jeśli koncepcja stoi — może to być reżimowa wrażliwość. Testuj walk-forward kroczący na 4–6 oknach. Jeśli strategia działa w 2 z 6 okien w trendzie i nie działa w 4 oknach konsolidacji — masz strategię trend-following, której nie ma w obecnym reżimie. Trzymasz ją w playbooku, włączasz, gdy wraca trend. Warunek dodatkowy: w każdym z „działających" okien musi być co najmniej 30 trade'ów i dodatnia expectancy po kosztach. 3 z 4 okien po 8 trade'ach każde to nie jest dowód, to nadzieja
- Jeśli koncepcja upada — strategia ginie, idziesz do następnego pomysłu
4. Monte Carlo na backteście — dlaczego jeden backtest to za mało
Backtest pokazuje jedną realizację historii. Strategia z 100 trade'ami w backteście miała 100 konkretnych okazji wejścia w 5 lat — gdyby historia toczyła się minimalnie inaczej, miałaby 95 lub 110, w innych miejscach, z innymi wynikami. Pojedynczy backtest jest jak pojedynczy rzut kostką — mówi ci coś, ale nie wszystko o rozkładzie wyników.
Monte Carlo na backteście symuluje, jak strategia mogłaby zachować się w alternatywnych historiach. Daje rozkład zamiast pojedynczej wartości — i ten rozkład pokazuje, jak duże jest realne ryzyko, którego pojedynczy backtest nie pokazuje.
Dwie podstawowe metody
Bootstrap trade'ów (sequence randomization): bierzesz listę 200 wyników trade'ów (np. +1,5R, −1R, +2,2R, −1R, +0,8R, ...) i losujesz z powtórzeniami 200 trade'ów do nowej historii. Powtarzasz 1000 razy. Dostajesz 1000 alternatywnych equity curve.
Block bootstrap: ten sam pomysł, ale losujesz bloki kolejnych trade'ów (np. po 10 trade'ów na raz). Zachowuje korelacje czasowe (volatility clustering — strata zwykle ciągnie za sobą stratę). Dla strategii FX block bootstrap z bloku 10–20 trade'ów jest realniejszy niż naiwny bootstrap pojedynczych trade'ów.
Co liczysz z 1000 alternatywnych historii
- Mediana zwrotu rocznego — środek rozkładu, lepsze niż wartość z pojedynczego backtestu
- Percentyl 5% — w 5% scenariuszy zwrot będzie tak słaby lub gorszy. To twój worst-realistic-case
- Maksymalny drawdown w percentylu 95% — w 5% scenariuszy DD będzie tak duży lub większy. Czy psychologicznie i kapitałowo wytrzymasz?
- Probability of ruin — w ilu % scenariuszy konto spadło poniżej progu (np. −30%)
Praktyczny przykład: backtest pokazuje +45% rocznie, max DD −12%. Monte Carlo bootstrap (1000 symulacji): mediana +38%, 5. percentyl +8%, 95. percentyl max DD −22%, probability of ruin (DD > 30%) = 4%. Interpretacja: strategia rzeczywiście ma dodatnią wartość oczekiwaną, ale w 1 na 25 scenariuszy DD przekroczy 30% — czy jesteś gotów emocjonalnie i kapitałowo?
Definicje metryk — pełen panel kontrolny
Zanim wejdziesz w kod, ustal jednoznaczne definicje. Bez tego masz wyniki, ale nie panel kontrolny:
- expectancy_R = mean(R) — średnia wartość transakcji w R (wypadkowa win rate i avg R per win/loss)
- profit_factor = Σ zysków / |Σ strat| — > 1,3 dla zdrowego systemu, < 1,1 niestabilny
- SQN (Van Tharp) = √N × mean(R) / std(R) — interpretacja: > 1,6 akceptowalny, > 2,5 dobry, > 3,0 doskonały (rzadkie u retaila, podejrzewaj overfitting jeśli próba mała)
- maxDD_pct = (1 − min(equity)/peak(equity)) × 100% — w procentach kapitału
- maxDD_duration — liczba trade'ów lub dni od szczytu equity do nowego szczytu
- recovery_factor = total_return / maxDD_pct — ile DD zwracasz w czasie życia strategii
Skrypt Pythona — block bootstrap dla strategii Forex
Jak odpalić bez środowiska programistycznego: wejdź na colab.research.google.com (darmowe, wymaga konta Google), kliknij „New Notebook", wklej poniższy kod do komórki, zaimportuj listę swoich zwrotów R z pliku CSV (jedna kolumna z liczbami w R per trade) — uruchomienie zajmuje 2 minuty. Notebook zapisuje się na Google Drive, można wracać do niego z dowolnego komputera.
import numpy as np
import pandas as pd
def block_bootstrap_strategy(trades_R, n_simulations=1000, block_size=10):
"""
Block bootstrap na liście wyników trade'ów wyrażonych w R.
trades_R: np.array, np. [1.5, -1.0, 2.2, -1.0, 0.8, ...] — wyniki w R
n_simulations: liczba alternatywnych historii
block_size: dlugosc bloku zachowujaca volatility clustering
Zwraca: dict z metrykami (mediana zwrotu, 5. percentyl, max DD, ruin prob)
"""
n_trades = len(trades_R)
block_size = min(block_size, n_trades) # ochrona przed block_size > liczba trade'ow
n_blocks = int(np.ceil(n_trades / block_size)) # zaokraglamy w gore zamiast obcinac konca
final_returns = []
max_drawdowns = []
ruin_count = 0
risk_per_trade = 0.01 # 1% per trade
for sim in range(n_simulations):
# losowanie bloków startowych z powtorzeniami
block_starts = np.random.randint(0, n_trades - block_size + 1, n_blocks)
# przycinamy do dlugosci oryginalu, zeby zachowac N=n_trades w symulacji
sim_trades = np.concatenate([trades_R[s:s + block_size] for s in block_starts])[:n_trades]
# konstrukcja equity curve (multiplicative compounding)
equity = 1.0
equity_curve = [1.0]
for r in sim_trades:
equity *= (1.0 + r * risk_per_trade)
equity_curve.append(equity)
equity_curve = np.array(equity_curve)
peak = np.maximum.accumulate(equity_curve)
drawdown = (equity_curve - peak) / peak
final_returns.append(equity - 1.0)
max_drawdowns.append(drawdown.min()) # ujemna wartosc
if drawdown.min() < -0.30:
ruin_count += 1
return {
'median_return': np.median(final_returns),
'p05_return': np.percentile(final_returns, 5),
'p95_return': np.percentile(final_returns, 95),
'p95_max_dd': np.percentile(max_drawdowns, 5), # 5. percentyl od dolu
'ruin_probability': ruin_count / n_simulations,
'mean_return': np.mean(final_returns),
}
# przykladowe uzycie
trades = np.array([1.5, -1.0, 2.2, -1.0, 0.8, -1.0, 1.3, 1.7, -1.0, 0.5,
-1.0, 2.1, -1.0, 1.4, 0.9, -1.0, 1.8, -1.0, 1.1, -1.0])
trades = np.tile(trades, 10) # symuluje 200 trade'ow
results = block_bootstrap_strategy(trades, n_simulations=2000, block_size=10)
print(f"Mediana zwrotu: {results['median_return']*100:.1f}%")
print(f"5. percentyl zwrotu: {results['p05_return']*100:.1f}%")
print(f"95. percentyl max DD: {results['p95_max_dd']*100:.1f}%")
print(f"Probability of ruin (DD > 30%): {results['ruin_probability']*100:.2f}%")
Wynik pokazuje prostą rzecz: czy strategia ma zapas na gorszą kolejność transakcji, czy przewraca się, gdy pierwsze 30 trade'ów ułoży się gorzej niż w backteście. Strategia przechodzi Monte Carlo dopiero wtedy, gdy zysk nie znika po przetasowaniu kolejności trade'ów, a 95. percentyl drawdownu nadal mieści się w limicie, który trader psychicznie i kapitałowo przeżyje. Operacyjny próg: mediana zwrotu i 5. percentyl oba dodatnie, max DD w 95. percentylu < −20% dla większości detalu, ruin probability < 1%. Wynik 5. percentyl ujemny, max DD > −30% w 5% scenariuszy, ruin probability > 5% — strategia operacyjnie nieakceptowalna, nawet jeśli mediana wygląda atrakcyjnie.
Interpretacja Monte Carlo dla różnych poziomów kapitału
Te same liczby Monte Carlo oznaczają co innego dla traderów z różnym kapitałem. Praktyka:
| Kapitał | Akceptowalne max DD (95. percentyl) | Akceptowalne ruin prob | Sizing per trade |
|---|---|---|---|
| 5 000 PLN (mikro / nauka) | −15% (DD = 750 PLN) | < 0,5% | 0,3–0,5% (15–25 PLN per trade) |
| 20 000 PLN (mały rachunek) | −20% (DD = 4 000 PLN) | < 1% | 0,5–1% (100–200 PLN per trade) |
| 50 000 PLN (rachunek operacyjny) | −25% (DD = 12 500 PLN) | < 2% | 1% (500 PLN per trade) |
Te same wyniki procentowe Monte Carlo oznaczają inne kwoty PLN i inny próg bólu psychologicznego — dlatego akceptowalny DD% musi być kalibrowany nie tylko matematycznie, ale pod konkretną kwotę, którą jesteś gotów stracić bez interwencji w system. Na 5 000 PLN każde 15% DD to 750 PLN — psychologicznie dotkliwe, bo przekłada się na realną decyzję „czy dopłacam, czy się wycofuję". Na 50 000 PLN 15% DD to 7 500 PLN — boli, ale kapitał operacyjny nadal pozwala kontynuować strategię bez paniki. Strategia akceptowalna dla rachunku 50k może być psychologicznie i operacyjnie nieakceptowalna dla 5k, mimo identycznych wyników procentowych w Monte Carlo.
Dlaczego block bootstrap, nie naiwny
Volatility clustering: w realnym FX po stratnym trade'u prawdopodobieństwo kolejnej straty jest wyższe niż średnie (rynek w trudnym reżimie zostaje przez chwilę). Naiwny bootstrap (losowanie pojedynczych trade'ów) zakłada niezależność, niedoszacowuje seryjność strat, niedoszacowuje max DD. Block bootstrap zachowuje seryjność i daje realniejszy rozkład max DD. Standard branżowy: bloki 5–20 trade'ów dla strategii FX intraday, 3–8 trade'ów dla swing.
5. Forward testing — demo, paper trade, mikrokonto
Forward test ma trzy etapy o rosnącej realności i rosnącym koszcie błędu. Skrócenie walidacji nie usuwa ryzyka — przenosi je na konto live. Różnica jest taka, że błąd w demo kosztuje wieczór, a błąd na live kosztuje kapitał.
Etap 1: Demo (30 dni minimum)
Konto demo brokera, ten sam strumień danych co konto live, identyczne warunki egzekucji w teorii. Zalety:
- Brak ryzyka kapitałowego — błędy wykonania i błędy strategii nie kosztują pieniędzy
- Pełna iteracja — możesz po 10 trade'ach wrócić do strategii i poprawić ją bez utraty kapitału
- Test integracji narzędzi — czy alerty działają, czy EA się uruchamia, czy reguły są poprawnie zakodowane
Wady:
- Slippage demo zwykle lepszy niż real — broker chce, żebyś założył live, więc demo egzekuje korzystniej
- Brak ryzyka uderzenia w margin — demo nie wyzwala instynktu przetrwania, który w realu powoduje hesytację przy wejściu i ręczne manipulowanie Stop Lossem
- Brak ryzyka requote — w realnym trybie ECN albo STP requote zdarza się przy publikacjach
30 dni demo ma odpowiedzieć na brutalne pytania: czy alert odpala się wtedy, kiedy trzeba, czy EA nie gubi sygnałów, czy broker pokazuje inny spread niż w testerze, czy trader nie poprawia reguł ręcznie. Próg minimum: 30 dni i 30 trade'ów. To nie jest statystycznie znacząca próba — to sanity check infrastruktury.
Auto-import wyników po API. Ręczny Excel dla daytradera to operacyjne samobójstwo — dwa miesiące ręcznego księgowania kończą się błędami i godzinami pracy nad arkuszem zamiast nad strategią. Skonfiguruj auto-import z MT4/MT5: MyFxBook i FX Blue (darmowe) dobrze nadają się do automatycznego track recordu, drawdownu, ekspozycji, R-multiple i podstawowych statystyk. Do głębszej diagnostyki MAE/MFE per trade sięgaj po Edgewonk (~170 USD jednorazowo) albo Tradervue — ich generowanie scatter plotów MAE/MFE jest natywną funkcją, a nie hackiem. Alternatywa dla zaawansowanych: własny eksport tick/bar data do Pythona z biblioteką pandas i ręczne liczenie MAE/MFE z OHLC.
Etap 2: Paper trade na realtime data feed (opcjonalny, 30–60 dni)
Wariant pomiędzy demo a mikrokontem: zapisujesz każdy sygnał, kalkulujesz hipotetyczny wynik z realistic spreads/slippage, ale nie otwierasz pozycji w MT. Zalety: brak konkurencji platformy demo (która dziwnie egzekuje przy wysokim wolumenie), pełna kontrola nad modelem kosztów. Wady: brak realnego sygnału egzekucyjnego, więc nie wiesz, czy w praktyce kliknąłbyś.
Etap 3: Mikrokonto live (90 dni minimum)
Konto live z minimalnym sizingiem (0,01–0,05 lota, kapitał 200–500 USD/PLN). Cel: sprawdzić strategię w warunkach realnego ryzyka, nie testować dochodu.
Co mierzy mikrokonto, czego nie mierzy demo:
- Realne warunki egzekucji — twój broker w trybie live może mieć szerszy spread, większy slippage, requote'y, opóźnienia mostka. Demo tego nie pokaże
- Twój poziom operacyjnego compliance — mikrokonto bezwzględnie weryfikuje współczynnik błędu ludzkiego: ręczne zamknięcia w trakcie drawdownu, „przesunięcie SL o 5 pipsów", ignorowanie sygnału przeciw aktualnej tezie. Mierzysz to jako error rate w dzienniku — odsetek sygnałów wykonanych niezgodnie z regułą
- Swap rzeczywisty — niektóre brokery mają inne tabele swapów dla demo i live
- Działanie integracji — czy twój EA, alerty, automatyzacje działają na live tak samo jak na demo
Próg minimum: 90 dni i 60–100 trade'ów. Wynik pozytywny: strategia ma podobną expectancy jak na demo (różnica do 0,1R), brak nieoczekiwanych zachowań egzekucyjnych, drawdown w spodziewanym przedziale, twoja dyscyplina utrzymana.
Sekwencja przejść — kryteria
| Z etapu | Do etapu | Kryteria przejścia |
|---|---|---|
| Backtest | Demo | WFA OOS pozytywne, Monte Carlo: 5. percentyl > 0, ruin prob < 2%, model kosztów realistyczny |
| Demo | Mikrokonto | 30+ dni, 30+ trade'ów, expectancy w przedziale ±0,15R od backtestu, brak nieoczekiwanych dziur |
| Mikrokonto | Pełny sizing | 90+ dni, 60+ trade'ów, expectancy w przedziale ±0,1R od backtestu, drawdown w przedziale, dyscyplina utrzymana |
Czas łączny od backtestu do pełnego sizingu: 4–6 miesięcy. Próby skrócenia tej sekwencji w praktyce kończą się stratą pierwszego istotnego drawdownu na live, zanim trader zrozumie, gdzie był błąd — bo eliminacja etapów walidacji to nie oszczędność czasu, tylko transfer ryzyka z demo na konto z prawdziwymi pieniędzmi.
Wariant dla polskiego retail tradera na etacie (CET workflow)
Pełny forward test wymaga sygnałów w oknach, w których fizycznie możesz reagować. Strategia generująca sygnały o 14:30 CET dla tradera siedzącego na callach do 17:00 jest operacyjnie niewykonalna, niezależnie od tego, jak dobry ma backtest. Dwa workflowy do wyboru:
- Manualny po pracy (18:30–22:00 CET). Sygnały tylko w końcówce sesji NY, przygotowanie zleceń oczekujących pod nocną sesję azjatycką, albo strategie D1/H4 ustawiane po zamknięciu świecy dziennej brokera. EOD review codziennie o 22:00–22:30 CET. Brak handlu w godzinach pracy
- Pełna automatyzacja alertów + EA. Strategia działa w godzinach pracy, ale nie wymaga manualnej reakcji — webhook TradingView do Telegrama lub VPS z EA przejmującym egzekucję. Trader zatwierdza wejścia z telefonu w przerwie albo system wchodzi automatycznie z server-side SL (Stop Loss zapisany po stronie serwera brokera, nie tylko w lokalnym EA — jeśli VPS padnie, SL nadal chroni pozycję). Cały szkielet architektury VPS/watchdog/autostart opisany w artykule 15.3, sekcja 4
Trzeci wariant — rezygnacja z intraday i przejście na swing D1/W1 z pozycjami 5–15 dni — eliminuje cały problem CET, bo decyzje podejmujesz raz dziennie po zamknięciu sesji.
6. Próg statystyczny — N, p-value, przedział ufności
Detal patrzy na backtest z 30 trade'ami, widzi WR 60% i myśli „strategia ma WR 60%". Statystyka mówi: przy próbie 30 trade'ów rzeczywiste WR strategii leży w przedziale ufności 41–77% z 95% prawdopodobieństwem.
Centralne Twierdzenie Graniczne, fat tails i N = 100 jako próg operacyjny
Klasyczny statystyczny minimalny próg N = 30 (Centralne Twierdzenie Graniczne) działa dla rozkładów bez grubych ogonów. Rynki finansowe mają wyraźnie grube ogony — pojedyncze trade'y +5R lub −3R (gap, news shock, flash crash) zaburzają średnią i odchylenie. W środowisku FX miarodajne wygładzenie statystyk następuje dopiero przy N = 100 transakcji per setup, optymalnie 200+. Próba 30 trade'ów wystarcza do wstępnej obserwacji, ale nie do żadnej decyzji o sizingu, awansie setupu czy modyfikacji strategii.
Przedział ufności WR vs próba
| Liczba trade'ów (N) | WR z próby | 95% przedział ufności | Czy odróżnisz edge od szumu? |
|---|---|---|---|
| 30 | 60% | 41–77% (±15 pp) | Nie — może być WR < 50% (stratna) |
| 50 | 60% | 45–74% (±12 pp) | Marginalnie — granica WR 50% |
| 100 | 60% | 50–69% (±10 pp) | Słabo — granica WR 50% |
| 200 | 60% | 53–67% (±5 pp) | Tak — z 95% pewnością WR > 50% |
| 500 | 60% | 55–64% (±3 pp) | Tak — wysoka pewność edge'u |
| 1000 | 60% | 57–63% (±2 pp) | Tak — bardzo wysoka pewność |
Wniosek operacyjny: strategia z mniej niż 100 trade'ów w backteście jest niewalidowana statystycznie. Strategia z 200+ trade'ów jest minimum akceptowalne. Strategia z 500+ trade'ów jest solidnie zwalidowana statystycznie.
Test statystyczny — czy WR jest istotnie wyższe niż 50%
Pełna statystyka: binomial test. Hipoteza zerowa: WR = 50% (strategia bez edge'u). Hipoteza alternatywna: WR > 50%. Z próby liczysz p-value — prawdopodobieństwo, że obserwowane wyniki pojawiłyby się przy hipotezie zerowej.
- p-value < 0,01 — silny dowód edge'u
- p-value 0,01–0,05 — umiarkowany dowód, ale akceptowalny
- p-value 0,05–0,10 — słaby dowód, granica
- p-value > 0,10 — brak dowodu, strategia może być losowym szumem
W Pythonie (SciPy ≥ 1.7): from scipy.stats import binomtest; binomtest(wins, n_trades, 0.5, alternative='greater').pvalue. Funkcja binom_test jest deprecated od 1.7 i usunięta od 1.12 — w nowych skryptach używaj binomtest ze zwracanym obiektem wynikowym.
Przykład: 60 wygranych z 100 trade'ów. binomtest(60, 100, 0.5, alternative='greater').pvalue = 0,028. Akceptowalne (p < 0,05). Ale 18 wygranych z 30: binomtest(18, 30, 0.5, alternative='greater').pvalue = 0,18 — brak dowodu, mimo „WR 60%".
Edge w R, nie tylko w WR
WR to tylko połowa obrazu. Strategia z WR 40% i avg win 3R, avg loss 1R ma expectancy +0,6R — bardzo dobra. Strategia z WR 70% i avg win 0,5R, avg loss 1R ma expectancy +0,05R — marginalna.
Pełna statystyka edge'u: t-test na średniej R per trade. Hipoteza zerowa: średnia R = 0. Liczysz t = (mean_R − 0) / (std_R / sqrt(N)).
Próbka 30 z mean +0,3R, std 1,5R: t = 0,3 / (1,5 / sqrt(30)) = 1,1 — p-value 0,14 (brak dowodu). Ta sama mean i std przy N = 200: t = 0,3 / (1,5 / sqrt(200)) = 2,83 — p-value 0,003 (silny dowód).
Reguła: nawet z dobrą expectancy w R próba 30 trade'ów nie da ci statystycznej pewności. Zawsze celuj w 200+ dla testów wstępnych, 500+ dla pełnej walidacji.
Pełna metryka edge'u w R — operacyjny wzór
Przykład numeryczny: WR 54%, avgWin 1,8R, avgLoss 1R → E = 0,54 × 1,8 − 0,46 × 1,0 = 0,97 − 0,46 = +0,51R. Jeśli ten wynik jest poniżej +0,15R przy próbie 100 trade'ów, system w środowisku live z dużym prawdopodobieństwem poślizgnie się poniżej zera po dołożeniu kosztów egzekucji, których backtest nie modeluje w pełni.
SQN (System Quality Number) van Tharpa
Łączy wartość oczekiwaną z odchyleniem (zmiennością) i wielkością próby. Praktyczna interpretacja używana w środowisku Van Tharpa[9]:
| SQN | Klasyfikacja | Decyzja operacyjna |
|---|---|---|
| < 1,6 | Brak dowodu na edge — masz hipotezę, nie system | Wracasz do backtestu, nie wlewasz pieniędzy |
| 1,6–2,0 | System słaby, akceptowalny w wąskich warunkach | Mały sizing, dalsze testy na innych okresach/parach |
| 2,0–2,5 | System dobry — kandydat do realnego kapitału | Standardowy sizing wg planu, monitoring kwartalny |
| > 2,5 | System bardzo dobry — rzadkie u retaila | Standardowy sizing; podejrzewaj overfitting jeśli próba mała |
Reguła: SQN > 2,0 przy N > 100 to dobry sygnał wstępny, ale nie zastępuje OOS ani modelu kosztów. Potrzebujesz osobno potwierdzenia na OOS, forward testu, modelu kosztów odpornego na pesymistyczny scenariusz i kontroli drawdownu w realnym czasie — sam SQN to filtr przed live, nie zielone światło.
7. Modelowanie kosztów: spread, slippage, swap, prowizja w testach
Niedomodelowanie kosztów to pułapka, która sama jedna może zamienić każdą strategię w zwycięską na backteście. Pełen model kosztów ma cztery składowe i każdą trzeba modelować osobno.
Spread: fixed vs variable
| Model | Charakterystyka | Kiedy używać |
|---|---|---|
| Fixed spread (np. 1,0 pipsa stałe) | MT4 default, prosty, zawyża wyniki w godzinach niskiej płynności | Tylko jako pierwszy szybki sanity check, nigdy do walidacji |
| Average spread (z historii brokera) | Średnia z 6–12 miesięcy, pojedyncza wartość | Dla strategii intraday w godzinach wysokiej płynności (LON, NY) |
| Time-of-day variable | Spread zależny od godziny (LON open: 0,3 pipsa, rollover: 4 pipsy) | Standard dla strategii intraday i swing |
| Tick-by-tick variable (Tick Data Suite, Dukascopy) | Realny spread z każdej sekundy historii, z book depth | Strategie skalpujące, news trading, profesjonalna walidacja |
Tick Data Suite (TDS) i Dukascopy tick data to standard branżowy dla profesjonalnego backtestu. TDS pozwala MT4 używać 99% modelu jakości z prawdziwymi tickami i variable spread. Koszt: 30–80 USD jednorazowo. Inwestycja zwraca się przy pierwszej strategii, której fixed-spread backtest pokazałby zysk, a variable-spread test pokaże stratę — czyli przy pierwszej strategii skalpującej albo news-trading.
Slippage — model statyczny vs dynamiczny
Slippage to różnica między ceną w backteście a realną ceną egzekucji. Modelowanie:
- Statyczny: stała wartość (np. 0,5 pipsa per entry/exit). Prosty, niedoszacowuje slippage'u w stresie
- Dynamiczny w funkcji ATR: slippage = 0,1 × ATR(14) M5. Większy slippage przy większej zmienności
- Dynamiczny w funkcji book depth (jeśli dostępny): slippage = funkcja wolumenu zlecenia / głębokości arkusza. Najrealniejszy, ale wymaga danych book depth
Praktyczna reguła dla detalu: slippage 0,3–0,5 pipsa w normalnych warunkach, 1–3 pipsy na breakoutach z wolumenu, 5–15 pipsów po publikacjach makro. Modeluj w trzech reżimach.
Swap (cost of carry)
Pozycje trzymane przez noc płacą lub otrzymują swap. W MT4 wartości są w punktach na lot za noc. Trzy regiony do uwzględnienia:
- Direction-dependent: long EUR/USD ma zwykle ujemny swap (pożyczasz USD wyżej oprocentowane), short EUR/USD ma dodatni
- Triple swap (środowy rollover w MT4): środa nocą naliczany jest 3× swap z weekendu. Strategie swing trzymające pozycje przez środę muszą to modelować
- Wartość bezwzględna w obecnym otoczeniu stóp: 2024–2026 r. — bardzo wysokie różnice stóp USD/EUR/JPY/AUD generują znaczące swapy (5–15 pipsów dziennie na niektórych parach long w niewłaściwym kierunku)
Praktyka: dla strategii swing z trzymaniem 3–8 dni swap może zjeść 30–80% expectancy brutto. Backtest bez swapu jest dla swing tradera bezwartościowy.
Prowizja
Konta ECN i STP zwykle mają komisję per RT (round turn — wejście + wyjście). Typowe wartości: 5–7 USD per lot RT na EUR/USD, 6–10 USD na minor pairs, 8–15 USD na exotics. Modelowanie:
Prowizja w pipsach = (komisja USD × kurs USD/PLN ÷ 10) ÷ wartość pipsa per lot. Dla EUR/USD: 6 USD ÷ 10 USD/pips per lot = 0,6 pipsa per RT.
Strategia skalpująca z 200 trade'ami miesięcznie i 0,1 lota: 200 × 0,1 × 6 = 120 USD komisji miesięcznie. Na kapitale 1 000 USD to 12% kapitału miesięcznie obrotowych kosztów prowizji, czyli 144% kapitału rocznie przy zachowanym wolumenie obrotu. Tak — strategia skalpująca z mikro lotami na małym kapitale nie ma sensu kosztowego, bo prowizja zjada wielokrotność oczekiwanego zwrotu. Próg sensowności: kapitał na tyle duży, żeby roczne koszty prowizji nie przekraczały 20–30% oczekiwanego zwrotu netto z edge'u.
Tick Data Suite — jak uruchomić backtest klasy profesjonalnej w MT4
TDS to standard branżowy dla backtestu skalpujących i news-trading strategii. Pełna instalacja w weekend:
- Zakup: tickdatasuite.com, koszt rzędu kilkudziesięciu USD jednorazowo (sprawdź aktualną cenę u dostawcy)
- Źródło danych: Dukascopy historical data (darmowe, tickdata bid/ask na poziomie milisekundy). Dostępność historii zależy od instrumentu — główne pary mają zwykle najdłuższą historię, egzotyki i CFD krótszą. Przed testem sprawdź ciągłość danych dla konkretnej pary i zakresu
- Setup: 2–3 godziny pierwszego konfigurowania — pobranie danych dla wybranych par, podpięcie do MT4 Strategy Tester, wybór modelu „Every tick"
- Po setupie: backtest na realnych tickach z variable spread per godzina, modelowaniem kosztów per broker, jakość modelu w MT4 99% zamiast domyślnych ~25–60%
Inwestycja zwraca się przy pierwszej strategii skalpującej lub news-trading, której fixed-spread backtest pokazałby zysk, a tick-by-tick test pokaże stratę po realnym variable spread w godzinach publikacji.
MAE/MFE — diagnostyka modelu egzekucji i exitów
Maximum Adverse Excursion (MAE) i Maximum Favorable Excursion (MFE) to najważniejsza diagnostyka tego, czy problem leży w wejściu, wyjściu czy samej strategii[11]. MAE per trade = jak daleko cena szła przeciwko pozycji przed osiągnięciem wyniku końcowego. MFE = maksymalny niezrealizowany zysk w trakcie życia pozycji.
| Sygnał z MAE/MFE | Diagnoza | Co zmienić |
|---|---|---|
| Większość stratnych ma MAE < 0,5× twojego SL | SL jest za ciasny — wybijają cię stopy szumu, nie przeciwnego ruchu | Rozszerz SL do mediany MAE pozycji zyskownych + bufor 0,3R |
| Twoje straty wylatują 3× dalej niż mediana MAE wygranych | SL jest za luźny — siedzisz na przegrywających trade'ach z nadzieją | Zaciśnij SL do mediany MAE wygranych + 0,3R bufora |
| 60% trade'ów osiąga MFE +2R, ale ty zamykasz na +1R | Tracisz edge na exit — TP jest problemem, nie entry | Częściowy TP (50% na 1,5R, 50% trailing po SMA-20) |
| MFE wygranych średnio +3R, twoje TP +1,5R | Tracisz połowę każdego wygranego trade'u na strachu przed cofnięciem | Statyczny TP zastąp trailing stop'em |
Edgewonk i Tradervue generują diagnostykę MAE/MFE po imporcie transakcji i danych rynkowych. MyFxBook oraz FX Blue traktuj głównie jako narzędzia do track recordu, ekspozycji, drawdownu i podstawowych statystyk — pełny scatter plot MAE/MFE per trade nie jest ich natywną mocną stroną. Jeśli chcesz pełny MAE/MFE, użyj Edgewonk/Tradervue albo policz go samodzielnie z danych OHLC/tick w Pythonie. Bez MAE/MFE diagnozujesz problemy „na oko" i nie odróżniasz problemu z wejściem od problemu z wyjściem.
Łączny model kosztów dla MT4 z TDS
# Pseudokod modelu kosztow do skryptu walidacji backtestu
def total_cost_per_trade(pair, hour_utc, atr_value, lot_size, hold_days):
"""Zwraca laczny koszt trade'u w pipsach."""
# 1. Spread (variable po godzinie)
spread_table = {
'EURUSD': {'low_liquidity': 1.5, 'normal': 0.7, 'peak': 0.3},
'GBPJPY': {'low_liquidity': 4.0, 'normal': 2.0, 'peak': 1.2},
# ...
}
if 22 <= hour_utc or hour_utc <= 6:
regime = 'low_liquidity'
elif 8 <= hour_utc <= 16:
regime = 'peak'
else:
regime = 'normal'
spread = spread_table[pair][regime]
# 2. Slippage (dynamiczny w ATR, dwustronny)
slippage = 2 * 0.1 * atr_value # entry + exit
# 3. Prowizja (EUR/USD = 0,6 pipsa RT)
commission_pips = {'EURUSD': 0.6, 'GBPJPY': 0.8}.get(pair, 0.7)
# 4. Swap (sredni za pozycje trzymana hold_days nocy)
swap_per_night = {'EURUSD': -0.3, 'GBPJPY': -0.5}.get(pair, -0.4) # ujemny dla shorta?
swap_total = swap_per_night * hold_days
return spread + slippage + commission_pips - swap_total
Przy walidacji: jeśli twoja strategia ma brutto expectancy +0,4R, a model kosztów dodaje 0,2R kosztów per trade — netto +0,2R. Jeśli model dodaje 0,5R kosztów — strategia jest stratna i nie poszłaby na live. Jeśli twój backtest nie modeluje kosztów — nie wiesz, w którym wariancie jesteś.
8. Cherry picking i selekcja sygnałów — najczęstszy grzech testera
Cherry picking metodologiczny to proces, w którym tester (świadomie lub nie) odrzuca część sygnałów strategii, zostawia te „dobre" i raportuje wyniki. Wynik: backtest pozornie stratnej strategii pokazuje zysk, bo statystycznie najgorsze sygnały zostały usunięte.
Trzy warianty cherry pickingu
Wariant 1: „Pomijam sygnały, które nie wyglądają dobrze". Strategia generuje sygnał, ale tester ręcznie ocenia kontekst — „ten sygnał jest w niewłaściwej fazie, pominę go". W backteście liczysz tylko sygnały, które „wyglądały dobrze". Problem: ocena „czy wygląda dobrze" w retrospektywie jest skażona — wiesz, jak skończyła się świeca po sygnale, więc twój filtr „nie wygląda dobrze" przypadkiem pokrywa się ze stratnymi instancjami.
Wariant 2: „Filtruję ex post na podstawie wyników". Tester widzi w backteście, że stratne trade'y są często we wtorki rano. Dodaje filtr „nie handluję wtorkami rano", retestuje strategię — wynik się poprawia. Filtr nie ma niezależnej hipotezy, dodał go po obejrzeniu wyników. W realu wtorki rano nie są systematycznie gorsze — strategia traci ten sztuczny edge.
Wariant 3: „Backtest na 'czystych' okresach". Tester odrzuca z backtestu okresy „anomaliczne" — np. marzec 2020 (COVID), październik 2008 (Lehman), grudzień 2018 (taper tantrum). Backtest na „normalnych" okresach pokazuje świetne wyniki. Problem: realne handlowanie obejmuje też anomalie. Strategia, która działa tylko poza nimi, w realu w którymś momencie spotka anomalię i zwraca cały zarobek.
Detekcja cherry pickingu
- Liczba zerwanych sygnałów — ile sygnałów strategia wygenerowała vs ile zostało wziętych. Jeśli > 10% sygnałów odrzucono, podejrzanie. Jeśli > 30%, niemal pewny cherry picking
- Powód odrzucenia — czy zdefiniowany przed testem (filtr w kodzie) czy ad hoc (ocena w trakcie)? Tylko pierwsze jest legalne
- Test na pełnych danych — uruchom strategię bez ręcznych odrzuceń, na pełnym zakresie danych włącznie z anomaliami. Porównaj wyniki. Jeśli „pełne" wyniki są dramatycznie gorsze — masz cherry picking
Arkusz „signal inventory" — twardy mechanizm kontrolny
Każdy sygnał strategii dostaje status w jednoznacznym arkuszu, prowadzonym automatycznie z logów lub półautomatycznie z dziennika:
| Status sygnału | Definicja | Akceptowalna częstotliwość |
|---|---|---|
taken | Sygnał wykonany zgodnie z regułą strategii | Cel: > 90% |
skipped_by_rule | Sygnał odfiltrowany przez kod / regułę zdefiniowaną przed testem (np. filtr news, korelacja, godzina) | Bez limitu — to jest legalne |
skipped_manual | Trader ręcznie pominął sygnał („nie podobał mi się układ") | < 10% — powyżej tego backtest jest skażony |
invalid_data | Sygnał wystąpił w warunkach awarii feedu, brokera lub infrastruktury | < 5% — powyżej tego problem operacyjny |
Reguła operacyjna: jeśli skipped_manual przekracza 10% sygnałów, backtest jest skażony cherry pickingiem i nie idzie do walidacji statystycznej. Wracasz do reguł i albo (a) formalizujesz powód pomijania jako filtr w kodzie, albo (b) przyjmujesz, że strategia wymaga dyscypliny, której nie masz, i wracasz do tablicy.
Brudna praktyka cherry pickingu z marketplace'u
9. Najczęstsze błędy w testowaniu
Błąd 1: Optymalizacja parametrów na całym zbiorze
Tester używa MT4 Optimization Mode, testuje 200 kombinacji parametrów na całych 5 latach danych, wybiera tę, która daje +180%. Brak walk-forwardu, brak OOS. To jest klasyczny curve fitting. Forward test takiej strategii praktycznie zawsze wypada źle. Naprawa: zawsze dziel dane 70/30, optymalizuj wyłącznie na IS, walidacja jednorazowa na OOS.
Błąd 2: Zbyt mała próba historyczna
Backtest na 6 miesiącach z 24 trade'ami nie jest backtestem — to anegdota. Reżim rynkowy z 6 miesięcy może być całkowicie niereprezentatywny. Minimum: 3 lata danych, 200+ trade'ów. Optymalnie: 5–10 lat danych, 500–2000 trade'ów.
Błąd 3: Backtest tylko na bid (lub tylko na ask)
Niektóre platformy backtestowe domyślnie używają tylko bid (cena sprzedaży). Trade long otwarty na bid, zamknięty na bid = brak modelowania spreadu. Każdy trade „dostaje" połowę spreadu jako zysk, której w realu nie ma. Naprawa: w MT4 ustaw model „Every tick" z TDS, w MT5 użyj „Every tick based on real ticks".
Błąd 4: Ignorowanie zmiany reżimu rynkowego
Strategia testowana na 2020–2023 (post-COVID, niskie stopy, QE) nie zachowuje się tak samo w 2024–2026 (wysokie stopy, QT, polityczne zaburzenia). Naprawa: walk-forward kroczący identyfikuje, w których reżimach strategia działa, w których nie. Strategia, która działa tylko w jednym reżimie, jest reżimowo wrażliwa — nie błędna, ale wymaga wyłączania w innych reżimach.
Błąd 5: Brak testowania na różnych parach
Tester optymalizuje strategię na EUR/USD, działa świetnie. Wniosek: „strategia działa". Ale nie wiesz, czy strategia jest specyficzna dla EUR/USD (mikrostruktura, profil zmienności) czy uniwersalna. Test na 5–8 parach pokazuje, na ilu działa. Strategia działająca tylko na jednej parze = silnie podejrzana o curve fitting do mikrostruktury tej pary.
Błąd 6: Mylenie returns z risk-adjusted returns
Strategia A: +35% rocznie, max DD 22%. Strategia B: +25% rocznie, max DD 8%. Detal patrzy na returns i wybiera A. Profesjonalista patrzy na Sharpe ratio i Calmar ratio:
- Sharpe A: 35 / std(monthly_returns) × sqrt(12) = np. 1,1
- Sharpe B: 25 / std(monthly_returns) × sqrt(12) = np. 1,8
- Calmar A: 35 / 22 = 1,6
- Calmar B: 25 / 8 = 3,1
Strategia B jest lepsza w sensie risk-adjusted — daje większą stabilność zwrotu na jednostkę ryzyka. Reguła: do oceny strategii używaj Sharpe (zwrot per zmienność), Sortino (zwrot per zmienność spadkowa), Calmar (zwrot per max DD).
Błąd 7: Brak monitoringu strategii post-deploy
Strategia przechodzi backtest, demo, mikrokonto, idzie na pełny sizing. Po 6 miesiącach trader nie wie, że strategia w obecnym kwartale ma expectancy −0,1R zamiast +0,3R. Strategia powinna być monitorowana po wdrożeniu: kwartalna walidacja, czy expectancy mieści się w przedziale ufności z backtestu. Jeśli wypada poniżej 5. percentyla z Monte Carlo — alarm, strategia może umierać. Szczegóły w artykule 15.5 (workflow EOD).
Błąd 8: Intervention bias po wdrożeniu
Trader co tydzień zmienia parametry albo dodaje filtry po serii 5–10 strat. W ten sposób zabija system, zanim statystycznie wolno cokolwiek ocenić. Reguła: decyzje o zmianie strategii dopiero po minimalnym N dla setupu — 30 trade'ów jako alarm, 100 trade'ów jako pełna decyzja. Seria 5 strat z rzędu na strategii z WR 52% ma prawdopodobieństwo ~3% — rzadkie, ale w pełni normalne. Każda interwencja przed minimalnym N to optymalizacja na szumie, nie na sygnale.
Tabela decyzyjna — kiedy poprawiać system, kiedy siebie
Najczęstszy błąd: trader miesza błędy systemu z błędami egzekucji i naprawia jedno zamiast drugiego. Twarde kryteria liczbowe:
| Sygnał | Kryterium liczbowe | Diagnoza | Akcja |
|---|---|---|---|
| Drawdown w realu | > 95. percentyl Monte Carlo z backtestu | Błąd systemu — strategia umiera lub reżim się zmienił | Pełen review strategii (sekcja 9, błąd 7) |
| Drawdown w realu | W przedziale 50.–95. percentyl MC | Normalny szum — wariancja w przedziale historycznym | Brak akcji, kontynuacja monitoringu |
| Error rate w dzienniku | > 5% sygnałów wykonanych niezgodnie z regułą | Błąd tradera — dyscyplina, nie strategia | Powrót do mikrokonta, audyt procedur wejścia |
| Expectancy live vs backtest | Spadek > 30% (np. backtest +0,4R, live +0,25R) | Najpierw sprawdź koszty (model spread/slippage), potem reżim | Korekta modelu kosztów + reconciliation sygnałów |
| Liczba trade'ów po deploy | < 30 — chcesz interweniować | Próba za mała — to intervention bias | Brak akcji, czekasz do N = 30 minimum, N = 100 dla decyzji |
| Seria strat z rzędu | ≤ historyczna max seria z backtestu | Normalna wariancja — nie sygnał do zmian | Brak akcji |
| Seria strat z rzędu | > 1,5× historyczna max seria z backtestu | Statystycznie nietypowe — flaga, ale nie wyrok | Redukcja sizingu o 50%, monitoring co 30 dni |
Logika tabeli: zanim ruszysz parametr strategii, sprawdź najpierw error rate i model kosztów. W 60–80% przypadków „strategia przestała działać" znaczy „trader zaczął inaczej egzekwować" albo „spread realny jest wyższy niż w backteście". Dotykanie reguł na podstawie 8 trade'ów jest dokładnie tym, co opisuje war story z sekcji 3.
10. Checklista — czy strategia jest gotowa do live
Łącznie 20 punktów w pięciu kategoriach: walidacja statystyczna (5), pułapki metodologiczne (6), model kosztów (4), forward test (3) i dyscyplina operacyjna (2). Próg minimalny do uruchomienia pełnego sizingu: 20/20; 17–19 oznacza powrót do niedociągniętych etapów; poniżej 17 — strategia nie jest gotowa nawet do testowania na realnym kapitale.
Walidacja statystyczna (5 punktów)
- Backtest pokrywa minimum 3 lata danych (optymalnie 5–10 lat)
- Próba transakcji ≥ 200 (akceptowalne minimum), ≥ 500 (mocna walidacja)
- Walk-forward analysis przeszedł pozytywnie (OOS expectancy w przedziale ±0,15R od IS)
- Monte Carlo bootstrap: 5. percentyl zwrotu rocznego > 0, ruin probability (DD > 30%) < 2%
- Test statystyczny: p-value (binomial / t-test) < 0,05
Pułapki metodologiczne (6 punktów)
- Brak look-ahead bias — strategia używa tylko danych z czasu t lub wcześniej
- Brak survivorship bias — testy na koszyku par aktywnych dziś, nie historycznym
- Brak curve fittingu — heatmapa parametrów pokazuje plateau, nie izolowany szczyt
- Brak overfittingu — wszystkie reguły i filtry mają uzasadnienie ex ante
- Brak cherry pickingu — zerwane sygnały < 10%, powody zdefiniowane przed testem
- Brak data snoopingu — to nie jest 30. testowana strategia z dziennika prób
Model kosztów (4 punkty)
- Spread modelowany jako variable (time-of-day lub tick-by-tick), nie fixed
- Slippage modelowany dynamicznie (statyczny lub ATR-based, w trzech reżimach)
- Swap modelowany dla strategii swing (per direction, triple Wednesday)
- Prowizja modelowana dla strategii skalpujących (komisja per RT)
Forward test (3 punkty)
- Demo 30+ dni, 30+ trade'ów, expectancy w przedziale ±0,15R od backtestu
- Mikrokonto live 90+ dni, 60+ trade'ów, expectancy w przedziale ±0,1R od backtestu
- Drawdown w trakcie forwardu nie przekracza 95. percentyla z Monte Carlo
Dyscyplina operacyjna (2 punkty)
- Egzekucja: zgodność sygnałów systemowych z realną egzekucją > 95% (mierzone jako error rate w dzienniku, status
skipped_manual< 10% z signal inventory) - Plan monitoringu post-deploy zdefiniowany — kwartalna walidacja expectancy vs Monte Carlo CI plus tabela decyzyjna z sekcji 9
Artefakty wymagane przed live (lista do archiwizacji)
Strategia idąca na pełny sizing musi zostawić ślad audytowy. Bez tego po 6 miesiącach nie odtworzysz, dlaczego coś działało albo gdzie pojawił się błąd:
- Plik danych historycznych użytych do backtestu (z hash'em, żeby wykluczyć podmianę)
- Konfiguracja strategii — pełen kod EA / skryptu / opis reguł, wraz z parametrami zamrożonymi po OOS
- Raport IS/OOS — equity curve, expectancy, SQN, profit factor, max DD per okno walk-forwardu
- Raport Monte Carlo — 1000+ symulacji, percentyle zwrotu i drawdownu, ruin probability
- Model kosztów — tabela spreadów per godzina, slippage per reżim, swap per direction, prowizja
- Eksport forward demo — log wszystkich sygnałów z 30 dni, status (taken / skipped), reconciliation z backtestem
- Dziennik mikrolive — 90 dni, każdy trade z R-multiple, MAE_R, MFE_R, kosztem rzeczywistym, screenem przed/po
- Lista odrzuconych sygnałów — signal inventory z powodami, weryfikacja error rate
- Screen ustawień brokera — typ konta, dźwignia, minimalny lot, koszty (na potrzeby reklamacji jakości egzekucji)
- Backup EA / skryptów / templates — wszystkie pliki MT4/MT5 w wersji zamrożonej na czas live
Folder projektu na dysku zewnętrznym lub w chmurze, struktura strategy_X/2026-Q2/{01_data, 02_IS, 03_OOS_locked, 04_montecarlo, 05_demo, 06_mikrolive, 07_artefacts}. Bez tego setupu masz strategię, której nie potrafisz zwalidować retrospektywnie po pierwszej gorszej serii.
20/20 — strategia gotowa do pełnego sizingu. 17–19 — wracaj, uzupełnij brakujące. Poniżej 17 — strategia nie jest gotowa, transferujesz niewykryte ryzyko z demo na konto live z prawdziwymi pieniędzmi.
FAQ — Najczęściej zadawane pytania
Ile czasu zajmuje pełna walidacja strategii od backtestu do live?
Czy MT4 Strategy Tester jest wystarczający do walidacji?
Co zrobić, jeśli moja strategia ma tylko 50 trade'ów w backteście?
Czy mogę pominąć demo, jeśli mam dobry backtest?
Co to są realistyczne wyniki dla strategii detalu?
Jak podatek wpływa na expectancy netto i kiedy strategia Forex przestaje mieć sens wobec pasywnego ETF?
Jak rozróżnić zmianę reżimu rynkowego od umierania strategii?
Czy używać forward testu bez backtestu?
Czy strategia może mieć dobry backtest, dobry walk-forward, dobry forward test, a w pełnym sizingu zaliczyć margin call?
Jak często retestować strategię po wdrożeniu?
Czy mogę kupić gotową strategię (EA) zamiast budować własną?
Źródła i bibliografia
- Lo A.W., MacKinlay A.C., A Non-Random Walk Down Wall Street, Princeton University Press, 1999. Akademickie podstawy testowania efektywności rynku, identyfikacja anomalii i ostrzeżenia przed data snoopingiem.
- Pardo R., The Evaluation and Optimization of Trading Strategies, Wiley, 2008. Metodologia walk-forward analysis, oceny i optymalizacji systemów transakcyjnych z naciskiem na unikanie over-optimization.
- Aronson D., Evidence-Based Technical Analysis, Wiley, 2007. Statystyczne podstawy walidacji strategii, testy istotności, korekta Bonferroni dla wielokrotnego testowania.
- Bandy H.B., Quantitative Technical Analysis, Blue Owl Press, 2015. Statystyczne metody walidacji strategii, identyfikacja over-fittingu, Monte Carlo bootstrap dla systemów tradingowych.
- Chan E., Quantitative Trading: How to Build Your Own Algorithmic Trading Business, Wiley, 2009. Praktyczne podejście do budowy i walidacji strategii ilościowych, modelowanie kosztów transakcyjnych.
- Kaufman P.J., Trading Systems and Methods, Wiley, 6th ed., 2020. Encyklopedyczne kompendium systemów transakcyjnych z rozdziałami poświęconymi testowaniu i walidacji.
- CME Group — materiały edukacyjne (cmegroup.com/education) dotyczące backtestingu, metodologii testowania strategii futures i zarządzania ryzykiem, przenoszalne na FX z uwzględnieniem różnic mikrostruktury.
- Bank for International Settlements (BIS), Triennial Central Bank Survey of Foreign Exchange Markets, 2022/2023. Dane o płynności, spreadach i kosztach transakcyjnych na rynku FX, baza dla realistycznych modeli kosztów.
- Tharp V.K., Definitive Guide to Position Sizing, IITM, 2008. Definicja R-multiple, formuła SQN (System Quality Number) i metodyka oceny jakości systemu na podstawie expectancy, odchylenia i wielkości próby.
- Tomasini E., Jaekle U., Trading Systems: A New Approach to System Development and Portfolio Optimisation, Harriman House, 2009. Praktyczne podejście do walk-forward i Monte Carlo na systemach tradingowych.
- Sweeney J., Maximum Adverse Excursion: Analyzing Price Fluctuations for Trading Management, Wiley, 1997. Klasyczna pozycja definiująca MAE i MFE jako narzędzia diagnostyki entry vs exit i optymalizacji SL/TP.
- López de Prado M., Advances in Financial Machine Learning, Wiley, 2018. Zaawansowane metody walidacji strategii, w tym combinatorial purged cross-validation i deflated Sharpe ratio do korekty na multiple testing.
- European Securities and Markets Authority (ESMA), Decision (EU) 2018/796 — restrictions on contracts for differences oraz okresowe komunikaty nadzorcze (esma.europa.eu). Wymóg disclosure'ów dla brokerów CFD w UE — procent stratnych rachunków detalicznych aktualizowany kwartalnie, baza dla informacji o odsetku stratnych rachunków CFD u brokerów detalicznych w UE.
- Ministerstwo Finansów RP, Ustawa o podatku dochodowym od osób fizycznych, art. 30b oraz formularz PIT-38 (podatki.gov.pl). Stawka 19% od dochodu z kapitałów pieniężnych dla rezydentów polskich, możliwość rozliczania strat w okresie 5 kolejnych lat.