Język AFL w Amibrokerze jest potężnym narzędziem konstruowania systemów inwestycyjnych. Można też przeprowadzić bardzo rozbudowane testy zanim zainwestuje się prawdziwe pieniądze. Jednak te kilka błędów może spowodować, że wszystkie testy będą przekłamane, a Twoja inwestycja będzie zagrożona. Zobacz jak się przed tym uchronić.

Błąd piąty jest charakterystyczny dla programowania systemów inwestycyjnych w Amibrokerze. Wynika on ze specyficznego podejścia w nim do zmiennych tablicowych. Oczywiście wynika też z niezrozumienia do końca jak są one obsługiwane.

Ciekawe jest to, że błędy takie trafia się głównie ludziom znającym już język AFL. Dzieje się tak w wyniku tego, że zaczynają swoją drogę od systemów prostych do bardziej skomplikowanych.

Akurat tydzień przed pisaniem tego artykułu otrzymałem zapytanie od jednego z moich uczniów: "czemu nie działa?". Był tam właśnie dokładnie taki błąd.

Nie zdradzę oczywiście jego kodu. Wyobraź sobie jednak prosty system np. na wybicie z formacji świecowej. Założenia są takie, że nie inwestujesz od razu gdy formacja wystąpi, tylko czekasz na potwierdzenie. Wybicie z zakresu formacji w jedną stronę daje sygnał kupna, wybicie w drugą daje zanegowanie formacji. Klasyczna interpretacja.

W takim razie, gdy występuje formacja chcesz zapamiętać jej najwyższą wartość, oraz najniższą. Dzięki temu uzyskasz kanał dwóch cen i możesz obserwować jego przebicie.

I tu pojawił się problem. Niektórzy bowiem próbują stosować konstrukcję: 

            //w zmiennej "formacja" są już miejsca gdzie ona występuje.
            kanalGorny = High;
            kanalGorny = Iif( formacja, kanalGorny, Ref(kanalGorny,-1));

Okazuje się jednak, że to nie tworzy kanału. Działa tylko dla następnego słupka, a potem jest lipa.

Wtedy pojawiają się pytania o kolejność przetwarzania danych. No bo przecież jeżeli od lewej strony tablicy, to powinno wstawić High tam gdzie występuje formacja, a w następnych słupkach powinno przepisywać tą wartość z poprzedniej komórki.

Jeżeli też spotkałeś taki problem, to musisz sobie zadać inne pytanie. Jak w ogóle przetwarzane są zmienne w funkcjach?

Otóż wywołanie funkcji powoduje utworzenie kopii zmiennej. Dlatego tworzona na nowo zmienna kanalGorny jest inną zmienną niż zmienna kanalGorny w parametrach funkcji. Przy obliczaniu kolejnych słupków dane są czytane z oryginalnej zmiennej, a zapisywane w nowej. Dopiero po policzeniu wszystkiego stara zmienna jest zastępowana nową. Dlatego nie ma dostępu do wyniku obliczeń w trakcie liczenia.

Jak w takim razie poradzić sobie z tym problemem?

Rozwiązań jest jak zwykle kilka. Najłatwiejsze jednak do zrozumienia jest to z pętlą. 

            kanalGorny = High;
            for(i=1; i<barsCount; i++)
            {
                        if( !formacja )  kanalGorny[i] = kanalGorny[i-1];
            }

Taki kod przeciągnie wartość kanału od formacji do końca wykresu lub do następnego wystąpienia formacji. Tam gdzie jest formacja zostawia High, a dla kolejnych słupków pobiera wartość ze słupka wcześniejszego. Tu nie ma problemu zmiennej i jej kopii. Tym prostym sposobem możesz już badać przecięcie wykresu i kanału.

Sposób zapisu za pomocą instrukcji tablicowych tu pominę. Jest on krótszy, ale znacznie trudniejszy do zrozumienia.

Zaczynaj od podstaw. Zobaczysz wtedy, że tworzenie systemów jest proste.

Licencja: Creative Commons