MQL4 könyv   Kereskedelmi műveletek programozása   Megbízások nyitása és elhelyezése

Megbízások nyitása és elhelyezése


Megbízások nyitására és függőben levő megbízások elhelyezésére az OrderSend() függvényt használjuk.

Az OrderSend() függvény

int OrderSend (string symbol, int cmd, double volume, double price, int slippage, double stoploss,
double takeprofit, string comment=NULL, int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)

 (jegyezd meg: itt és lentebb a függvényfejlécet elemezzük, és ez nem egy példa arra, hogy hogyan használjuk a függvényhívást egy programban).

Vizsgáljuk meg részletesen, hogy ez a függvény miből áll!

OrderSend a függvény név. A függvény visszaküldi a jegyzési számot (jegyzés, 'ticket' a megbízás egyedi azonosító száma) amit a kereskedelmi szerver rendel a megbízáshoz, vagy -1-et küld vissza, ha a kereskedelmi kérést visszautasította a szerver, vagy az ügyfélterminál. Azért hogy a kereskedelmi kérés elutasításának az okáról információt kapj, GetLastError() függvényt kell használnod (lent meg fogunk tárgyalni a leggyakoribb hibák közül néhányat).

symbol a kereskedés tárgyának neve. Mindegyik szimbólum egy string változó. Például az Euro/amerikai dollár devizapárnál ez az érték EURUSD. Ha a megbízást egy előre meghatározott szimbólumon nyitjuk, ezt a paramétert egyértelműen megadhatjuk: EURUSD, EURGBP, stb. Azonban, ha Expert Advisort használsz valamilyen szimbólum ablakban, használhatod a beépített Symbol() függvényt. Ez a függvény visszaküld egy olyan string értéket, ami annak a szimbólum nevének felel meg amelyik szimbólum ablakában az EA-t vagy a scriptet végrehajtjuk.

cmd a művelet típusa. A művelet típusa egy előre definiált állandó vagy annak az értéke, és a kereskedés típusát határozza meg.

volume a kereskedés tárgyának mennyisége. A megbízások előtt mindig ellenőrizni kell a számla egyenleget. Függőben levő megbízások fedezetének  összege nem korlátozott.

price a nyitó ár. A rá vonatkozó követelmények és korlátozások alapján határozzuk meg (lásd: A megbízások jellemzői és a kereskedés végrehajtás szabályai ). Ha az ár, amit a nyitási kérelemben megadtunk nem létezik vagy eltér az aktuális piaci ártól, a kereskedelmi kérést visszautasítják. Azonban, ha az ár eltér az aktuális ártól, de az eltérés a slippage (csúszás) értékén belül van, ezt a kereskedelmi kérést az ügyfélterminál el fogja fogadni és elküldi a kereskedelmi szervernek.

slippage, csúszás a kért nyitó ár maximális megengedett eltérése a valós piaci ártól (pontokban). Ezt a paramétert nem használjuk a függőben levő megbízások elhelyezésekor.

stoploss az a kért záró ár, ami meghatározza a maximális veszteséget az adott üzleten. A beállításkor figyelembe kell venni a rá vonatkozó követelményeket és korlátozásokat (lásd: A megbízások jellemzői és a kereskedés végrehajtás szabályaiKövetelmények és korlátozások a kereskedelemben).

takeprofit az a kért záró ár, ami meghatározza a maximális nyereséget az adott üzleten. A beállításkor figyelembe kell venni a rá vonatkozó követelményeket és korlátozásokat (lásd A megbízások jellemzői és a kereskedés végrehajtás szabályai, Követelmények és korlátozások a kereskedelemben).

comment a megjegyzés szövege. A megjegyzés utolsó részét módosíthatja a kereskedelmi szerver.

magic a magic number. A felhasználó megbízásának azonosítására használhatjuk. Néhány esetben ez az egyetlen információ, ami segít azonosítani, hogy a megbízás melyik programhoz tartozik, melyik nyitotta azt. A paramétert a felhasználó állítja be; az értéke azonos vagy különböző lehet több megbízás esetében.

expiration a lejárat a dátuma. Amint ez a idő elérkezik, a függőben levő megbízás automatikusan törölve lesz a szerveroldalon. Néhány kereskedelmi szerveren nem lehet beállítani a függőben levő megbízás lejárati idejét. Ebben az esetben, ha megpróbálod beállítani ezt a paraméter egy nem nulla értékre, a kérést vissza fogják utasítani.

arrow_color a megbízás nyitását jelző nyíl színe az ábrában. Ha ez a paraméter hiányzik, vagy az értéke CLR_NONE, a nyitás helye nem jelenik meg az ábrán.

Néhány kereskedelmi szerveren korlátozott a nyitott és függőben levő megbízások száma. Ha ezt a határt elértük, minden kereskedelmi kérést, ami megbízás nyitására, vagy függőben levő megbízás elhelyezésére irányul, vissza fog utasítani a kereskedelmi szerver.

Megbízások nyitása


Először úgy tűnhet, hogy az OrderSend() függvény túl bonyolult. Azonban a szóban forgó paraméterek egyszerűek, és sikeresen használhatjuk őket a kereskedelmedben. Azért hogy ezt belássuk, vizsgáljuk meg a legegyszerűbb variációt, amivel az OrderSend() kereskedelmi függvényt egy megbízás nyitására használunk.

Először is meg kell jegyeznünk, hogy az OrderSend() függvénynek előre definiált paraméterei vannak (lásd: Függvény hívás, Függvény leírás és 'return' operátor). 

Ez azt jelenti, hogy ezt a függvényt leegyszerűsített módban használhatjuk, ami a minimális paraméter készletet igényel. Ezek a paraméterek a következők:

symbol egy szükséges paraméter, mert tudnunk kell, hogy mivel akarunk kereskedni. Ha azt akarjuk, hogy a programunk minden szimbólum ablakában működjön, akkor ezt a paramétert a Symbol() függvénnyel kell helyettesíteni;

cmd – például: nyissunk egy piaci Buy megbízást; ebben az esetben az OP_BUY paramétert fogjuk megadni;

volume - itt tudjuk megadni a kereskedés nagyságát, például, 0.1 lot;

price - a Buy megbízás Ask ára;

slippage - a csúszást általában 0-3 pontban határozzuk meg. Most legyen 2 pont;

stoploss – a stop megbízást nem tudjuk a megengedett minimum távolságnál közelebb elhelyezni, a megengedett minimum távolság rendszerint 5 pont (lásd: Követelmények és korlátozások a kereskedelemben); most tegyük a stop megbízást 15 pont távolságra a nyitó ártól, mégpedig: Bid - 15*Point;

