NinjaTrader: OnBarClose, OnEachTick, OnPriceChange - kiedy strategia liczy
W skrócie: w NinjaTrader 8 jedno ustawienie, Calculate, decyduje o tym, jak często platforma wywołuje logikę strategii: raz na zamkniętą świecę, na każdym ticku albo przy każdej zmianie ceny. Od niego zależy, co znaczy “bieżąca świeca” w kodzie. Największa pułapka: zwykły backtest liczy na zamknięciu świecy niezależnie od tego, co ustawisz, więc strategia tickowa wygląda w teście inaczej niż na żywo. Kto zna MT5, znajdzie tu ten sam problem co “każdy tik kontra nowa świeca”, tylko rozwiązany przełącznikiem.
Trzy tryby
Strategia w NinjaScript ma jedną główną metodę, OnBarUpdate(). Ustawienie Calculate mówi, kiedy platforma ją
wywoła.
| Tryb | Kiedy wywoływana jest logika | Co oznacza świeca [0] |
|---|---|---|
| OnBarClose | raz, gdy świeca się zamknie | ostatnia zamknięta świeca |
| OnEachTick | przy każdym ticku | świeca, która właśnie się tworzy |
| OnPriceChange | tylko gdy zmieni się cena | świeca, która właśnie się tworzy |
OnBarClose jest domyślny i najprostszy. Sygnał powstaje na zamkniętej świecy, zlecenie idzie na początku następnej. Kod jest krótki, wynik powtarzalny, obciążenie procesora małe.
OnEachTick wywołuje logikę przy każdej transakcji na rynku. Na kontrakcie takim jak NQ to tysiące wywołań na minutę w ruchliwych godzinach. Potrzebny, gdy strategia ma reagować w środku świecy: wejście na dotknięcie poziomu, przesuwanie stop lossa co tick.
OnPriceChange to kompromis. Jeśli dziesięć kolejnych transakcji przeszło po tej samej cenie, logika wykona się raz. Dla strategii, która patrzy tylko na cenę, wynik jest taki sam jak w OnEachTick przy ułamku obciążenia. Nie nadaje się, gdy kod liczy wolumen albo liczbę ticków.
Ta sama linia kodu, inne znaczenie
Najwięcej błędów bierze się z tego, że Close[0] zmienia znaczenie razem z trybem. W OnBarClose to cena
zamknięcia gotowej świecy. W dwóch pozostałych to ostatnia cena świecy, która jeszcze trwa, i z każdym tickiem
jest inna.
Warunek “zamknięcie powyżej średniej” przeniesiony bez zmian z OnBarClose do OnEachTick przestaje znaczyć
zamknięcie. Strategia wchodzi w chwili, gdy cena pierwszy raz przebije średnią w trakcie świecy, także wtedy,
gdy świeca zamknie się z powrotem poniżej. W trybach tickowych zamknięta świeca to [1].
Jest też rozwiązanie mieszane: tryb tickowy i sprawdzanie sygnału tylko na pierwszym ticku nowej świecy
(IsFirstTickOfBar). Sygnały liczone są wtedy raz na świecę z zamkniętych danych, a zarządzanie pozycją
działa co tick.
Pułapka w backteście
W Strategy Analyzerze dane historyczne są domyślnie przetwarzane świeca po świecy. Platforma zna cztery ceny świecy i wywołuje logikę raz na świecę, niezależnie od ustawionego trybu Calculate. Strategia z OnEachTick jest więc testowana jak OnBarClose, a na żywo działa inaczej. Wyniki testu i konta rozjeżdżają się od pierwszego dnia.
Są dwa sposoby, żeby test był bliżej prawdy.
Tick Replay odtwarza historię tick po ticku i wtedy tryby tickowe działają w teście tak jak na żywo. Wymaga danych tickowych i wydłuża test wielokrotnie.
Drugi sposób to dodanie do strategii drugiej, drobnej serii danych (np. 1 tick albo 1 sekunda) i wysyłanie zleceń na niej. Logika sygnału zostaje na zamkniętych świecach, a wypełnienia zleceń są liczone z drobnych danych. Tańsze niż Tick Replay i często wystarcza.
Odpowiedniki w MT5
Kto pisze boty w MQL5, zna ten problem pod inną nazwą.
| NinjaTrader | MT5 |
|---|---|
| OnBarClose | bot sam wykrywa nową świecę w OnTick i liczy sygnał tylko wtedy |
| OnEachTick | logika w OnTick przy każdym ticku |
| OnPriceChange | brak gotowego odpowiednika, warunek trzeba dopisać w kodzie |
| backtest świeca po świecy | tryb “Tylko ceny otwarcia” albo “1 minuta OHLC” |
| Tick Replay | tryb “Każdy tik na podstawie rzeczywistych tików” |
Różnica w podejściu: w MT5 o częstotliwości decyduje kod bota, a tryb testu wybiera się osobno w testerze. W NinjaTrader tryb jest ustawieniem strategii, ale backtest i tak ma swoje zdanie. W obu platformach skutek niedopatrzenia jest ten sam: test na świecach zawyża wynik strategii, która wchodzi w środku świecy. Na liczbach z MT5 pokazuję to w artykule OHLC kontra prawdziwe tiki.
Który tryb wybrać
Zaczynam od pytania, czy strategia naprawdę potrzebuje ticków. Jeśli sygnał powstaje na zamknięciu świecy, a stop loss i take profit leżą jako zlecenia u brokera, OnBarClose wystarczy i test będzie zgodny z kontem.
Tryb tickowy ma sens, gdy wejście lub wyjście zależy od ceny w środku świecy. Wtedy test bez Tick Replay albo drobnej serii danych nie jest wiarygodny i nie ma co na nim optymalizować.
[DO UZUPEŁNIENIA: własny przykład strategii w NinjaTrader - ten sam test w OnBarClose i z Tick Replay, różnica w wyniku.]
Checklista
- wiem, czy strategia podejmuje decyzje na zamkniętej świecy, czy w jej trakcie,
- w trybie tickowym zamknięta świeca to
[1], a nie[0], - sygnały liczone raz na świecę, zarządzanie pozycją co tick, jeśli strategia tego wymaga,
- backtest strategii tickowej z Tick Replay albo z drobną serią danych do wypełnień,
- wynik testu porównany z kilkoma dniami na koncie symulacyjnym,
- OnPriceChange tylko wtedy, gdy kod nie liczy wolumenu ani ticków.
Powiązane
- OHLC kontra prawdziwe tiki
- Mikro kontrakty futures: MES, MNQ, MGC
- Spread w backteście: świece M1 kontra tiki
- Pojęcia z artykułu: słowniczek, skorowidz
Źródła
- NinjaTrader 8 Help Guide, hasła Calculate, OnBarUpdate, IsFirstTickOfBar, Tick Replay: ninjatrader.com/support/helpGuides/nt8
Ostrzeżenie: handel kontraktami futures i CFD wiąże się z wysokim ryzykiem utraty kapitału. Artykuł ma charakter edukacyjny i nie jest rekomendacją inwestycyjną.