Ошибка "OrderSend error 131. - страница 3

 
PPC:

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

Нету плюса. 

...

eevviill 16.10.2015 13:27 # 

 

mors:
Была такая же ошибка, спасибо за совет, всё заработало. Кто нибудь может объяснить почему нельзя выставить объём 0,1.
Надо NormalizeDouble(Lot,2)
 
eevviill:

eevviill 16.10.2015 13:27 # 

 

mors:
Была такая же ошибка, спасибо за совет, всё заработало. Кто нибудь может объяснить почему нельзя выставить объём 0,1.
Надо NormalizeDouble(Lot,2)
Молодой человек, вы или ЧУКЧА или галимый трололо или тупо набиваете посты. Если я в сове забиваю на принт инфу по макслоту (через маркетинфо) и мне печатает "0" (см. мой первый пост в этой ветке), то какой нахрен "Надо NormalizeDouble(Lot,2)"! Лол. С Вами диалог close.
 
PPC:
Молодой человек, вы или ЧУКЧА или галимый трололо или тупо набиваете посты. Если я в сове забиваю на принт инфу по макслоту (через маркетинфо) и мне печатает "0" (см. мой первый пост в этой ветке), то какой нахрен "Надо NormalizeDouble(Lot,2)"! Лол. С Вами диалог close.
MarketInfo() в тестере не гарантировано, тем более, если на оффлайнграфике или без связи с сервером! А NormalizeDouble() работает в любом режиме!
 

Обновитесь на 902 билд, пожалуйста.

В нем тестирование в оффлайне исправлено.

 
Так ведь только вчера выложили обновление 900 билда. А сегодня уже 902???
 
AlexeyVik:
Так ведь только вчера выложили обновление 900 билда. А сегодня уже 902???
Да, официальным релизом стал 902 билд.
 

Тема старая, но я попробую ответить. Тоже сталкивался с этой проблемой. И оказалось всё гораздо проще. Почему-то никто не хочет учитывать шаг изменения лота. Конечно почти что у всех брокеров шаг равен 0,01. Но не у всех, а именно в MetaQuote! 

Почему возникает ошибка 131. Например наш советник хочет открыть ордер с лотом 0,23.  Но в МаркетИнфо уже забито что минимальный лот 0,10, а шаг изменения лота например 0,05. То есть мы может открывать лот начиная с 0,10, далее 0,15  0,20  0,25  0,30 и тд.    Но нужный нам лот 0,23 не попадает в этот список, поэтому и возникает ошибка 131.

Предлагаю вам рассмотреть во такой код. 

if (lot < MarketInfo(Symbol(),MODE_MINLOT))   lot = MarketInfo(Symbol(),MODE_MINLOT);  // проверяем чтобы наш лот НЕ был меньше минимального

        if (lot > MarketInfo(Symbol(),MODE_MAXLOT))  lot = MarketInfo(Symbol(),MODE_MAXLOT);  // проверяем чтобы наш лот НЕ был больше максимального

        double lotstep = MarketInfo(Symbol(),MODE_LOTSTEP);   // это шаг лота

        lot = (int)(lot/lotstep) * lotstep;  /// вот такая вот формула  (лот делим на шаг, округляем до целых, и умножаем на шаг)

        lot = NormalizeDouble(lot,2);

 
Sergey Kruglov:

Тема старая, но я попробую ответить. Тоже сталкивался с этой проблемой. И оказалось всё гораздо проще. Почему-то никто не хочет учитывать шаг изменения лота. Конечно почти что у всех брокеров шаг равен 0,01. Но не у всех, а именно в MetaQuote! 

Почему возникает ошибка 131. Например наш советник хочет открыть ордер с лотом 0,23.  Но в МаркетИнфо уже забито что минимальный лот 0,10, а шаг изменения лота например 0,05. То есть мы может открывать лот начиная с 0,10, далее 0,15  0,20  0,25  0,30 и тд.    Но нужный нам лот 0,23 не попадает в этот список, поэтому и возникает ошибка 131.

Предлагаю вам рассмотреть во такой код. 

if (lot < MarketInfo(Symbol(),MODE_MINLOT))   lot = MarketInfo(Symbol(),MODE_MINLOT);  // проверяем чтобы наш лот НЕ был меньше минимального

        if (lot > MarketInfo(Symbol(),MODE_MAXLOT))  lot = MarketInfo(Symbol(),MODE_MAXLOT);  // проверяем чтобы наш лот НЕ был больше максимального

        double lotstep = MarketInfo(Symbol(),MODE_LOTSTEP);   // это шаг лота

        lot = (int)(lot/lotstep) * lotstep;  /// вот такая вот формула  (лот делим на шаг, округляем до целых, и умножаем на шаг)

        lot = NormalizeDouble(lot,2);


А зачем NormalizeDouble в конце? Да и функция округления давно предложена еще со времен MT3 (суть почти та же, но без двух приведений от double к int, после которого снова приведение к double). Для округления к ближайшей корректной величине лота:

double VolumeRound(double volume, double volumeMin, double volumeMax, double volumeStep)
{
   if (volumeStep == 0.0)
      return volumeMin;

   return (MathMin(MathMax(MathRound(volume / volumeStep) * volumeStep, volumeMin), volumeMax));
}

Для округления к ближайшей меньшей корректной величине:

double VolumeCast(double volume, double volumeMin, double volumeMax, double volumeStep)
{
   if (volumeStep == 0.0)
      return volumeMin;

   return (MathMin(MathMax(MathFloor(volume / volumeStep) * volumeStep, volumeMin), volumeMax));
}
 

Опять начинаете звездолёт изобретать!!! Я просто показал пример, на пальцах объяснил почему происходит ошибка. Да, возможно твой код с округление правильнее, но и мой код работает нормально и выглядит он проще. 

А NormalizeDouble  может и не нужно, но добавил чтобы не получилось  такое , например -  лот=0,150000. 

 
Sergey Kruglov:

Опять начинаете звездолёт изобретать!!!

)) Здесь на Вы?

Я просто показал пример, на пальцах объяснил почему происходит ошибка. Да, возможно твой код с округление правильнее, но и мой код работает нормально и выглядит он проще. 

Здесь уже на "ты". Определитесь, пожалуйста ))

Насчет проще - не заметил. Правильно он тоже не будет работать. Давайте посчитаем, что он выдаст при следующих значениях:

  • minLot = 0.1
  • lotStep = 0.25
  • lot = 0.212354

На выходе будет 0. Проблема в том, что:

  1. Проверка на граничные значения объема происходит ранее, чем это нужно.
  2. Производится приведение к int, о чем я сразу сказал. Так лучше не делать при операциях с вещественными числами, когда на выходе требуется вещественное значение.

А NormalizeDouble  может и не нужно, но добавил чтобы не получилось  такое , например -  лот=0,150000. 

И что страшного в этом значении? NormalizeDouble - это лишняя операция в приведенном коде. 
Причина обращения: