Adat függvény

Egy szokásos Expert Advisort a gyakorlati munka során felhasználhatunk információs forrásnak is, mert ez a kereskedő számára jó minőségű információs támogatást biztosíthat.

 A kereskedés alatt a helyzet folyamatosan változik, különféle események zajlanak. Azért hogy megfelelő döntéseket hozzon, a kereskedőnek tájékozottnak kell lennie. Ezt elősegítendő az Expert Advisorban különféle függvényeket használunk. Ezeknek a függvényeknek az a célja, hogy bizonyos tényekről és folyamatokról tájékoztassák a felhasználót.

Egy egyszerű Expert Advisorban erre a célra a beépített Comment() függvényt használjuk, ami az előre beállított szöveget a szimbólumablak bal felső sarkában jeleníti meg. Ez az információ megjelenítési módszer nem éppen kényelmes, mert a szövegeket gyakran helyezheti egymásra a charton. Tehát ezt a módszert csak korlátozottan használható rövid üzenetek bemutatására.

Ismerjük meg az információ megjelenítésének alapvetően különböző módszerét – ahol az egész üzenetet egy különálló ablakban jelenítjük meg, és grafikus objektumokat használunk arra, hogy az üzenet szövegét kialakítsuk. A grafikus objektumok használatának van egy kézzelfogható előnye: a grafikus objektumokat el tudjuk mozdítani (a Comment() függvény szövegeitől eltérően) miközben az üzeneteket létrehozzuk.

Egy különálló segédablakot hozunk létre az információk megjelenítésére egy megfelelően beállított egyéni indikátorral. Ennek az indikátornak az egyetlen feladata ennek a segédablaknak a létrehozása, ezért semmilyen számítást nem hajt végre az indikátor, és indikátorvonalakat sem hoz létre. Az  Inform.mq4 indikátor kódja a következőképpen néz ki:
//--------------------------------------------------------------------
// Inform.mq4 
// The code should be used for educational purpose only.
//--------------------------------------------------------------------
#property indicator_separate_window // Separate indicator window
//--------------------------------------------------------------------
int start() // Special function start()
 {
 }
//--------------------------------------------------------------------

Azonban a programozó egyéb hozzáadott kódsorokkal módosíthatja az indikátor tulajdonságait. Például a segédablak egy bizonyos részében indikátorvonalakat is elhelyezhet. A fenti példában annak az egyszerű indikátornak a kódját láthatjuk, amellyel azt a segédablakot hozzuk létre, amelyben a grafikus objektumokat meg fogjuk jeleníteni.

Az Inform() felhasználói függvény

int Inform(int Mess_Number,int Number=0,double Value=0.0)

A függvény grafikus objektumokat fog létrehozni az  Inform.mq4 indikátor által létrehozott segédablakban. A függvény meghatározza a grafikus objektumok pozícióját az indikátor segédablakban: minden új üzenetet az ablak alsó részében jelenít meg (a legalsó sorban) a kívánt színben, és a korábban mutatott üzeneteket föntebb helyezi (egy sorral följebb). Ha 15 másodpercen belül új üzenetet nem jelenik meg, az ablakban minden üzenet megszürkül (hogy ne tévessze meg a felhasználót).

Paraméterek:

Mess_Number - üzenetszám, értéke a következő lehet:

  •  0 - üzenet ne legyen megjelenítve, újraindítja az időzítőt;
  •   -1 - minden grafikus objektumot, amit létrehozott a függvény, törölni kell;
  •  (egy vagy több) - a segédablakban bemutatott üzenetek száma;

Number – ezt az egész számot néhány üzenetben használjuk;

Value - ezt a valós számot néhány üzenetben használjuk.

Az Inform() függvény grafikus objektumokat hoz létre, ha az Inform.mqh include fájl segítségével beillesztjük egy szokásos EA-ba: :
//----------------------------------------------------------------------------
// Inform.mqh
// The code should be used for educational purpose only.
//----------------------------------------------------------------------- 1 --
// Function that displays graphical messages on the screen.
//----------------------------------------------------------------------- 2 --
int Inform(int Mess_Number, int Number=0, double Value=0.0)
 {
 // int Mess_Number // Message number 
 // int Number // Integer to be passed
 // double Value // Real number to be passed
 int Win_ind; // Indicator window number
 string Graf_Text; // Message line
 color Color_GT; // Color of the message line
 static int Time_Mess; // Last publication time of the message
 static int Nom_Mess_Graf; // Graphical messages counter
 static string Name_Grf_Txt[30]; // Array of graphical message names
//----------------------------------------------------------------------- 3 --
 Win_ind= WindowFind("inform"); // Searching for indicator window number
 if (Win_ind<0)return; // If there is no such a window, leave
//----------------------------------------------------------------------- 4 --
 if (Mess_Number==0) // This happens at every tick
 {
 if (Time_Mess==0) return; // If it is gray already
 if (GetTickCount()-Time_Mess>15000)// The color has become updated within 15 sec
 {
 for(int i=0;i<=29; i++) // Color lines with gray
 ObjectSet( Name_Grf_Txt[i], OBJPROP_COLOR, Gray);
 Time_Mess=0; // Flag: All lines are gray
 WindowRedraw(); // Redrawing objects
 }
 return; // Exit the function
 }
//----------------------------------------------------------------------- 5 --
 if (Mess_Number==-1) // This happens at deinit()
 {
 for(i=0; i<=29; i++) // By object indexes
 ObjectDelete(Name_Grf_Txt[i]);// Deletion of object
 return; // Exit the function
 }
//----------------------------------------------------------------------- 6 --
 Nom_Mess_Graf++; // Graphical messages counter
 Time_Mess=GetTickCount(); // Last publication time 
 Color_GT=Lime;
//----------------------------------------------------------------------- 7 --
 switch(Mess_Number) // Going to message
 {
 case 1:
 Graf_Text="Closed order Buy "+ Number;
 PlaySound("Close_order.wav"); break;
 case 2:
 Graf_Text="Closed order Sell "+ Number;
 PlaySound("Close_order.wav"); break;
 case 3:
 Graf_Text="Deleted pending order "+ Number;
 PlaySound("Close_order.wav"); break;
 case 4:
 Graf_Text="Opened order Buy "+ Number;
 PlaySound("Ok.wav"); break;
 case 5:
 Graf_Text="Opened order Sell "+ Number;
 PlaySound("Ok.wav"); break;
 case 6:
 Graf_Text="Placed pending order "+ Number;
 PlaySound("Ok.wav"); break;
 case 7:
 Graf_Text="Order "+Number+" modified into the market one";
 PlaySound("Transform.wav"); break;
 case 8:
 Graf_Text="Reopened order "+ Number; break;
 PlaySound("Bulk.wav");
 case 9:
 Graf_Text="Partly closed order "+ Number;
 PlaySound("Close_order.wav"); break;
 case 10:
 Graf_Text="New minimum distance: "+ Number;
 PlaySound("Inform.wav"); break;
 case 11:
 Graf_Text=" Not enough money for "+
 DoubleToStr(Value,2) + " lots";
 Color_GT=Red;
 PlaySound("Oops.wav"); break;
 case 12:
 Graf_Text="Trying to close order "+ Number;
 PlaySound("expert.wav"); break;
 case 13:
 if (Number>0)
 Graf_Text="Trying to open order Sell..";
 else
 Graf_Text="Trying to open order Buy..";
 PlaySound("expert.wav"); break;
 case 14:
 Graf_Text="Invalid password. EA doesn't function.";
 Color_GT=Red;
 PlaySound("Oops.wav"); break;
 case 15:
 switch(Number) // Going to the error number
 {
 case 2: Graf_Text="Common error."; break;
 case 129: Graf_Text="Wrong price. "; break;
 case 135: Graf_Text="Price changed. "; break;
 case 136: Graf_Text="No prices. Awaiting a new tick.."; break;
 case 146: Graf_Text="Trading subsystem is busy"; break;
 case 5 : Graf_Text="Old version of the terminal."; break;
 case 64: Graf_Text="Account is blocked."; break;
 case 133: Graf_Text="Trading is prohibited"; break;
 default: Graf_Text="Occurred error " + Number;//Other errors
 }
 Color_GT=Red;
 PlaySound("Error.wav"); break;
 case 16:
 Graf_Text="Expert Advisor works only for EURUSD";
 Color_GT=Red;
 PlaySound("Oops.wav"); break;
 default:
 Graf_Text="default "+ Mess_Number;
 Color_GT=Red;
 PlaySound("Bzrrr.wav");
 }
//----------------------------------------------------------------------- 8 --
 ObjectDelete(Name_Grf_Txt[29]); // Deleting 29th (upper) object
 for(i=29; i>=1; i--) // Cycle for array indexes ..
 { // .. of graphical objects
 Name_Grf_Txt[i]=Name_Grf_Txt[i-1];// Raising objects:
 ObjectSet( Name_Grf_Txt[i], OBJPROP_YDISTANCE, 2+15*i);
 }
 Name_Grf_Txt[0]="Inform_"+Nom_Mess_Graf+"_"+Symbol(); // Object name
 ObjectCreate (Name_Grf_Txt[0],OBJ_LABEL, Win_ind,0,0);// Creating
 ObjectSet (Name_Grf_Txt[0],OBJPROP_CORNER, 3 ); // Corner
 ObjectSet (Name_Grf_Txt[0],OBJPROP_XDISTANCE, 450);// Axis Х
 ObjectSet (Name_Grf_Txt[0],OBJPROP_YDISTANCE, 2); // Axis Y
 // Текстовое описание объекта
 ObjectSetText(Name_Grf_Txt[0],Graf_Text,10,"Courier New",Color_GT);
 WindowRedraw(); // Redrawing all objects
 return;
 }
//----------------------------------------------------------------------- 9 --

