Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Изучаешь MQL5? Начни с документации!
Ahmad Mehdiyev
478
Ahmad Mehdiyev 2012.09.14 15:00 
Помогите исправить код. Что не так с подсчетом порядкового номера ордера в коде этого скрипта? Работает отлично пока открыты ордера в одном символе. В ситуации когда есть несколько ордеров в разных символах начинает глючить. Сбиваются порядковые номера ордеров каждой валютной пары и вызвать с помощью 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
1739
TarasBY 2012.09.14 16:44  
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
Сергей 2012.09.14 16:55  

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

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

Ahmad Mehdiyev
478
Ahmad Mehdiyev 2012.09.14 17:59  
Нужно чтобы велся подсчет ордеров отдельно по символам. Поясню задачу на примере. Открыты 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
1739
TarasBY 2012.09.14 18:12  
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 2012.09.14 19:43  
Попробовал и большое вам спасибо. Скрипт работает как надо! Вообще-то скрипт был в качестве примера и в надежде что будет исправлена та его часть которая отвечает за пересчет ордеров. Хотел было попросить подправить код для применения в эксперте но сам справился. Еще раз ОГРОМНОЕ СПАСИБО!
Сергей
256
Сергей 2012.09.14 19:52  
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 2012.09.15 07:12  

Уважаемый 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);
}
//+------------------------------------------------------------------+   
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий