Скачать MetaTrader 5

Неверная работа функции закрытия позиции

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Igor Slepnev
1820
Igor Slepnev  

Здравствуйте!

Столкнулся с такой проблемой на МТ5:

Вместо закрытия позиции, получаю открытие в противоположную сторону.

Т.е. например вместо закрытия по виртуальному стопу: открывается позиция в обратную сторону тем же объемом, а иногда и даже большим.

Чисто из наблюдений при закрытии позиции, брокер открывает отложенный ордер(стоп или лимит) и сделка закрывается когда этот ордер срабатывает.

Код описывающий логику, привожу на примере виртуального трейлинга:

#include <Trade\Trade.mqh>

#include <Trade\PositionInfo.mqh>

input double TrailingStart = 1;

input double TrailingDistance = 5;

input double TrailingStep = 2;

CTrade trade;

CPositionInfo position_info;

void VirtualTrailing ()
{
   if(PositionSelect(_Symbol))
   {   
      
      double open_price = PositionGetDouble (POSITION_PRICE_OPEN);
      if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY )
      {
         double current_sl = buy_sl;
         //double current_tp = PositionGetDouble (POSITION_TP);
         double sl = SymbolInfoDouble (_Symbol, SYMBOL_BID) - pips * _Point * TrailingDistance;
         double minimal = SymbolInfoDouble (_Symbol, SYMBOL_BID) - pips * _Point * SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
         //--- нормализация значения
         sl = NormalizeDouble(sl, _Digits); 
         //--- нормализация значения
         minimal = NormalizeDouble(minimal, _Digits); 
         //--- если на полученный от индикатора уровень невозможно установить стоплосс, 
         //    он будет установлен на ближайший возможный уровень
         //sl = MathMin(sl, minimal);
         if ( sl > open_price + TrailingStart * pips * _Point && (current_sl == 0 || sl > current_sl + TrailingStep * pips * _Point) )
         {
            //trade.PositionModify (_Symbol, sl, current_tp);
            current_sl = sl;
         }
         
         if ( SymbolInfoDouble (_Symbol, SYMBOL_BID) < current_sl )
         {
           CloseAll ();
         }
         
         buy_sl = current_sl;
      }
      else if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL )
      {
         double current_sl = sell_sl;
         double sl = SymbolInfoDouble (_Symbol, SYMBOL_ASK) + pips * _Point * TrailingDistance;
         double minimal = SymbolInfoDouble (_Symbol, SYMBOL_ASK) + pips * _Point * SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
         //--- нормализация значения
         sl = NormalizeDouble(sl, _Digits); 
         //--- нормализация значения
         minimal = NormalizeDouble(minimal, _Digits); 
         //--- если на полученный от индикатора уровень невозможно установить стоплосс, 
         //    он будет установлен на ближайший возможный уровень
         //sl = MathMax(sl, minimal);
         if ( sl < open_price - TrailingStart * pips * _Point && (current_sl == 0 || sl < current_sl - TrailingStep * pips * _Point) )
         {
            //trade.PositionModify (_Symbol, sl, current_tp);
            current_sl = sl;
         }
         
         if ( SymbolInfoDouble (_Symbol, SYMBOL_ASK) > current_sl )
         {
            CloseAll ();
         }
         
         sell_sl = current_sl;
      }
   }
}

void CloseAll ()
{    
   int n = 30;
 if( position_info.Select(_Symbol) && position_info.Volume () > 0 )
 { 
   Print ("Closing position on symbol: " + _Symbol + " with volume: " + position_info.Volume ());
   while (!trade.PositionClose (_Symbol, Slippage) && --n > 0)
   {
      Sleep (1000);
   }
   //ClosePosition (_Symbol, PositionGetDouble (POSITION_VOLUME), Slippage);
 }
}
Mikhail Filimonov
5931
Mikhail Filimonov  
Igormq5:

Здравствуйте!

Столкнулся с такой проблемой на МТ5:

Вместо закрытия позиции, получаю открытие в противоположную сторону.

Т.е. например вместо закрытия по виртуальному стопу: открывается позиция в обратную сторону тем же объемом, а иногда и даже большим.

Чисто из наблюдений при закрытии позиции, брокер открывает отложенный ордер(стоп или лимит) и сделка закрывается когда этот ордер срабатывает.

Код описывающий логику, привожу на примере виртуального трейлинга:

#include <Trade\Trade.mqh>

#include <Trade\PositionInfo.mqh>

input double TrailingStart = 1;

input double TrailingDistance = 5;

input double TrailingStep = 2;

CTrade trade;

CPositionInfo position_info;

void VirtualTrailing ()
{
   if(PositionSelect(_Symbol))
   {  
     
      double open_price = PositionGetDouble (POSITION_PRICE_OPEN);
      if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY )
      {
         double current_sl = buy_sl;
         //double current_tp = PositionGetDouble (POSITION_TP);
         double sl = SymbolInfoDouble (_Symbol, SYMBOL_BID) - pips * _Point * TrailingDistance;
         double minimal = SymbolInfoDouble (_Symbol, SYMBOL_BID) - pips * _Point * SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
         //--- нормализация значения
         sl = NormalizeDouble(sl, _Digits);
         //--- нормализация значения
         minimal = NormalizeDouble(minimal, _Digits);
         //--- если на полученный от индикатора уровень невозможно установить стоплосс,
         //    он будет установлен на ближайший возможный уровень
         //sl = MathMin(sl, minimal);
         if ( sl > open_price + TrailingStart * pips * _Point && (current_sl == 0 || sl > current_sl + TrailingStep * pips * _Point) )
         {
            //trade.PositionModify (_Symbol, sl, current_tp);
            current_sl = sl;
         }
        
         if ( SymbolInfoDouble (_Symbol, SYMBOL_BID) < current_sl )
         {
           CloseAll ();
         }
        
         buy_sl = current_sl;
      }
      else if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL )
      {
         double current_sl = sell_sl;
         double sl = SymbolInfoDouble (_Symbol, SYMBOL_ASK) + pips * _Point * TrailingDistance;
         double minimal = SymbolInfoDouble (_Symbol, SYMBOL_ASK) + pips * _Point * SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
         //--- нормализация значения
         sl = NormalizeDouble(sl, _Digits);
         //--- нормализация значения
         minimal = NormalizeDouble(minimal, _Digits);
         //--- если на полученный от индикатора уровень невозможно установить стоплосс,
         //    он будет установлен на ближайший возможный уровень
         //sl = MathMax(sl, minimal);
         if ( sl < open_price - TrailingStart * pips * _Point && (current_sl == 0 || sl < current_sl - TrailingStep * pips * _Point) )
         {
            //trade.PositionModify (_Symbol, sl, current_tp);
            current_sl = sl;
         }
        
         if ( SymbolInfoDouble (_Symbol, SYMBOL_ASK) > current_sl )
         {
            CloseAll ();
         }
        
         sell_sl = current_sl;
      }
   }
}

void CloseAll ()
{   
   int n = 30;
 if( position_info.Select(_Symbol) && position_info.Volume () > 0 )
 {
   Print ("Closing position on symbol: " + _Symbol + " with volume: " + position_info.Volume ());
   while (!trade.PositionClose (_Symbol, Slippage) && --n > 0)
   {
      Sleep (1000);
   }
   //ClosePosition (_Symbol, PositionGetDouble (POSITION_VOLUME), Slippage);
 }
}

Добрый день!

Код нужно оформлять, нажав кнопку SRC

#include <Trade\Trade.mqh>

#include <Trade\PositionInfo.mqh>

input double TrailingStart = 1;

input double TrailingDistance = 5;

input double TrailingStep = 2;

CTrade trade;

CPositionInfo position_info;

void VirtualTrailing ()
{
   if(PositionSelect(_Symbol))
   {   
      
      double open_price = PositionGetDouble (POSITION_PRICE_OPEN);
      if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY )
      {
         double current_sl = buy_sl;
         //double current_tp = PositionGetDouble (POSITION_TP);
         double sl = SymbolInfoDouble (_Symbol, SYMBOL_BID) - pips * _Point * TrailingDistance;
         double minimal = SymbolInfoDouble (_Symbol, SYMBOL_BID) - pips * _Point * SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
         //--- нормализация значения
         sl = NormalizeDouble(sl, _Digits); 
         //--- нормализация значения
         minimal = NormalizeDouble(minimal, _Digits); 
         //--- если на полученный от индикатора уровень невозможно установить стоплосс, 
         //    он будет установлен на ближайший возможный уровень
         //sl = MathMin(sl, minimal);
         if ( sl > open_price + TrailingStart * pips * _Point && (current_sl == 0 || sl > current_sl + TrailingStep * pips * _Point) )
         {
            //trade.PositionModify (_Symbol, sl, current_tp);
            current_sl = sl;
         }
         
         if ( SymbolInfoDouble (_Symbol, SYMBOL_BID) < current_sl )
         {
           CloseAll ();
         }
         
         buy_sl = current_sl;
      }
      else if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL )
      {
         double current_sl = sell_sl;
         double sl = SymbolInfoDouble (_Symbol, SYMBOL_ASK) + pips * _Point * TrailingDistance;
         double minimal = SymbolInfoDouble (_Symbol, SYMBOL_ASK) + pips * _Point * SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
         //--- нормализация значения
         sl = NormalizeDouble(sl, _Digits); 
         //--- нормализация значения
         minimal = NormalizeDouble(minimal, _Digits); 
         //--- если на полученный от индикатора уровень невозможно установить стоплосс, 
         //    он будет установлен на ближайший возможный уровень
         //sl = MathMax(sl, minimal);
         if ( sl < open_price - TrailingStart * pips * _Point && (current_sl == 0 || sl < current_sl - TrailingStep * pips * _Point) )
         {
            //trade.PositionModify (_Symbol, sl, current_tp);
            current_sl = sl;
         }
         
         if ( SymbolInfoDouble (_Symbol, SYMBOL_ASK) > current_sl )
         {
            CloseAll ();
         }
         
         sell_sl = current_sl;
      }
   }
}