takeprofit - adjunk stop megbízást 15 pont távolságra a nyitó ártól: Bid + 15*Point;

itt van a simpleopen.mq4 script, amivel elküldjük a Buy megbízást:
//--------------------------------------------------------------------
// simpleopen.mq4 
// The code should be used for educational purpose only.
//--------------------------------------------------------------------
int start() // Special function start()
 { // Opening BUY
 OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
 return; // Exit start()
 }
//--------------------------------------------------------------------

Ha elindítod ezt a scriptet, ez az esetek többségében működni fog. A script egy különleges függvényből áll, ami tartalmazza az OrderSend() megbízás megnyitó függvényt és a 'return' operátort. Írjuk le a végrehajtás algoritmust programsoronként és eseményenként!

1. A felhasználó csatolta a scriptet a szimbólumablakhoz azáltal, hogy az egérgombbal áthúzta a scriptnevet a navigátorból az ügyfélterminál azon szimbólum ablakába, amely szimbólumon nyitni akar egy 0.1 lot méretű Buy megbízást, a nyitási ártól 15 pont távolságra elhelyezett stop szintekkel.

2. A script a csatolásának a pillanatában, az ügyfélterminál átadja a vezérlést (azzal, hogy elindítja azt) a különleges start() függvénynek (itt kell emlékeztetnünk, hogy egy script start() függvénye abban a pillanatban elindul, amint a scriptet csatoljuk a szimbólumablakhoz, míg egy EA start() függvénye csak akkor indul el mikor a legközelebbi tick érkezik a szimbólumra).

3. A különleges start() függvény  szerkezetén belül a a vezérlés lekerül abba a sorba, ami a megbízást megnyitó függvényt hívja:

 OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);

Ennek a függvénynek a végrehajtása előtt a program kiszámítja minden formális paraméter értékét:

3.1. Mivel a scriptet az Eur/USd ablakához csatoltuk, a beépített Symbol() függvény az EURUSD string értéket fogja visszaküldeni.

3.2. A függvény hívás pillanatában Ask =1.2852 és Bid =1.2850.

3.3. A StopLoss értéke ebben az esetben: 1.2850-15*0.0001 = 1.2835, míg a TakeProfit = 1.2865.

4.Az OrderSend() függvény végrehajtása :

4.1. A függvény kialakított egy megbízás megnyitása iránti kereskedelmi kérést, és átadta ezt a kérést az ügyfélterminálnak.

4.2. A függvény a kereskedelmi kérés küldésével egyidejűleg átadta a vezérlést az ügyfélterminálnak, ezért a küldő program végrehajtása leállt.

4.3. Az ügyfélterminál ellenőrizte a megkapott kereskedelmi kérést. Nem észlelt semmilyen helytelen paramétert, úgyhogy ez a kérést továbbküldte a szervernek.

4.4. A szerver megkapta a kereskedelmi kérést, ellenőrizte azt, nem észlelt semmilyen helytelen paramétert, és úgy döntött, hogy végrehajtja a kérést.

4.5. A szerver végrehajtotta a kérést azáltal, hogy csinált egy tranzakciót az adatbázisában, és a végrehajtott kéréssel kapcsolatos információt visszaküldte az ügyfélterminálnak.

4.6. Az ügyfélterminál megkapta az információt arról, hogy az utolsó kereskedelmi kérését végrehajtották, feltünteti ezt az eseményt a terminál ablakban és a szimbólumablakban, és visszaküldi a vezérlést a programba.

4.7. Ha visszakapta a vezérlést, a program továbbra is működni fog attól a programsortól, ahonnan a vezérlés korábban átkerült az ügyfélterminálhoz (és ahová később visszaküldték).

Figyelem!

Vedd észre, hogy a 4.2 - 4.7 lépések alatt a program nem hajtott végre semmilyen műveletet - a program a szerver válaszára várakozott.

5. A program fölötti ellenőrzés a következő operátorhoz - a 'return' operátorhoz kerül.

6. A 'return' operátor végrehajtása azzal végződik, hogy kilép a start() függvényből, és a program végrehajtása befejeződik (emlékeztetnünk kell, hogy a scriptek befejezik a munkájukat a végrehajtásuk után) – és a vezérlés visszakerül az ügyfélterminálhoz.

A script teljesítette feladatát: a Buy megbízást az előre beállított paraméterekkel megnyitotta. A scriptek használata nagyon kényelmes, ha egy kicsi, egyszerű műveletet kell végrehajtani; ebben az esetben egy script használata ésszerű. A 4.6. lépéstől a kereskedő látja a megbízást a képernyőn.


 81.ábra. Megbízás adása a simpleopen.mq4 script segítségével.

Az események nem mindig a fent bemutatott módon zajlanak. Lehetséges, hogy a kereskedelmi kérést visszautasítja az ügyfélterminál vagy a szerver. Kísérletképpen próbáljuk meg, hogy például megváltoztatjuk a szimbólumnevet: legyen GBPUSD (ez megengedett). Ezzel a változtatással a következő programot fogjuk kapni:

int start() // Special function start
 { // Opening BUY
 OrderSend("GBPUSD",OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
 return; // Exit start()
 }

Indítsuk el a scriptet ugyanabban az Eur/Usd szimbólum ablakban. A scripttől azt várjuk, hogy nyisson egy megbízást a Gbp/Usd ablakban. Azonban, mivel a scriptet az Eur/Usd ablakhoz csatoltuk, nem nyithat megbízást a Gbp/Usd ablakban.

Az ilyen programok hátránya a funkcionális korlátozásuk. Ebben az esetben, a felhasználó hozzácsatolta a scriptet a szimbólumablakhoz és vár arra, hogy a megbízás teljesüljön. Azonban a megbízás nem teljesül. A felhasználó nem tudja, hogy ennek mi az oka: a programkódban rejlő algoritmikus hiba, a kereskedelmi kérés ”elveszett” a szerverre vezető úton, vagy a kereskedelmi kérést visszautasította az ügyfélterminál, vagy egyéb más akadály történt.

Hogy a felhasználót ellássuk (és nagyon fontos, hogy a programot is) a kereskedelmi kérés végrehajtásával kapcsolatos információval, szükség van a hibák feldolgozására.

Hibafeldolgozás

Az ügyfélterminál egy nagyon fontos tulajdonsága az, hogy ha egy hiba történik egy alkalmazás végrehajtása alatt, az ügyfélterminál nem állítja le a program végrehajtását. Hibákat okoz az alkalmazásban használt algoritmus tökéletlensége. Néhány esetben hibát okoz valamely külső tényező (programra gyakorolt hatása). A hibák belső okai lehetnek az MQL4 követelményeinek bármilyen megszegése, vagy kereskedés szabályainak megsértése, például érvénytelen árak használata. A külső okok azok, amelyek nem kapcsolatosak az alkalmazási programmal, mint például a félbeszakadt kapcsolat.

Ha egy hiba történik egy program végrehajtása során, a program továbbra is futni fog, és az ügyfélterminál létre fogja hozni a GetLastError() függvényen keresztül a hibakód-értékét.

A GetLastError() függvény

int GetLastError()

A függvény visszaküldi az újonnan történt hiba kódját, azután a különleges last_error változó értéke tárolja az utolsó hiba kódját. A következő GetLastError() hívás 0-t fog visszaküldeni.

Az alábbiakban a hibakód alapján azonosítani fogunk minden lehetséges hibát. Több hiba történhet egy program végrehajtása alatt; a GetLastError() függvény csak a legújabb hiba kódértékét küldi vissza, ezért minden alkalommal, amikor  szükségünk van erre az információra, ajánlott a GetLastError() függvényt futtatni, közvetlenül azután a programsor után, amiben a hiba történhetett.

Hiba 130. érvénytelen stop megbízás

Az utoljára vizsgált script nem elemzi a hibákat, ezért a felhasználó továbbra is tájékozatlan marad a megbízás végrehajtásának a folyamatát illetően. A GetLastError() függvény használatának egyszerűbb variációjában a program elemez egy hibát és erről tájékoztatja a felhasználót. Ha futtatod a confined.mq4 scriptet az Eur/Usd ablakban, egy hiba fog történni.
//--------------------------------------------------------------------------
// confined.mq4 
// The code should be used for educational purpose only.
//--------------------------------------------------------------------------
int start() // Special function start
 { // Opening BUY
 OrderSend("GBPUSD",OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
 Alert (GetLastError()); // Error message
 return; // Exit start()
 }
//--------------------------------------------------------------------------

Csak egy sort adtunk hozzá, de ettől nagyon informatív lett a script:

 Alert (GetLastError()); // Error message

A GetLastError() függvény visszaküldi az utolsó hiba kódját, amit az Alert() függvény arra használ, hogy bemutassa ezt az értéket a képernyőn. Miután  confined.mq4 scriptet csatoltuk az Eur/Usd szimbólumablakhoz, a script végrehajtásra kerül, melynek következtében a felhasználó a következő üzenetet fogja látni:


 82. ábra. A confined.mq4 eur/usd ablak történt végrehajtásakor kapott hibakód.

A Függelék  hibakód jegyzékében megkereshetjük, hogy milyen hiba történt a program végrehajtásánál. Ebben az esetben, 130-as hiba (az érvénytelen stop megbízás) történt. Ez azt jelenti, hogy a formális paraméterek értékei, amiket az OrderSend() függvényben használtunk, nem tartják be azokat a feltételeket, amiket a Követelmények és korlátozások a kereskedelemben című  fejezetben ismertetünk. Nézzük meg alaposabban mi okozta a hibát: az aktuális Bid és Ask piaci árakat az Eur/Usd szimbólumablakból vettük, amihez a scriptet csatoltuk. Azonban ezeket az értékeket arra használjuk, hogy egy Gbp/Usd iránti kereskedelmi kérést alakítsunk ki. Ezért a Gbp/Usd Ask = 1.9655 aktuális áránál, az új megbízás aktuális TakeProfit értéke (Eur/Usd Bid =1.2930) 1.2930+15*0.0001=1. 2945, ami lényegesen alacsonyabb a minimális megengedett értéknél, vagyis érvénytelen.

Ebben az esetben egy algoritmikus hiba történt. Azért hogy ezt ki javítsd, a szimbólumárak helyes értékeit kell használnod. Ezeket az értékeket a MarketInfo() függvény alkalmazásával kaphatjuk meg. Az improved.mq4 megnyitja a Gbp/Usd megbízást, bármilyen szimbólumablakban indítjuk el:
//------------------------------------------------------------------------------
// improved.mq4 
// The code should be used for educational purpose only.
//------------------------------------------------------------------------------
int start() // Special function start
 {
 double bid =MarketInfo("GBPUSD",MODE_BID); // Request for the value of Bid
 double ask =MarketInfo("GBPUSD",MODE_ASK); // Request for the value of Ask
 double point =MarketInfo("GBPUSD",MODE_POINT);//Request for Point
 // Opening BUY
 OrderSend("GBPUSD",OP_BUY,0.1,ask,3,bid-15*Point,bid+15*Point);
 Alert (GetLastError()); // Error message
 return; // Exit start()
 }
//------------------------------------------------------------------------------

A fenti hiba nem történik meg ennek a scriptnek a végrehajtásakor, a végrehajtás azzal fog végződni, hogy a küvetkező üzenetet kapjuk: 0 (nulla). Ez azt jelenti, hogy a GetLastError() függvény a 0 értéket küldte vissza, az ügyfélterminál nem talált hibákat a kereskedelmi kérés végrehajtásában.

Vizsgáljunk meg egyéb gyakori hibákat! Térjünk vissza arra a módszerre, hogy a megbízást ugyanazon a szimbólumon nyitjuk, mint amelyik szimbólum ablakához a scriptet hozzáerősítettük.

Hiba 129. érvénytelen ár

Néhány esetben egyszerű hiba történik - a kettős ár hibás értékét adjuk meg nyitó árként. A Buy megbízásokat (lásd: Követelmények és korlátozások a kereskedelemben)  az Ask árnál nyitjuk. Lent bemutatjuk, mi történik, ha tévedésből a scriptben a Bid árat adjuk meg mistaken.mq4:
//-------------------------------------------------------------------------
// mistaken.mq4 
// The code should be used for educational purpose only.
//-------------------------------------------------------------------------
int start() // Special function start
 { // Opening BUY
 OrderSend(Symbol(),OP_BUY,0.1,Bid,3,Bid-15*Point,Bid+15*Point);
 Alert (GetLastError()); // Error message
 return; // Exit start()
 }
//-------------------------------------------------------------------------

Mielőtt a kereskedelmi kérést elküldi a szervernek, az ügyfélterminál elemzi, hogy az ár és stop kért értékei betartják-e a megengedett értékekre vonatkozó szabályokat. Ezalatt az ellenőrzés alatt kiderül, hogy a kért nyitó ár hibás, úgyhogy az ügyfélterminál nem fogja a kereskedelmi kérést elküldeni a szervernek. A GetLastError() függvény a 129-es értéket fogja visszaküldeni  (lásd:  Hibakódok). A script végrehajtása a megfelelő hibaüzenet megjelenésével fog végződni:


83. ábra. Hiba 129 (érvénytelen ár) a  mistaken.mq4  végrehajtásával.


Hiba 134. nincs elég pénz a kereskedéshez

Hasonló eredményt (hiba 134) kapunk, ha nincs elegendő szabad pénz, ekkor semmi szín alatt nem teljesül a megbízás. Megtudhatod, hogy mennyi fedezet kell 1 lot méretű megbízás megnyitásához a MarketInfo(symbol_name, MODE_MARGINREQUIRED) függvény használatával.

Figyelem!

Egy standard méretű lot mérete ugyanazon a szimbólumon változhat a különböző dealing centerekben.

A megbízáshoz szükséges szabad egyenleg fordítottan arányos a tőkeáttétellel. Ugyanakkor valamely a szimbólumon 1 pont értéke független a tőkeáttételtől.

3. táblázat. 1 lot kötésméret 1 pont értékének lehetséges variációi (a letéti pénznem US dollár).


Dealing Center 1 Dealing Center 2 Dealing Center 3
Buy Sell 1pt Buy Sell 1pt Buy Sell 1pt
EUR/USD 1296.40 1296.20 10.00 1296.50 1296.20 10.00 1000.00 1000.00 10.00
GBP/USD 1966.20 1966.00 10.00 1376.48 1376.20 7.50 1000.00 1000.00 10.00
AUD/USD 784.40 784.20 10.00 1569.20 1568.40 20.00 1000.00 1000.00 10.00
USD/JPY 1000.00 1000.00 8.29 1000.00 1000.00 8.29 1000.00 1000.00 8.29
USD/CHF 1000.00 1000.00 8.02 1000.00 1000.00 8.02 1000.00 1000.00 8.02
EUR/CHF 1296.40 1296.20 8.02 1296.35 1296. 35 8.02 1000.00 1000.00 8.02

2007.12.16. árak.

Vizsgáljuk meg, hogy milyen módszerrel számolják ki 1 lot méretű kötésnél 1 pont értékét.

1.       Dealing Center (a leggyakoribb)

Azokon a szimbólumokon, ahol az USD szerepel a nevezőben, 1 lot fedezete egyenlő az aktuális kettős ár megfelelő értékének 1000 szeresével, míg 1 pont értéke egyenlő 10 dollárral.

Azokon a szimbólumokon, ahol az USD a számlálóban szerepel, 1 lot fedezete egyenlő 1000.00 dollárral, míg 1 pont értéke fordítottan arányos az aktuális szimbólum másik tagjával, 1/(Bid). Például USD/CHF-en Bid= 1.2466 és 1 pont értéke 10/1. 2466 = 8.02.

A kereszt devizák esetében, 1 lot fedezetét a számláló pénznemére számítjuk, míg 1 pont értéket a nevező pénznemére. Például: az EUR/CHF-en 1 lot letéti igénye 1296.40 (az EUR/USD alapján), míg 1 pont értéke 8.02 (az USD/CHF alapján).

2.       Dealing Center

Néhány dealing center esetében a fedezet és a pontérték számításának a szabálya szimbólumonként különböző lehet. Például: 1 lot fedezete és 1 pont értéke arányosan nagyobb vagy kisebb lehet, mint az 1. Például ez a tényező GBP/USD esetén 0.75 lehet, míg AUD/USD esetén 2.0. Az értékek ilyen meghatározása nem jár semmilyen gazdasági változással; ilyen esetben meg kell fontolni ezt a sajátosságot a megbízás adásakor. Szintén figyelembe kell venni, hogy 1 lot buy és sell mérete kereszt devizák esetében esetén ugyanaz.

3.       Dealing Center

Vannak olyan dealing centerek is, ahol 1lot fedezet igénye 1000.00 dollár minden szimbólumon. Ugyanakkor 1 pont értéke továbbra is arányos az aktuális. Ennek következtében a tőkeáttétel mindegyik szimbólumon más.

Figyelem!

1 pont értékét, minded olyan szimbólumon, amit nem az USD-hez viszonyítva jegyzünk, a nevezőben szereplő devizához viszonyítunk.

Általában nincs több módszer a fenti értékek meghatározására. De azt hiszem szükségtelen hangsúlyozni, hogy a valódi pénzel történő kereskedést megelőzően meg kell győződni róla, hogy a dealing center milyen számítási módszert használ, és ezt a módszert figyelembe kell venni a kódolás során.

Szabad margin

Kódolásnál nagyon fontos figyelembe venni a felhasználható egyenleget. Szabad margin az az összeg, ami a kereskedelem végrehajtásakor rendelkezésre áll .

Lássunk egy példát! Legyen az egyenleg ( Balance) 5000.00, nyitott megbízások nincsenek a terminálban. Nyissuk egy 1 lot nagyságú Buy megbízást a 3. dealing center feltételei szerint. A következő szabályt is alkalmazza a 3. dealing center:

Figyelem!

Ha különböző irányú megbízásokat nyitunk egy szimbólumon, az azonos irányban kötött megbízások margin összege közül a kisebb a szabad margint növeli (ez a szabály nem alkalmazható minden dealing centerben).

A terminál ablak mutatni fogja a nyitott megbízásokkal kapcsolatos információt. Jegyezd meg, a margin 1000.00 és megbízás nyitásakor a profit -30.00, azért a szabad margin 5000-1000 -30=3970.00:


84. ábra. Buy megbízás a terminál ablakban. A kép hibás (a szerkesztő megjegyzése).

Miután ugyanakkora Sell megbízást nyitottunk, a szabad margin növekedni fog. A két ellentétes megbízás közül a kisebb fedezet igénye a szabad margint növeli, az 1000.00 dolláros sell megbízás miatt a szabad margin 1000.00 dollárral növekedni fog. A 85. ábrán azt az esetet látjuk, amikor az ellentétes megbízások margin igénye egyenlő és ezek kiegyenlítik egymást.


85. ábra. Buy és Sell megbízás a terminál ablakban.

Amikor egy kisebb margin igényű Sell megbízást nyitunk a szabad margin szintén növekedni fog. Ebben az esetben a kisebb margin igényű kötési irány margin igénye 700.00 dollár, ami a szabad margint 700.00 dollárral fogja növelni, és a margin igény a különböző irányú megbízások összesített fedezet igényei közti különbség lesz (86. ábra).


86. ábra. Buy és Sell megbízás a terminál ablakban.

Ha még egy 0.1 lot nagyságú Sell megbízást nyitunk (100.00 fedezettel), az irányonkénti összesített fedezet igények közül a kisebb 700.00 + 100 00 = 800.00 lesz. Ezért a margin (azzal a helyzettel összehasonlítva, ahol csak a Buy megbízás volt nyitva) 800.00 dollárral csökkent. A 86. ábrával összehasonlítva, a margin csökken, míg a szabad tőke 100.00 dollárral növekszik (lásd a 87. ábrát).


87. ábra. Buy és Sell megbízások a terminál ablakban.

A Free Margin a 86. és 87. ábrán több mint 100.00 dollárral különbözik, mert az összes profit az aktuális ár változása miatt csökkent (a csökkenés 8.00).

Ha hasonló manipulációkat végzünk egy másik dealing centerben akkor megfigyelhetjük, hogy a szabad margin meghatározása más módszerrel történik. Néhány dealing center a következő szabályt alkalmazza:

Figyelem!

Semmilyen megbízás nyitása nem szabadít fel tőkét és/vagy nem növeli meg a szabad margint. Azonban az ellentétes megbízások megnyitása nem köt le újabb tőkét , a megbízások tőkeigénye a különböző irányú megbízások integrált tőkeigényei közül a magasabb érték lesz, (a szabályt nem alkalmazza minden dealing center).

Például, ha korábban nyitottál egy 4 lotos USD/JPY Buy megbízást 2. dealing centerben, a tőke és a szabad margin nem fognak megváltozni egy 4 lotos Sell megbízás megnyitásnál. 

 
88. ábra. A különböző irányú megbízások nem módosítják a tőkét.

Számításokat végezhetsz, hogy megtudd, az aktuális tőke elég-e egy megbízás megnyitására. Ezen kívül használhatod az AccountFreeMarginCheck() függvényt, amely visszaküldi a maradék szabad margin értékét, ami a meghatározott nagyságú, adott szimbólumon történő megbízás megkötése után maradna. Ha a visszaküldött érték egyenlő vagy több mint 0, akkor van elég pénz a számlán. Ha ez kevesebb 0-nál, akkor ilyen méretű megbízás ezen a szimbólumot nem nyitható, az ügyfélterminál 134. hibát fog visszaküldeni, ha a nyitást mégis megkiséreljük.

Hogy megtudjuk, az adott dealing centeren mennyi szabad marginra van szükség az adott szimbólumon 1 lot nagyságú megbízás megnyitásához, használjuk az egyszerű conditions.mq4 scriptet:
//--------------------------------------------------------------------------
// conditions.mq4 
// The code should be used for educational purpose only.
//--------------------------------------------------------------------------
int start() // Special function start
 {
 Alert(Symbol()," Sell = ",AccountFreeMargin()// At selling
 -AccountFreeMarginCheck(Symbol(),OP_SELL,1));
 Alert(Symbol()," Buy = ",AccountFreeMargin() // At buying
 -AccountFreeMarginCheck(Symbol(),OP_BUY,1));
 return; // Exit start()
 }
//--------------------------------------------------------------------------

Ez a kifejezés

AccountFreeMargin() - AccountFreeMarginCheck(Symbol(),OP_SELL,1)

lehetővé teszi, hogy kiszámítsuk a különbséget az elérhető szabad margin, és a megbízás feltételezett megnyitása után maradó szabad margin között.

Ha olyankor indítjuk el a script végrehajtását, amikor tőzsdei megbízások nincsenek a terminálban, információt kapunk az 1 lot nagyságú buy illetve sell megbízás megnyitásához szükséges fedezet nagyságáról az adott szimbólumon:


89. ábra. 1-lot fedezet igénye különböző szimbólumokon a   conditions.mq4 script alkalmazása alapján.

Ha olyan szimbólum ablakában indítjuk el a  conditions.mq4 scriptet ahol nyitott megbízások vannak, más értékeket fogunk kapni, a dealing center számítási módszerétől függően.

Egyéb hibák és a MarketInfo() függvény

Vannak további korlátozások az OrderSend() függvény paramétereinek meghatározásakor. Ez a maximális és a minimális megbízási árlépések, vagy a maximális és a minimális kötésméret értéke stb. A MarketInfo() függvény használata lehetővé teszi, hogy a szimbólumokkal kapcsolatos különféle információt kérdezzünk le az ügyféltermináltól.

MarketInfo() függvény

double MarketInfo(string symbol, int type)

A függvény a szimbólumokkal kapcsolatos különféle információt küldi vissza, amiket az ügyfélterminál Market Watch ablakában láthatunk. Az aktuális szimbólummal kapcsolatos információkat előre definiált változókban tárolja a terminál.

Paraméterek:

symbol – a szimbólum neve;

type – azonosító, amely meghatározza, hogy milyen fajta információt kérünk a függvénytől. Az azonosító értékek a következők lehetnek (lásd: MarketInfo függvény azonosítók).

Néha változás történik a szerveroldalon. Például a gyorsan változó árak következtében a brókered növelheti azt a minimális távolságot, ami korlátozza a függőben levő megbízások és a stop megbízások elhelyezését. Később egy nyugodt piacnál a bróker megint csökkentheti ez a távolságot. Így néhány paraméter értékét bármikor megváltoztathatják.

A ha azt akarod, hogy a programjaid stabilan működjenek, minimális legyen a visszautasított kérés, frissítened kell az információkörnyezet paramétereit a MarketInfo() és RefreshRates() függvényekkel, az OrderSend() függvény végrehajtása előtted.

Példa

Példa egy olyan egyszerű scriptre, ami egy Buy megbízást ad a szabad margin 35% százalékával és előre beállított stop szintekel  (openbuy.mq4).


//-------------------------------------------------------------------------------
// openbuy.mq4 
// The code should be used for educational purpose only.
//-------------------------------------------------------------------------- 1 --
int start() // Special function start
 {
 int Dist_SL =10; // Preset SL (pt)
 int Dist_TP =3; // Preset TP (pt)
 double Prots=0.35; // Percentage of free margin
 string Symb=Symbol(); // Symbol
//-------------------------------------------------------------------------- 2 --
 while(true) // Cycle that opens an order
 {
 int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// Min. distance
 double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// Min. volume
 double Step =MarketInfo(Symb,MODE_LOTSTEP);//Step to change lots
 double Free =AccountFreeMargin(); // Free Margin
 double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//Cost per 1 lot
 //-------------------------------------------------------------------- 3 --
 double Lot=MathFloor(Free*Prots/One_Lot/Step)*Step;// Lots
 if (Lot < Min_Lot) // If it is less than allowed
 {
 Alert(" Not enough money for ", Min_Lot," lots");
 break; // Exit cycle
 }
 //-------------------------------------------------------------------- 4 --
 if (Dist_SL < Min_Dist) // If it is less than allowed
 {
 Dist_SL=Min_Dist; // Set the allowed
 Alert(" Increased the distance of SL = ",Dist_SL," pt");
 }
 double SL=Bid - Dist_SL*Point; // Requested price of SL
 //-------------------------------------------------------------------- 5 --
 if (Dist_TP < Min_Dist) // If it is less than allowed
 {
 Dist_TP=Min_Dist; // Set the allowed
 Alert(" Increased the distance of TP = ",Dist_TP," pt");
 }
 double TP=Bid + Dist_TP*Point; // Requested price of TP
 //-------------------------------------------------------------------- 6 --
 Alert("The request was sent to the server. Waiting for reply..");
 int ticket=OrderSend(Symb, OP_BUY, Lot, Ask, 2, SL, TP);
 //-------------------------------------------------------------------- 7 --
 if (ticket>0) // Got it!:)
 {
 Alert ("Opened order Buy ",ticket);
 break; // Exit cycle
 }
 //-------------------------------------------------------------------- 8 --
 int Error=GetLastError(); // Failed :(
 switch(Error) // Overcomable errors
 {
 case 135:Alert("The price has changed. Retrying..");
 RefreshRates(); // Update data
 continue; // At the next iteration
 case 136:Alert("No prices. Waiting for a new tick..");
 while(RefreshRates()==false) // Up to a new tick
 Sleep(1); // Cycle delay
 continue; // At the next iteration
 case 146:Alert("Trading subsystem is busy. Retrying..");
 Sleep(500); // Simple solution
 RefreshRates(); // Update data
 continue; // At the next iteration
 }
 switch(Error) // Critical errors
 {
 case 2 : Alert("Common error.");
 break; // Exit 'switch'
 case 5 : Alert("Outdated version of the client terminal.");
 break; // Exit 'switch'
 case 64: Alert("The account is blocked.");
 break; // Exit 'switch'
 case 133:Alert("Trading forbidden");
 break; // Exit 'switch'
 default: Alert("Occurred error ",Error);// Other alternatives 
 }
 break; // Exit cycle
 }
//-------------------------------------------------------------------------- 9 --
 Alert ("The script has completed its operations ---------------------------");
 return; // Exit start()
 }
//-------------------------------------------------------------------------- 10 --

A script a start() különleges  függvényből áll (1-10 blokkok). Az 1-2 blokkokban a megbízások nyitási értékeit állítjuk be. A 2-9 blokk egy while() ciklusoperátor, amiben minden szükséges számítást végrehajtunk. Ez a ciklus a kódban végrehajtja a megbízás nyitását. A 2-3 blokkban az információskörnyezet változóit frissítjü. A 3-4-5-6 blokkokban a lot méretet és a stop szinteket számoljuk ki. A 7-8-9 blokkban a hibafeldolgozást végezzük. A 9-10 blokkban, a szükséges üzenet jelenítjük meg, majd a script befejezte a munkáját.

Vizsgáljuk meg a programkód néhány jellemzőjét! Könnyű észrevenni, hogy a kereskedelmi kérést a 6-7 blokkban alakítjuk ki. A 3-4 blokkban kiszámoljuk a lot méretét. Itt megvizsgáljuk, hogy az elérhető szabad margin elegendő-e megbízás nyitásához. Ha a 3-4 blokkban kiderül, hogy kevés a fedezet akkor a megfelelő üzenet megjelenítésével a ‘break' operátor kilép a 2-9  ciklusból. Ha a vezérlés átkerül a 9-10 blokkba a script befejezi a működését. Az üzenetek a 9. blokkban fölöslegesek. Azok csak a felhasználót segítik, hogy milyen folyamatok zajlanak a scriptben, - mikor van a programnak vége, és a késedelem oka a hálózatban vagy a szerveren van.

Ha a szabad margin elegendő a megbízás nyitásához, a vezérlés lekerül a 4-5 blokkhoz majd az 5-6 blokkhoz. Ezekben a blokkokban cikluskijárat nincs. Az 1-2 blokkban a TP-t szándékosan 3 pontra választottuk. A brókerek többsége 5 pontra állítja be a minimális távolságot. Az 5-6 blokkban a program fel fogja fedezni, hogy az előre beállított érték kevesebb a megengedettnél. A program olyan TP értéket fog beállítani, ami nem mond ellent a korlátozásnak.

Azután a vezérlés a 6-7 blokkhoz kerül, hogy nyissa meg a megbízást. A blokk első sora üzenetet küld a felhasználónak. A kereskedelmi kérést csak azután küldjük el. Felmerül egy kérdés: Miért jelenítjük meg az üzenetet azelőtt, mielőtt a kereskedelmi kérést elküldjük? Először adhatnánk az utasítást, majd azután tájékoztathatnánk erről a felhasználót. A válasz erre a kérdésre szorosan összefügg azzal a technológiával, ahogy a kérést elküldjük az ügyfélterminálnak és azután a szervernek (lásd a 66. ábrát). Ez esetben a kereskedelmi kérést az OrderSend() függvényben egy értékadó operátor jobb oldalán alakítjuk ki. A így megalkotott kereskedelmi kérés ebből a függvényből küldjük a szerverre, és az értékadó operátor végre fog hajtódni, miután a szerver a kérés sorsáról visszaküldte a választ. Így, az egyetlen lehetőség tájékoztatni a felhasználót a kereskedelmi kérés küldéséről az, hogy az értékadó operátor előtt küldjük az üzenetet arról az eseményről, ami az értékadó operátor jobb oldalán a kereskedelmi függvényben történik.

Előbb-utóbb az ügyfélterminál visszaküldi a vezérlést a programnak, a 6-7 blokkban a program az értékadó operátort végre fogja hajtani, aminek következtében a 'ticket' változó felvesz egy értéket, és a vezérlés tovább jut a hibaelemező 7-8-9. blokkhoz.

Ha a megbízás teljesül a szerveren, akkor a megbízás jegyszáma hozzárendelődik 'ticket' változóhoz. Ez azt jelenti, hogy a script teljesítette a feladatát és a programnak nem szükséges tovább futnia. A 7-8 blokkban lévő 'break' operátor kilép a while() ciklusból. A vezérlés eljut a 9-10 blokkba (a cikluson kívül), és a program befejeződik.

Azonban, ha a kísérlet, hogy megnyissuk a megbízást nem sikerül, akkor a vezérlés a 8-9. hibaelemező blokkba kerül. Két hibacsoport létezik: azok ahol még van remény a megbízás sikeres megnyitására és azok, amelyek a programvégrehajtás egyértelmű végződéséhez vezetnek. Az 'Error' változó ebben az esetben az utolsó hiba kódját kapja, azét a hibáét, amit az OrderSend() függvény végrehajtásánál visszaküldött a szerver vagy az ügyfélterminál.

A 8-9 blokk első 'switch’ operátorában az kiküszöbölhető hibákat soroljuk fel. Ebben a csoportban minden hibát különbözőképpen kezelünk. Például, ha az ár változott (hiba 135) elegendő, ha frissítjük a környezeti paramétereket a RefreshRates() függvény használatával és ismét megkíséreljük, hogy nyissuk a megbízást. Ha a "No prices" (nincsenek árak) (hiba 136) hiba történik, nincs értelem kérést küldi a kereskedelmi szervernek. Ebben az esetben várnunk kell egy új tickre (addig a szerveren nincsenek elérhető árak) és azután újra próbálkozhatunk a megbízás nyitásával. Ezért ott egy várakozó ciklus kell elhelyezni a blokkban, a 136. hiba elhárításához. Ez a várakozó ciklus megszakad, amint egy új tick érkezik. Kilépünk a switch() operátorból a  'continue' operátorral, amely megszakítja a while() ciklus aktuális ismétlését és kezd egy újat.

Kritikus hibákat más módon dolgozzuk fel. Ha egy ilyen hiba történik, a program értesíti a felhasználót és befejezi a munkáját. Ezért használjuk a 'break' operátort (az utolsó a 8-9 blokkban) amely megszakítja a while() és ez a program végződésével jár.

Meg kell jegyeznünk, hogy ebbe a példába szándékosan nem foglaltunk bele mindent hibát. Ebben az esetben nem az a szándékunk, hogy ellássuk a felhasználót egy kész programmal. Nagyon fontos, hogy a programozó saját maga elemezze a hibákat, és önállóan döntse el, hogy hogyan dolgozza fel a hibákat a programban. Ugyanakkor, néhány hibát nem lehet feldolgozni, mert a program úgy van felépítve, hogy nem érzékeli ezeket, például ebben az esetben a 129 és 130 hibák.

A fenti példában van egy olyan kis algoritmikus hiba, amit nem találhatunk meg sem a fordításnál sem az ügyfélterminálban, sem a szerveren.

Figyelem!

Kritikus fontosságú minden ”csipetnyi” kódrészlet a hatókörétől függetlenül.

A kód a 4-5 blokkban:

//--------------------------------------------------------------------------- 4 --
 if (Dist_SL<Min_Dist) // If it is less than allowed.
 {
 Dist_SL=Min_Dist; // Set the allowed
 Alert(" Increased the distance of SL = ",Dist_SL," pt");
 }
 double SL = Bid - Dist_SL*Point; // Requested price of SL
//--------------------------------------------------------------------------- 5 --

A számítások során az if() operátor törzsében a Dist_SL változó új értéket kap. Tételezzük fel, hogy ez szokványos minimális távolság: 5 pont. Az első végrehajtásnál (gyors piacon), ezt az értéket a szerveren 20 pontra módosítják. A Min_Dist változó meg fogja kapni a 20-as értéket.

 int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// Minimum distance

Most tegyük fel, hogy a kereskedelmi kérést 136. hiba miatt utasították vissza. A program a 8-9 blokkban fogja követni az új ticket. Ebben az időszakban a szerver megváltoztathatja a minimális távolság értékét, például azt 10 pontra csökkenti. Amikor az új tick megérkezik az vezérlés átkerül az új ciklusba, és a Min_Dist változó új értéke egyenlő lesz 10-zel. Azonban a Dist_SL változó értéke változatlanul 20 marad (a 4-5 blokk kódja alapján a Dist_SL értéke csak növekedhet). Azért hogy kizárd ezt az algoritmikus hibát, a 4-5 blokkot olyan módon kell átírni, ahol csak az az érték változna meg ami a körülményektől függ, (ebben az esetben ez SL értéke), míg Dist_SL értéke nem változna, például így:

//------------------------------------------------------------------------- 4 --
 double SL = Bid - Dist_SL*Point; // Requested price of SL
 if (Dist_SL<Min_Dist) // If it is less than allowed
 {
 SL = Bid - Min_Dist*Point; // Requested price of SL
 Alert(" Increased the distance of SL = ",Min_Dist," pt");
 }
//------------------------------------------------------------------------- 5 --

Hasonló változtatást kell csinálni 5-6 blokkban a másik stop megbízással.

Függőben levő megbízások adása

Alapvető különbség a függőben levő, és a piaci megbízások elhelyezése között a programozásban nincs.

Meg kell jegyezned azonban a tényt, hogy a függőben lévő megbízások elhelyezésekor és módosításakor a rendelkezésre álló fedezetet nem ellenőrzi sem az ügyfélterminál sem a szerver. Itt nincs korlátozás. A számlán rendelkezésre álló összegnél nagyobb összegre is adható függőben levő megbízás. Ezek a megbízások határozatlan ideig a szerveren maradhatnak. Amikor a piaci ár eléri a függőben levő megbízás kért nyitó árát a szerver akkor végez ellenőrzést. Ha van elegendő pénz a számlán, akkor nyitja ezt a megbízást, vagyis az piaci megbízássá válik. Ha nincs fedezet, akkor azt törölni fogja.

WindowPriceOnDropped() függvény

Az MQL4-ben van egy nagyon hasznos lehetőség – programozási módszerrel meg tudjuk határozni a szimbólumablakban annak a helynek a koordinátáit ahová egy Expert Advisort vagy egy scriptet elhelyeztünk, mikor az egérrel hozzácsatoltuk őket az ablakhoz. Például meg tudjuk szerezni azt a koordináta értékét, ahová a scriptet áthúztuk, ha használjuk a WindowPriceOnDropped() függvényt.

double WindowPriceOnDropped()

A függvény visszaküldi az chart azon pontján lévő ár értékét, ahová az EA-t vagy a scriptet leejtettük. Az érték csak akkor lesz igaz, ha az EA-t vagy a scriptet az egérrel helyeztük el ('drag and drop'). Ezt az értéket nem határozhatjuk meg egyéni indikátorok csatolásánál.

Példa

Példa egy olyan egyszerű scriptre, ami elhelyez egy BuyStop megbízást a szabad margin 35%-ával és előre beállított stop szintekkel  (openbuystop.mq4).


//------------------------------------------------------------------------------------
// openbuystop.mq4 
// The code should be used for educational purpose only.
//------------------------------------------------------------------------------- 1 --
int start() // Special function start
 {
 int Dist_SL =10; // Preset SL (pt)
 int Dist_TP =3; // Preset TP (pt)
 double Prots=0.35; // Percentage of free margin
 string Symb=Symbol(); // Symbol
 double Win_Price=WindowPriceOnDropped(); // The script is dropped here
 Alert("The price is set by the mouse as Price = ",Win_Price);// Set by the mouse
//------------------------------------------------------------------------------- 2 --
 while(true) // Cycle that opens an order
 {
 int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// Min. distance
 double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// Min. volume
 double Free =AccountFreeMargin(); // Free Margin
 double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//Cost per 1 lot
 double Lot=MathFloor(Free*ProtsOne_LotMin_Lot)*Min_Lot;// Lots
 //------------------------------------------------------------------------- 3 --
 double Price=Win_Price; // The price is set by the mouse
 if (NormalizeDouble(Price,Digits)< // If it is less than allowed
 NormalizeDouble(Ask+Min_Dist*Point,Digits))
 { // For BuyStop only!
 Price=Ask+Min_Dist*Point; // No closer
 Alert("Changed the requested price: Price = ",Price);
 }
 //------------------------------------------------------------------------- 4 --
 double SL=Price - Dist_SL*Point; // Requested price of SL
 if (Dist_SL < Min_Dist) // If it is less than allowed
 {
 SL=Price - Min_Dist*Point; // Requested price of SL
 Alert(" Increased the distance of SL = ",Min_Dist," pt");
 }
 //------------------------------------------------------------------------- 5 --
 double TP=Price + Dist_TP*Point; // Requested price of TP
 if (Dist_TP < Min_Dist) // If it is less than allowed
 {
 TP=Price + Min_Dist*Point; // Requested price of TP
 Alert(" Increased the distance of TP = ",Min_Dist," pt");
 }
 //------------------------------------------------------------------------- 6 --
 Alert("The request was sent to the server. Waiting for reply..");
 int ticket=OrderSend(Symb, OP_BUYSTOP, Lot, Price, 0, SL, TP);
 //------------------------------------------------------------------------- 7 --
 if (ticket>0) // Got it!:)
 {
 Alert ("Placed order BuyStop ",ticket);
 break; // Exit cycle
 }
 //------------------------------------------------------------------------- 8 --
 int Error=GetLastError(); // Failed :(
 switch(Error) // Overcomable errors
 {
 case 129:Alert("Invalid price. Retrying..");
 RefreshRates(); // Update data
 continue; // At the next iteration
 case 135:Alert("The price has changed. Retrying..");
 RefreshRates(); // Update data
 continue; // At the next iteration
 case 146:Alert("Trading subsystem is busy. Retrying..");
 Sleep(500); // Simple solution
 RefreshRates(); // Update data
 continue; // At the next iteration
 }
 switch(Error) // Critical errors
 {
 case 2 : Alert("Common error.");
 break; // Exit 'switch'
 case 5 : Alert("Outdated version of the client terminal.");
 break; // Exit 'switch'
 case 64: Alert("The account is blocked.");
 break; // Exit 'switch'
 case 133:Alert("Trading fobidden");
 break; // Exit 'switch'
 default: Alert("Occurred error ",Error);// Other alternatives 
 }
 break; // Exit cycle
 }
//------------------------------------------------------------------------------- 9 --
 Alert ("The script has completed its operations -----------------------------");
 return; // Exit start()
 }
//------------------------------------------------------------------------------- 10 --

Az openbuystop.mq4 script szerkezete ugyanúgy épül fel, mint az openbuy.mq4 script, tehát nem szükséges részletesen leírni azt. Csak a programok közti alapvető különbségekre fogjuk fordítani a figyelmünket.

Az ár szintjét ahol a scriptet hozzáerősítettük a szimbólumablakhoz, a következő sor határozza meg:

 double Win_Price=WindowPriceOnDropped(); // A script is dropped here

Ennek a változónak az értékét végig megtartjuk a program működése alatt. Ez azért szükséges, hogy a kért nyitó ár a későbbiekben ne változzon. A script minden alkalommal ahhoz az árhoz viszonyítva számítja ki az kért ár értékei, ahol a felhasználó csatolta a scriptet.

Könnyű belátni az  openbuystop.mq4 script alapján, hogy itt nem vizsgáljuk a fedezet meglétét, a szabad margint a 3-4. blokkban elemezzük. Ha az ár kiszámított értéke nem felel meg a függőben levő Stop megbízás elhelyezése a követelményeinek ( lásd: A megbízások jellemzői és a kereskedés végrehajtás szabályaiKövetelmények és korlátozások a kereskedelemben), akkor az értékét újraszámoljuk.

A hibafeldolgozó blokkban szintén van néhány apró változtatás: néhány hibával nem foglalkozunk, de néhány új hibakódot feldolgozunk.

Ésszerű korlátozások

A kereskedelmi függvények használatával összefüggésben figyelembe kell venni néhány általános korlátozást. Például, a 146. hiba csak fordul elő, ha több program ad kereskedelmi kérést ugyanazon szimbólum különböző ablakaiban. A véleményünk szerint ez a gyakorlat megengedett, de nem ésszerű.

Sokkal hatékonyabb egy olyan kereskedő programot létrehozni és használni, ami feldolgozza a kereskedelem minden sajátosságát. Ha csak egy kereskedő programot használunk, akkor lehetetlen ellentétes kereskedelmi kéréseket küldeni egyidejűleg. Azonfelül, az algoritmus sokkal jobban szervezett lehet egy ilyen programban: elemzi a sikeres kereskedés valószínűségét és eszerint a valószínűség szerint osztja el a rendelkezésre álló fedezetet.

A kereskedés végrehajtásához hatékonyabb egy teljes értékű Expert Advisort használni, míg a scripteket csak egyszeri számításokra vagy hasznos információk megjelenítésére ajánlott alkalmazni. Ugyanakkor, ha a kereskedő nem használ Expert Advisort az automatizált kereskedelemre, a scriptek használatáról kiderül, hogy sokkal hatékonyabban működnek, mint az ügyfélterminál vezérlőpultja.