[АРХИВ!] Любой вопрос новичка, чтоб не захламлять форум. Профи, не проходите мимо. Без вас никуда - 4. - страница 361

 
veti-k:

Нет это уже слишком.. Что болье волотильне от хотябы от 20-50 пипсов
USDJPY
 

Ребята, подскажите:

При тестировании советника на стандартных индикаторах, входящих в поставку МТ4 на валютных парах - вопросов нет - всё работает согласно алгоритма торговли.

При тестировании на металлах: серебро, золото - ордера не открываются, пишет в "Журнале" тестера - деление на нуль.

Вх. параметры одни и теже, история на этом пятизначном ДЦ (форекс4ю) - закачана по тестируемым инструментам.

В чем возможна причина? Просьба к телепатам не отправлять. Советник написан мной лично по варианту учебника.

 
Roman.:

Ребята, подскажите:

При тестировании советника на стандартных индикаторах, входящих в поставку МТ4 на валютных парах - вопросов нет - всё работает согласно алгоритма торговли.

При тестировании на металлах: серебро, золото - ордера не открываются, пишет в "Журнале" тестера - деление на нуль.

Вх. параметры одни и теже, история на этом пятизначном ДЦ (форекс4ю) - закачана по тестируемым инструментам.

В чем возможна причина? Просьба к телепатам не отправлять. Советник написан мной лично по варианту учебника.

При любом делении на переменную необходимо сперва проверять не равна ли она нулю.
 
Roman.:

Ребята, подскажите:

При тестировании советника на стандартных индикаторах, входящих в поставку МТ4 на валютных парах - вопросов нет - всё работает согласно алгоритма торговли.

При тестировании на металлах: серебро, золото - ордера не открываются, пишет в "Журнале" тестера - деление на нуль.

Вх. параметры одни и теже, история на этом пятизначном ДЦ (форекс4ю) - закачана по тестируемым инструментам.

В чем возможна причина? Просьба к телепатам не отправлять. Советник написан мной лично по варианту учебника.


Дык код бы глянуть. А вообще можно (в программе Notepad++) автоматически промаркировать все места, где идёт вхождение знака деления в коде и посмотреть, может в каком-то случае действительно возникает деление на ноль.
 
drknn:

Дык код бы глянуть. А вообще можно (в программе Notepad++) автоматически промаркировать все места, где идёт вхождение знака деления в коде и посмотреть, может в каком-то случае действительно возникает деление на ноль.


Да уже смотрю обложив всё принтами до куда дошла распринтовка, там всё в порядке значит...

В ф-ии нормализации объёмов для металлов была эта ошибка (деления на нуль), щас её нет, появилась другая 131 - неправильный объём, хотя задан явно = 0,01 лот, смотрю в общем...

Для валют эта ф-ия нормализации объёма работает исправно.... Может есть общая для них (для металлов и валют)?

//--------------------------------------------------------------------
// Lot_MM.mqh
// 
//--------------------------------------------------------------- 1 --
// Функция вычисления количества лотов.
// Глобальные переменные:
// double Lots_New - количество лотов для новых ордеров (вычисляется)
// double Lots     - желаемое количество лотов, заданное пользовател.
// double  MaksRisk  - процент риска
// Возвращаемые значения:
// true  - если средств хватает на минимальный лот
// false - если средств не хватает на минимальный лот
//--------------------------------------------------------------- 2 --
bool Lot_MM()                            // Позовательская ф-ия
  {
   int time, ticket;                  // Наибольшее время открытия и номер ордера
   double orderLots;                  // Lots   
   double orderProfit;                // Profit
   double Price;                      // Цена открытия рыночного ордера
   double SL;                         // Значение StopLoss ордера
   double  TP;                        // Значение TakeProfit ордера
   string Symb   =Symbol();                    // Финансовый инструм.
   double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//Размер свободных средств, необходимых для открытия 1 лота
   double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// Мин. размер. лотов
   double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
   double Step   =MarketInfo(Symb,MODE_LOTSTEP);//Шаг изменен размера
   double Free   =AccountFreeMargin();         // Свободные средства
   double LotVal =MarketInfo(Symbol(),MODE_TICKVALUE);//стоимость 1 пункта для 1 лота
   

//--------------------------------------------------------------- 3 --
   if (Lots>0)                                 // Лоты заданы явно..
{                                              // ..проверим это
      double Money=Lots*One_Lot;               // Стоимость открываемого ордера   
      if(Money<=AccountFreeMargin())             // Средств хватает..     
         {  
          Lots_New=Lots;                           // ..принимаем заданное
            // else                                     // Если не хватает..
            // Lots_New=MathFloor(Free/One_Lot/Step)*Step;// Расчёт лотов 
            Print("Функция Lot_MM: Lots_New  = ", Lots_New);    
...
...
...
...
 // ---------НОРМАЛИЗУЕМ НОВЫЕ РАСЧЕТНЫЕ ЛОТЫ И ОТКРЫВАЕМ ОЧЕРЕДНУЮ ПОЗИЦИЮ...            
                    Lots_New = NormalizeLots(Lots_New);  
   return(true);                               // Выход из польз. ф-ии
  }
//--------------------------------------------------------------- 6 --

//+------------------------------------------------------------------+
//| Нормализация лота                                                |
//+------------------------------------------------------------------+

double NormalizeLots(double lot)
{
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   double lots = NormalizeDouble(lot / lotStep, 0) * lotStep;   
   lots = MathMax(lots, MarketInfo(Symbol(), MODE_MINLOT));
   lots = MathMin(lots, MarketInfo(Symbol(), MODE_MAXLOT));   
   return (lots);
}
 

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

 Print ("Функция открытия ордера с рынка - продажа: Teeth = ",  NormalizeDouble(Teeth,Digits), " upfractal = ", upfractal," Цена Bid = ", NormalizeDouble(Bid,Digits), " Lots_New = ", NormalizeDouble(Lots_New,2));                
Ticket=OrderSend(Symbol(),1,0.01,Bid,50,0,0,"Antiunity-start",Magic,0,Red);    

 
Techno:
При любом делении на переменную необходимо сперва проверять не равна ли она нулю.

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

Пока бесполезно... Пишет ту же ошибку...

 Print ("Функция открытия ордера с рынка - продажа: Teeth = ",  NormalizeDouble(Teeth,Digits), " upfractal = ", upfractal," Цена Bid = ", NormalizeDouble(Bid,Digits), " Lots_New = ", NormalizeDouble(Lots_New,2));                
          Ticket=OrderSend(Symbol(),1,Lots_New,Bid,50,0,0,"Antiunity-start",Magic,0,Red);            
          Print ("Функция открытия ордера с рынка - продажа: старт");      

На счёте в тестере 10 000, открывал позицию по золоту и 0,01 и 0,1 и 1 лотом - бесполезно.

Может кто сталкивался с подобным вопросом? Подскажите, плз...

 

Добавьте себе в пользовательские подпрограммы мою функцию проверки лота. И вызывайте её перед каждым OrderSend(). Округление в моей длл-ке делается по законам математики: если округляемое число заканчивается в дробной части цифрой >=5, то округляется в большую сторону. Ну и соответственно, <=4 округляется в меньшую сторону. Насколько я понял, в языках программирования с этим почему-то проблемы - пришлось ваять свою длл-ку. Вобщем-то код очень простой, но покопался в своё время в инете не мало, прежде чем нашёл оптимальное решение. Исходник dll-ки нужен?

// ============ ProverkaLota() =====================================================================
// функция принимает нормализует лот ордера
//-----------------------------------------------------
double ProverkaLota(double LotOrdera,string SMB){
  double SMB_MinLot=MarketInfo(SMB,MODE_MINLOT);
  double SMB_MaxLot=MarketInfo(SMB,MODE_MAXLOT);
  double SMB_LotStep=MarketInfo(SMB,MODE_LOTSTEP);
  LotOrdera=OkruglenieDoSotykh(LotOrdera);// округляем до сотых

 if(SMB_LotStep==0.1){// округляем до десятых
   LotOrdera/=10;
   LotOrdera=OkruglenieDoSotykh(LotOrdera);
   LotOrdera*=10;// возвращаем дробную часть ордера на место
 }
 if(LotOrdera<SMB_MinLot){
   LotOrdera=SMB_MinLot;
 }
 if(LotOrdera>SMB_MaxLot){
   LotOrdera=SMB_MaxLot;
 }
 return(LotOrdera);
}
// =================================================================================================
Файлы:
basic_dll_1.zip  190 kb
 
drknn:

Добавьте себе в пользовательские подпрограммы мою функцию проверки лота. И вызывайте её перед каждым OrderSend(). Округление в моей длл-ке делается по законам математики: если округляемое число заканчивается в дробной части цифрой >=5, то округляется в большую сторону. Ну и соответственно, <=4 округляется в меньшую сторону. Насколько я понял, в языках программирования с этим почему-то проблемы - пришлось ваять свою длл-ку. Вобщем-то код очень простой, но покопался в своё время в инете не мало, прежде чем нашёл оптимальное решение. Исходник dll-ки нужен?


Да. Спасибо.
Причина обращения: