Выбор нужной позиции

 

 Есть функция, которая не всегда работает правильно. Выбирает не ту позицию из двух открытых.ЧТО НЕ ТАК?

//+------------------------------------------------------------------+
//| Check for position traling4                                      |
//+------------------------------------------------------------------+
void Traling4(void)
  {
   double  macd_current;
   double  macd_previous;
   double  signal_current;
   double  signal_previous;
   double  atr;
   double  buff_MACD_main[];           // MACD for indicator main buffer
   double  buff_MACD_signal[];         // MACD for indicator signal buffer
   double  buff_ATR[];                 // ATR indicator buffers
   ArraySetAsSeries(buff_MACD_main,true);
   ArraySetAsSeries(buff_MACD_signal,true);
   ArraySetAsSeries(buff_ATR,true);
   if(BarsCalculated(handle_macd)<2 || BarsCalculated(handle_atr)<2)
      return;
   if(CopyBuffer(handle_macd,0,0,2,buff_MACD_main)          !=2 ||
      CopyBuffer(handle_macd,1,0,2,buff_MACD_signal)        !=2 ||
      CopyBuffer(handle_atr,0,0,2,buff_ATR)                 !=2)
     {
      Print("CopyBuffer from Indicator failed, no data");
      return;
     }
   macd_current    =buff_MACD_main[0];
   macd_previous   =buff_MACD_main[1];
   signal_current  =buff_MACD_signal[0];
   signal_previous =buff_MACD_signal[1];
   atr             =buff_ATR[0];
   long   Spread=SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
   double Bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   double Ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double Dist=atr/_Point;
   double sl_buy=NormalizeDouble(Bid-Dist*_Point,_Digits);
   double sl_sell=NormalizeDouble(Ask+Dist*_Point,_Digits);
//--- check for trailing stop
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(position.SelectByIndex(i))
         if(MAGIC==PositionGetInteger(POSITION_MAGIC) && PositionGetString(POSITION_SYMBOL)==_Symbol)
           {
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
              {
               if(macd_current>0)
                  if(macd_current>=macd_level*_Point)
                     if(macd_current<signal_current && macd_previous>signal_previous)
                       {
                        if(sl_buy-PositionGetDouble(POSITION_PRICE_OPEN)>_Point*Spread && sl_buy>PositionGetDouble(POSITION_SL) && PositionGetDouble(POSITION_SL)>0)
                           if(sl_buy>PositionGetDouble(POSITION_PRICE_OPEN) && Bid-sl_buy>SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point)
                              if(sl_buy-PositionGetDouble(POSITION_PRICE_OPEN)>SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point && PositionGetInteger(POSITION_TIME)<OpenCandle(_Symbol))
                                 if(PositionGetDouble(POSITION_SL)-PositionGetDouble(POSITION_PRICE_OPEN)<sl_buy-PositionGetDouble(POSITION_PRICE_OPEN))
                                   {
                                    //--- modify position
                                    if(ExtTrade.PositionModify(Symbol(),sl_buy,0))
                                       printf("Long position by %s to be modified(4)",Symbol());
                                    else
                                      {
                                       printf("Installing protective level(4) failed by %s : '%s'",Symbol(),ExtTrade.ResultComment());
                                       printf("Modify parameters : SL=%f,TP=%f",sl_buy,0);
                                      }
                                   }
                       }
              }
            else
              {
               if(macd_current<0)
                  if(macd_current<=(-macd_level*_Point))
                     if(macd_current>signal_current && macd_previous<signal_previous)
                       {
                        if(PositionGetDouble(POSITION_PRICE_OPEN)-sl_sell>_Point*Spread && sl_sell<PositionGetDouble(POSITION_SL) && PositionGetDouble(POSITION_SL)>0)
                           if(sl_sell<PositionGetDouble(POSITION_PRICE_OPEN) && sl_sell-Ask>SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point)
                              if(PositionGetDouble(POSITION_PRICE_OPEN)-sl_sell>SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point && PositionGetInteger(POSITION_TIME)<OpenCandle(_Symbol))
                                 if(PositionGetDouble(POSITION_PRICE_OPEN)-PositionGetDouble(POSITION_SL)<PositionGetDouble(POSITION_PRICE_OPEN)-sl_sell)
                                   {
                                    //--- modify position
                                    if(ExtTrade.PositionModify(Symbol(),sl_sell,0))
                                       printf("Short position by %s to be modified(4)",Symbol());
                                    else
                                      {
                                       printf("Installing protective level(4) failed by %s : '%s'",Symbol(),ExtTrade.ResultComment());
                                       printf("Modify parameters : SL=%f,TP=%f",sl_sell,0);
                                      }
                                   }
                       }
              }
           }
  }
ЧТО НЕ ТАК?

 

Как минимум, нужно видеть, как объявлены position и ExtTrade. Скорее всего, 

position.SelectByIndex(i)

не выбирает позицию так, как это делает PositionGetSymbol или PositionSelect.

 
Ihor Herasko:

Как минимум, нужно видеть, как объявлены position и ExtTrade. Скорее всего, 

не выбирает позицию так, как это делает PositionGetSymbol или PositionSelect.

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>

input int    StopLoss           = 580;
input double Risk               = 3;
input double Level_MACD         = 0.00073;
input int    macd_level         = 3;
//---
int    handle_stoch_M1=0;
int    handle_stoch=0;
int    handle_stoch_cl=0;
int    handle_macd_cl=0;
int    handle_macd=0;
int    handle_atr=0;
int    handle_maLOW=0;
int    handle_ma=0;
bool   ExtHedging=false;
CTrade ExtTrade;
CPositionInfo  position;

#define MAGIC 123

Как то так.

 
Как по мне так PositionInfo.mqh это зло. Давно отказался от его использования.
 
Konstantin Nikitin:
Как по мне так PositionInfo.mqh это зло. Давно отказался от его использования.
Как же выбрать позицию в пятерке при хеджинге?

 
Vitaly Stepanov:
Как же выбрать позицию в пятерке при хеджинге
int total = 0,
    Magic = 12345;
#ifdef __MQL5__
  total = PositionsTotal();
#else
  total = OrdersTotal();
#endif

for(int cnt=0; cnt<total; cnt++)
{
  #ifdef __MQL5__
     if( _Symbol != PositionGetSymbol(cnt) ) continue;
     if( PositionGetInteger(POSITION_TYPE)!= ORDER_TYPE_BUY && PositionGetInteger(POSITION_TYPE)!= ORDER_TYPE_SELL ) continue;
     if( PositionGetInteger(POSITION_MAGIC) != Magic ) continue;
  #else
     if( !OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES) ) continue;
     if( OrderSymbol() != _Symbol) continue;
     if( OrderMagicNumber() != Magic ) continue;
     if( OrderType()!= ORDER_TYPE_BUY && OrderType()!= ORDER_TYPE_SELL ) continue;
  #endif
}
 
Konstantin Nikitin:

Мне больше нравится выбор по тикету.

 ulong ticket = 0;
  if(posTotal > 0)
   {
    for(int i = PositionsTotal(); i-- > 0;)
     {
      ticket = PositionGetTicket(i);
// и делай с ним что хошь
     }
   }

Дело в том, что все действия с позициями требуют тикет позиции.

 
какие ещё варианты?
 
Vitaly Stepanov:
какие ещё варианты?

Больше никаких.

Совсем недавно выбор по символу работал исключительно с одной позицией и на hadge счетах выбирал только одну позицию. Я даже начал писать Константину, что так неправильно. Но увидев индекс в запросе полез в документацию и был приятно удивлён изменениям.

 
Vitaly Stepanov:
какие ещё варианты?

ЗЫ

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

CPositionInfo::SelectByIndex()

fxsaber, 2016.12.01 08:41

@Rashid Umarov, зачем выбор позиции для Hedge и Netto сделали по-разному?
//+------------------------------------------------------------------+
//| Select a position on the index                                   |
//+------------------------------------------------------------------+
bool CPositionInfo::SelectByIndex(const int index)
  {
   ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
//---
   if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      ulong ticket=PositionGetTicket(index);
      if(ticket==0)
         return(false);

     }
   else
     {
      string name=PositionGetSymbol(index);
      if(name=="")
         return(false);
     }
//---
   return(true);
  }
PositionGetTicket отлично работает на обоих типах счетов. Поэтому вся функция могла бы быть только в виде выделенных строк.
 
Alexey Viktorov:

Мне больше нравится выбор по тикету.

Дело в том, что все действия с позициями требуют тикет позиции.

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

PositionGetString(POSITION_SYMBOL);
PositionGetInteger(POSITION_MAGIC);
PositionGetDouble(POSITION_PROFIT);

где в этих функциях тикет

Причина обращения: