Скачать MetaTrader 5

Подсчет порядкового номера ордера.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Ahmad Mehdiyev
478
Ahmad Mehdiyev  
Помогите исправить код. Что не так с подсчетом порядкового номера ордера в коде этого скрипта? Работает отлично пока открыты ордера в одном символе. В ситуации когда есть несколько ордеров в разных символах начинает глючить. Сбиваются порядковые номера ордеров каждой валютной пары и вызвать с помощью OrdN, например, 3-й EURUSD из списка 3-х EURUSD и 4-х AUDUSD уже невозможно. (код писал сам, далеко не профи в MQL).
#property show_inputs

extern string order_number_descr  = " 1 - last, 2 - 2nd last, etc";
extern int    OrdN = 1;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
//----
   int MaxTime=0;
   int OrdTicketN=0;
   int i, total=OrdersTotal();
   int digits   = MarketInfo(Symbol(),MODE_DIGITS);
   double value = NormalizeDouble(WindowPriceOnDropped(),digits);
//-----------find the OrderTicket of the order---------
   
   for(i=total-OrdN;i>=0;i--) {
   if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false) continue;
   if(OrderSymbol()!=Symbol()) continue;
   if(OrderType()>1) continue;   
      if (MaxTime < OrderOpenTime()) {
         MaxTime = OrderOpenTime();
         OrdTicketN = OrderTicket();
      }
   }
//======================================
   for(i=total-1;i>=0;i--) {
   if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if(OrderSymbol()==Symbol()) {
      if(OrderTicket()==OrdTicketN) {
         if(OrderType()==OP_BUY)     
         if(value>Ask)
            OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(), value,OrderExpiration(),White);
         if(OrderType()==OP_SELL)
         if(value<Bid)
            OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(), value,OrderExpiration(),White);      
        }
      }  
   }}
   return(0);
  }
//+------------------------------------------------------------------+

TarasBY
1740
TarasBY  
pro_:
Помогите исправить код. Что не так с подсчетом порядкового номера ордера в коде этого скрипта? Работает отлично пока открыты ордера в одном символе. В ситуации когда есть несколько ордеров в разных символах начинает глючить. Сбиваются порядковые номера ордеров каждой валютной пары и вызвать с помощью OrdN, например, 3-й EURUSD из списка 3-х EURUSD и 4-х AUDUSD уже невозможно. (код писал сам, далеко не профи в MQL).

Исправления "от телепата" (с трудом понимаю Вашу супер-задачу):

#property show_inputs

extern string order_number_descr  = " 1 - last, 2 - 2nd last, etc";
extern int    OrdN = 1;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
//----
   int MaxTime=0;
   int OrdTicketN=0;
   int i, li_cnt = 1, total=OrdersTotal();
   int digits   = MarketInfo(Symbol(),MODE_DIGITS);
   double value = NormalizeDouble(WindowPriceOnDropped(),digits);
//-----------find the OrderTicket of the order---------
   
   for(i=total-1;i>=0;i--) {
   if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false) continue;
   if(OrderSymbol()!=Symbol()) continue;
   if(OrderType()>1) continue;   
      if (MaxTime < OrderOpenTime())
      {
          MaxTime = OrderOpenTime();
          if (li_cnt < OrdN) {li_cnt++; continue;}
          if (OrderType()==OP_BUY)
          {
             if (value>Ask) OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(), value,OrderExpiration(),White);
             break;
          }
          else if(OrderType()==OP_SELL)
          {
              if(value<Bid) OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(), value,OrderExpiration(),White); 
              break;
          } 
      }
  }
   return(0);
  }
//+------------------------------------------------------------------+
Сергей
256
Сергей  

Предлагаю танцевать от печки.

Какую задачу вы хотите решить этим скриптом?

Ahmad Mehdiyev
478
Ahmad Mehdiyev  
Нужно чтобы велся подсчет ордеров отдельно по символам. Поясню задачу на примере. Открыты 3 ордера по EURUSD. Скрипт (в оригинале, до исправления "от телепата" :)) выставляет ТР на один из них. Какой именно (1-й, 2-й или 3-й) указывается с помощью extern int OrdN. Все отлично работает пока в списке открытых ордеров только ордера одного символа. Скрипт с OrdN=2 установит ТР на 2-й снизу ордер в списке, OrdN=3 на самый первый открытый ордер и т.д.. Но в случае торговли в более чем одной валютной паре, правильно выбрать порядковый номер ордера уже невозможно - "мешают" ордера других символов (2-й по EURUSD становится 5-м или 7-м в общем списке). Хотелось бы чтобы применяя скрипт к каждому графику по которому есть открытая позиция можно было указать порядковый номер ордера ЭТОГО символа. На примере: к трем позициям по EURUSD добавлены 4 по AUDUSD. Необходимо изменить первую часть (!) скрипта так, чтобы применяя его к графику EURUSD можно было указать порядковый номер ордера ИМЕННО этого символа (например последнего ордера указав OrdN=1), а на графике AUDUSD соответственно порядковый номер ордера не общего списка а только AUDUSD (например самый первый из 4-х открытых ордеров указав OrdN=4). Надеюсь это пояснение не запутало вас еще больше. Чтобы не перенапрячь телепатические способности :) можно попробовать скрипт на демке.
TarasBY
1740
TarasBY  
pro_:
Нужно чтобы велся подсчет ордеров отдельно по символам. Поясню задачу на примере. Открыты 3 ордера по EURUSD. Скрипт (в оригинале, до исправления "от телепата" :)) выставляет ТР на один из них. Какой именно (1-й, 2-й или 3-й) указывается с помощью extern int OrdN. Все отлично работает пока в списке открытых ордеров только ордера одного символа. Скрипт с OrdN=2 установит ТР на 2-й снизу ордер в списке, OrdN=3 на самый первый открытый ордер и т.д.. Но в случае торговли в более чем одной валютной паре, правильно выбрать порядковый номер ордера уже невозможно - "мешают" ордера других символов (2-й по EURUSD становится 5-м или 7-м в общем списке). Хотелось бы чтобы применяя скрипт к каждому графику по которому есть открытая позиция можно было указать порядковый номер ордера ЭТОГО символа. На примере: к трем позициям по EURUSD добавлены 4 по AUDUSD. Необходимо изменить первую часть (!) скрипта так, чтобы применяя его к графику EURUSD можно было указать порядковый номер ордера ИМЕННО этого символа (например последнего ордера указав OrdN=1), а на графике AUDUSD соответственно порядковый номер ордера не общего списка а только AUDUSD (например самый первый из 4-х открытых ордеров указав OrdN=4). Надеюсь это пояснение не запутало вас еще больше. Чтобы не перенапрячь телепатические способности :) можно попробовать скрипт на демке.

А в моей правке что мешает попробовать на демке?!

P.S. А вообще, условие на модификацию тэйка нужно проверять на MODE_STOPLEVEL - по-взрослому. :)

И, в конечном итоге, код может выглядеть так:

#property show_inputs

