Előre definiált változók és a RefreshRates függvény
Az MQL4 nyelvben vannak előre definiált változó nevek.
Az előre definiált változó egy változó előre definiált névvel, aminek az értékét az ügyfélterminál határozza meg, és nem változtathatjuk meg programozási módszerekkel. Az előre definiált változók visszatükrözik az aktuális chart (szimbólum ábra) állapotát abban a pillanatban, amikor a programjaink (Expert Advisor, script vagy egyéni indikátor) indulnak, vagy a RefreshRates() függvény végrehajtódik.
Az előre definiált változók listája:
Ask - az aktuális szimbólum utoljára ismert eladási ára;
Bid - az aktuális szimbólum utoljára ismert vételi ára;
Bars - egy aktuális ábrán levő bárok száma;
Point –egy pont értéke az aktuális pénznemben;
Digits – az aktuális szimbólum árában levő tizedespont utáni számjegyek száma.
Az előre definiált tömbök nevei:
Time - az aktuális bár nyitási ideje;
Open - az aktuális bár nyitó ára;
Close - az aktuális bár záró ára;
High - az aktuális bár legnagyobb ára;
Low - az aktuális bár minimális ára;
Volume - az aktuális bárban lévő tickek száma.
(a tömbök fogalmát és az előre definiált tőmböket az Arrays részben ismertetjük).Az előre definiált változók tulajdonságai
Az előre definiált változók neveit nem lehet a felhasználó által létrehozott változók azonosítására használni. Az előre definiált változókat használhatunk a kifejezésekben a változókra vonatkozó szabályok szerint, de egy előre definiált változó értékét nem változtathatjuk meg. Ha megpróbálunk lefordítani egy olyan programot, ami egy olyan értékadó operátort tartalmaz, amelyben egy előre definiált változót helyeztek egy egyenlőségjel jobb oldalán, a Meta Editor hibaüzenetet fog adni. Elérhetőség tekintetében az előre definiált változók globális változók, ezek bármely programrészről elérhetők (lásd:A változók típusai).Az előre definiált változók legfontosabb tulajdonságai a következők:
Figyelem!
Minden előre definiált változó értékét automatikusan frissíti az ügyfélterminál, abban a pillanatban, amikor a különleges függvényeket elindítja.
Az előre definiált változók előző és aktuális értékei egyenlők lehetnek, de magát az értéket frissíteni fogják. Egy különleges függvény végrehajtásának legelső pillanatában ezeket a változókat frissítik és már az első programsorokból elérhetők. Hagy illusztráljuk az előre definiált változó frissítését a következő példán (predefined.mq4 Expert Advisor):
//--------------------------------------------------------------------
// predefined.mq4
// The code should be used for educational purpose only.
//--------------------------------------------------------------------
int start() // Special funct. start
{
Alert("Bid = ", Bid); // Current price
return; // Exit start()
}
//--------------------------------------------------------------------
Könnyű észrevenni, hogy ez a program a Bid változó értékeit mutatja a riasztási ablakban, amely minden alkalommal egyenlő lesz az aktuális árral. Ugyanezzel a módszerrel tudod ellenőrizni más változók értékeit. Például az Ask változó szintén a pillanatnyi ártól függ. A Bars változó értéke szintén változni fog, ha a bárok száma változik. Ez annál a ticknél történik, aminél egy új bár kezdődik az ablakban. A Point értéke egy instrumentum tulajdonságainak részletes leírástól függ. Például EUR/USD-nél ez az érték 0.0001, USD/JPY-nél 0.01. A Digits érték ezeknél a valutapároknál egyenlő 4-gyel illetőleg 2-vel.
Itt van az előre definiált változók egy másik fontos tulajdonsága:
Figyelem!
Az ügyfélterminál az előre definiált változók készletét külön-külön biztosítja mindegyik elindított program számára. Mindegyik elindított program a saját történelmi adatait használja.
Ha egy ügyfélterminálban több alkalmazási program (Expert Advisor, script, indikátorok) fut egyszerre, az ügyfélterminál mindegyiküknek külön-külön létre fogja hozni az előre definiált változók (történelmi adatok) értékeinek különálló készletét. Elemezzük részletesen ennek a megoldásnak az okait. Az 52. ábra a különleges start() függvénykülönböző végrehajtás hosszát mutatja két Expert Advisor végrehajtása során. Az egyszerűség kedvéért tegyük fel, hogy a vizsgált Expert Advisorokon kívül nincs másik különleges függvény és minkét Expert Advisors ugyanannak a szimbólumnak azonos idősíkján működik (különböző ablakokban).
52. ábra. A start() függvény műveleti
ideje kisebb vagy nagyobb lehet két tick
közötti
időintervallumnál.
Az Expert Advisorok különbözhetnek a start() függvényük végrehajtás idejében. Közepes szintű Expert Advisornál ez az időtartam 1- 100 milliszekundum. Vannak Expert Advisorok amelyeknél ez másodperceket vagy tíz másodperceket is igénybe vesz. A tickek között időintervallum szintén különböző: több milliszekundum, több perc és néha több tíz perc. Elemezzük az adott példán, hogyan befolyásolja a tickek érkezése az Expert Advisor 1 és Expert Advisor 2 start() függvényeinek végrehajtását.
A t 0 időpillanatnál az Expert Advisor 1-et hozzácsatoljuk az ügyfélterminálhoz és az tickváró módba kerül. Amint a t 1 tick megérkezik, a terminál elindítja a különleges start() függvényt. Azzal együtt a program megkapja az előre definiált változók frissített készletét. Végrehajtása alatt a program használhatja ezeket az értékeket, ezek változatlanok fognak maradni a start() műveleti ideje alatt. Miután start() befejezi a futását, a program ismét tick váró módba fog kerülni.
Az a legközelibb esemény, aminél az előre definiált változók új értékeket kaphatnak egy új tick. Az Expert Advisor 1 start() függvényének végrehajtási ideje T1 lényegesen rövidebb, mint a tickek érkezése közötti időköz, például: t1 - t2 vagy t2 - t3, , stb.. Tehát, a vizsgált Expert Advisor 1 végrehajtási időszaka alatt nem alakul ki olyan helyzet, amiben az előre definiált változók értékei elavulnak, vagyis (utoljára ismert) értékei különböznének az aktuális helyzettől.
Az Expert Advisor 2-nél más a helyzet, mert a start () függvény végrehajtási ideje T2 néha felülmúlja a tickek közötti időközt. Az Expert Advisor 2 start()függvényét szintén a t 1 pillanatban indítják el. Az 52. ábrán láthatjuk, hogy a t 1 - t 2 tickek közötti idő nagyobb a start() T2 végrehajtásnál, ezért a program végrehajtásának ez alatt az időszaka alatt az előre definiált változókat nem frissítették (ebben az időszakban a szerverről új értékek nem származnak, úgyhogy azokat az értékeket kell használni, amiket a t 1 pillanatban kaptunk).
Az Expert Advisor 2-t legközelebbi végrehajtása a t 2 pillanatban kezdődik, amikor a második ticket megkapjuk. Ezzel együtt az előre definiált értékek készletét szintén frissítik. 52. ábrában látjuk, hogy a t 31 pillanat, az új tick érkezése a start() végrehajtási időszakán belül van. Felmerül egy kérdés: Mi lesz az Expert Advisor 2 számára elérhető előre definiált változók értéke a t 3 időponttól (mikor a harmadik tick érkezik) a t 32 időpontig, amikor start() befejezi a működését? A választ a következő szabállyal összhangban megtalálhatjuk:
Figyelem!
Az előre definiált változók értékeit mentik a különleges függvények végrehajtásának egész időszaka alatt. Ezeket az értékeket erőszakosan frissíthetjük a RefreshRates() beépített függvény használatával.
Így (ha RefreshRates() függvényt nem hajtották végre) a start() végrehajtásának az egész időszaka alatt az Expert Advisor 2 az előre definiált változók azon készletét használja, amit akkor mentett, amikor a második ticket megkapta. Bár a két Expert Advisor ugyanabban az ablakban működik, a t 3 pillanattól kezdve a két EA az előre definiált változók különböző értékeivel fog működni. Az Expert Advisor 1 a t 3 pillanatban érkező új adatokkal fog dolgozni, míg az Expert Advisor 2 azokat az adatokat használja, amelyek a t 2 pillanatban érkeztek.
Figyelem!
A hosszabb program végrehajtási idő és a rövidebb tickek közötti időtartam esetén nagyobb a valószínűsége annak, hogy a következő tick a programvégrehajtás-időszak alatt fog jönni. A történelmi adatok készletének helyi másolata mindegyik program számára lehetővé teszi, az előre definiált változók álladóságát minden különleges függvény teljes végrehajtási ideje alatt.
A t 4 pillanattól kezdve, amikor a következő tick jön, mindkét EA megint el fog indulni az előre definiált változók azon saját készletének használatával, amelyeket a t 4 pillanatban (amikor a negyedik tick jött) megkaptak.
RefreshRates() függvény
bool RefreshRates()
A RefreshRates() beépített függvény lehetővé teszi, hogy frissítsük a történelmi adatok értékeinek helyi másolatát. Más szóval ez a függvény erőszakosan frissíti az aktuális piaci adatokat (Volume, az utolsó szerver idő Time[0], Bid, Ask, stb.).Ezt a függvényt akkor használhatjuk, amikor egy program sokáig végzi a számításait és eközben az adatokat frissíteni kell.
A RefreshRates() függvény TRUE-t küld vissza, ha a végrehajtása pillanatában a terminálnak van új információja (új történelmi adatokkal kapcsolatos információ, ha egy új tick jött a különleges függvények végrehajtás alatt). Ez esetben az előre definiált változók helyi másolatainak a készletét frissíteni fogjak.
RefreshRates() FALSE-ot küld vissza, ha a végrehajtásának pillanatáig az ügyfélterminál történelmi adatait még nem frissítették. Ekkor az előre definiált változók helyi másolatai nem változnak.
Figyelem!
Vedd észre, hogy RefreshRates() csak azt a programot befolyásolja, amiben azt elindítják, (és nem minden programot, ami egy időben fut az ügyfélterminálban).
Illusztráljuk
a RefreshRates()
végrehajtást egy példán!
Feladat
21. feladat: Számolja ki az olyan ismétlések a számát, amelyeket a ciklusoperátor a tickek között végre tud hajtani, (egymást követő 5 tick).
Ezt a feladatot csak a RefreshRates() használatával oldhatjuk meg (countiter.mq4 script ):
//--------------------------------------------------------------------
// countiter.mq4
// The code should be used for educational purpose only.
//--------------------------------------------------------------------
int start() // Special funct. start()
{
int i, Count; // Declaring variables
for (i=1; i<=5; i++) // Show for 5 ticks
{
Count=0; // Clearing counter
while(RefreshRates()==false) // Until...
{ //..a new tick comes
Count = Count+1; // Iteration counter
}
Alert("Tick ",i,", loops ",Count); // After each tick
}
return; // Exit start()
}
//--------------------------------------------------------------------
A problémafelvetés feltételei szerint a számításokat csak a legközelebbi öt tick esetén kell elvégezni, ezért tudunk scriptet használni. Két változót használunk a programban: i a tickeket számolja és a Count – számolja az ismétléseket. A külső ciklus a feldolgozott tickek számával összhangban szervezett (1-től 5-ig). A for-ciklus elindítja az ismétlések számolását (a while belső ciklust) és kijelzi a riasztási ablakban az ismétlések és a tickek számát.
A belső 'while' ciklus addig fog működni, amíg a RefreshRates() visszatérési értéke FALSE (hamis) vagyis amíg egy új tick nem jön. A while' futása alatt (a tickek közötti időközben) a Count értéke állandóan növekedni fog; vagyis a 'while' ciklusokat fogja számolni. Ha valamely pillanatban a RefreshRates() visszatérési értéke TRUE (igaz) ez azt jelenti, hogy az előre definiált változók új értéket kaptak az ügyfélterminálban, vagyis egy új tick jött. Ekkor a vezérlés a 'while' cikluson kívülre kerül és a számolás így kész.
A countiter.mq4 script végrehajtásnak eredményeképpen megjelenik egy riasztási ablak:
53. ábra. Az EUR/USD charton dolgozó countiter.mq4 script eredményei.
Láthatjuk, hogy 1 másodperc alatt (a negyedik és az ötödik tick közötti időköz) a script 3 milliónál is több ismétlést hajtott végre. Hasonló eredményeket kapunk más tickeken végzett egyszerű számításoktól.
Térjünk vissza az előző példához ( predefined.mq4 Expert Advisor).Korábban láttuk azt, hogyha a RefreshRates()-t nem hajtjuk végrea z Expert Advisor 2-ben, akkor az előre definiált változók helyi másolatainak az értékei változatlanok fognak maradni a start() végrehajtás egész időszaka alatt. Példánkban a t 2 időponttól a t 32időpontig. Ha a harmadik tick után (amikor start() fut) a RefreshRates() függvény végrehajtjuk például a t 31 időpontban, a helyi másolatok értékei frissítésre kerülnek. A start függvény végrehajtásából fennmaradó időszak alatt, a t 31 (RefreshRates() végrehajtás) és a t 32 (a start() végrehajtás vége) időpontok között, az előre definiált változók helyi másolatainak az új értékei lesznek elérhetők az Expert Advisor 2 számára, amiket az ügyfélterminál a t 3 időponttól kezdődően biztosít.
Ha az Expert Advisor 2-ben a a RefreshRates() függvényt a t 11 vagy a t 21 időpontban hajtjuk végre (akkor amikor a start() függvény kezdete óta még nem volt újabb tick), az előre definiált változók helyi másolatai nem fognak megváltozni. Ilyen esetben az előre definiált változók helyi másolatainak az értékei egyenlők lesznek azokkal az értékekkel, amelyeket az ügyfélterminál a start() különleges függvény utolsó indítása pillanatában meghatározott.