Проблема с Zero divide

 

Я прочитал похожие темы, попытался решить проблему но не получается.

Вот код.

extern int   CloseHour     = 23;      // Время закрытия, часы
extern int   CloseMinute   = 1;      // Время закрытия, минуты
extern color clClose    = Yellow;   // 
extern double Lot = 0.1;

int tpbuy,tpsell,kbuy,ksell;
int ExpertBars;
int init()
{
ExpertBars = Bars;
return(0);
}
int start()
  {
  bool isNewBar=false;
if (ExpertBars !=Bars) {ExpertBars=Bars; isNewBar=true;}
if (isNewBar) {
  if(DayOfWeek()>1&&DayOfWeek()<6)
   {
   if(OrdersTotal()<1){
   double STOPLEVEL;
   /*Условие на покупку*/
   {
   //Расчет TP
   kbuy=NormalizeDouble((Close[1]-Low[1]),4)/NormalizeDouble((High[1]-Open[1]),4);
   tpbuy=NormalizeDouble((High[1]-Open[1]),4)*NormalizeDouble(kbuy,2);
    STOPLEVEL=MarketInfo("GBPUSD",MODE_STOPLEVEL);
   if(STOPLEVEL<NormalizeDouble(tpbuy,0)){
   OrderSend(Symbol(),OP_BUY,Lot,NormalizeDouble(Ask,Digits),0,0,Ask+NormalizeDouble(tpbuy,0)*Point,"",0,0,Blue);}}
   /*Условие на продажу*/
   {
  //Расчет TP
   ksell=NormalizeDouble((High[1]-Open[1]),4)/NormalizeDouble((Close[1]-Low[1]),4);
   tpsell=NormalizeDouble((Close[1]-Low[1]),4)*NormalizeDouble(ksell,2);
   STOPLEVEL=MarketInfo("GBPUSD",MODE_STOPLEVEL);
    if(STOPLEVEL<NormalizeDouble(tpsell,0)){
   OrderSend(Symbol(),OP_SELL,Lot,NormalizeDouble(Bid,Digits),0,0,Bid-NormalizeDouble(tpsell,0)*Point,"",0,0,Red);}}
   }
   double pBid, pAsk;
   if(Hour()==CloseHour && Minute()>=CloseMinute) {
    for (int i=OrdersTotal()-1; i>=0; i--) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
       
          if (OrderType()==OP_BUY) {
            pBid=MarketInfo(OrderSymbol(), MODE_BID);
            OrderClose(OrderTicket(), OrderLots(), pBid, 0, clClose);
          }
          if (OrderType()==OP_SELL) {
            pAsk=MarketInfo(OrderSymbol(), MODE_ASK);
            OrderClose(OrderTicket(), OrderLots(), pAsk, 0, clClose);}
            }}}}}
   return(0);
  }
 

Например High[1] может быть вполне равно Open[1] (1-й бар без нижней тени) и тогда Ваша конструкция

kbuy=NormalizeDouble((Close[1]-Low[1]),4)/NormalizeDouble((High[1]-Open[1]),4);

выдаст ошибку ZeroDivide. То же самое и следующая (1-й бар без верхней тени):

ksell=NormalizeDouble((High[1]-Open[1]),4)/NormalizeDouble((Close[1]-Low[1]),4);
 
goldtrader:

Например High[1] может быть вполне равно Open[1] (1-й бар без нижней тени) и тогда Ваша конструкция

выдаст ошибку ZeroDivide. То же самое и следующая (1-й бар без верхней тени):


Я добавил изменения но ошибка не исчезла, буду рад любым предложениям.
extern int   CloseHour     = 23;      // Время закрытия, часы
extern int   CloseMinute   = 1;      // Время закрытия, минуты
extern color clClose    = Yellow;   // 
extern double Lot = 0.1;