extern int    OrdN = 1;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
{
//----
    int li_cnt = 1, total = OrdersTotal();
    double value = WindowPriceOnDropped(),
           ld_STOPLEVEL = (MarketInfo (Symbol(), MODE_STOPLEVEL) / Point);
//-----------find the OrderTicket of the order---------
   
    for (int i = total - 1; i >= 0; i--)
    {
        if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;
        if (OrderSymbol() != Symbol()) continue;
        if (OrderType() > 1) continue;   
        if (li_cnt < OrdN) {li_cnt++; continue;}
        if (OrderType() == OP_BUY)
        {
            value = NormalizeDouble (MathMax (value, Bid + ld_STOPLEVEL), Digits);
            OrderModify (OrderTicket(), OrderOpenPrice(), OrderStopLoss(), value, OrderExpiration(), White);
            break;
        }
        else
        {
            value = NormalizeDouble (MathMin (value, Ask - ld_STOPLEVEL), Digits);
            OrderModify (OrderTicket(), OrderOpenPrice(), OrderStopLoss(), value, OrderExpiration(), White); 
            break;
        } 
    }
    return (0);
}
//+------------------------------------------------------------------+
Ahmad Mehdiyev
478
Ahmad Mehdiyev  
Попробовал и большое вам спасибо. Скрипт работает как надо! Вообще-то скрипт был в качестве примера и в надежде что будет исправлена та его часть которая отвечает за пересчет ордеров. Хотел было попросить подправить код для применения в эксперте но сам справился. Еще раз ОГРОМНОЕ СПАСИБО!
Сергей
256
Сергей  
pro_:
Нужно чтобы велся подсчет ордеров отдельно по символам. Поясню задачу на примере. Открыты 3 ордера по EURUSD. Скрипт (в оригинале, до исправления "от телепата" :)) выставляет ТР на один из них. Какой именно (1-й, 2-й или 3-й) указывается с помощью extern int OrdN. Все отлично работает пока в списке открытых ордеров только ордера одного символа. Скрипт с OrdN=2 установит ТР на 2-й снизу ордер в списке, OrdN=3 на самый первый открытый ордер и т.д.. Но в случае торговли в более чем одной валютной паре, правильно выбрать порядковый номер ордера уже невозможно - "мешают" ордера других символов (2-й по EURUSD становится 5-м или 7-м в общем списке). Хотелось бы чтобы применяя скрипт к каждому графику по которому есть открытая позиция можно было указать порядковый номер ордера ЭТОГО символа. На примере: к трем позициям по EURUSD добавлены 4 по AUDUSD. Необходимо изменить первую часть (!) скрипта так, чтобы применяя его к графику EURUSD можно было указать порядковый номер ордера ИМЕННО этого символа (например последнего ордера указав OrdN=1), а на графике AUDUSD соответственно порядковый номер ордера не общего списка а только AUDUSD (например самый первый из 4-х открытых ордеров указав OrdN=4). Надеюсь это пояснение не запутало вас еще больше. Чтобы не перенапрячь телепатические способности :) можно попробовать скрипт на демке.

Так что нужно? Считать или выставлять? Шутка по выделенному.

Непонятно, что значит 1-й, 2-й и т.д. ордер?

По цене?(сверху или снизу), по времени открытия(срабатывания)(раньше-позже), по списку(сверху или снизу) и т.д.

А первая фильтрация, кАнЭчнА, по символу.

Ahmad Mehdiyev
478
Ahmad Mehdiyev  

Уважаемый hhohholl, спасибо вам за участие, за желание помочь ну и за юмор тоже. Проблема решена, спасибо TarasBY. Отвечая на ваш вопрос скажу: подсчет вела первая часть скрипта, выставление вторая, т.е. скрипт в итоге делал и то и другое. :) Проблема была с первой частью. Позволю себе выложить код в том виде в каком я хотел его получить от вас (еще раз спасибо TarasBY, он кажется действительно телепат, без шуток). В таком виде первая часть выдает OrderTicket выбранного ордера, а вторая, в данном случае, выставление ТР, а при желании и соответствующих изменениях делает с ним что угодно (в разумных пределах, кАнЭчнА) :). Всем удачи!

#property show_inputs

extern int    OrdN = 1;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
{
//----
    int li_cnt = 1, total = OrdersTotal();
    int OrderTicketN;
    double value = WindowPriceOnDropped(),
           ld_STOPLEVEL = (MarketInfo (Symbol(), MODE_STOPLEVEL) / Point);

//-----------------------------------------------------
    for (int i = total - 1; i >= 0; i--)
    {
        if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue;
        if (OrderSymbol() != Symbol()) continue;
        if (OrderType() > 1) continue;   
        if (li_cnt < OrdN) {
            li_cnt++; 
            OrderTicketN = OrderTicket();
            continue;
        }
    }
//-----------------------------------------------------
    for(i=total-1;i>=0;i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
    if (OrderSymbol()== Symbol()) {
        if (OrderTicket()==OrderTicketN) {
        if (OrderType() == OP_BUY)
        {
            value = NormalizeDouble (MathMax (value, Bid + ld_STOPLEVEL), Digits);
            OrderModify (OrderTicket(), OrderOpenPrice(), OrderStopLoss(), value, OrderExpiration(), White);
            break;
        }
        else
        {
            value = NormalizeDouble (MathMin (value, Ask - ld_STOPLEVEL), Digits);
            OrderModify (OrderTicket(), OrderOpenPrice(), OrderStopLoss(), value, OrderExpiration(), White); 
            break;
        } 
        }
    }}}
    return (0);
}
//+------------------------------------------------------------------+   
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий