Függő megbízások módosítása2013-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: 646

    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: 646

    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: 646

    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: 646

    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.

Hozzájárulok, hogy az adatvédelmi nyilatkozat szerint biztonságosan kezeld megadott adataimat, valamint hasznos anyagokat és egyedi ajánlatokat küldj nekem termékeiddel, szolgáltatásaiddal kapcsolatban e-mailben