A 2-3 blokkban leírjuk a függvényben használt változókat. A grafikus objektumok neveit a Name_Grf_Txt tömbben tároljuk. A függvényben megvalósított módszer szerint, a program egy új grafikus objektumot hoz létre mindegyik új üzenethez. Az objektumok teljes mennyisége 30 lehet, mindegyik objektum egy egysoros szöveges bejegyzés. Nagy képernyőfelbontás esetén valamennyi sort láthatjuk, amint növekszik a sorok száma minden új objektum létrehozásával.

A 3-4 blokkban az "Inform” indikátor segédablakának számát keressük meg, ahová az üzenetek fognak kerülni. Ha az indikátor nincs csatolva, a függvény leállítja a működését. Ha az indikátorablak nincs csatolva, az üzeneteket nem lehet megjeleníteni, de ez nem hat az EA egyéb működésére - minden más függvény működni fog a normális módon, kereskedést szintén végre fogja hajtani.

A 4-5 blokkban az üzenetek színeit elemezzük. A függvényt a Mess_Number=0 paraméterrel hívja az Expert Advisor minden ticknél, (lásd az usualexpert.mq4  Expert Advisor start() függvényét). Ha minden létező objektum szürke, a függvény befejezi az operációit. Azonban ha a Time_Mess változó értéke nem nulla, az objektumok tulajdonsága megváltozik, mégpedig minden objektum megszürkül. Ha (az 5-6 blokkban) a függvényhívásban a Mess_Number=-1 paramétert találjuk, akkor minden olyan objektumot, amit korábban ez a függvény hozott létre, törölni fogunk. Ez akkor lehet szükséges, amikor az EA-t lekapcsoljuk a szimbólumablakról. Ebben az esetben az ismert szabály szerint mindegyik alkalmazási programnak törölnie kell minden objektumot, amit a végrehajtás alatt létrehozott , (lásd a deinit() függvényt az usualexpert.mq4 Expert Advisorban). 

Ha a programban a vezérlés a 6-7 blokkba kerül, akkor az a megadott jellemzőkkel létre fog hozni egy grafikus objektumot az indikátor segédablak alsó részén (a legalsó sorban; itt a sor fogalma viszonylagos; valójában a grafikus objektumok elhelyezkedését az előre beállított koordináták határozzák meg). Mindegyik újonnan létrehozott objektumnak egyedi neve van. Az objektumnevek létrehozásához az üzenet történelmi sorszámát használjuk, ezért a 6-7 blokkban egy üzenetszámlálót helyezünk el (a későbbiek során az így kapott Nom_Mess_Graf változó értékét arra fogjuk használni, hogy a 8-9 blokkban kialakítsuk az objektumok egyedi nevét). Itt elemezzük az utolsó üzenet megjelenésének időpontját, és itt állítjuk be az új üzenet színét (zöld).

A 7-8 blokkban lévő 'switch' operátor megkeresi a függvényhívásban szereplő Mess_Number paraméternek megfelelő 'case' variációt. Minden 'case' variációhoz tartozik a Graf_Text változónak egy új értéke és ez az érték (string) lesz az új üzenet tartalma. Néhány fontos üzenetnek a színét megváltoztathatjuk például pirosra. Minden üzenet hangjelzéssel párosul, amit a PlaySound() függvény végrehajtásával hozunk létre (lásd: Hang fájlok).

Az új grafikus objektum létrehozása és a létezők módosítása a 8-9 blokkban történik. Az objektumok száma korlátozott, ezért a legrégebbi objektumot minden alkalommal törölni kell, mikor egy új üzenet érkezik. Minden más létező objektum elmozdul egy sorral felfelé. Az objektumok azért mozdulnak el, mert megváltoztatjuk a tulajdonságaikat, - a függőleges koordinátákat. Az objektumok vízszintes koordinátái változatlanok maradnak.

Miután minden szükséges előkészületet elvégeztünk (minden üzenetet elmozdítottunk egy sorral felfelé), létrehozzuk az új üzenetet a 7-8 blokkban meghatározott egyedi névvel és tulajdonságokkal. A grafikus objektum típusa Text Label. Az ilyen típusú objektumokat a felhasználó önkényesen áthelyezheti a szimbólumablakon belül, függetlenül az üzenet eredeti pozíciójától.

Az Inform() függvényt a program bármely pontjáról hívhatjuk, ahol implicite egy szöveges üzenet megjelenítésére van szükség. Hosszú működés során az üzeneteket felhalmozódnak az ablakban. A felhasználó meg tudja nézni a régebbi üzeneteket a segédablak átméretezésével (például az ablak felső szélének felfelé húzásával). Beállítható az ablak olyan méretűre, amikor csak a szükséges számú üzenetsort látjuk (általában három-négy sor ajánlott).


156. ábra. Szimbólumablak. Üzenetek az indikátor segédablakban.

Könnyű belátni, hogy a függvénnyel bemutatott üzenetek számát növelhetjük. Ha ki akarjuk terjeszteni a programot, elegendő, ha a 7-8 blokkban a 'switch' operátorhoz újabb ‘case' variációkat adunk hozzá).