как правильно увеличивать объем ордера в редакторе метатрейлер 4

 

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

Здравствуйте . Пожалуйста ответе мне на вопрос или посоветуйте что нибудь. в тестере стротегий выдает ошибку 131. не могу грамотно увеличивать лот. если лот по умолчанию не меняеться то ордера открываются как только хочу увеличить лот . то он не открывает лот. по умолчанию лот равен 0,01 а увеличиваю я его на 0,01. тестар брокера подерживает даный объем лотов. я просто хочу применить мартингей а тестор не открывает ордера и вот не знаю что делать. буду блогодарен вам если ответите на мой вапрос

 
nazim25:

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

Здравствуйте . Пожалуйста ответе мне на вопрос или посоветуйте что нибудь. в тестере стротегий выдает ошибку 131. не могу грамотно увеличивать лот. если лот по умолчанию не меняеться то ордера открываются как только хочу увеличить лот . то он не открывает лот. по умолчанию лот равен 0,01 а увеличиваю я его на 0,01. тестар брокера подерживает даный объем лотов. я просто хочу применить мартингей а тестор не открывает ордера и вот не знаю что делать. буду блогодарен вам если ответите на мой вапрос

Надо проверять шаг изменения лота, вот код. Стал переделывать на мультиплатформенный, вроде не проверял еще.

#ifdef __MQL4__
    #property strict
    #include <AvLib\errors.mqh>
#endif
#ifdef __MQL5__
    #include <MT4Orders.mqh>
#endif    


#define ORDER_OK               0
#define ORDER_SELECT_ERROR     1
#define ORDER_PROFIT_LESS_ZERO 2
#define ORDER_TYPE_ERROR       3
#define ORDER_IS_CLOSED        4
#define ORDER_CLOSE_ERROR      5

// открывает ордер с проверкой, нормализацией данных и возвратом измененных данных
int OpenOrderWithCheck(string symbol, int cmd, double& volume, double& price, int slippage, 
  double &stoploss, double &takeprofit, string comment, int magic, datetime expiration, 
  color arrow_color)
{
//   int dig = (int) MarketInfo(symbol, MODE_DIGITS);   // Количество знаков после запятой по инструменту
   int dig = (int) SymbolInfoInteger(symbol, SYMBOL_DIGITS);   // Количество знаков после запятой по инструменту
   
   double minlot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);   // Минимальный размер лота
   double lotstep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP); // Шаг изменения размера лота 
   double maxlot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);   // Максимальный размер лота 

   
   int lot = (int)(volume/lotstep); // округлили до целого числа шагов изменения лота
   volume = (double)lot * lotstep;  // теперь имеем правильный объем, кратный шагу изменения лота 
   
   if(volume < minlot)
   {
      // я предпочитаю такую обработку, но выдаю алерт, чтобы исправить ошибку, пару раз помогало :)  
      // ниже читаете коммент про логгирование в файлы
      volume = minlot;
      Alert("OpenOrderWithCheck()", " The volume less than the minimum, set the minimum value = ", DoubleToString(volume, 2), " lot");
   }
   if(volume > maxlot)
   {
      volume = maxlot;
      Alert("OpenOrder()WithCheck", " The volume is larger than the maximum, I set the minimum value = ", DoubleToString(volume, 2), " lot");
   }
   
   // При открытии рыночного ордера (OP_SELL или OP_BUY) в качестве цены открытия могут использоваться 
   // только самые последние цены Bid (для продажи) или Ask (для покупки). 
   if(cmd == OP_BUY )
      price = SymbolInfoDouble(symbol, SYMBOL_ASK);;
   if(cmd == OP_SELL)
      price = SymbolInfoDouble(symbol, SYMBOL_BID);;
   
   takeprofit = NormalizeDouble(takeprofit, dig); // цены надо округлять до количества знаков после запятой
   stoploss = NormalizeDouble(stoploss, dig);
   price = NormalizeDouble(price, dig);
   
   ResetLastError();
   int ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);

   if(ticket < 0)
   {
#ifdef __MQL4__    
      string err = GetMyLastError();
      // тут вместо принта можно выполнить свое действие, лично я пишу протокол в лог-файл
      Print("Error of open order, ", err);
#else
    #ifdef __MQL5__      
        Print("Error of open order, ", GetLastError());
    #endif   
#endif 
   }
   else
   {
      bool os = OrderSelect(ticket, SELECT_BY_TICKET);
      if(os == true)
      {
         price      = OrderOpenPrice();
         // нужно запрашивать реальный объем, т.к. на счетах ECN при посылке ордера с большим объемом может открыться несколько ордеров
         // с разными объемами и разными ценами из-за того, что в стакане просто нет заявки с нужным лотом по запрошенной цене
         volume     = OrderLots();      
         stoploss   = OrderStopLoss();
         takeprofit = OrderTakeProfit();        
      }
   }   
   return ticket;
}
 