int tpbuy,tpsell,kbuy,ksell;
int ExpertBars;
int init()
{
ExpertBars = Bars;
return(0);
}
int start()
  {
  bool isNewBar=false;
if (ExpertBars !=Bars) {ExpertBars=Bars; isNewBar=true;}
if (isNewBar) {
  if(DayOfWeek()>1&&DayOfWeek()<6)
   {
   if(OrdersTotal()<1){
   double STOPLEVEL;
   //Buy
   
   /*Условие на покупку*/
   {
   //Расчет TP
   if(High[1]!=Open[1]&&Close[1]!=Low[1]){
   kbuy=NormalizeDouble((Close[1]-Low[1]),4)/NormalizeDouble((High[1]-Open[1]),4);
   tpbuy=NormalizeDouble((High[1]-Open[1]),4)*NormalizeDouble(kbuy,2);
    STOPLEVEL=MarketInfo("GBPUSD",MODE_STOPLEVEL);
   if(STOPLEVEL<NormalizeDouble(tpbuy,0)){
   OrderSend(Symbol(),OP_BUY,Lot,NormalizeDouble(Ask,Digits),0,0,Ask+NormalizeDouble(tpbuy,0),"",0,0,Blue);}}}
   
   /*Условие на продажу*/
   {
  //Расчет TP
  if(High[1]!=Open[1]&&Close[1]!=Low[1]){
   ksell=NormalizeDouble((High[1]-Open[1]),4)/NormalizeDouble((Close[1]-Low[1]),4);
   tpsell=NormalizeDouble((Close[1]-Low[1]),4)*NormalizeDouble(ksell,2);
   STOPLEVEL=MarketInfo("GBPUSD",MODE_STOPLEVEL);
    if(STOPLEVEL<NormalizeDouble(tpsell,0)){
   OrderSend(Symbol(),OP_SELL,Lot,NormalizeDouble(Bid,Digits),0,0,Bid-NormalizeDouble(tpsell,0),"",0,0,Red);}}}
   }
   double pBid, pAsk;
   if(Hour()==CloseHour && Minute()>=CloseMinute) {
    for (int i=OrdersTotal()-1; i>=0; i--) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
       
          if (OrderType()==OP_BUY) {
            pBid=MarketInfo(OrderSymbol(), MODE_BID);
            OrderClose(OrderTicket(), OrderLots(), pBid, 0, clClose);
          }
          if (OrderType()==OP_SELL) {
            pAsk=MarketInfo(OrderSymbol(), MODE_ASK);
            OrderClose(OrderTicket(), OrderLots(), pAsk, 0, clClose);}
            }}}}}
   return(0);
  }
 
oyshen:
Я добавил изменения но ошибка не исчезла, буду рад любым предложениям.


Сколько знаков в цене инструмента?
 

Из своего скромного опыта рискну предположить, что ошибка эта появляется только по причине вот этой строки

kbuy=NormalizeDouble((Close[1]-Low[1]),4)/NormalizeDouble((High[1]-Open[1]),4);

либо её аналога для селл-позиции.

Не более того.

Попобуйте задать (переписать)  эти "выражения"  как-нить иначе. Без действия деления. 

Или уберите их совсем.  Задайте ksell и kbuy без привязки к ценам. Константой.

И посмотрите, - будет ли ошибка? 

 

У Вас ноль может получиться как раз в результате нормализации.

Я бы делал как-то так

 double res = NormalizeDouble((High[1]-Open[1]),4);
 if (res != 0.0) kbuy=NormalizeDouble((Close[1]-Low[1]),4)/res;
 

мне кажется выражение:


 if (res != 0.0)

не совсем правильное

ибо в МКЛ4 выражение 0 и 0.0 и 0.0000 абсолютно разные :-) при проверке некоторых индикаторах я пришел к такому выводу.

 
oyshen:
Я добавил изменения но ошибка не исчезла, буду рад любым предложениям.


double NormalizeDouble( double value, int digits)

Округление числа с плавающей запятой до указанной точности.

Поэтому сравнение

//Расчет TP
   if(High[1]!=Open[1]&&Close[1]!=Low[1])

не спасает от деления на ноль в пятизнаке конструкцию

   kbuy=NormalizeDouble((Close[1]-Low[1]),4)/NormalizeDouble((High[1]-Open[1]),4);
Я обычно использую высоту в пунктах. Если автора устроит, то эту конструкцию можно записать без всяких NormalizeDouble

   kbuy=(Close[1]-Low[1]+Point)/(High[1]-Open[1]+Point);
C ksell, аналогично
 
Vladon:

мне кажется выражение:

не совсем правильное

ибо в МКЛ4 выражение 0 и 0.0 и 0.0000 абсолютно разные :-) при проверке некоторых индикаторах я пришел к такому выводу.

Неправильным выражение можно назвать только тогда, когда оно не обеспечивает нужный результат. В данном случае страховку от ошибки zero divide То есть я думаю, что оно правильное.

Другая сторона - насколько оно оптимально. У нас здесь res имеет тип double. Я предполагаю, что при сравненни с 0 (тип int) сначала будет сделано приведение типов, то есть 0 будет превращён в 0.0 . То есть сравнивая double с int вы неявно закладываете в код лишнюю операцию. Впрочем это лишь моё предположение. Не желаете проверить?

 

Код сам по себе очень сырой и еще долго не будет работать.

Что это - if(STOPLEVEL<NormalizeDouble(tpbuy,0)) ?

Почему проскальзывание нулевое? 

 
leonid553:

Задайте ksell и kbuy без привязки к ценам. Константой.

И посмотрите, - будет ли ошибка?


Задать константой нельзя, так как они для каждой сделки будут свои.

P.S. Дважды в одну и тужу воду не войдешь...

Причина обращения: