Forex programozás Fórum Kérdések az MQL4 programozási nyelvvel kapcsolatban A legnagyobb veszteségű pozi zárása

7 bejegyzés megtekintése - 1-7 / 7
  • Szerző
    Bejegyzés
  • kosza
    Tag
    Bejegyzések száma: 23

    Szia Radu!
    Többször is segítettél már, de most megint kínom van. Nem bírok rájönni, mifenét tolok el. Az lenne a cél, hogy a megnyitott pozikból zárja a legnagyobb veszteségest. Ehhez csináltam egy MaxLoss()-t, ami jó értéket ad vissza:

    double MaxLossLong()
      {
       double MaxLossLong;
       int cnt= OrdersTotal();
       for(i=0; i<cnt; i++)
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if(OrderSymbol()!=Symbol()) continue;
          type=OrderType();
          if(type==OP_BUY) 
           {
          if(OrderProfit()<=MaxLossLong) MaxLossLong=OrderProfit();    
           }      
         }
         
       return (MaxLossLong);
      }  

    Ezek után ezzel szeretném bezárni:

    `if(ClMaxLoss==1&&LoLot()*ShLot()>0&&ShLot()>=LoLot())
    {

    for(i=0; i<OrdersTotal(); i++) // Order searching cycle
    {
    if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
    if(OrderSymbol()!=Symbol()) continue;
    type=OrderType();
    if(type==OP_BUY)
    {
    RefreshRates();
    if(MaxLossLong()==OrderProfit()&&BuyCnt>1)CloseOrder(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID));
    }
    }
    }

    Nem műkszik. Nyilván valami alap dolgot szúrok el, de képtelen vagyok rájönni, mit.
    Köszönöm.

    kosza
    Tag
    Bejegyzések száma: 23

    Nem jól raktam be a záró-kódrészletet. Újra próbálom:

    if(ClMaxLoss==1&&LoLot()*ShLot()>0&&ShLot()>=LoLot())
    {
    
    for(i=0; i<OrdersTotal(); i++) // Order searching cycle 
            {
             if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
             if(OrderSymbol()!=Symbol()) continue;
             type=OrderType();
             if(type==OP_BUY)
               {
                RefreshRates();
                if(MaxLossLong()==OrderProfit()&&BuyCnt>1)CloseOrder(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID));            
               }
            }
    }
    Radulovic Attila
    Tag
    Bejegyzések száma: 653

    Ha jól értem, konkrétan a zárással van a problémád, és nem a megfelelő pozíció megtalálásával. A hivatkozott CloseOrder() függvényt nem látom, így arról nem tudok mit mondani :)

    Viszont: nem sok cikket írtam programozás témájában, de a zárásról pont igen. Mindenképpen olvasd el azt, szerintem segíteni fog.

    Jelezz majd vissza, hogy mire jutottál.

    kosza
    Tag
    Bejegyzések száma: 23

    Szia! A gond az, hogy ugyanez a CloseOrder() függvény nagyszerűen működik a kód más részein. Pl a psar váltáskor a nyereséges pozik zárása:
    `if(SingleClSARChCl==1&&ClSARPrev<Close[ClSARSignalBar] && ClSARCurr>Close[ClSARSignalBar])
    {
    for(i=0; i<OrdersTotal(); i++) // Order searching cycle
    {
    if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
    if(OrderSymbol()!=Symbol()) continue;
    if(OrderMagicNumber()!=Magic) continue;

    type=OrderType();
    if(type==OP_BUY)
    {
    RefreshRates();
    if(OrderProfit()>0)CloseOrder(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID));
    }
    }
    }`
    Azért ideteszem a függvényt:
    bool CloseOrder(int ticket,double lot,double price)
    {
    if(!OrderSelect(ticket, SELECT_BY_TICKET)) return(false);
    if(OrderCloseTime() > 0) return(false);

    int dig=MarketInfo(OrderSymbol(),MODE_DIGITS);
    string _lot=DoubleToStr(lot,2);
    string _price=DoubleToStr(price,dig);

    bool res=OrderClose(ticket,lot,price,Slippage,clClose);
    if(res)
    {
    Sleep(SleepOk);
    return (res);
    }

    int code=GetLastError();
    Sleep(SleepErr);

    return (false);
    }`

    Ideteszem újra a kicsit átfogalmazott problémás részt:

    if(ClMaxLoss==1&&LoLot()*ShLot()>0&&SellCnt>1)  // ha long és short is van és shortból több, mint egy darab
    {
    for(i=0; i<OrdersTotal(); i++) // Order searching cycle 
            {
             if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
             if(OrderSymbol()!=Symbol()) continue;
             if(OrderMagicNumber()!=Magic) continue;
             type=OrderType();
             if(type==OP_SELL)
               {
                RefreshRates();            
                if(MaxLossShort()==OrderProfit())CloseOrder(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK));  
               // ha olyat talál, aminek a vesztesége megegyezik a legnagyobb veszteségű short pozival, zárja le
               
               }
            }
    }

    Ehelyett azt csinálja, hogy nem a legnagyobb veszteségű pozit zárja, hanem az utolsónak megnyitottat.
    Ha a RefreshRates() utáni sort kicserélem erre:

    if(Ask-OrderOpenPrice()>=Delta*Point*fpc())CloseOrder(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK));            
               // ha az ask és megnyitott pozi nyitási ára közötti különbség nagyobb, mint "Delta" pip, zárja le a pozit;
               // (az fpc() a bróker digitjétől függen ad vissza 10-et vagy százat)

    ez működik, a megfelelő pozikat zárja le.
    Ezek szerint a hiba ott van valahol a kicserélt sorban. Nem segít az sem, hogyha az „orderprofit” helyett a nyitó és az aktuális „ask” segítségével határozom meg a veszteséget.
    Előre is köszönöm a segítségedet.

    kosza
    Tag
    Bejegyzések száma: 23

    Nna, az első két kódrészletet újra küldöm. Nem vágom, hogy miért szövegként tette be. Bocs. Tehát sar váltásra pozi zárás

    if(SingleClSARChCl==1&&ClSARPrev>Close[ClSARSignalBar] && ClSARCurr<Close[ClSARSignalBar])
       {
          for(i=0; i<OrdersTotal(); i++) // Order searching cycle 
            {
             if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
             if(OrderSymbol()!=Symbol()) continue;
             if(OrderMagicNumber()!=Magic) continue;
    
             type = OrderType();
             if(type == OP_SELL)
               {
                RefreshRates();
    
                if(OrderProfit()>0)CloseOrder(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK));
               }
            }
         }

    a záró fgv

    bool CloseOrder(int ticket,double lot,double price)
      {
       if(!OrderSelect(ticket, SELECT_BY_TICKET)) return(false);
       if(OrderCloseTime() > 0) return(false);
    
       int dig=MarketInfo(OrderSymbol(),MODE_DIGITS);
       string _lot=DoubleToStr(lot,2);
       string _price=DoubleToStr(price,dig);
    
       bool res=OrderClose(ticket,lot,price,Slippage,clClose);
       if(res) 
         {
          Sleep(SleepOk);
          return (res);
         }
    
       int code=GetLastError();
       Sleep(SleepErr);
    
       return (false);
      }
    Radulovic Attila
    Tag
    Bejegyzések száma: 653

    Én a linkelt cikkben bemutatott kódot használom. Nincs most kapacitásom minden lehetséges hibát végiggondolni a kódod kapcsán, ott a teljes megoldást át tudod nézni.

    Kapkodós észrevételeim:

    • a linkelt cikkben beszélek a ciklusokkal kapcsolatos problémákról, azt mindenképp nézd át
    • a Sleep() sikeres zárás esetén felesleges, nem tudom, mi célból van bent
    • a zárófüggvénybe én nem vinném be az aktuális árat, mert menet közben az változhat; használd inkább a zárandó típustól függően a MODE_BID és MODE_ASK árakat
    • ha nem sikerül zárnod, akkor tudni kellene, hogy miért nem sikerül; a GetLastError() közvetlenül az OrderClose után jöjjön, a res false ágában. Írasd ki, és nézd meg, hogy mi a nyűgje.
    kosza
    Tag
    Bejegyzések száma: 23

    O.K. Köszönöm

7 bejegyzés megtekintése - 1-7 / 7
  • Be kell jelentkezni a hozzászóláshoz.