Radu MetaTrader a blogja | További ingyenes és hasznos eszközök MetaTraderhez | Kérdésed merült fel? Kérdezz!
MQL4 Könyv tartalomjegyzék | Stratégiák programozása MetaTrader platformra | Fogalomtár | Gyakran Ismételt Kérdések

MQL4 Könyv   Programozás MQL4-ben   Példák a megvalósításra


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 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.

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 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()
}

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.