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:
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.
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 );
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 );