точнее 134. не правильный объем. 

Lots=NormalizeDouble(Lots,2); не спосает

 
double lot = NormalizeDouble(MathMin(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX), MathMax(LOT, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))), 2);
 
nazim25:

точнее 134. не правильный объем. 

Lots=NormalizeDouble(Lots,2); не спосает

Достаточно просто:

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Приведение объема к ближайшему допустимому значению                                                                                                                                      |
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double VolumeCast(double volume, double volumeMin, double volumeMax, double volumeStep)
{
   if (volumeStep == 0.0)
      return volumeMin;

   return (MathMin(MathFloor(volume / volumeStep) * volumeStep + volumeMin, volumeMax));
}
 
Alexey Volchanskiy:

Надо проверять шаг изменения лота, вот код. Стал переделывать на мультиплатформенный, вроде не проверял еще.

Вместо:

 int lot = (int)(volume/lotstep); // округлили до целого числа шагов изменения лота
 volume = (double)lot * lotstep;  // теперь имеем правильный объем, кратный шагу изменения лота

Нужно:

 int lot = (int)(volume/lotstep); // округлили до целого числа шагов изменения лота
 volume = (double)lot * lotstep + minlot;  // теперь имеем правильный объем, кратный шагу изменения лота
 

всем спосибо за ответ и двойне спосибо за быстрый ответ.

я забыл уточнить что я чайник

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

 

int ut=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, teks);

Lots=Lots+0,01;

Lots=NormalizeDouble(Lots,2);

это я написал просто 

и что же мне суда поставить чтоб следюший ордер открылся с увеличенным лотом 

 
nazim25:

всем спосибо за ответ и двойне спосибо за быстрый ответ.

я забыл уточнить что я чайник

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

 

int ut=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, teks);

Lots=Lots+0,01;

Lots=NormalizeDouble(Lots,2);

это я написал просто 

и что же мне суда поставить чтоб следюший ордер открылся с увеличенным лотом 

я же привел в посте #2 функцию со всеми проверками. Вы даже не читаете ответы?

 
Ihor Herasko:

Вместо:

Нужно: volume = (double)lot * lotstep + minlot;  // теперь имеем правильный объем, кратный шагу изменения лота

Несогласен, это правильно только, если lot == 0, в противном случае задаем неверный volume

Сделаны же далее проверки на вшивость

int lot = (int)(volume/lotstep); // округлили до целого числа шагов изменения лота
   volume = (double)lot * lotstep;  // теперь имеем правильный объем, кратный шагу изменения лота 
   
   if(volume < minlot)
   {
      // я предпочитаю такую обработку, но выдаю алерт, чтобы исправить ошибку, пару раз помогало :)  
      // ниже читаете коммент про логгирование в файлы
      volume = minlot;
      Alert("OpenOrderWithCheck()", " The volume less than the minimum, set the minimum value = ", DoubleToString(volume, 2), " lot");
   }
   if(volume > maxlot)
   {
      volume = maxlot;
      Alert("OpenOrder()WithCheck", " The volume is larger than the maximum, I set the minimum value = ", DoubleToString(volume, 2), " lot");
   }
 
Alexey Volchanskiy:

я же привел в посте #2 функцию со всеми проверками. Вы даже не читаете ответы?

ей богу я почитал . еслиб всё поенел . то не зодовал лишних вапросов. мне бы какую нибудь простую функцию или хотяты источник где бы я смог решить свой вапрос 


double teks=Ask+TakeProfit;

teks = NormalizeDouble(teks,5);

RefreshRates();

int ut=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, teks);

Lots=Lots+0,01;

Lots=NormalizeDouble(Lots,2);

ну скажите мне пожалуйсто что сюда поставить что просто при следюшит тике тестор открый мне ордер с увеличаным лотом

 
Alexey Volchanskiy:

Несогласен, это правильно только, если lot == 0, в противном случае задаем неверный volume

Сделаны же далее проверки на вшивость

спосибо вам ну всем остальным . я почитаю и буду проверять путем тыка и ошибок. глядиш что то и получиься