Co zrobić kiedy oglądasz kod czyjegoś systemu inwestycyjnego i jest on nieczytelny?
Autorem artykułu jest Rafał Wysocki
Internet jest kopalnią wiedzy. Pasjonaci z całego świata dzielą się swoimi odkryciami i doświadczeniem. Nawet tak złożone rzeczy jak systemy inwestycyjne są publikowane w wielu miejscach. Czasami są to całe gotowce, czasami fragmenty rozwiązań. Jednak takie kody są niejednokrotnie bardzo zagmatwane.
Jakość kodów z internetu jest bardzo różna, ale często można się w nich czymś zainspirować.
Znajdujesz wreszcie interesujący, ale skomplikowany, wielokrotnie zagnieżdżony kod. Może jeszcze bez właściwego formatowania i komentarzy. Większość twórców systemów inwestycyjnych albo zamknie stronę uznając, że nie rozszyfruje go. Niektórzy będą łamać sobie głowę usiłując dociec "co autor tutaj chciał uzyskać". Jedynie nieliczni najpierw zajmą się czytelnością i przejrzystością kodu.
Przykładowy, bardzo prosty, szkoleniowy system w AFL. Inwestuje on na przecięcia dwóch średnich. Przygotowany jest do rysowania sygnałów na wykresie, a zarazem do backtestu, optymalizacji czy walk-forwardu.
//#######################################################
P1=Optimize("Period1",Param("Period1",10,2,25,1),2,26,2);
P2=Optimize("Period2",Param("Period2",50,20,100,2),20,100,5);
if (P1>=P2){Buy=Short=False;}else{
Buy=Cross(MA(Close,P1),MA(Close,P2));
Short=Cross(MA(Close,P2),MA(Close,P1));}
Sell=Short;Cover=Buy;
PlotShapes(Buy*shapeUpArrow,colorGreen);PlotShapes(Sell*shapeDownArrow,colorRed);
//#######################################################
Oczywiście jest to kod specjalnie przeze mnie zaciemniony. Działa i liczy prawidłowo. Ale pomimo, ze jest bardzo prostym kodem - jest nieczytelny.
Jak sprawić, aby był bardziej strawny dla osoby, która nie jest programistą?
Po pierwsze: Zastosuj prawidłowe formatowanie tekstu. Zastosuj prawidłowe wcięcia i dodaj odstępy. Zarówno wewnątrz instrukcji, jak i pomiędzy grupami elementów. Istnieje kilka sposobów uznanych formatowań. Tutaj przedstawię Ci mój ulubiony.
//#######################################################
P1 = Optimize("Period1",Param("Period1",10,2,25,1),2,26,2);
P2 = Optimize("Period2",Param("Period2",50,20,100,2),20,100,5);
if (P1 >= P2)
{
Buy = Short = False;
}
else
{
Buy = Cross(MA(Close,P1),MA(Close,P2));
Short = Cross(MA(Close,P2),MA(Close,P1));
}
Sell = Short;
Cover = Buy;
PlotShapes(Buy*shapeUpArrow,colorGreen);
PlotShapes(Sell*shapeDownArrow,colorRed);
//#######################################################
- dodaj spacje przed operatorami i po nich (tutaj " = ", " >= ")
- niech w jednej linii znajduje się tylko jedna instrukcja
- sformatuj instrukcje blokowe, dodaj wcięcia dla wszystkich bloków. Tutaj instrukcja if ma po sobie bloki wykonywane w zależności od warunku.
- podziel na moduły. Tutaj najpierw są parametry, potem obliczenia. Na koniec jest skompletowanie brakujących zmiennych oraz rysowanie strzałek.
Wciąż ten sam kod, a już wygląda lepiej. Od razu widać co wykonuje się gdy warunek jest prawdą, a co gdy fałszem. Od razu widać gdzie następuje przygotowanie do obliczeń, gdzie właściwe obliczenia i gdzie znajduje się ostatnie porządkowanie wyników.
Po drugie: Rozwiń zagnieżdżenia. W prezentowanym kodzie nie są one nawet tak głębokie, ale i tak czytelność bardzo przez nie traci. Zamiast wpisywania funkcji jako parametrów w innych funkcjach - użyj zmiennych pośrednich. Nadaj im dodatkowo nazwy, które ułatwią analizę kodu.
//#######################################################
Parametr1 = Param("Period1",10,2,25,1);
Parametr2 = Param("Period2",50,20,100,2);
P1 = Optimize("Period1", Parametr1 ,2,26,2);
P2 = Optimize("Period2", Parametr2 ,20,100,5);
if (P1 >= P2)
{
Buy = Short = False;
}
else
{
Srednia1 = MA(Close,P1);
Srednia2 = MA(Close,P2);
Buy = Cross( Srednia1 , Srednia2 );
Short = Cross( Srednia2 , Srednia1 );
}
Sell = Short;
Cover = Buy;
PlotShapes(Buy*shapeUpArrow,colorGreen);
PlotShapes(Sell*shapeDownArrow,colorRed);
//#######################################################
Od razu widać skąd się biorą parametry z okienka "Properties", skąd się biorą parametry do optymalizacji. Widać też gdzie są liczone średnie i jak liczone są ich przecięcia.
Po trzecie: Dodaj własne komentarze
//#######################################################
//Pytanie o parametry w okienku properties
Parametr1 = Param("Period1",10,2,25,1);
Parametr2 = Param("Period2",50,20,100,2);
//Parametry podczas optymalizacji
P1 = Optimize("Period1", Parametr1 ,2,26,2);
P2 = Optimize("Period2", Parametr2 ,20,100,5);
//obliczenia
if (P1 >= P2)
{
//nic nie licz, gdy okres średniej drugiej jest mniejszy niż okres średniej pierwszej
Buy = Short = False;
}
else
{
//policz śrenie
Srednia1 = MA(Close,P1);
Srednia2 = MA(Close,P2);
//znajdź ich przecięcia
Buy = Cross( Srednia1 , Srednia2 );
Short = Cross( Srednia2 , Srednia1 );
}
//zamknięcie poprzedniej inwestycji, gdy otwiera się w drugim kierunku
Sell = Short;
Cover = Buy;
//narysuj strzałki
PlotShapes(Buy*shapeUpArrow,colorGreen);
PlotShapes(Sell*shapeDownArrow,colorRed);
//#######################################################
Po czwarte: Dodatkowo możesz wprowadzić rysowanie samych średnich. Na początku kodu zapytaj o kolory, a po obliczeniu średnich narysuj je.
//#######################################################
//Pytanie o parametry średniej 1 w okienku properties
Parametr1 = Param("Period1",10,2,25,1);
Kolor1 = ParamColor("Color1",colorRed);
//Pytanie o parametry średniej 2 w okienku properties
Parametr2 = Param("Period2",50,20,100,2);
Kolor2 = ParamColor("Color2",colorBlue);
//Parametry podczas optymalizacji
P1 = Optimize("Period1", Parametr1 ,2,26,2);
P2 = Optimize("Period2", Parametr2 ,20,100,5);
//obliczenia
if (P1 >= P2)
{
//nic nie licz, gdy okres średniej drugiej jest mniejszy niż okres średniej pierwszej
Buy = Short = False;
}
else
{
//policz śrenie
Srednia1 = MA(Close,P1);
Srednia2 = MA(Close,P2);
//narysuj średnie
Plot(Srednia1,"Szybka", Kolor1 ,styleLine);
Plot(Srednia2,"Wolna", Kolor2 ,styleLine);
//znajdź ich przecięcia
Buy = Cross( Srednia1 , Srednia2 );
Short = Cross( Srednia2 , Srednia1 );
}
//zamknięcie poprzedniej inwestycji, gdy otwiera się w drugim kierunku
Sell = Short;
Cover = Buy;
//narysuj strzałki
PlotShapes(Buy*shapeUpArrow,colorGreen);
PlotShapes(Sell*shapeDownArrow,colorRed);
//#######################################################
I tak mało czytelny kod staje się bardzo czytelny. Nawet gdy zapiszesz go na dysku i wrócisz do niego za rok, szybko zorientujesz się o co w nim chodzi.
Oczywiście tak również należy pisać własne systemy inwestycyjne. Pisz czytelnie dla siebie samego. W momencie gdy piszesz, pamiętasz wszystko i możesz mieć wrażenie, że nie potrzebujesz komentarzy, formatowania, czy zmiennych pośrednich. Jednak będzie Ci znacznie łatwiej, gdy wrócisz do tego zapisu po długim okresie.
Ułatwiaj sobie pracę i zawsze twórz bibliotekę gotowych rozwiązań. Przyjdzie taki moment, że zacznie to procentować i przyspieszy znacznie Twoje pisanie systemów.
---
Chcesz zbudować własny system inwestycyjny?
Zobacz więcej na http://zobacz.CzarodziejAFL.pl/
Akcje, Kontrakty FW20, DAX, S&P500, Forex.
Artykuł pochodzi z serwisu
www.Artelis.pl