Példák a megvalósításra
Az előző részben elemeztünk egy példát a különleges függvények végrehajtására az egyszerű simple.mq4 Expert Advisor segítségével. Gyakorlásképpen elemezzük ennek a programnak még néhány módosítását!Példa
Példa egy helyes programszerkezetre
Általános szabály, hogy a függvényleírásokat ugyanabban a sorrendben írják le a programban, ahogyan őket az ügyfélterminál végrehajtásra hívja, mégpedig először az init() különleges függvény leírása, azután a start() és végül a deinit() következik. Azonban különleges függvények végrehajtása a tulajdonságaik alapján, és nem a programban elfoglalt helyük alapján történik. Változtassuk meg a függvényleírások sorrendjét és lássuk az eredményt (Expert Advisor possible.mq4).
//--------------------------------------------------------------------
// possible.mq4
// To be used as an example in MQL4 book.
//--------------------------------------------------------------------
int Count=0; // Global variable
//--------------------------------------------------------------------
int start() // Special funct. start()
{
double Price = Bid; // Local variable
Count++;
Alert("New tick ",Count," Price = ",Price);// Alert
return; // exit start()
}
//--------------------------------------------------------------------
int init() // Special funct. init()
{
Alert ("Function init() triggered at start");// Alert
return; // Exit init()
}
//--------------------------------------------------------------------
int deinit() // Special funct. deinit()
{
Alert ("Function deinit() triggered at exit");// Alert
return; // Exit deinit()
}
//--------------------------------------------------------------------
Indítsd el ezt az Expert Advisor és látni fogod, hogy a különleges függvények védrehajtási sorrendje egy programban nem függ a leírásuk sorrendjétől. Megváltoztathatod a függvényleírások pozícióit egy forráskódban és az eredmény ugyanaz lesz, mint a simple.mq4 Expert végrehajtásában.
Figyelem!
Példa a helytelen programszerkezetre
Azonban a program másképp fog viselkedni, ha megváltoztatjuk a fejrész pozícióját. A példánkban start() függvényt a fejrész elé tesszük (incorrect.mq4 Expert Advisor):
//--------------------------------------------------------------------
// incorrect.mq4
// To be used as an example in MQL4 book.
//--------------------------------------------------------------------
int start() // Special funct. start()
{
double Price = Bid; // Local variable
Count++;
Alert ("New tick ",Count," Price = ",Price);// Alert
return; // Exit start()
}
//--------------------------------------------------------------------
int Count=0; // Global variable
//--------------------------------------------------------------------
int init() // Special funct. init()
{
Alert ("Function init() triggered at start");// Alert
return; // Exit init()
}
//--------------------------------------------------------------------
int deinit() // Special funct. deinit()
{
Alert ("Function deinit() triggered at exit");// Alert
return; // Exit deinit()
}
//--------------------------------------------------------------------
Amikor megpróbálja lefordítani a Meta Editor ezt az Expert Advisort, egy hibaüzenetet fog küldeni:
36.
ábra. Hibaüzenet az incorrect.mq4 fordítása
alatt.
Az ebben a sorban:
int Count=0; // Global variable
deklarált változó minden függvényen kívül van ugyan, de nem a program kezdetén, hanem valahol a közepén.
A meghatározó momentum a programszerkezetben az, hogy a Count globális változó deklarációja egy függvény után van (ez esetben a start() különleges függvény után). Ebben a részben nem tárgyaljuk a globális változók használatának a részleteit; a változók fajtáit és használatuk szabályait a Változók részben fogjuk leírni. Most csak azt kell tudnunk, hogy bármilyen globális változót korábban kell deklarálni (a szövegben korábban említeni) ezen változó első használatánál (ez a start() függvényben van). Az elemezett programban ezt a szabályt megszegtük és a szerkesztő egy hibaüzenetet küldött.Példa
Példa felhasználói függvény használatára
És most lássuk, hogy a program hogyan viselkedik felhasználói függvényekkel. Ezért írjunk egy egyszerű Expert Advisor kódot a simple.mq4 példája alapján, majd elemezzük azt. Ez a program felhasználói függvényekkel így fog kinézni (Expert Advisor userfunction.mq4):
//--------------------------------------------------------------------
// userfunction.mq4
// To be used as an example in MQL4 book.
//--------------------------------------------------------------------
int Count=0; // Global variable
//--------------------------------------------------------------------
int init() // Special funct. init()
{
Alert ("Function init() triggered at start");// Alert
return; // Exit init()
}
//--------------------------------------------------------------------
int start() // Special funct. start()
{
double Price = Bid; // Local variable
My_Function(); // Custom funct. call
Alert("New tick ",Count," Price = ",Price);// Alert
return; // Exit start()
}
//--------------------------------------------------------------------
int deinit() // Special funct. deinit()
{
Alert ("Function deinit() triggered at exit");// Alert
return; // Exit deinit()
}
//--------------------------------------------------------------------
int My_Function() // Custom funct. description
{
Count++; // Counter of calls
}
//--------------------------------------------------------------------
Először is lássuk, hogy mi maradt változatlan.
Változatlan részek:
1. A fejrész változatlan.
// userfunction.mq4
// To be used as an example in MQL4 book.
//--------------------------------------------------------------------
int Count=0; // Global variable
2.Az init() különleges függvény változatlan.
int init() // Special funct. init()
{
Alert ("Function init() triggered at start");// Aler
return; // Exit init()
}
3.A deinit() különleges függvény is változatlan.
int deinit() // Special funct. deinit()
{
Alert("Function deinit() triggered at exit"); // Alert
return; // Exit deinit()
}
A változások:
1. Hozzáadva: a My_Function() felhasználói függvény.
int My_Function() // Custom function description
{
Count++; // Counter of calls
}
2. A start() különleges függvény kódja szintén változott: most ez tartalmazza a felhasználói függvényhívást, de a Count változó számítása nincs benne.
int start() // Special funct. start()
{
double Price = Bid; // Local variable
My_Function(); // Custom function call
Alert("New tick ",Count," Price = ",Price);// Alert
return; // Exit start()
}
A Program végrehajtás részben az init() és deinit() végrehajtási rendjét elemeztük. Ebben a példában ezeket a függvényeket ugyanúgy fogják végrehajtani, tehát most nem fogunk elidőzni velük. Elemezzük a start() különleges függvény végrehajtását és a My_Function() felhasználói függvényt. A felhasználói függvényleírásnak minden különleges függvényen kívül kell lennie, ezt a követelményt teljesítettük. A felhasználói függvényhívás a start() kódjában van, ami szintén helyes.
Az init() végrehajtása után a végrehajtás folytatódik:
31.a start() különleges függvény arra vár, hogy elindítsa az ügyfélterminál. Amikor egy új tick jön, a terminál el fogja indítani ezt a függvényt. Végül a következő műveleteket fogja végrehajtani:
32 (1). Ebben a sorban
double Price = Bid; // Local variable
ugyanazokat a műveleteket hajtja végre:
32.1(1). Helyi változót inicializálják (lásd: A változók típusai). Ennek a lokális változónak az értéke elérhető lesz a start() különleges függvény bármilyen részéről.32.2(1). Az értékadó operátort végrehajtják. Az utolsó elérhető árajánlatot fogják adni a változó értékének (például az első ticknél ez egyenlő 1.2744-gyel).
33(1). Aztán jön a My_Function() hívása:
My_Function(); // Custom function call
Ezt a sort végre fogják hajtani a start() függvényen belül. Ezen kódrész végrehajtásnak az eredménye (felhasználói függvényhívás) a vezérlés átadása a függvény törzsre (függvényleírás) majd visszatérése a hívás helyére.
34(1). Csak egy operátor van a felhasználói függvényleírásban:
Count++;
Az első függvényhívásnál a Count egyenlő nullával. A Count++ operátor végrehajtásának eredményeként a Count értéke eggyel növekszik. Miután egyszer végrehajtotta ezt az operátort, a felhasználói függvény befejezi a működését és a vezérlést visszaküldi arra a helyre, ahonnan a függvényhívást kapta.
Tudni kell, hogy a felhasználói függvényeket csak a különleges függvényekből lehet hívni (vagy olyan másik felhasználói függvényből, amelyet különleges függvényből hívtak). Bármelyik aktuális pillanatban a különleges függvények közül az egyik működik (vagy a start() vár egy új tickre és akkor elindítja az ügyfélterminál) és a felhasználói függvényeket csak a különleges függvényekben hajthatjuk végre.
Jelen esetben a vezérlés visszatér a start() különleges függvényhez és az végrehajtja a függvényhívás utáni sort:
35(1). Ez a sor az Alert() hívását tartalmazza:
Alert ("New tick ",Count," Price = ",Price);// Alert
Az Alert() függvény egy ablakban mutatni fog minden állandó és változó, amelyeket a zárójeleiben felsoroltak:
New tick 1 Price = 1.2744 |
36(1). A return
return; // Exit start()
operátor befejezi a start() függvény működését.
37. A vezérlés átkerül az ügyfélterminálra, ami vár egy új tickre.
A start() további végrehajtásainál a változók új értékeket fognak kapni és az Alert() üzeneteket fog mutatni, vagyis a program a 32 - 36. pontokat fogja végrehajtani. A start() mindegyik végrehajtásnál (mindegyik ticknél) hívja a My_Functiont felhasználói függvényt és ezt a függvényt végre fogja hajtani. Start() végrehajtása ismétlődni fog, amíg a felhasználó úgy nem dönt, hogy befejezi a programot. Ebben az esetben a deinit() különleges függvény lesz végrehajtva és a program abba fogja hagyni működés.
Az userfunction.ех4 program, működése során, mutatni fog egy Alert() ablakot, ami üzeneteket tartalmaz. Figyelem, a program futásának az eredménye ugyanaz lesz mint az egyszerű simple.mq4 Expert Advisor eredménye. Világos, mert az userfunction.mq4 ugyanazokat a szerkezeti blokkokat tartalmazza, csak más elrendezésben. Ha egy másik, megfelelő elrendezést használnánk, az eredmény ugyanez lenne.