void CloseAll ()
{    
   int n = 30;
 if( position_info.Select(_Symbol) && position_info.Volume () > 0 )
 { 
   Print ("Closing position on symbol: " + _Symbol + " with volume: " + position_info.Volume ());
   while (!trade.PositionClose (_Symbol, Slippage) && --n > 0)
   {
      Sleep (1000);
   }
   //ClosePosition (_Symbol, PositionGetDouble (POSITION_VOLUME), Slippage);
 }
}
Igor Slepnev
1820
Igor Slepnev  
Прошу прощения, исправил.
Mikhail Filimonov
5931
Mikhail Filimonov  
Igormq5:
Прошу прощения, исправил.
А Вы не пробовали обойтись без стандартных библиотек?
Igor Slepnev
1820
Igor Slepnev  
Mikalas:
А Вы не пробовали обойтись без стандартных библиотек?
Пробовал, разные функции, но суть происходящего не меняет.
Mikhail Filimonov
5931
Mikhail Filimonov  
Igormq5:
Пробовал, разные функции, но суть происходящего не меняет.

Да, нет, должно сильно менять!

Потому что в OrderSend() Вы точно указываете направление сделки

Mikhail Filimonov
5931
Mikhail Filimonov  

И потом, в МТ5 может быть только одна позиция!

Зачем Вы 30 раз пытаетесь закрыть её?

Если она не закрылась с первого раза, значит

есть к тому причина. Хорошо бы выяснить её. 

vchek
6
vchek  
int cnt;
for(cnt=0;cnt <800;cnt++)
    {if(OrderSelect(cnt,SELECT_BY_POS ,MODE_HISTORY)==true  && Symbol()==OrderSymbol())
     {if(OP_SELL!=0){int at2 = OrderTicket();
      double ao2 = OrderOpenPrice(); double ac2 = OrderClosePrice();}
      if(OP_BUY!=0){int at1 = OrderTicket();
      double ao1 = OrderOpenPrice(); double ac1 = OrderClosePrice();}

} }

Почему ат1,ао1,ас1=0, в истории bay ордера есть.

Alekseu Fedotov
941
Alekseu Fedotov  
vchek:
int cnt;
for(cnt=0;cnt <800;cnt++)
    {if(OrderSelect(cnt,SELECT_BY_POS ,MODE_HISTORY)==true  && Symbol()==OrderSymbol())
     {if(OP_SELL!=0){int at2 = OrderTicket();
      double ao2 = OrderOpenPrice(); double ac2 = OrderClosePrice();}
      if(OP_BUY!=0){int at1 = OrderTicket();
      double ao1 = OrderOpenPrice(); double ac1 = OrderClosePrice();}

} }

Почему ат1,ао1,ас1=0, в истории bay ордера есть.

А так!

 int cnt;
   for(cnt=0;cnt<OrdersHistoryTotal();cnt++)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY)==true && Symbol()==OrderSymbol())
        {if(OrderType()==0)  //OP_SELL
           {
            int at2=OrderTicket();
            double ao2=OrderOpenPrice(); double ac2=OrderClosePrice();
           }
         if(OrderType()==1) //OP_BUY
           {
            int at1=OrderTicket();
            double ao1=OrderOpenPrice(); double ac1=OrderClosePrice();
           }
        }
     }

 пробуйте.

vchek
6
vchek  
r772ra:

А так!

Спасибо, работает.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий