Függő megbízások módosítása 2013-09-05T16:46:34+00:00

Radu.hu Fórum Kérdések az MQL4 programozási nyelvvel kapcsolatban Függő megbízások módosítása

10 bejegyzés megtekintése - 1-10 / 10
  • Szerző
    Bejegyzés
  • Szalai Gergely
    Tag
    Bejegyzések száma: 8

    szia Radu!

    problémám akadt függő megbízások módosításával kapcsolatban. amit szeretnék megoldani:
    szeretnék egy futó gyertya maximumától (high) illetve minimumától (low) függő szinteken megbízásokat elhelyezni. miután megnyílt a gyertya elhelyezem a függő megbízásokat és utána az árfolyam változásához igazodva szeretném igazítani a nyitási-, “ST” és a “TP” szinteket. de sajnos mikor módosítani akarom a megbízást nem sikerül. mit nem csináltam helyesen? vagy van valamilyen korlát a módosításokra? sajnos, nem tudom.
    kimásoltam az aktuális részleteket:

    //függő megbízások elhelyzése-----------------------------------------
       if
       (
          vetel==0//még nem indítottunk függő vételi megbízást
       && eladas==0//még nem indítottunk függő eladasi megbízást
       )
       {
    //tervezett kereskedési szintek meghatározása
          nyitasszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51)*Point;//vételi pozíció tervezett nyitásszintje
          vesztesegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51-kockazat)*Point;//vételi pozíció tervezett veszteségszintje
          nyeresegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51+nyeresegcel)*Point;//vételi pozíció tervezett nyereségszintje
          nyitasszint_tervezett_eladas=Low[0]-51*Point;//eladási pozíció tervezett nyitásszintje
          vesztesegszint_tervezett_eladas=Low[0]-(51-kockazat)*Point;//eladási pozíció tervezett veszteségszintje
          nyeresegszint_tervezett_eladas=Low[0]-(51+nyeresegcel)*Point;//eladási pozíció tervezett nyereségszintje
    //függő megbízások elhelezése
          while//vételi függő megbízás küldése
          (
             vetel<1//amíg a vételi függő megbízást el nem helyezi a szerver
          )
          {
             vetel=OrderSend(Symbol(), OP_BUYSTOP, LOT, nyitasszint_tervezett_vetel, 25, vesztesegszint_tervezett_vetel, nyeresegszint_tervezett_vetel, "vetel", 1, 0, Green);//függő vételi megbízás küldése
          }
    
          while//eladási függő megbízás küldése
          (
             eladas<1//amíg az eladási függő megbízást el nem helyezi a szerver
          )
          {
             eladas=OrderSend(Symbol(), OP_SELLSTOP, LOT, nyitasszint_tervezett_eladas, 25, vesztesegszint_tervezett_eladas, nyeresegszint_tervezett_eladas, "eladas", 2, 0, Red);//függő eladási megbízás küldése
          }
       }
    //--------------------------------------------------------------------
    
    
    //függő megbízások módosítása-----------------------------------------
       if
       (
          vetel>0//él a függő vételi megbízást
       && eladas>0//él a függő eladási megbízást
       )
       {
          OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES);//vételi megbízás kiválasztása
          if//vételi megbízás vizsgálata
          (
             OrderType()==OP_BUYSTOP//a vételi megbízás függő (nem nyílt még meg)
          )
          {
    //függő vételi pozíció új tervezett kereskedési szintjeinek meghatározása
             nyitasszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51)*Point;//vételi pozíció új tervezett nyitásszintje
             vesztesegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51-kockazat)*Point;//vételi pozíció új tervezett veszteségszintje
             nyeresegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51+nyeresegcel)*Point;//vételi pozíció új tervezett nyereségszintje
    
             while//amíg a vételi függő megbízást nem módosítja a szerver
             (
                OrderModify(vetel, nyitasszint_tervezett_vetel, vesztesegszint_tervezett_vetel, nyeresegszint_tervezett_vetel, 0, Green)//vételi függő megbízás módosítása
             )
             {
             }
          }
    
          OrderSelect(eladas, SELECT_BY_TICKET, MODE_TRADES);//eladási megbízás kiválasztása
          if//eladási megbízás vizsgálata
          (
             OrderType()==OP_SELLSTOP//az eladási megbízás függő (nem nyílt még meg)
          )
          {
    //függő eladási pozíció új tervezett kereskedési szintjeinek meghatározása
             nyitasszint_tervezett_eladas=Low[0]-51*Point;//eladási pozíció új tervezett nyitásszintje
             vesztesegszint_tervezett_eladas=Low[0]-(51-kockazat)*Point;//eladási pozíció új tervezett veszteségszintje
             nyeresegszint_tervezett_eladas=Low[0]-(51+nyeresegcel)*Point;//eladási pozíció új tervezett nyereségszintje
    
             while//amíg az eladási függő megbízást nem módosítja a szerver
             (
                OrderModify(eladas, nyitasszint_tervezett_eladas, vesztesegszint_tervezett_eladas, nyeresegszint_tervezett_eladas, 0, Red)//eladási függő megbízás módosítása
             )
             {
             }
          }
       }
    //--------------------------------------------------------------------

    remélem érthetően fogalmaztam.

    köszi: g

    Radulovic Attila
    Tag
    Bejegyzések száma: 643

    A módosítás során csak akkor próbálj meg módosítani, ha a meglévőtől eltérő értéket akarsz beállítani. Ezt érdemes ellenőrizni.
    A fix 51 ponttal nem tudom, mit szeretnél pontosan de talán nem emiatt nem működik a programod.

    A while() feltételénél valami szofisztikáltabb megoldás kellene, mert így ha rossz a kódod, akkor a végtelenségig próbálkozik majd a hibás adatokkal. A minimum, hogy a while -on belülre rakod a távolságszámításos sorokat is!

    Egyébként mi a hibakód a módosítási próbálkozás esetén? Anélkül elég nehéz találgatni:)

    Szalai Gergely
    Tag
    Bejegyzések száma: 8

    szia!

    először is köszönöm szépen a gyors választ, sokat segítettél! mint ahogy lenni szokott, így most is a hiba “user error”-ra vezethető vissza.
    a 51-es számba nem vagyok beleszerelmesedve ezt természetesen majd változtatni szeretném.
    megpróbáltam megoldani, hogy figyelje az árfolyam változását és csak akkor módosítgasson ha az a feltételek szerint változik. így megszűnt a végtelen ciklus. köszönöm! szerinted egy számláló beiktatása; mondjuk 10 próbálgatás után hagyja az egészet és fusson tovább, helyes irányba lendítené a dolgot?

    még egy kérdés, a hibakódokkal kapcsolatban:
    találtam egy ErrorDescription() függvényhez hasonló akármit az http://docs.mql4.com/check/GetLastError oldalon. ez használható ahogy ott jelezték. mert nekem nem sikerült.

    köszi!
    bemásolom a változtatott sorokat (lehet, hogy nem azt csináltam, amit leírtam)…

    //függő megbízások elhelyezése----------------------------------------
       if
       (
          vetel==0//még nem helyeztük el a függő vételi megbízást
       && eladas==0//még nem helyeztük el a függő eladási megbízást
       )
       {
    //függő megbízások elhelyezése
          while//vételi függő megbízás küldése
          (
             vetel<1//amíg a vételi függő megbízást el nem helyezi a szerver
          )
          {
    //tervezett kereskedési szintek meghatározása
             nyitasszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51)*Point;//vételi pozíció tervezett nyitásszintje
             vesztesegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51-kockazat)*Point;//vételi pozíció tervezett veszteségszintje
             nyeresegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51+nyeresegcel)*Point;//vételi pozíció tervezett nyereségszintje
    
             vetel=OrderSend(Symbol(), OP_BUYSTOP, LOT, nyitasszint_tervezett_vetel, 25, vesztesegszint_tervezett_vetel, nyeresegszint_tervezett_vetel, "vetel", 1, 0, Green);//függő vételi megbízás küldése
    
             if//hibakód vizsgálata
             (
                vetel<1//nem helyezte el a szerver a függő vételi megbízást
             )
             {
                Print(GetLastError() ,"-as hibakód: ");//hibakód kiírása
             }
          }
    
          while//eladási függő megbízás küldése
          (
             eladas<1//amíg az eladási függő megbízást el nem helyezi a szerver
          )
          {
    //tervezett kereskedési szintek meghatározása
             nyitasszint_tervezett_eladas=Low[0]-51*Point;//eladási pozíció tervezett nyitásszintje
             vesztesegszint_tervezett_eladas=Low[0]-(51-kockazat)*Point;//eladási pozíció tervezett veszteségszintje
             nyeresegszint_tervezett_eladas=Low[0]-(51+nyeresegcel)*Point;//eladási pozíció tervezett nyereségszintje
    
             eladas=OrderSend(Symbol(), OP_SELLSTOP, LOT, nyitasszint_tervezett_eladas, 25, vesztesegszint_tervezett_eladas, nyeresegszint_tervezett_eladas, "eladas", 2, 0, Red);//függő eladási megbízás küldése
    
             if//hibakód vizsgálata
             (
                eladas<1//nem helyezte el a szerver a függő vételi megbízást
             )
             {
                Print(GetLastError() ,"-as hibakód: ");//hibakód kiírása
             }
          }
       }
    //--------------------------------------------------------------------
    
    //függő megbízások módosítása-----------------------------------------
       if
       (
          vetel>0//él a függő vételi megbízást
       )
       {
          OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES);//vételi megbízás kiválasztása
          if//vételi megbízás vizsgálata
          (
             OrderType()==OP_BUYSTOP//a vételi megbízás függő (nem nyílt még meg)
          )
          {
             if//kereskedési szintek változásának vizsgálata
             (
                nyitasszint_tervezett_vetel<High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51)*Point//emelkedett a tervezett nyitási szint
             )
             {
                frissites_megbizas_vetel=false;//még nem frissítettük a vételi függő megbízás kereskedési szintjeit
    
                while//amíg a vételi függő megbízást nem módosítja a szerver
                (
                   frissites_megbizas_vetel==false//ha még nem frissültek a függő vételi megbízás a kereskedési szintjei
                )
                {
    //tervezett kereskedési szintek frissítése
                   nyitasszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51)*Point;//vételi pozíció új tervezett nyitásszintje
                   vesztesegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51-kockazat)*Point;//vételi pozíció új tervezett veszteségszintje
                   nyeresegszint_tervezett_vetel=High[0]+(MarketInfo(Symbol(), MODE_SPREAD)+51+nyeresegcel)*Point;//vételi pozíció új tervezett nyereségszintje
    
                   frissites_megbizas_vetel=OrderModify(vetel, nyitasszint_tervezett_vetel, vesztesegszint_tervezett_vetel, nyeresegszint_tervezett_vetel, 0, Green);//vételi függő megbízás módosítása
    
                   if//hibakód vizsgálata
                   (
                      !frissites_megbizas_vetel//nem teljesült a függő vételi megbízás kereskedési szintjeinek a frissítése
                   )
                   {
                      Print(GetLastError() ,"-as hibakód: ");//hibakód kiírása
                   }
                }
             }
          }
       }
    
       if
       (
          eladas>0//él a függő eladási megbízást
       )
       {
          OrderSelect(eladas, SELECT_BY_TICKET, MODE_TRADES);//eladási megbízás kiválasztása
          if//eladási megbízás vizsgálata
          (
             OrderType()==OP_SELLSTOP//az eladási megbízás függő (nem nyílt még meg)
          )
          {
             if//kereskedési szintek változásának vizsgálata
             (
                nyitasszint_tervezett_eladas>Low[0]-51*Point//süllyedt a tervezett nyitási szint
             )
             {
                frissites_megbizas_eladas=false;//még nem frissítettük az eladási függő megbízás kereskedési szintjeit
    
                while//amíg az eladási függő megbízást nem módosítja a szerver
                (
                   frissites_megbizas_eladas==false//ha még nem frissültek a függő eladási megbízás a kereskedési szintjei
                )
                {
    //tervezett kereskedési szintek frissítése
                   nyitasszint_tervezett_eladas=Low[0]-51*Point;//eladási pozíció új tervezett nyitásszintje
                   vesztesegszint_tervezett_eladas=Low[0]-(51-kockazat)*Point;//eladási pozíció új tervezett veszteségszintje
                   nyeresegszint_tervezett_eladas=Low[0]-(51+nyeresegcel)*Point;//eladási pozíció új tervezett nyereségszintje
    
                   frissites_megbizas_eladas=OrderModify(eladas, nyitasszint_tervezett_eladas, vesztesegszint_tervezett_eladas, nyeresegszint_tervezett_eladas, 0, Red);//eladási függő megbízás módosítása
    
                   if//hibakód vizsgálata
                   (
                      !frissites_megbizas_eladas//nem teljesült a függő eladási megbízás kereskedési szintjeinek a frissítése
                   )
                   {
                      Print(GetLastError() ,"-as hibakód: ");//hibakód kiírása
                   }
                }
             }
          }
       }
    //--------------------------------------------------------------------
    Radulovic Attila
    Tag
    Bejegyzések száma: 643

    A számláló beiktatását mindenképpen javaslom, igen! A legutóbbi, zárásról szóló cikkemben találsz részletes levezetést, az applikálható erre a problémára is.
    Ha x próbálkozás után nem sikerül valamit megoldani, akkor ettől függetlenül persze kezelni kell a helyzet további sorsát is.

    A GetLastError() függvénnyel le tudod kérdezni a hibakódot. A lekérdezés után a GetLastError() kiürül, úgyhogy kapásból rakd el a vélt/várt hiba után a GetLastError() által visszaadott egész számot.

    A szám jelentését itt találod, vagy használd az include\stderror.mqh fájlt!

    Szalai Gergely
    Tag
    Bejegyzések száma: 8

    köszönöm szépen!
    ismét nagyon sokat segítettél.

    üdv: g

    Szalai Gergely
    Tag
    Bejegyzések száma: 8

    szia!

    lenne még egy kérdésem a függő megbízásokkal kapcsolatban. a módosításokon túl, ha törölni szeretném. és először kiválasztom és megvizsgálom, hogy függő-e még. majd utána megpróbálom törölni. amit rendre szépen meg is tesz. de sajnos a következő lefutásnál, ismét beleszalad. azaz az OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES) és az OrderType() függvények arra az eredményre jutnak, hogy még van él ezen a ticket számon függő vételi megbízás.
    utána már csak szerencsétlen OrderDelete(vetel, Green) esik bele állandóan a for-ciklusban a 4108 “invalid ticket” kóddal jelölt hibába. mivel akkor már nincs ilyen ticket számon order.
    ha törölte a szerver az függő megbízást, miért nem azt az információt kapom vissza az OrderSelect() és OrderType() vizsgálata után?
    vagy teljesen rosszul használom ezt a két függvényt?

    if//függő vételi megbízás törlése
       (
          OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES)//vételi megbízás kiválasztása
       && OrderType()==OP_BUYSTOP//a vételi megbízás függő (még nem nyílt meg)
       )
       {
          for//10szer próbálja meg törölni a függő vételi megbízást
          (
             i=1; i<=10; i++
          )
          {
             if
             (
                OrderDelete(vetel, Green)//vételi függő megbízás törlése
             )
             {
                break;//törölte a szerver a függő vételi megbízást, ciklus megszakítása
             }
             else//hibakód vizsgálata
             {
                hibakod=GetLastError();//a hibakód tárolása
                Print("A függő vételi megbízás törlésénél a ", hibakod, "-as kódú hiba lépett fel!");//hibakód kiírása
             }
          }
       }
    Radulovic Attila
    Tag
    Bejegyzések száma: 643

    Egy nem aktív pozíciót akarsz újra és újra törölni. A szerver csak végre akarja hajtani, amit mondasz neki – mivel ez nem sikerül, hibakódot kapsz.

    Amikor megnézed, hogy a törlendő pozíció függő típusú-e, rakd mellé azt a feltételt is, hogy OrderCloseTime() == 0.

    Ha ugyanis egy pozíció lezárult, akkor ez a függvény mindenképpen visszaadja a zárási időpontot Unix timestampben. Ha egy pozíciónak nincs ilyenje (azaz a visszakapott érték nulla), az azt jelenti hogy ő még a Kereskedések panelen belül létezik. Ha nullánál nagyobb értéke van, akkor pedig már csak a Számlatörténetben létezik.

    Az OrderClosePrice() -t ne használd, mert annak folyamatosan van értéke! (a záráskor a zárási ár, addig pedig az aktuális piaci árnak megfelelő Ask/Bid érték)

    A MODE_TRADES konstans használata felesleges, mivel ha SELECT_BY_TICKET módban választasz ki pozíciót, akkor a metatrader automatikusan tudni fogja, hogy melyik “fiókhoz” (Számlatörténet/Kereskedések) nyúljon.

    Továbbá a számlatörténetet a felhasználó is tudja korlátozni: ha pl. csak a napi lezárult kereskedéseket listázza ki a Számlatörténet ablakban, akkor az annál régebbi pozíciókat sehogy nem tudod elérni. Ezért ha az OrderSelect pozíciókiválasztás sikertelen, akkor ne is próbálkozz semmilyen művelettel.

    Szerintem erről a témáról is írok majd egy cikket:)

    Szalai Gergely
    Tag
    Bejegyzések száma: 8

    halihó!

    először is; köszönöm szépen a segítséget! csak pontosítanám, hogy értem-e vagy csak szeretném…

    az OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES) esetében teljesen felesleges megjelölni a MODE_TRADES konstanst, úgyis kiválasztja a Ticket szám és a SELECT_BY_TICKET konstans alapján. ha például teljesen kihagynám a konstanst, helyesen működne?

    javaslatod szerint az OrderType() mellett vizsgáljam meg az OrderCloseTime() értékét is. ilyenkor elegendő egyszer alkalmazni az OrderSelect() függvényt vagy mindkettő elé külön-külön be kell iktatni a helyes működéshez?

    így:

    if//függő vételi megbízás törlése
       (
          OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES)//vételi megbízás kiválasztása
       && OrderType()==OP_BUYSTOP//a vételi megbízás függő (még nem nyílt meg)
       && OrderCloseTime()==0//még nem záródott be a megbízás
       )
    

    vagy így a helyes:

    if//függő vételi megbízás törlése
       (
          OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES)//vételi megbízás kiválasztása
       && OrderType()==OP_BUYSTOP//a vételi megbízás függő (még nem nyílt meg)
       && OrderSelect(vetel, SELECT_BY_TICKET, MODE_TRADES)//vételi megbízás kiválasztása
       && OrderCloseTime()==0//még nem záródott be a megbízás
       )
    

    tehát ha futás közben első ízben elér idáig a program az OrderType() segítségével el tudom dönteni, hogy függő megbízást vagy épp egy megnyílt pozíciót jelöl a “vetel” Ticket. miután sikeresen törölte a függő megbízást, a program a további futása során újra elér idáig de akkor már az OrderType() nem ad megfelelő információt csak az OrderCloseTime() segít a dolgokon.

    ha bezáródott egy függő megbízás az OrderType() megtartja a legutolsó értékét?

    köszi: g

    Radulovic Attila
    Tag
    Bejegyzések száma: 643

    Mától használható az MQL4 kód beillesztése funkció! Jelöld ki a kódodat amit bemásolsz, és nyomd meg az MQL4 kód beillesztése gombot a szövegdoboz felett!

    A MODE_TRADES – mint írtam – elhagyható, próbáld ki! Az OrderSelect() által kiválasztott pozíció mindaddig kiválasztva marad, ameddig a pozíció adatai elérhetőek és amennyiben nem történik közben más pozíciókiválasztás. Erre főleg ciklusokon belüli alkalmazásnál kell figyelni.

    Az első példád a helyes, viszont én annyit módosítanék a kódodon, hogy:

    if (OrderSelect(vetel, SELECT_BY_TICKET)) {
    
       if (OrderType() == OP_BUYSTOP && OrderCloseTime() == 0) {
       
       }
    }

    Az OrderSelect legyen először, aztán ha az sikeres, majd foglalkozol az adott pozíció adataival. Addig felesleges!

    Szalai Gergely
    Tag
    Bejegyzések száma: 8

    nagyon szépen köszönöm!

    ismét sokat segítettél.

    üdv: g

10 bejegyzés megtekintése - 1-10 / 10

A hozzászóláshoz jelentkezz be!

Adhatok Neked még több ingyenes tartalmat?

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