MQL4 programozás: legutolsó pozíció lekérdezése

Utolsó pozíciók lekérdezése

Nagyon rég volt már programozással kapcsolatos poszt, úgyhogy illik már ez ügyben is tennem valamit. Innentől kezdve kisebb-nagyobb posztokban fogok foglalkozni mindenki számára hasznos, gyakorta felmerülő funkciók megosztásával és részletesebb tárgyalásával.

Mai áldozatunk: hogyan kérdezhető le a nyitott pozíciók vagy a számlatörténet pozíciói közül a legutolsó pozíció ? Hogyan lehet lekérdezni a nyitott pozíciók darabszámát általunk megadott feltételek alapján? Sajnálatos tény, hogy az mql4 nyelvben nincsen egyetlen olyan beépített függvény sem, amely az életünket ilyen szempontból megkönnyítené. Hozzunk hát létre párat!

Mi számít legutolsó pozíciónak?

Természetesen ez is jelenthet mindenkinek mást, szóval definiáljuk: a legutolsó pozíció az időben legfiatalabb, azaz a legújabb pozíciót jelenti. 

Amennyiben a legelső (legkorábban nyitott) pozícióra vagyunk kíváncsiak, az megint más kérdés – abban az esetben ugyanis a legrégebben nyitott pozícióra gondolunk.

A legutolsó pozíciót egyébként nagyon könnyű azonosítani: mindig, minden körülmények között neki a legnagyobb a ticket száma. Ezt a tényt fogjuk használni a probléma megoldásához.

Ticket szám

A ticket szám a pozíció bróker által kiadott, egyértelmű és egyedi azonosító száma. Egy pozíció ticket száma soha nem változhat meg! A ticket számok a Számlatörténet és a Kereskedés panelen az első oszlopban láthatóak.

A függő megbízások (buy stop, buy limit, sell stop és sell limit) ticket számai nem változnak meg akkor, amikor a bróker teljesíti azt nekünk. Így a teljesült buy vagy sell pozíciók “öröklik” azon függő megbízás ticket számát, amelyből születtek.

Fontos továbbá, hogy amikor a függő pozícióból élő pozíció lesz, a pozícióhoz tartozó nyitóidőpont a kihelyezési dátumról a teljesülés dátumára fog változni. Ezért a nyitóidőpont alapján történő rendezés során úgy tűnhet, hogy a bróker felborította a ticket számok sorrendjét; ez azonban csak abból a tényből ered, hogy az adott pozíció függő típusként lett korábban létrehozva. Az alábbi képpel illusztrálom a helyzetet: jól látszik, hogy ticket szám ugyanaz, míg a nyitóidőpont és a típus természetesen eltérnek egymástól.

Függő pozícióból élő pozíció

Függő pozícióból élő pozíció

 

Szűrés egyéb feltételek alapján, pozíciók megkülönböztetése

Ömlesztett pozíciók közül történő horgászás esetén nyilván ezernyi szűrési feltételünk van. Ilyen lehet például a magic szám, pozíciótípus, nyitott-e még a pozíció, stb. Ezekre ki kell térnünk a programkódban is – én melegen ajánlom azt, hogy előre elkészített függvényeket használjunk és mindig, minden körülmények között szűrjünk magic számra. Ha most nem is futtattok több robotot, vagy kevertek kézi kötéseket a robot kötései mellé, a jövőben szükségetek lehet a pozíciók elkülönítésére. A magic szám használata mindenképpen fontos! A backtesztben ugyanis minden tökéletesen működik, hiszen ott alap esetben csak egy stratégia pozíciói léteznek. Nincsen kézi kötés, nincs másik futtatott robot. Ez azonban a valós idejű futtatásnál nincs mindig így – elég egyszer elfeledkeznünk arról, hogy nem voltunk elég körültekintőek! Elég egy kézi kötés, és az OrdersTotal() -ra épülő feltételeink azonnal elhasalnak.

Emiatt a beépített OrdersTotal() és OrdersHistoryTotal() függvényt is csak a pozíciók végignyálazása során használjuk majd – ebben a cikkben egy egyéni pozíciószámláló függvényt is létrehozunk majd.

Pozíciók listája

A pozíciók listájára kettő lista (tár, queue, “fiók”) áll rendelkezésünkre: az egyik az aktív pozíciók listája (MODE_TRADES), a másik pedig a már lezártaké (MODE_HISTORY).

Pozíciók kiválasztásához az OrderSelect() függvény használható, amelynek három paramétere van:

  1. egy szám, amely lehet az adott lista numerikus indexe, illetve konkrét ticket szám
  2. a kiválasztás módja (lásd lentebb)
  3. a lista, ahonnan dolgozni szeretnénk (MODE_TRADES vagy MODE_HISTORY; ha nem adunk meg semmit, az alapértelmezés a MODE_TRADES).

Hivatkozás egy konkrét pozícióra

Mindenképpen számmal lehet hivatkozni egy pozícióra, azonban erre két különböző mód létezik:

  1. hivatkozás a queue indexével (SELECT_BY_POS)
  2. hivatkozás konkrét ticket számmal (SELECT_BY_TICKET)

Amennyiben az utóbbit használjuk, nem szükséges megadni azt, hogy mely pozíciólistából guberálunk, hisz’ a ticket szám egyértelműen azonosítja a pozíciót. Nyissunk egy tetszőleges pozíciót (kézzel), és a ticket számát (1234567) helyettesítsük be az alábbi kódba:

OrderSelect (1234567, SELECT_BY_TICKET);
 
Print (OrderTicket(), " pozíció nyitóára: ", OrderOpenPrice());

Az OrderSelect() -nek megadtuk a konkrét pozíció ticket számát (1234567), valamint azt hogy ticket alapján szeretnénk azonosítani őt (SELECT_BY_TICKET). Abban az esetben (tehát majdnem mindig), ha nem tudjuk a konkrét ticket számot, a numerikus index alapján fogunk dolgozni.

OrderSelect (0, SELECT_BY_POS);
 
Print (OrderTicket(), " pozíció nyitóára: ", OrderOpenPrice());

A számlatörténet és az aktív pozíciók numerikus indexe mindig nullától indul, tehát az index legmagasabb értéke mindig OrdersTotal() – 1 vagy OrdersHistoryTotal() – 1. Amennyiben olyan indexű pozíciót akarunk kiválasztani amely nem létezik, hibaüzenetet fogunk kapni. Természetesen ez a nem létező ticket számokra is igaz!

Amennyiben sikeresen kiválasztottunk egy pozíciót, az adott pozíció minden adatához hozzáférünk mindaddig, amely más pozíciót nem választunk ki. Erre érdemes különös figyelmet fordítani: ha kiválasztottunk egy pozíciót, akkor a későbbiekben – pláne ha függvényeket használunk – előfordulhat, hogy egy függvényünk szintén OrderSelect() segítségével megváltoztatja az aktív kiválasztott pozíciót. Ekkor hirtelen olyan adatokkal fogunk dolgozni, amelyek nem passzolnak az adott helyzethez és káoszt okozhatnak. Mindig figyeljünk oda, hogy éppen mikor és melyik pozíciót választjuk ki!

A nem létező pozíciókkal kapcsolatban: az OrderSelect() függvény visszatérési értéke csak akkor true, ha sikerült kiválasztani az adott pozíciót.

if (OrderSelect(0, SELECT_BY_POS)) {
    Print ("Pozíció sikeresen kiválasztva!");
}
else {
    Print ("Pozíció kiválasztása sikertelen: ", GetLastError());
}

A GetLastError() segít a hiba megállapításában: egy nullánál nagyobb számot ad vissza, amennyiben valamilyen hiba történt. A hibakódokat itt olvashatjátok.

Pozíciók “átnyálazása”

Ahhoz, hogy biztonsággal megállapítsuk a számunkra fontos pozíciók ticket számait, mindig végig kell futni a számlatörténet/aktív pozíciólista pozícióit (vagylagosan!). Ez azt jelenti, hogy ha csak egy pozíció ticket számára van szükségünk, akkor is ki kell választanunk az összes pozíciót az adott listában. A kiválasztás mindenképpen szükséges, hiszen csak ezután tudjuk eldönteni, hogy az adott pozíció adatai alapján beleesik-e az általunk definiált kondíciókba.

Írassuk ki az összes BUY típusú EURUSD pozíciót!

(Megjegyzés: a továbbiakban nem fogom külön kérni, hogy nyissatok több pozíciót; legyen nyitva több pozíciótok vegyesen buy, sell, EURUSD, GBPUSD, tetszőleges instrumentumokon!)

for (int i = 0; i < OrdersTotal(); i++) {
    if (OrderSelect(i, SELECT_BY_POS)) {
        if (OrderSymbol() == "EURUSD" && OrderType() == OP_BUY) {
            Print (OrderTicket());
        }
    }
}

 A fenti kód egymás alá fogja kiírni az összes buy típusú EURUSD instrumentumon nyitott pozíciót. A ciklus nullától indul és addig fut, ameddig i < OrdersTotal() feltétel igaz. Ha tehát 5 pozíciónk van, akkor a pozíciók indexe 0-tól 4-ig terjed. A ciklus minden körben eggyel növeli i értékét. Ötször fut le tehát ciklusunk, ebből azonban csak annyiszor fogunk “bejutni” a második if feltételen belülre, ha EURUSD instrumentumú buy pozíció van éppen terítéken.

Mivel a pozícióindex folyamatosan változhat, javaslom hogy minden esetben ticket alapján dolgozzunk. Vagyis, ne reménykedjünk abban hogy az éppen nyitott pozíciónk 0-ás indexe sosem fog változni! Kérdezzük le a ticket számát, és későbbi hivatkozáskor is használjuk azt!

Nézzük meg, hogyan tudunk a fenti kódból egy egyszerű függvényt létrehozni!

void PozicioTipus (int Tipus, string Instrumentum = "") {
 
   // Ha nincs megadva az instrumentum,
   // az aktuális chart szimbólumát vesszük alapul
 
   if (Instrumentum == "") {
      Instrumentum = Symbol();
   }
 
   for (int i = 0; i &lt; OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         if (OrderSymbol() == Instrumentum &amp;&amp; OrderType() == Tipus) {
            Print (OrderTicket());
         }
      }
   }
}

A fenti függvényt a későbbiekben így használhatjuk:

PozicioTipus (OP_BUY);
PozicioTipus (OP_BUY, "EURGBP");

Természetesen a kód egy kis módosításával pillanatokon belül megszületik első pozíciószámláló függvényünk is, mintegy az utolsó pozíció keresése során folytatott út melléktermékeként:

int PozicioSzamlalo (int Tipus, int MagicNumber = 0, string Instrumentum = "") {
 
   int
      Darabszam = 0;
 
   // Ha nincs megadva az instrumentum,
   // az aktuális chart szimbólumát vesszük alapul
 
   if (Instrumentum == "") {
      Instrumentum = Symbol();
   }
 
   for (int i = 0; i &lt; OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         if (OrderSymbol() == Instrumentum &amp;&amp; OrderType() == Tipus &amp;&amp; OrderMagicNumber() == MagicNumber) {
            Darabszam++;
         }
      }
   }
 
   return (Darabszam);
}
 
// Használat:
 
// 5-ös magic számú buy pozíciók megszámlálása
Print (PozicioSzamlalo (OP_BUY, 5));
 
// Magic szám nélküli sell pozíciók megszámlása
Print (PozicioSzamlalo (OP_SELL));
 
// Magic szám nélküli, EURGBP -n nyitott buy limit pozíciók megszámlása
Print (PozicioSzamlalo (OP_BUYLIMIT, 0, "EURGBP"));

A függvény visszatérési értéke egy egész szám – az érintett pozíciók darabszáma. Természetesen a kódot érdemes kiegészíteni egy olyan feltétellel, hogy amennyiben Tipus értéke egy általunk definiált konstans (pl. OP_ALL), akkor az összes pozíciót számolja, ne csak egy konkrét típust. Ekkor már készen is vagyunk egy egyéni pozíciószámláló függvénnyel, de újabb konstansokat is létrehozhatunk, amely saját kényelmünket szolgálja: például OP_BUYSELL – buy és sell pozíciók “begyűjtésére”.

#define OP_ALL          6     // Minden pozíció
 
int PozicioSzamlalo (int Tipus = OP_ALL, int MagicNumber = 0, string Instrumentum = "") {
 
   int
      Darabszam = 0;
 
   // Ha nincs megadva az instrumentum,
   // az aktuális chart szimbólumát vesszük alapul
 
   if (Instrumentum == "") {
      Instrumentum = Symbol();
   }
 
   for (int i = 0; i &lt; OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         if (OrderSymbol() == Instrumentum &amp;&amp; (Tipus == OP_ALL || OrderType() == Tipus) &amp;&amp; OrderMagicNumber() == MagicNumber) {
            Darabszam++;
         }
      }
   }
 
   return (Darabszam);
}

Megjegyzés: idegen kódokban konstansok helyett gyakran találkozhatunk a konstansok értékeinek megfelelő számokkal (pl.: OP_BUY = 0, OP_SELL = 1, stb.). Habár ez is jó megoldás, véleményem szerint a későbbi kódolvasást megkönnyítendő érdemesebb inkább a konstansokat használni, hiszen így egy pillanat alatt egyértelmű hogy mely pozíciókra gondoltunk anno.

A legutolsó pozíció megkeresése

A megfelelő feltételek alapján már képesek vagyunk csak azon pozíciókkal foglalkozni, amelyek beleesnek az általunk fontosnak tartott halmazba. Innen már csak egy dolgunk van: a halmaz lehető legnagyobb ticket számának megállapítása!

#define OP_ALL          6     // Minden pozíció
 
int UtolsoPozicio (int Tipus = OP_ALL, int MagicNumber = 0, string Instrumentum = "") {
 
   int
      UtolsoTicket = 0;
 
   // Ha nincs megadva az instrumentum,
   // az aktuális chart szimbólumát vesszük alapul
 
   if (Instrumentum == "") {
      Instrumentum = Symbol();
   }
 
   for (int i = 0; i &lt; OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         if (OrderSymbol() == Instrumentum &amp;&amp; (Tipus == OP_ALL || OrderType() == Tipus) &amp;&amp; OrderMagicNumber() == MagicNumber) {
            UtolsoTicket = MathMax (UtolsoTicket, OrderTicket());
         }
      }
   }
 
   return (UtolsoTicket);
}

Lássuk, mi történik: a függvény kezdetekor létrehoztunk egy UtolsoTicket nevű változót. A cikluson belül a MathMax() függvénnyel megnézzük, hogy az aktuális pozíció ticket száma – OrderTicket() – nagyobb-e, mint az UtolsoTicket változó értéke. Amennyiben igen, átállítjuk az UtolsoTicket változó értékét a MathMax() által visszaadott, magasabb számértékre. A függvény visszatérési értéke így a halmazunkon belüli legmagasabb ticket számot fogja visszaadni: az időben legkésőbb nyílt, azaz a legutolsó pozíciót.

Ha a számlatörténetben is szeretnénk ugyanezt a keresést elvégezni, még egy kis bonyolítás szükséges: tegyük állíthatóvá azt, hogy for ciklusunk mely pozíciókon szaladjon végig!

int UtolsoPozicio (int Tipus = OP_ALL, int MagicNumber = 0, int Lista = MODE_TRADES, string Instrumentum = "") {
 
   int
      UtolsoTicket = 0,
      Darabszam = 0;
 
   // Ha nincs megadva az instrumentum,
   // az aktuális chart szimbólumát vesszük alapul
 
   if (Instrumentum == "") {
      Instrumentum = Symbol();
   }
 
   if (Lista == MODE_TRADES) {
      Darabszam = OrdersTotal();
   }
   else {
      Darabszam = OrdersHistoryTotal();
   }
 
   for (int i = 0; i &lt; Darabszam; i++) {
      if (OrderSelect(i, SELECT_BY_POS, Lista)) {
         if (OrderSymbol() == Instrumentum &amp;&amp; (Tipus == OP_ALL || OrderType() == Tipus) &amp;&amp; OrderMagicNumber() == MagicNumber) {
            UtolsoTicket = MathMax (UtolsoTicket, OrderTicket());
         }
      }
   }
 
   return (UtolsoTicket);
}

Függvényünk Lista nevű paramétere alapesetben a MODE_TRADES értéket kapja meg, azaz ha az aktív pozíciók közül kukázunk, akkor szükségtelen megadni. Ha a számlatörténet a kívánt cél, adjunk meg MODE_HISTORY -t! A Darabszam nevű változó a Lista alapján kapja meg értékét, és az OrderSelect() függvényt is kibővítettük a Lista nevű változóval. Így kerek a világ, most már tudunk az aktív és lezárt pozíciók között is keresgélni!

// Az utolsó BUY pozíció
// az aktív tradek közül
UtolsoPozicio (OP_BUY);
 
// Az utolsó 23-as magic számú
// BUY pozíció az aktív tradek közül
UtolsoPozicio (OP_BUY, 23);
 
// Az utolsó 23-as magic számú
// EURGBP BUY pozíció az aktív tradek közül
UtolsoPozicio (OP_BUY, 23, MODE_TRADES, "EURGBP");
 
