W poprzednim odcinku „Profesjonalnego inwestora" pokazaliśmy, jak zbudować prostego robota inwestycyjnego, który będzie otwierał pozycję długą, gdy na wykresie pojawi się sekwencja trzech wzrostowych świec, i krótką, gdy pojawi się sekwencja trzech świec spadkowych. Sprawdzając jego działanie na rachunku demo, zauważyliśmy, że zawiera on transakcje zbyt często, a jedynym ograniczeniem jest dla niego wielkość dostępnych na rachunku wolnych środków. Dlaczego tak się dzieje i jak rozwiązać ten problem?
Problem funkcji OnTick()
Na wstępie chcieliśmy zaznaczyć, że dzisiejszym odcinkiem wkraczamy na nieco bardziej zaawansowany poziom programowania, do którego zrozumienia potrzebna jest przynajmniej lektura poprzednich części tego cyklu. Ponadto chcieliśmy nadmienić, że wszystkie zaproponowane tutaj rozwiązania dotyczące kodowania poszczególnych elementów robota nie są ani najbardziej efektywne, ani ostateczne. Z programowaniem jest bowiem jak z matematyką – do rozwiązania problemu można dojść na wiele sposobów. Dlatego też zachęcamy czytelników do wysyłania sugestii, uwag i propozycji na nasz adres e-mail, najlepiej e-mail autora tego cyklu.
Przejdźmy teraz do sedna dzisiejszego tematu. Tydzień temu wspominaliśmy, że instrukcje robota umieszczone są wewnątrz funkcji specjalnej „OnTick()", która jest wywoływana za każdym razem, gdy kurs danego aktywa (w przypadku naszego robota była to para walutowa EUR/USD) wykona minimalny ruch, wynikający z zawarcia jakiejś transakcji na rynku. Tym samym nasz robot z każdym takim tickiem sprawdzał, czy warunki otwarcia pozycji są spełnione. Przykładowo – jeśli uruchomiliśmy go na wykresie minutowym, na którym właśnie budowana była kolejna świeca, a trzy poprzednie były wzrostowe, to z każdym tickiem robot otwierał długą pozycję (dopóki nie zabrakło mu środków na rachunku). Z każdą nową transakcją robot dostawał bowiem informację, że na wykresie są trzy białe świece. Ten przykład dobrze ilustruje to, jak istotnym elementem programowania jest przewidywanie różnych możliwych scenariuszy. Musimy pamiętać, że robot będzie działał tak, jak go „nauczymy", sam z siebie nic nie wymyśli, a już na pewno się nie domyśli, że gdzieś popełniamy błąd. Instrukcje muszą więc bardzo precyzyjnie wyjaśniać to, w jaki sposób ma działać nasza strategia. Pamiętajmy, że podczas kompilacji kodu program sprawdza tylko poprawność składni, nie jest natomiast w stanie wychwycić błędów w konstrukcji samej strategii (przykładowo – program nie zwróci błędu, jeśli warunki kupna i sprzedaży ustawiliśmy na odwrót).
Aby rozwiązać nasz problem, musimy zakodować robotowi kolejny warunek – by kryteria otwarcia pozycji sprawdzał tylko wtedy, gdy na wykresie pojawi się nowa świeca. W tym celu musimy zbudować funkcję logiczną, która zwróci „true", gdy na wykresie pojawi się nowa świeca, i „false", gdy takowa się nie pojawi. Jak to zrobić?
Zmienna statyczna
Sposobów dodania takiego warunku jest dużo. My wybraliśmy propozycję vlogera (https://www.youtube.com/channel/UC6NkmY-LH2p8tJdpLJ2M7iA) zaprezentowaną w odcinku 11. Kod funkcji logicznej „IsNewCandle()" zaprezentowany jest na obrazku obok. Logika tej funkcji polega w skrócie na tym, że sprawdza ona, czy na wykresie pojawiła się nowa świeca czy nie. W tym celu z każdym tickiem będzie ona porównywać aktualną liczbą świec do tej sprzed ticku i jeśli liczby będą sobie równe, to zwróci „false" (bo nie pojawiła się nowa świeca), a jeśli będą różne, to zwróci „true".