Small Moneymanagement-Indicator разрушен новым MQL4

 

Привет кодеры,

Я сделал небольшой индикатор Moneymanagement, который отлично работал для меня. Но после выхода нового MQL4 он вызывает проблемы, с которыми я не могу справиться.

Когда вы перетаскиваете этот индикатор на свой график, справа от него появляются цифры. Первое число означает Stoploss в пунктах, а второе - размер лота. В опциях вы можете выбрать риск. Другое число - это уровни Stoploss. Но когда я меняю валютную пару, цифры исчезают. Вместо них я вижу несколько раз слово "Label". И когда я смотрю на список индикаторов, мой индикатор также исчезает. В общем, после смены валютной пары индикатор исчез, а вместо цифр остались Label.

Я в полном замешательстве. Раньше этот индикатор работал без проблем. За помощь буду очень признателен.

Вот код:

#property indicator_chart_window
//--- input parameters
extern int  Risk=2;
extern int SL_Levels=20;
int multi, exp, SL, i, k;
double MoneyRisk, Spread, _modifySpread, lots;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      if (ObjectFind("SL"+i) == -1)
      {
         ObjectCreate("SL"+i, OBJ_LABEL, 0, 0, 0);
         ObjectSet("SL"+i, OBJPROP_CORNER, 1);
         ObjectSet("SL"+i, OBJPROP_XDISTANCE, 3);
         ObjectSet("SL"+i, OBJPROP_YDISTANCE, k);
         k=k+15;    
      }
   }
   if (ObjectFind("Spread") == -1)
   {
      ObjectCreate("Spread", OBJ_LABEL, 0, 0, 0);
      ObjectSet("Spread", OBJPROP_CORNER, 3);
      ObjectSet("Spread", OBJPROP_XDISTANCE, 3);
      ObjectSet("Spread", OBJPROP_YDISTANCE, 1);
   }
   
//-- 4 / 5 Digit Settings --
   multi   = 1;
   exp     = 0;
   if (Digits==5 || Digits==3)
   {
      _modifySpread = 0.1;
      multi=10;
      exp=1;
   }
//----
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   for(i=1; i<=SL_Levels; i++)
   {
      ObjectDelete("SL"+i);
   }
   ObjectDelete("Spread");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
   Spread     = MarketInfo(Symbol(), MODE_SPREAD)*_modifySpread;
   MoneyRisk  = AccountBalance()*Risk*0.01;
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
      ObjectSetText("SL"+i, SL+ " : "+DoubleToStr(lots, 2), 10, "Calibri", Red);
      k=k+15;
      SL = SL+MathFloor(((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1)/2);     
   }
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
   ObjectSetText("Spread", DoubleToStr(Spread,1), 10, "Calibri", Red);
   WindowRedraw();
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

во-первых, вы не можете использовать "exp" для int, это зарезервировано

во-вторых, вы выражаете "SL"

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);

в разделе init, плохая идея

потому что если вы получите ошибку 4066, то "SL" = 0

тогда вы получите нулевое деление на "lots"

lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);

и индикатор останавливается, и вам приходится перезагружать индикатор.

 
Я понимаю. Только что изменил переменную exp, но подскажите, как проверить или избежать ошибки 4066? Я читал, что это связано с тем, что MetaTrader обновляет только котировки текущего графика и таймфрейма. Но что бы вы посоветовали сделать, чтобы избежать 4066?
 

очевидно, что вы не можете избежать обновления ;-), но вы должны избежать ситуации "zero divide".

поэтому вы должны проверить, равна ли одна из переменных 0.... в случае избежания нулевого деления.

и поскольку вы не можете остановить индикатор, вы должны что-то придумать.

пример:

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
if (SL == 0) // because error 4066 (for example)
   {
   SL = Someting;
   }
lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
 

Вы правы... Я не могу избежать этого. :-)

Я имел в виду, могу ли я дождаться завершения обновления, прежде чем продолжить расчет SL? Проблема в том, что я не могу дать SL случайное значение, потому что тогда весь индикатор будет бесполезен. Поэтому я хотел бы проверить ошибку 4066 и, если она возникнет, подождать и снова проверить, прежде чем продолжать.

 

