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    Egy szokásos program létrehozása   A megbízások nyilvántartása



A megbízások nyilvántartása

 

Már említettük, hogy a programalgoritmusok létrehozására nincsenek szigorú szabályok. Ugyanakkor az algoritmusok döntő többségének a feladata a rendelkezésre álló megbízások figyelembevételével a kereskedési döntések létrehozása. Néhány esetben, mint például megbízások nyitásához nincs szükség arra, hogy már legyen egy másik, létező megbízásunk a kereskedés végrehajtásának a pillanatában. Más esetben egy függőben lévő megbízás elhelyezésének feltétele lehet, hogy a már létező piaci megbízásnak ne legyen beállított stop szintje. Lehet olyan algoritmus is amely két ellentétes függőben lévő megbízás elhelyezésén alapul.

A kereskedési taktika megvalósításához a döntéshozatal pillanatában ismernünk kell az aktuális állapotot: milyen piaci és függőben levő megbízások léteznek, és ezeknek milyen jellemzőik vannak? A két lehetséges megoldás közül az egyiket választhatjuk.

Az első megoldás szerint, a szükséges programkód részletet (amiben a megbízásokat elemezzük) közvetlenül abban a programban helyezzük el, ahol az elérhető megbízásokra vonatkozó információt felhasználjuk. Ez a megoldás technikailag megvalósítható, de használhatatlan lehet, ha az algoritmusban változtatásokat csinálunk. Ebben az esetben, a programozónak ellenőrizni kell minden olyan programrészt, ahol a megbízásokat elemezzük, és minden programrészben a szükséges változtatásokat végre kell hajtani. Egy másik, hatékonyabb megoldás, ha létrehozunk egy univerzális megbízás elemző függvényt és azt használjuk minden alkalommal, amikor frissíteni akarjuk az aktuális megbízásokkal kapcsolatos információt. Egyfelől ez a megoldás lehetővé teszi, hogy egyszerűsítsük a programkódot. Másfelől lehetővé teszi a programozónak, hogy ezt a kész függvényt használja mikor másik programot kódol.

Mielőtt létrehozunk egy megbízás elemző függvény, el kell döntenünk, hogy milyen paramétereket kell elemezni. A legtöbb esetben a következő paraméterek értékeit használjuk a kereskedelmi döntések meghozatalakor:

  • az összes megbízás száma;
  • a különböző típusú megbízások száma (például a Buy megbízások száma, a SellStop megbízások, vagy a BuyLimit megbízások, stb.);
  • minden egyes megbízás minden jellemzője (jegyszám (ticket), StopLoss és TakeProfit szintek, kötés méret, stb.).

A fenti információknak elérhetőknek kell lenniük másik függvényekből, hogy ezt az információt azok feldogozhassák. Ezért minden paramétert, ami a megbízásokat jellemez, egy globális tömbben helyezünk el. Összesen három tömböt használunk a megbízások nyilvántartására:

  • a jelenlegi megbízások tömbje a Mas_Ord_New, tartalmazza a jelenlegi piaci és függőben levő megbízások jellemzőivel kapcsolatos információt, a függvény utolsó végrehajtásának pillanatában;
  • az előző megbízások tömbje a Mas_Ord_Old, tartalmazza a piaci és függőben levő megbízások jellemzőivel kapcsolatos információt, a függvény előző végrehajtásának pillanatában;
  • a Mas_Tip tömb elem értékei a különböző típusú megbízások összegét tartalmazzák (az aktuális pillanatban).

Az Arrays Mas_Ord_New és Mas_Ord_Old tömbök hasonlóak és azonos dimenziójúak; az köztük a különbség, hogy az első a megbízások aktuális állapotát mutatja, míg a második az ezt megelőző állapotot. Határozzuk meg, hogy a tömbelemek milyen jellemzők értékeit tartalmazzák!

4. táblázat. A Mas_Ord_New és Mas_Ord_Old tömbök elemeinek az összefüggése a megbízások jellemzőivel.


Nem meghatározott Nyitó ár StopLoss TakeProfit A megbízás(aonosító) száma

A megbízás lot mérete 

A megbízás típusa Magic Number Megjegyzés
Indexek 0 1 2 3 4 5 6 7 8
0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 0.0 1.2583 1.2600 1.2550 123456.0 1.4 1.0 1177102416.0 1.0
2 0.0 1.2450 1.2580 1.2415 123458.0 2.5 2.0 1177103358.0 0.0
3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
. . . 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
30 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

A tömb első indexe határozza meg a megbízás sorszámát a tömbben. Az első felismert (függőben levő vagy nyitott) megbízás jellemzői  kerülnek  az első sorba, a második felismert megbízásé a másodikba stb. A tömb első indexének legnagyobb értéke 31 lehet, így a tömbben legfeljebb 30 megbízással kapcsolatos információt tárolhatunk egyidejűleg. Ha a kereskedési stratégia azt igényli, hogy egyidejűleg harmincnál több megbízással dolgozunk, akkor a tömb deklarálásánál a megfelelő értéket kell adni az első indexnek. (A legtöbb esetben a 30-as érték is lényegesen meghaladja a szükségletet, amit általában 2-től 10-15 megbízásig terjed. Ebben a példában 30-as értéket használunk, mert azt feltételezzük, hogy a függvényt szokatlan kereskedési stratégiákban is használni fogjuk).

A tömb második indexe (az oszlopok) a megbízás jellemzőket tartalmazza. Ha a tömb második dimenziójának indexe egyenlő 1-gyel, akkor az az elem a megbízás nyitó árának az értékét tartalmazza, ha az index 2, akkor az a StopLoss értéke, ha 3, akkor TakeProfit, stb. (lásd a 4. táblázatot). A [0][0] indexű tömbelem értéke a tömbben szereplő megbízások számával egyenlő. Azokat a tömbelemeket, amelyeknek az első vagy a második indexe 0, nem használjuk (a [0][0] indexű elemet kivéve).

A 4. táblázatban egy olyan tömböt láthatunk, amely tömb két, egyidejűleg elérhető megbízással kapcsolatos információt tartalmaz. A Mas_Ord_New[0][0] tömbelem értéke 2.0, mert a megbízások száma kettő. A tömb első sorának az elemei egy Sell megbízás jellemzőinek az értékeit tartalmazzák (Mas_Ord_New[1][6] = 1.0, (lásd: Types of Trades). Ezek szerint a Mas_Tip tömb 0 indexű elemének értéke jelenti az összes Buy megbízása számát, az 1indexű elem értéke a Sell megbízások összegét, 2 indexű a BuyLimit megbízásokét, stb. A 4. táblázatban szereplő esetben a Mas_Tip tömb elemeinek az értéke következő lesz:

5. táblázat. A Mas_Tip tömb elemeinek értéke a különböző típusú megbízások számát jelzi.


Buy Sell BuyLimit SellLimit BuyStop SellStop
Index 0 1 2 3 4 5
Value 0 1 1 0 0 0

Ebben az esetben, a  Mas_Tip tömb elemeinek az értékei a következőket jelentik: Ha a Mas_Tip[1] egyenlő 1 az azt jelenti, hogy egy Sell megbízásunk van; ha Mas_Tip[2] egyenlő 1 akkor egy függőben levő BuyLimit megbízásunk van. A tömb többi elemének értéke nulla - ez azt jelzi, hogy az adott típusú megbízás nincs a kereskedelemben. Ha egyidejűleg több azonos típusú megbízás is elérhető a kereskedelemben, a tömb megfelelő eleménél érték az adott típusú megbízások számával lesz egyenlő. Például, ha három BuyStop megbízásunk van, akkor a Mas_Tip[4] értéke 3 lesz.

A Terminal() megbízásokat elemző függvényt javasolt a Terminal.mqh include fájlban kialakítani.

A Terminal() felhasználói függvény

int Terminal()

A függvény a piaci és a függőben levő megbízásokat elemzi. A függvény végrehajtása során változnak  a következő globális tömböt értékei:

  • Mas_Ord_New - a rendelkezésre álló megbízások jellemzőit tartalmazó tömb a függvény végrehajtásának pillanatában;
  • Mas_Ord_Old - a rendelkezésre álló megbízások jellemzőit tartalmazó tömb a függvény előző végrehajtásának pillanatában;
  • Mas_Tip – a különböző típusú megbízások száma.

A Terminal.mqh include fáj a Terminal() megbízás elemző felhasználói függvény leírását tartalmazza:

//--------------------------------------------------------------------
// Terminal.mqh
// The code should be used for educational purpose only.
//------------------------------------------------------------------------------ 1 --
// Order accounting function
// Global variables:
// Mas_Ord_New[31][9]   // The latest known orders array
// Mas_Ord_Old[31][9]   // The preceding (old) orders array
                        // 1st index = order number
                        // [][0] not defined
                        // [][1] order open price (abs. price value)
                        // [][2] StopLoss of the order (abs. price value)
                        // [][3] TakeProfit of the order (abs. price value)
                        // [][4] order number        
                        // [][5] order volume in lots (abs. price value)
                        // [][6] order type 0=B,1=S,2=BL,3=SL,4=BS,5=SS
                        // [][7] order magic number
                        // [][8] 0/1 comment availability
// Mas_Tip[6]           // Array of the amount of orders of all types
                        // [] order type: 0=B,1=S,2=BL,3=SL,4=BS,5=SS
//------------------------------------------------------------------------------ 2 --
int Terminal()
  {
   int Qnt=0;                          // Orders counter

//------------------------------------------------------------------------------ 3 --
   ArrayCopy(Mas_Ord_Old, Mas_Ord_New);// Saves the preceding history
   Qnt=0;                              // Zeroize orders counter
   ArrayInitialize(Mas_Ord_New,0);     // Zeroize the array
   ArrayInitialize(Mas_Tip,    0);     // Zeroize the array
//------------------------------------------------------------------------------ 4 --
   for(int i=0; i<OrdersTotal(); i++) // For market and pending orders
     {
      if((OrderSelect(i,SELECT_BY_POS)==true)     //If there is the next one
      &&
(OrderSymbol()==Symbol()))               //.. and our currency pair
        {
         //--------------------------------------------------------------------- 5 --
         Qnt++;                                   // Amount of orders
         Mas_Ord_New[Qnt][1]=OrderOpenPrice();    // Order open price
         Mas_Ord_New[Qnt][2]=OrderStopLoss();     // SL price
         Mas_Ord_New[Qnt][3]=OrderTakeProfit();   // TP price
         Mas_Ord_New[Qnt][4]=OrderTicket();       // Order number
         Mas_Ord_New[Qnt][5]=OrderLots();         // Amount of lots
         Mas_Tip[OrderType()]++;                  // Amount of orders of the type
         Mas_Ord_New[Qnt][6]=OrderType();         // Order type
         Mas_Ord_New[Qnt][7]=OrderMagicNumber();  // Magic number
         if (OrderComment()=="")
            Mas_Ord_New[Qnt][8]=0;                // If there is no comment
         else
            Mas_Ord_New[Qnt][8]=1;                // If there is a comment
         //--------------------------------------------------------------------- 6 --
        }
     }
   Mas_Ord_New[0][0]=Qnt;                         // Amount of orders
//------------------------------------------------------------------------------ 7 --
   return;
  
}
//------------------------------------------------------------------------------ 8 --

1-2 blokkban, a megjegyzésekben megadjuk a globális tömbök elemértékeinek az értelmezését. A globális tömböket a Variables.mqh  include fájlban deklaráljuk. A 3-4 blokkban a Mas_Ord_New tömb elem értékeit átmásoljuk a Mas_Ord_Old tömbbe. Így a rendelkezésre álló megbízások előző állapotát eltároljuk és ezeket az adatokat továbbra is használhatjuk a programban. Ezután a Mas_Ord_New és Mas_Tip tömbök elemeinek az értékeit nullára állítjuk be, mielőtt az új adatokat ezekben a tömbökben elhelyeznénk a 4-7 blokkban.

A 4-7 blokk tartalmazza azt a ciklust, amiben minden piaci és függőben levő megbízást ellenőrzünk azon a szimbólumon melynek ablakához az EA-t hozzácsatoltuk. A megbízásokat az OrderSelect() függvénnyel választjuk ki az alapértelmezett MODE_TRADES paraméterrel. Az 5-6 blokkban a kiválasztott megbízás minden szükséges jellemzőjét kiszámoljuk és a kapott értékeket elraktározzuk az aktuális megbízások Mas_Ord_New tömbjében. Eközben a különböző típusú megbízások számát is összegezzük és a kapott értékeket adjuk a Mas_Tip tömb megfelelő elemei értékeinek. A ciklus végén valamennyi megbízás számát adjuk a Mas_Ord_New [0][0] elem értékének.

A lezárt és törölt megbízásokat nem elemezzük (az OrderSelect() függvényt a MODE_HISTORY paraméterrel nem hajtjuk végre). Az a szabály, hogy a lezárt és törölt megbízásokkal kapcsolatos információt nem használjuk a kereskedő EA-kban. A lezárt és törölt megbízások információit a számlatörténet vizsgálata során használjuk. Ezeket az információkat például a profit változását bemutató diagram létrehozására használhatjuk. Azonban ezek az információk nincsenek befolyással az új kereskedelmi döntésekre. Technikailag ezeket a megbízásokat elemezhetjük, de ez egy olyan különálló feladat, aminek nincs kapcsolata a kereskedelemmel.

A megbízásokkal kapcsolatos eseményeket egy programban, azokban a sorokban elemezzük, ahol a fenti tömbökben szereplő adatokat összehasonlítjuk. Például, ha Mas_Ord_Old tömb tartalmazza a 246810 jegyszámú függőben levő megbízást, és a Mas_Ord_New tömbben ugyanaz a 246810 számú megbízás típusa megváltozott, ez azt jelenti, hogy a függőben levő megbízás piaci megbízássá vált. Szintén elemezni kell a megbízásokat a kereskedés végrehajtásakor (a kereskedés létrejötte utáni állapot figyelembevételével).  A Terminal() függvény legelső végrehajtása előtt a Mas_Ord_Old és Mas_Ord_New tömbök üresek,  vagyis mindkét tömb minden elemének értéke nulla. Ez azt jelenti, hogy a függvény első végrehajtása után a Mas_Ord_Old tömb a következő sorban:

 ArrayCopy(Mas_Ord_Old, Mas_Ord_New);// Store the preceding history

nulla értékeket kap a Mas_Ord_New tömbből, ami a hamis működéshez vezet az a tömbök értékeit használó függvényeknél. Azért, hogy ezt megakadályozzuk, az usualexpert.mq4 Expert Advisor  inicializálása során a Terminal() függvényt egyszer végrehajtjuk, és a start() függvényben történő első végrehajtáskor a Mas_Ord_Old tömb már helyes értékeket tartalmaz.