Obsługa wielu interwałów z poziomu AFL

Począwszy od wersji 4.11 możliwe jest użycie wielu interwałów wewnątrz jednej formuły AFL. Funkcje zmiany interwałów można podzielić na 3 kategorie:

  1. zmieniajce interwał tablic: O, H, L, C, V, OI, Avg:TimeFrameSet, TimeFrameRestore
  2. kompresujące / rozciągające pojedynczą tablicę to określonego interwałuTimeFrameCompress, TimeFrameExpand
  3. pozwalające na bezpośredni dostęp do danych (cena,wolumen) w innym interwale TimeFrameGetPrice

Funkcje pierwszej kategorii używane są gdy konieczne jest obliczenie wartości na wskaźnikach w innym interwale niż aktualnie wybrany. Przykładowo gdy niezbędne jest obliczenie 13-okresowej średniej kroczącej na danych 5-minutowych oraz 9-okresowej średniej kroczącej z danych godzinnych, a obecnie wybranym interwałem jest 1-minuta, należy zastosować następującą formułę.

TimeFrameSet( in5Minute ); // przełącz na interwał 5-minut

/* MA używa teraz do obliczeń dnych 5-minutowych, ma5_13 zawiera skompresowane dane 13-okresowej średniej kroczącej bazowanej na danych 5-minutowych */

ma5_13 =
MA( C, 13 );

TimeFrameSet( inHourly ); // przełącz na interwał godzinny

mah_9 =
EMA( C, 9 ); // 9-okresowa średnia krocząca z danych godzinnych

TimeFrameRestore(); // przywróć interwał do początkowego

Plot( Close, "Price", colorWhite, styleCandle );

// rysuj rozciągniętą średnią

Plot( TimeFrameExpand( ma5_13, in5Minute), "13-okresowa średniej krocząca z danych 5-minutowych", colorRed );
Plot( TimeFrameExpand( mah_9, inHourly), "9-okresowa średniej krocząca z danych godzinnych", colorRed );

TimeFrameSet( interval ) - w momencie zmiany interwału wymienia tablice zawierające dane cena/wolumen (czyli open, high, low, close, volume, openint, avg) na skompresowane do określonego interwału dane. Wszystkie obliczenia prowadzone są teraz na danych skompresowanych. Aby przywrócić początkowy interwał, należy użyć funkcji TimeFrameRestore(). Interwał określany jest w sekundach, czyli 60 oznacza interwał 1-minutowy. Możliwe jest również użycie predefiniowanych zmiennych, wygodniejszych w zastosowaniu - czyli: n1Minute, in5Minute, in15Minute, inHourly, inDaily, inWeekly, inMonthly.

TimeFrameRestore() - przywraca oryginalne wartości zmienione przez użycie TimeFrameSet. Istotne jest, iż tylko tablice OHLC, V, OI oraz Avg są przywrócone do wartości stanu początkowego po użyciu TimeFrameRestore(). Wszystkie pozostałe zmienne utworzone w innym interwale pozostają skompresowane. Aby użyć ich w interwale początkowym - należy najpierw rozciągnąć dane to bieżącego interwału używając TimeFrameExpand.

Po zmianie interwału przez użycie TimeFrameSet() wszystkie funkcje działają na zmienionym interwale do czasu przywrócenia interwału początkowego przez użycie TimeFrameRestore(), lub zmiany na inny interwał przez ponowne użycie TimeFrameSet(). Dobrą praktyką jest, aby ZAWSZE przywrócić interwał początkowy.

Kiedy interwał jest przełączony na inny niż opczątkowy, wyniki wszystkich funkcji użytych od czasu zastosowania TimeFrameSet() są również skompresowane. Gdy zachodzi konieczność użycia ich w interwale początkowym, potrzebne jest ich 'rozciągnięcie' (jest to opisane w dalszej części tego rozdziału). Zmienne utworzone przed użyciem TimeFrameSet() pozostają niezmienione - czyli w takim interwale w jakim były utworzone. Pozwala to na użycie dowolnej liczby interwałów w obrębie jednej formuły.

Istotną sprawą jest, że możliwe jest jedynie skompresowanie danych z interwału krótszego na dłuższy. Zatem pracując na danych 1-minutowych można uzyskać interwały 2, 3, 4, 5, 6, ....N-minutowe. Natomiast bazując na danych 15-minutowych niemożliwe jest uzyskanie danych 1-minutowych. Z tego samego powodu nie można uzyskać interwałów śródsesyjnych z danych EOD.

Druga kategoria: TimeFrameCompress/TimeFrameExpand pozwalają na skompresowanie / rozciągnięcie pojedynczych zmiennych z / do innych interwałów. Szczególnie ważną jest funkcja TimeFrameExpand() która używana jest to dekompresowania (rozciągnięcia) zmiennych obliczonych w innym interwale. Jest to niezbędne do ich poprawnego wyświetlania i użycia w interwale początkowym. Przykładowo - gdy chcemy wyświetlić średnią kroczącą bazowaną na danych tygodniowych - jej wartości muszą być rozciągnięte tak aby jedna wartość średniej tygodniowej odpowiadała 5 wartościom danych dziennych.

TimeFrameExpand( zmienna, interwał, tryb = expandLast ) - rozciąga skompresowaną zmienną z 'interwału' w którym zmienna została utworzona do interwału bazowego ('interwał' musi odpowiadać interwałowi w którym zmienna była utworzona przy użyciu TimeFrameCompress lub TimeFrameSet):
expandLast - skompresowana zmienna jest rozciągana zaczynając od ostatniego słupka danego okresu (czyli tygodniowa cena zamknięcia, najwyższa i najnisza cena są dostępne w piątek)
expandFirst - skompresowana zmienna jest rozciągana zaczynając od pierwszego słupka danego okresu (czyli tygodniowa cena otwarcia jest dostępna w poniedziałek)
expandPoint - wartość zmiennej jest przypisana do ostatniego słupka danego okresu, dla pozostałych słupków nie jest przypisana wartość zmiennej (pozostają puste) .

Uwaga: tryb expandFirst użyty dla cenn innych niż otwarcie (Open) może spowodować, że formuła będzi się odwoływać do danych z przyszłości. Przykładowo - jeśli utworzona zostanie w tym trybie (ExpandFirts) zmienna zawierająca najwyższą cenę tygodniową, rozciągnięcie do interwału dziennego w trybie ExpandFirst spowoduje, że cena ta będzie teoretycznie znana już od poniedziałku (a nie jak w rzeczywistości od piątku)

TimeFrameCompress pozwala na skompresowanie pojedynczej zmiannej bez potrzeby zmieniania wszystkich cen OHLC,V. Użycie TimeFrameCompress() nie wpływa na rezultaty innych funkcji.

wc = TimeFrameCompress( Close, inWeekly );

/* interwał jest ciągle niezmieniony i w dalszym ciągu program używa danych bazowych, np. dziennych */

dailyma =
MA( C, 14 );

/* ale obliczenie średniej ze skompresowanych danych pozwala na użycie danych tygodniowych */

weeklyma =
MA( wc, 14 ); // wc jest skompresowaną zmienną

Plot( dailyma, "DailyMA", colorRed );

weeklyma =
TimeFrameExpand( weeklyma, inWeekly ); // rozciągnięcie zmiennej aby można było prawidłowo wyświetlić wykres

Plot( weeklyma, "WeeklyMA", colorBlue );

W tej formule interwał pozostał niezmieniony, użyta była tylko pojedyncza skompresowana zmienna

TimeFrameCompress( array, interval, mode = compressLast )
- kompresuje daną zmienną do zadanego interwału w jednym z następujących trybów:
compressLast - wartość ostatnia (Close) zmiennej w danym interwale
compressOpen - wartość pierwsza (Open) zmiennej w danym interwale
compressHigh - najwyższa wartość zmiennej w danym interwale
compressLow - najniższa wartość zmiennej w danym interwale
compressVolume - suma wartości zmiennej w danym interwale

Graph0 = TimeFrameExpand( TimeFrameCompress( Close, inWeekly, compressLast ), inWeekly, expandLast );
Graph1 = TimeFrameExpand( TimeFrameCompress( Open, inWeekly, compressOpen ), inWeekly, expandFirst );

Trzecia grupa to jedna użyteczna funkcja: TimeFrameGetPrice która pozwala odwołać się do cen i wolumenu z innego interwału bez potrzeby przełączania, kompresowania i rozciągania zmiennych. Funkcja te pozwala nie tylko na odwołanie się do bieżących danych ale również danych historycznych z różnych interwałów.

TimeFrameGetPrice( pricefield, interval, shift = 0, mode = expandFirst );
- odwołuje się do cen OHLCV z wyższych interwałów. Działa natychmiastowo i nie ma zupełnie potrzeby użycia funkcji TimeFrameSet.
Cena tojedno z następujących pól: "O", "H", "L", "C", "V", "I" (open interest - liczba otwartych pozycji). Interval to interwał okrelonyw sekundach. Shift (przesunięcie) pozwana na odwołanie się w wyższym interwale do danych wcześniejszych (gdy shift przyjmuje wartości ujemne) i przyszłych (wartości dodatnie). Przykładowo -1 da w efekcie poprzednią wartość zmiennej (tak jak funkcja Ref, ale z wyższego interwału).

Przykłady:

TimeFrameGetPrice( "O", inWeekly, -1 ) // gives you previous week Open price
TimeFrameGetPrice( "C", inWeekly, -3 ) // gives you weekly Close price 3 weeks ago
TimeFrameGetPrice( "H", inWeekly, -2 ) // gives you weekly High price 2 weeks ago
TimeFrameGetPrice( "O", inWeekly, 0 ) // gives you this week Open price.
TimeFrameGetPrice( "H", inDaily, -1 ) // daje najwyższą cenę ubiegłego dnia (bazując na danych śródsesyjnych).

Shift działa jak funkcja Ref() ale stosowany jest do danych skompresowanych.

Note these functions work like these 3 nested functions

funkcje te działają jak trzy zagnieżdżone funkcje, dlatego też gdy shift = 0 dane skompresowane mogą odwoływać się do przyszłości (np. najwyższa cena tygodnia może być znana już w poniedziałek). Dlatego jeśli funkcja ta jest użyta w systemie transakcyjnym, należy pamiętać aby odwoływać się do danych wcześniejszych poprzez stosowanie ujemnych wartośći parametru shift.

Jedyną różnicą jest to, że TimeFrameGetPrice jest 2x szybsza niż zagnieżdżone Expand/Compress.

Wydajność funkcji TimeFrame:

a) Pomiary wykonano na komputerze z procesorem Athlon 1.46GHz, 18500 słupków danych dziennych skompresowanych do interwału tygodniowego.

TimeFrameGetPrice( "C", inWeekly, 0 ) - 0.0098 sec (9.8 milliseconds)
TimeFrameSet( inWeekly ) - 0.012 sec (12 milliseconds)
TimeFrameRestore( ) - 0.006 sec (6 milliseconds)
TimeFrameCompress( Close, inWeekly, compressLast ); - 0.0097 sec (9.7 milliseconds)
TimeFrameExpand( array, inWeekly, expandLast ); - 0.0098 sec (9.8 milliseconds)

b) Pomiary wykonano na komputerze z procesorem Athlon 1.46GHz, 1000 słupków danych dziennych skompresowanych do interwału tygodniowego - wszystkie funkcje poniżej 0.0007 sec (0.7 millisecond)

EXAMPLES

Przykład 1: Rysowanie wykresu tygodniowego MACD z danych dziennych

TimeFrameSet( inWeekly );
m =
MACD(12, 26 ); // MACD z danych tygodniowych
TimeFrameRestore();

m1 =
TimeFrameExpand( m, inWeekly );

Plot( m1, "Weekly MACD", colorRed );
PlotShapes( Cross( m1, 0 ) * shapeUpArrow, colorGreen );
PlotShapes( Cross( 0, m1 ) * shapeDownArrow, colorGreen );

PRZYKŁAD 2: tygodniowy wykres świecowy rysowany wraz z wykresem dziennym

wo = TimeFrameGetPrice( "O", inWeekly, 0, expandPoint );
wh =
TimeFrameGetPrice( "H", inWeekly, 0, expandPoint );
wl =
TimeFrameGetPrice( "L", inWeekly, 0, expandPoint );
wc =
TimeFrameGetPrice( "C", inWeekly, 0, expandPoint );

PlotOHLC( wo, wh, wl, wc, "Weekly Close", colorWhite, styleCandle );
Plot( Close, "Daily Close", colorBlue );

EXAMPLE 3: Uproszczony system Triple screen

/* przełącza interwał na tygodniowy */
TimeFrameSet( inWeekly );
whist =
MACD( 12, 26 ) - Signal( 12, 26, 9 );
wtrend =
ROC( whist, 1 ); // trend tygodniowy - tygodniowa zmiana tygodniowego histogramu MACD
TimeFrameRestore();

/* rozciągnięcie obliczonego MACD do interwału dziennego, aby można było go użyć z sygnałami z danych dziennych */
wtrend =
TimeFrameExpand( wtrend, inWeekly );


/* elder ray */
bullpower=
High - EMA(Close,13);
bearpower=
Low - EMA(Close,13);

Buy = wtrend > 0 /* test 1: wzrostowy trend tygodniowy */
AND
bearpower <
0 AND bearpower > Ref( bearpower, -1 ) /* test 2: bear power ujemny ale rosnący */
AND
H > Ref( H, -1 ); /* test 2: czy cena ustanowiła nowe maksimum */

BuyPrice = Ref( H, -1 ); // określenie poziomu zlecenia stop;

Sell = 0 ; // zamykaj pozycję tylko przy użyciu zleceń stop
ApplyStop( stopTypeProfit, stopModePercent, 30, True );
ApplyStop( stopTypeTrailing, stopModePercent, 20, True );