// Az utolsó 23-as magic számú
// EURGBP BUY pozíció a lezárt tradek közül
UtolsoPozicio (OP_BUY, 23, MODE_HISTORY, "EURGBP");
 
// Az utolsó 23-as magic számú
// EURGBP pozíció a lezárt tradek közül
UtolsoPozicio (OP_ALL, 23, MODE_HISTORY, "EURGBP");

A függvény lefutásakor nem ír ki semmit, visszatérési értéke pedig a keresett ticket azonosító lesz. Ezt már elrakhatjuk egy változóba, felhasználhatjuk if feltételekben, kiírathatjuk a Print() függvénnyel. Ha visszatérési értéke nulla, akkor vagy nem talált megfelelő pozíciót a feltételek alapján, vagy nincs nyitott pozíció, stb.

A legelső pozíció megkeresése

Házi feladat: létrehozni a legelső pozíció kikeresésére vonatkozó függvényt. Talán már el sem kell árulnom, hogy a MathMin() függvényt érdemes használni a MathMax() helyett. Mivel azonban a ticket számot tároló változónk kiindulási értéke nulla, így mindenképpen értéket kell neki adnunk, hiszen a nulla egészen biztos, hogy minden ticket számnál kisebb lesz. A ciklus megfelelő if feltételén belül tehát hozzunk létre egy újabbat, ami csak arra figyel, hogy a végeredményt tároló változónk értéke nulla-e. Amennyiben igen, beállítjuk neki az első ciklusfordulóban érintett pozíció ticket számát – a többi ciklusfordulóban pedig ehhez képest keressük a kisebb ticket számot.

A számlatörténet korlátjai

Fontos figyelembe venni, hogy az OrdersHistoryTotal() figyelembe veszi a Metatrader terminálban a felhasználó által beállított múltbéli adatok mennyiségét. Azaz ha a Számlatörténet panelen az “Utolsó hónap” opció van beállítva, akkor semmilyen módon nem férhetünk hozzá az aktuális hónapnál régebben lezárt pozíciókhoz.

Az aktuális pozícióadatok pontossága

Felmerülhet a kérdés, hogy mi van akkor, ha az éppen aktuális tick-re elindult programunk futása közben a pozícióindex változik – azaz megszűnik vagy épp születik egy új pozíció. Megnyugtatásként: egy tickre éppen futó példány futási ideje alatt nem változik a pozíciódarabszám. Ha egy pozíció bróker által megszületik vagy lezárul, ez a történés hamarabb történik meg, mint a program futásának kezdete.

Természetesen ha mi zárunk vagy nyitunk (piacon, azaz mintha kézzel tevékenykednénk) egy pozíciót, a pozícióindex természetesen azonnal megváltozik. Ezeket a tényeket a program tervezésénél mindenféleképpen figyelembe kell venni! Főleg zárásnál okozhat ez problémát – de erről majd legközelebb.

Egyéb információk lekérdezése

A fenti for ciklussal megépített függvények egyértelműen sok más feladatra is használhatóak. Mivel már képesek vagyunk szűrni a számunkra fontos pozíciókat, megtudhatjuk például a pozíciótömeg átlagárát, összlotját, stb. Ezen funkciókra javallott létrehozni egy-egy specifikus függvényt, kialakítva ezzel egy alapvető támogatást későbbi munkáinkhoz.

Zárszó

Remélem, tudtam segíteni új információkkal! Amennyiben úgy érzed, kihagytam egy olyan információt ami nélkül nem lehet élni, jelezd!

És persze lájkolj és/vagy kommentelj, ha szeretnél még több ilyen cikket:)

 

Írta: | 2017-08-20T19:03:50+00:00 2011. november 27., vasárnap|MQL4, Olvasnivaló programozóknak|20 hozzászólás

A szerzőről:

Radulovic Attila vagyok, a radu.hu tulajdonosa és szerkesztője. Remélem, hasznosnak találod az oldalamon található anyagokat! Célom, hogy hatékony segítséget nyújtsak Neked a kereskedéssel és az automatizálással kapcsolatban. Érdekel a véleményed, kérlek írd meg kommentben!

20 hozzászólás

  1. Povi 2011. november. 29. kedd - 16:07- Válasz

    Köszönjük a bejegyzést, a gyakorlatban is alkalmazható tudást ad, rendkívül hasznos és személy szerint én örülnék további hasonlóaknak is.
    Köszi Povi

    • radu 2011. november. 29. kedd - 19:55

      Igyekszem, lesz még ilyesmi 😉

  2. Povi 2011. december. 5. hétfő - 03:54- Válasz

    A “while” ciklus operátor fejlécében lehet két feltételt használni? Pl.: while (feltétel1 || feltétel2).
    Köszönöm

    • radu 2011. december. 5. hétfő - 08:44

      Igen, lehet! A while addig fog futni, ameddig a két feltétel közül legalább egy igaz. (|| esetén; && esetén nyilván mindkettő feltételnek igaznak kell lennie!)

  3. Povi 2011. december. 6. kedd - 12:49- Válasz

    Válaszodat köszönöm, ám újabb kérdésem lenne:
    kijelölök egy ordert majd elvégzem a szükséges lekérdezést. Ha később újabb adatra van szükség erről a poziról -de még nem lett másik order kiválasztva- meg marad a kijelölés vagy minden lekérdezés előtt OrderSelect kell?
    Üdv Povi

  4. radu 2011. december. 6. kedd - 16:08- Válasz

    A kijelölés megmarad. Ennek ellenére a pozíció záródása, illetve megnyíló pending order esetén mindenképpen javaslok egy újabb OrderSelectet.

  5. Forexbandit 2011. december. 10. szombat - 06:56- Válasz

    Kedves Radu!
    Kérlek írd le nekem, hogy hogy tudom meg az Utolsó Tickethez tartozó OrderType-ot és OrderProfit-ot a legutolsó példánál, ahol a függvény visszatérési értéke az UtolsóTicket.
    Köszönöm előre is.

    • radu 2011. december. 10. szombat - 09:43

      Mivel már tudod a ticket számát, egyszerűen kiválasztod – utána azt kérdezel le, amit szeretnél.

  6. saxo06 2011. december. 21. szerda - 10:47- Válasz

    Hello,
    Próbáltam szkripttel, programmal (EA) több devizapárra pozit nyitni, de azt válaszolja, hogy “ismeretlen devizapár”. Csak olyan blogbejegyzéseket olvastam, amiben azt írják, hogy ez nem lehetséges, de akkor meg minek megadni az OrderSend() függvénynél a Symbol() -t, ha az ugysem lehet más, mint az aktuális chart instrumentuma?
    A kérdésem inkább az, hogy te tudsz-e valami megoldást a problémára?
    Csak kíváncsiságból írtam egy programot, ami randomszerűen választ devizapárt (tömbből), irányt és pl. +/-50 pippel pozit nyit(na).
    Kézzel egyszer próbáltam, találomra nyitottam 5 pozit 5 véletlenül kiválasztott devizapáron, véletlen irányba (dobókockával:-), 100 pip TP és stop távolsággal, és 4 nyert. Érdekelt volna robottal ugyanez, de nem engedi az MT4, illetve a brókercégek,…többet is próbáltam.
    Üdv.Attila

    • radu 2011. december. 22. csütörtök - 16:54

      Az OrderSend() függvénnyel bármilyen olyan instrumentumra tudsz nyitni pozit, amelyet az adott bróker elfogad – viszont mindenképpen meg kell adni. Tehát a minimum a Symbol() (vagy egy változó, amibe korábban a függvény értékét átadtad), de megadhatod szövegesen is, ha több instrumentumot kezelsz egyidőben.

      Írasd ki a Symbol() függvénnyel az instrumentum nevét, és hasonlítsd össze azzal, amelyet megadsz az OrderSend() -nek. Sok brókernél van egy pont, alulvonás vagy egyéb karakter pluszban az instrumentum neve előtt/után.

      Amennyiben olyan instrumentumon próbálsz nyitni, amelyen nem engedélyezett a kereskedés, szintén futhatsz ilyesmi problémába.

      A végkövetkeztetés tehát az, hogy valamilyen kisebb-nagyobb hibát vétettél a kódban, és ez okozza a problémádat. Ha megosztod a kódot, akkor igyekszem segíteni benne.

      Illetve fontos még azt megjegyezni, hogy visszatesztben bajos az egyszerre több instrumentum kezelése. Bár a problémád úgy érzem nem ez!

  7. saxo06 2011. december. 23. péntek - 09:59- Válasz

    Hello,
    Kösz a választ, amúgy 4106-os hibát adott, ami ismeretlen szimbólum, de amikor írtam egy kis scriptet, ami köt 5 különféle instrumentumot, hogy megmutassam a hibát, és azonnal rájöttem, hogy mindenhol a Close[0]-val adtam meg az árat -:)), ami nem az adott instrumentumé, hanem az adott charton lévőé. Ennek ellenére nem volt szép, hogy a program nem az árak kifogásolta, hanem a szimbol nevét.
    üdv. Attila

  8. […] hozzákezdenénk, mindenképpen javaslom a korábbi, “Utolsó pozíció lekérdezése” című cikkem elolvasását. A cikkben leírom a ticket számok lényegét, alapszintű […]

  9. Ferenc_ 2013. december. 25. szerda - 13:49- Válasz

    Általában a ticket szám, mindig egyre nagyobb. Bár mindig így lenne, könnyebb lenne a programozók dolga. Sajnos néha van kivétel. Mint nálam IronFx demoszámlán. Program fejlesztés közben vette észre, különben szabad szemmel nehéz az ilyesmit észrevenni. A havi összesítő programot készítettem, a programom kimutatta a rossz sorrendet, a hónapok végénél. Kénytelen voltam egy 2 dimenziós tömbe eltárolni az OrderSelect()- el lekérdezett múltbeli adatokat, legalább a dátumot és ticket számot, majd rendezni és csak utána felhasználni. A rendezéshez külön függvényt (quicksort) használtam, mert a beépített ArraySort-tal nem lehet, csak egy dimenziós tömböt rendezni, struktúra tömb, meg nincs.

    Egyébként rengeteget segítséget jelent nekem ez a blog köszönöm.

  10. Radulovic Attila 2013. december. 25. szerda - 16:17- Válasz

    A ticket szám mindig növekszik, legalábbis én ennek ellenkezőjét még nem tapasztaltam. Ha mutatnál egy számlakivonatot, azt megköszönném.

    Szerintem maximum rendszerhibáról lehet szó, demónál ennél cifrább dolgok is előfordulhatnak.

    A quicksort rendben van, én is használom – de kizárólag olyan esetben, amikor nem a ticket szám alapján szeretnék rendezni.

  11. Ferenc_ 2013. december. 27. péntek - 13:38- Válasz

    http://data.hu/get/7249351/DetailedStatement.rar
    Ennél az IronFx demo számlánál a #25097984 től találni néhány rossz sorrendűt. A #25167162 is. Megadhatom a jelszót is, amúgy is ezt a számlát lenulláztam. Egyébként így is úgy is rendezni kellet, mert az orderek záró dátuma és nem a nyító dátuma szerint kellett a sorrend.

    • Radulovic Attila 2013. december. 30. hétfő - 20:47

      A megoldás – ahogy már e-mailben leírtam – az, hogy a STOP/LIMIT megbízások ticket száma és kihelyezési dátuma a kihelyezéskor korrelál, míg a teljesüléskor (vagyis amikor a STOP/LIMIT -ből élő pozícióvá válnak) a teljesülés dátumát veszi fel a pozíció. Így fordulhat elő az általad leírt jelenség.

  12. Ferenc_ 2013. december. 31. kedd - 11:52- Válasz

    Tényleg, mivel a robotom amit teszteltem, csak függő megbízással dolgozott. Backteszttel ellentétben, itt a MetaTrader elrejtette a függő megbízásokat a listában, ezért elkerülte a figyelmem.

  13. BillyBill 2015. november. 18. szerda - 22:43- Válasz

    Jó kis írás!
    Annyit fűznék hozzá, hogy a függvények “fejlécébe” is bele lehetne tenni a szimbólumot, pl.
    void PozicioTipus (int Tipus, string Instrumentum = Symbol())
    így már nincs szükség erre:
    if (Instrumentum == “”) {
    Instrumentum = Symbol();
    Kicsit rövidebb, kicsit gyorsabb így.

    • Radulovic Attila 2015. november. 21. szombat - 08:23

      Az általad javasolt megoldás nem működik sem a régi, sem az új MQL4 nyelvben.

  14. BillyBill 2015. november. 27. péntek - 21:18- Válasz

    Való igaz, úgy baromság, ahogy van. Fáradt voltam már. Bocsi a beleokvetetlenkedésért.

Hagyj üzenetet

Adhatok Neked még több ingyenes tartalmat?

Értesítelek hetente megjelenő új tartalmaimról.