Кстати, у меня такая же проблема с этим индикатором. Но почему этой проблемы не было в "старом" MetaTrader? Здесь я всегда получаю ноль для ATR(5). ПОЧЕМУ?!!! Раньше такого не было... Я ненавижу этот новый MetaTrader...!

int start()
//----
  {
   double Spread = MarketInfo(Symbol(), MODE_SPREAD);
   double ATR = iATR(NULL, PERIOD_D1, 5, 0);
   int exp1 = 0;
   if (Digits==5 || Digits==3)
   {
      Spread=Spread*0.1;
      exp1 = 1;
   }
   Comment  (
            "ADR(5): ",DoubleToStr(ATR*MathPow(10,Digits-exp1),1),
            " || TODAY: ",(iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1),
            " || ", DoubleToStr(((iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1)/(ATR*MathPow(10,Digits-exp1))*100), 2), "%",
            "\n" +
            "SPREAD: ", Spread,
            " || RATIO: ",DoubleToStr((Spread/ATR)*MathPow(10,-(Digits-exp1-2)), 2),"%"
            );
//----
   return(0);
  }
 
Что вы имеете в виду под нулем? Я печатаю все комментарии и ATR(5) показывает результат больше нуля... выше 50 на самом деле...
 

Кажется, я нашел проблему! Это определенно проблема обновления. Когда я сейчас меняю валюту, индикатор работает. Но затем я открыл валютную пару, которую еще не открывал сегодня. Тогда я получил следующее сообщение:


Откройте пару, которую вы еще не открывали сегодня. Переключитесь на любой таймфрейм, кроме D1. Затем перетащите индикатор на свой график. Результатом будет ошибка, как указано выше. Мне кажется, что ATR(5) дневного графика некорректен из-за отсутствия ДНЕВНЫХ ДАННЫХ. Открытие "свежего" графика на таймфрейме D1 не вызывает никаких проблем. И когда вы переключаетесь на другой таймфрейм, все также в порядке, потому что ATR(5) корректен. Я заметил, что я могу переключаться на любую пару, пока я остаюсь на графике D1. Но переключение на другие пары в других таймфреймах, кроме D1, вызывает проблемы до тех пор, пока MetaTrader не получит ежедневные данные. Итак, мой вопрос теперь в том, как я могу получить ежедневные данные, чтобы мой ATR-расчет был правильным, когда я открываю новый график в таймфрейме, который не является D1?
 

Вы должны поместить что-то вроде

if(number==0)dothis; else dothis; 

в файле ShowSpread.mq4


Просто найдите строку, где происходит это деление на ноль.

 
mar:

Кажется, я нашел проблему! Это определенно проблема обновления. Когда я сейчас меняю валюту, индикатор работает. Но затем я открыл валютную пару, которую еще не открывал сегодня. Тогда я получил следующее сообщение:


Откройте пару, которую вы еще не открывали сегодня. Переключитесь на любой таймфрейм, который вам нравится, кроме D1. Затем перетащите индикатор на свой график. В результате вы получите ошибку, как описано выше. Мне кажется, что ATR(5) дневного графика некорректен из-за отсутствия ДНЕВНЫХ ДАННЫХ. Открытие "свежего" графика на таймфрейме D1 не вызывает никаких проблем. И когда вы переключаетесь на другой таймфрейм, все также нормально, потому что ATR(5) корректен. Я заметил, что я могу переключаться на любую пару, пока я остаюсь на графике D1. Но переключение на другие пары в других таймфреймах, кроме D1, вызывает проблемы, пока MetaTrader не получил дневные данные. Итак, мой вопрос заключается в том, как я могу получить ежедневные данные, чтобы мой ATR-расчет был правильным, когда я открываю новый график на таймфрейме, который не является D1?
qjol уже сказал вам, где проблема. Почему бы вам не последовать или хотя бы проверить то, что вам посоветовали люди, если вы просите о помощи?
 

angevoyageur, я думаю, вы не видели это сообщение от меня:

mar 2014.04.02 08:16 #

Вы правы... Я не могу избежать этого :-)

"Я имел в виду, могу ли я дождаться завершения обновления, прежде чем продолжить SL-расчет? Проблема в том, что я не могу дать SL случайное значение, потому что тогда весь индикатор будет бесполезен. Поэтому я хотел бы проверить наличие ошибки 4066, и если она возникнет, я хотел бы как-то подождать и снова проверить, прежде чем продолжать."

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