having trouble converting double to int then back to double

 

ok some times it outputs something like 44.99999999 or 44.00000001 its like it has some small math error 

double m1_IRS = iRSI(NULL,1,14,PRICE_CLOSE,0);
      int temp1 = m1_IRS*100;
      m1_IRS = temp1*1;
      m1_IRS = m1_IRS/100;


and one other thing i added 2 more indicator buffers that show the high and the low for each candle but i want to be able to turn them off and on don't know how to do that in the code.


//+------------------------------------------------------------------+
//|                                                       rsibot.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+

//
int window_index=0;
int lastsec = TimeSeconds(TimeCurrent());
bool alarm_ultra_extreme = false;
bool alarm_extreme = false;
//#property copyright   
//#property link        
//#property description
extern color normal = clrLime;
extern color extreme = clrYellow; 
extern color ultra_extreme = clrRed;

extern int   extreme_high = 64;
extern int   extreme_low  = 36;
extern int   ultra_extreme_high = 68;
extern int   ultra_extreme_low  = 32;

extern bool  alarm_ultra_extreme_on_1m   = false;
extern bool  alarm_ultra_extreme_on_5m   = false;
extern bool  alarm_ultra_extreme_on_15m  = false;
extern bool  alarm_ultra_extreme_on_60m  = false;
extern bool  alarm_extreme_on_1m         = false;
extern bool  alarm_extreme_on_5m         = false;
extern bool  alarm_extreme_on_15m        = false;
extern bool  alarm_extreme_on_60m        = false;

bool  alarm_ultra_extreme_1m      = false;
bool  alarm_ultra_extreme_5m      = false;
bool  alarm_ultra_extreme_15m     = false;
bool  alarm_ultra_extreme_60m     = false;
bool  alarm_extreme_1m            = false;
bool  alarm_extreme_5m            = false;
bool  alarm_extreme_15m           = false;
bool  alarm_extreme_60m           = false;

#property strict

#property indicator_separate_window
#property indicator_minimum    0
#property indicator_maximum    100
////// changed from 1 to 3 
#property indicator_buffers    3
#property indicator_color1     DodgerBlue
#property indicator_level1     30.0
#property indicator_level2     70.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT
//--- input parameters
input int InpRSIPeriod=14; // RSI Period
//--- buffers
double ExtRSIBuffer[];
double ExtPosBuffer[];
double ExtNegBuffer[];
double ExtMaxBuffer[];
double ExtMinBuffer[];
double ExtPosMax;
double ExtNegMax;
double ExtPosMin;
double ExtNegMin;
bool playalarm = false;

color m1color = normal;
color m5color = normal;
color m15color = normal;
color m60color = normal;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   string short_name;
  
//--- 2 additional buffers are used for counting.
////// changed to 5 from 3 ////////////
   IndicatorBuffers(5);
   
   SetIndexBuffer(3,ExtPosBuffer);
   SetIndexBuffer(4,ExtNegBuffer);
   
//--- indicator line
   SetIndexStyle(0,DRAW_LINE);
   
///////////////////////////////////////////////   
   SetIndexStyle(1,DRAW_LINE,EMPTY,1,clrRed);
   SetIndexStyle(2,DRAW_LINE,EMPTY,1,clrGreen);
/////////////////////////////////////////////////
   
   SetIndexBuffer(0,ExtRSIBuffer);

////////////////////////////////////////////////   
   SetIndexBuffer(1,ExtMaxBuffer);
   SetIndexBuffer(2,ExtMinBuffer);
///////////////////////////////////////////////   

//--- name for DataWindow and indicator subwindow label
   short_name="RSI("+string(InpRSIPeriod)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
///////////////////////////////////////   
   //SetIndexLabel(3,"Max");
   //SetIndexLabel(4,"Min");
//--- check for input
   if(InpRSIPeriod<2)
     {
      Print("Incorrect value for input variable InpRSIPeriod = ",InpRSIPeriod);
      return(INIT_FAILED);
     }
//---
   SetIndexDrawBegin(0,InpRSIPeriod);
////////////////////////////////////////
   
   SetIndexDrawBegin(1,InpRSIPeriod);
   SetIndexDrawBegin(2,InpRSIPeriod);
   
    window_index=WindowFind(short_name);
    Print(window_index);
      if(window_index<0){window_index=0;}
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
  
  
  
   int    i,pos;
   double diff,max,min;
//---
   if(Bars<=InpRSIPeriod || InpRSIPeriod<2)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtRSIBuffer,false);
   ArraySetAsSeries(ExtPosBuffer,false);
   ArraySetAsSeries(ExtNegBuffer,false);
   ArraySetAsSeries(ExtMaxBuffer,false);
   ArraySetAsSeries(ExtMinBuffer,false);
   ArraySetAsSeries(close,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
//--- preliminary calculations
   pos=prev_calculated-1;
   if(pos<=InpRSIPeriod)
     {
      //--- first RSIPeriod values of the indicator are not calculated
      ExtRSIBuffer[0]=0.0;
      ExtPosBuffer[0]=0.0;
      ExtNegBuffer[0]=0.0;
      double sump=0.0;
      double sumn=0.0;
      for(i=1; i<=InpRSIPeriod; i++)
        {
        
         ExtMaxBuffer[i]=0.0;
         ExtMinBuffer[i]=0.0;
         ExtRSIBuffer[i]=0.0;
         ExtPosBuffer[i]=0.0;
         ExtNegBuffer[i]=0.0;
         diff=close[i]-close[i-1];
         if(diff>0)
            sump+=diff;
         else
            sumn-=diff;
        }
      //--- calculate first visible value
     
     
      ExtPosBuffer[InpRSIPeriod]=sump/InpRSIPeriod;
      ExtNegBuffer[InpRSIPeriod]=sumn/InpRSIPeriod;
      if(ExtNegBuffer[InpRSIPeriod]!=0.0){
         ExtRSIBuffer[InpRSIPeriod]=100.0-(100.0/(1.0+ExtPosBuffer[InpRSIPeriod]/ExtNegBuffer[InpRSIPeriod]));
         ExtMaxBuffer[InpRSIPeriod]=ExtRSIBuffer[InpRSIPeriod];
         ExtMinBuffer[InpRSIPeriod]=ExtRSIBuffer[InpRSIPeriod];
      }else
        {
         if(ExtPosBuffer[InpRSIPeriod]!=0.0){
            ExtRSIBuffer[InpRSIPeriod]=100.0;
            ExtMaxBuffer[InpRSIPeriod]=ExtRSIBuffer[InpRSIPeriod];
            ExtMinBuffer[InpRSIPeriod]=ExtRSIBuffer[InpRSIPeriod];
         }else
            ExtRSIBuffer[InpRSIPeriod]=50.0;
            ExtMaxBuffer[InpRSIPeriod]=ExtRSIBuffer[InpRSIPeriod];
            ExtMinBuffer[InpRSIPeriod]=ExtRSIBuffer[InpRSIPeriod];
        }
      //--- prepare the position value for main calculation
      pos=InpRSIPeriod+1;
     }
     
     
//--- the main loop of calculations
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
     
      
      diff=close[i]-close[i-1];
      max=high[i]-close[i-1];
      min=low[i]-close[i-1];
      
      ExtPosMax=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(max>0.0?max:0.0))/InpRSIPeriod;
      ExtNegMax=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(max<0.0?-max:0.0))/InpRSIPeriod;
      
      ExtPosMin=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(min>0.0?min:0.0))/InpRSIPeriod;
      ExtNegMin=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(min<0.0?-min:0.0))/InpRSIPeriod;
      
      ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(diff>0.0?diff:0.0))/InpRSIPeriod;
      ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(diff<0.0?-diff:0.0))/InpRSIPeriod;
      
      
      
      if(ExtNegMax!=0.0)
         ExtMinBuffer[i]=100.0-100.0/(1+ExtPosMin/ExtNegMin);
                   
      else
        {
         if(ExtMinBuffer[i]!=0.0)
            ExtMinBuffer[i]=100.0;
         else
            ExtMinBuffer[i]=50.0;
        }
      
      if(ExtNegMax!=0.0)
         ExtMaxBuffer[i]=100.0-100.0/(1+ExtPosMax/ExtNegMax);
                   
      else
        {
         if(ExtMaxBuffer[i]!=0.0)
            ExtMaxBuffer[i]=100.0;
         else
            ExtMaxBuffer[i]=50.0;
        }
     
      
      
      if(ExtNegBuffer[i]!=0.0)
         ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
          
      else
        {
         if(ExtPosBuffer[i]!=0.0)
            ExtRSIBuffer[i]=100.0;
         else
            ExtRSIBuffer[i]=50.0;
        }
     }
     
      double m5_IRS = iRSI(NULL,5,14,PRICE_CLOSE,0);
      int temp5 = m5_IRS*100;
      m5_IRS = temp5*1;
      m5_IRS = m5_IRS/100;
      if(m5_IRS > extreme_high || m5_IRS < extreme_low){
         
         if(m5_IRS > ultra_extreme_high || m5_IRS < ultra_extreme_low){
          
          // change color to ultra extreme  
            m5color = ultra_extreme;
          
          // turn off alarm for extreme  
            if(alarm_extreme_5m == true){
               alarm_extreme_5m = false;
            }
            
          // turn on alarm for ultra extreme   
            if(alarm_ultra_extreme_on_5m == true){
               
               alarm_ultra_extreme_5m = true;
            
            }
                      
            
         }else{
         // turn on alarm for extreme
            if(alarm_extreme_on_5m == true){
               alarm_extreme_5m = true;
            }
         // turn off alarm for uptra extreme
            if(alarm_ultra_extreme_5m == true){
               alarm_ultra_extreme_5m = false;
            }
         // change color to extreme 
            m5color = extreme;
         }
         
         
      }else{
         alarm_extreme_5m = false;
         alarm_ultra_extreme_5m = false;
         m5color = normal;
      }
     
      ObjectCreate("m_5",OBJ_LABEL,window_index,0,0);
      ObjectSetText("m_5","M5    "+m5_IRS,9,NULL,m5color);
      ObjectSet("m_5",OBJPROP_CORNER,0);
      ObjectSet("m_5",OBJPROP_XDISTANCE,10);
      ObjectSet("m_5",OBJPROP_YDISTANCE,50);
      
      double m15_IRS = iRSI(NULL,15,14,PRICE_CLOSE,0);
      int temp15 = m15_IRS*100;
      m15_IRS = temp15*1;
      m15_IRS = m15_IRS/100;
      if(m15_IRS > extreme_high || m15_IRS < extreme_low){
         
         if(m15_IRS > ultra_extreme_high || m15_IRS < ultra_extreme_low){
          
          // change color to ultra extreme  
            m15color = ultra_extreme;
          
          // turn off alarm for extreme  
            if(alarm_extreme_15m == true){
               alarm_extreme_15m = false;
            }
            
          // turn on alarm for ultra extreme   
            if(alarm_ultra_extreme_on_15m == true){
               
               alarm_ultra_extreme_15m = true;
            
            }
                      
            
         }else{
         // turn on alarm for extreme
            if(alarm_extreme_on_15m == true){
               alarm_extreme_15m = true;
            }
         // turn off alarm for uptra extreme
            if(alarm_ultra_extreme_15m == true){
               alarm_ultra_extreme_15m = false;
            }
         // change color to extreme 
            m15color = extreme;
         }
         
         
      }else{
         alarm_extreme_15m = false;
         alarm_ultra_extreme_15m = false;
         m15color = normal;
      }
      
      ObjectCreate("m_15",OBJ_LABEL,window_index,0,0);
      ObjectSetText("m_15","M15  "+m15_IRS,9,NULL,m15color);
      ObjectSet("m_15",OBJPROP_CORNER,0);
      ObjectSet("m_15",OBJPROP_XDISTANCE,10);
      ObjectSet("m_15",OBJPROP_YDISTANCE,35);
      
      double m60_IRS = iRSI(NULL,60,14,PRICE_CLOSE,0);
      int temp60 = (m60_IRS*100);
      m60_IRS = temp60*1;
      m60_IRS = (m60_IRS/100);
      if(m60_IRS > extreme_high || m60_IRS < extreme_low){
         
         if(m60_IRS > ultra_extreme_high || m60_IRS < ultra_extreme_low){
          
          // change color to ultra extreme  
            m60color = ultra_extreme;
          
          // turn off alarm for extreme  
            if(alarm_extreme_60m == true){
               alarm_extreme_60m = false;
            }
            
          // turn on alarm for ultra extreme   
            if(alarm_ultra_extreme_on_60m == true){
               
               alarm_ultra_extreme_60m = true;
            
            }
                      
            
         }else{
         // turn on alarm for extreme
            if(alarm_extreme_on_60m == true){
               alarm_extreme_60m = true;
            }
         // turn off alarm for uptra extreme
            if(alarm_ultra_extreme_60m == true){
               alarm_ultra_extreme_60m = false;
            }
         // change color to extreme 
            m60color = extreme;
         }
         
         
      }else{
         alarm_extreme_60m = false;
         alarm_ultra_extreme_60m = false;
         m60color = normal;
      }
      
      ObjectCreate("m_60",OBJ_LABEL,window_index,0,0);
      ObjectSetText("m_60","M60  "+m60_IRS,9,NULL,m60color);
      ObjectSet("m_60",OBJPROP_CORNER,0);
      ObjectSet("m_60",OBJPROP_XDISTANCE,10);
      ObjectSet("m_60",OBJPROP_YDISTANCE,20);
      
      double m1_IRS = iRSI(NULL,1,14,PRICE_CLOSE,0);
      int temp1 = m1_IRS*100;
      m1_IRS = temp1*1;
      m1_IRS = m1_IRS/100;
      if(m1_IRS > extreme_high || m1_IRS < extreme_low){
         
         if(m1_IRS > ultra_extreme_high || m1_IRS < ultra_extreme_low){
          
          // change color to ultra extreme  
            m1color = ultra_extreme;
          
          // turn off alarm for extreme  
            if(alarm_extreme_1m == true){
               alarm_extreme_1m = false;
            }
            
          // turn on alarm for ultra extreme   
            if(alarm_ultra_extreme_on_1m == true){
               
               alarm_ultra_extreme_1m = true;
            
            }
                      
            
         }else{
         // turn on alarm for extreme
            if(alarm_extreme_on_1m == true){
               alarm_extreme_1m = true;
            }
         // turn off alarm for uptra extreme
            if(alarm_ultra_extreme_1m == true){
               alarm_ultra_extreme_1m = false;
            }
         // change color to extreme 
            m1color = extreme;
         }
         
         
      }else{
         alarm_extreme_1m = false;
         alarm_ultra_extreme_1m = false;
         m1color = normal;
      }
      
      ObjectCreate("m_1",OBJ_LABEL,window_index,0,0);
      ObjectSetText("m_1","M1    "+m1_IRS,9,NULL,m1color);
      ObjectSet("m_1",OBJPROP_CORNER,0);
      ObjectSet("m_1",OBJPROP_XDISTANCE,10);
      ObjectSet("m_1",OBJPROP_YDISTANCE,65);
      
      if(lastsec>45){
     
      lastsec = TimeSeconds(TimeCurrent());
     
     }
     
     if((alarm_extreme_1m == true || alarm_extreme_5m == true || alarm_extreme_15m == true || alarm_extreme_60m == true 
     || alarm_ultra_extreme_1m == true || alarm_ultra_extreme_5m == true || alarm_ultra_extreme_15m == true || alarm_ultra_extreme_60m == true )
      && (lastsec <= (TimeSeconds(TimeCurrent())-10))){
       
       PlaySound("alert2.wav");
       Print(ExtRSIBuffer[(rates_total-1)]+" alert"+iRSI(NULL,0,14,PRICE_CLOSE,0) );
       lastsec = TimeSeconds(TimeCurrent());
     }
     
     
//---
   return(rates_total);
  }
//+------------------------------------------------------------------+


 

ok some times it outputs something like 44.99999999 or 44.00000001 its like it has some small math error

------------------

this is because the floating nuber issus ,and cannot be slove within mql.

but you can fix it by Point or by LotsStep.

for Price,fix it like this:

void OnStart()
  {
     double x=123.1234567891;
     Print("before: x=",x);
     x=(int)(x/Point)*Point; //or use MathRound()
     Print("after : x=",x);
   }
2018.11.07 01:12:12.739    testscript EURAUD,H4: 123.12345
2018.11.07 01:12:12.739    testscript EURAUD,H4: 123.1234567891



for lots,refer to  MarketInfo(xxx, MODE_LOTSTEP)

 
Feng Guozheng:

ok some times it outputs something like 44.99999999 or 44.00000001 its like it has some small math error

------------------

this is because the floating nuber issus ,and cannot be slove within mql.

but you can fix it by Point or by LotsStep.

for Price,fix it like this:

void OnStart()
  {
     double x=123.1234567891;
     Print("before: x=",x);
     x=(int)(x/Point)*Point; //or use MathRound()
     Print("after : x=",x);
   }
2018.11.07 01:12:12.739    testscript EURAUD,H4: 123.12345
2018.11.07 01:12:12.739    testscript EURAUD,H4: 123.1234567891



for lots,refer to  MarketInfo(xxx, MODE_LOTSTEP)


ok so like this then 

double m1_IRS = iRSI(NULL,1,14,PRICE_CLOSE,0);
      double temp1 = m1_IRS*100;
      m1_IRS = MathRound(temp1);
      m1_IRS = m1_IRS/100;
 
imjeffd:


ok so like this then 

you learn so fast haha
 
Feng Guozheng:
you learn so fast haha

yah the only thing is it don't work though

 
imjeffd:

yah the only thing is it don't work though

doesnt work well? why?
 
Feng Guozheng:
doesnt work well? why?

it dose the some thing even tried NormalizeDouble() it still did not work

 
imjeffd: it dose the some thing even tried NormalizeDouble() it still did not work

You are not being clear of what it is you describe as is not working or what you expect to "work". Plus you must remember the "doubles" or "floats" are not exact decimal numbers. Here is a pocket link from another thread that may help you understand that you can't always get an exact number:

Forum on trading, automated trading systems and testing trading strategies

MathRound fails for one particular number

Fernando Carreiro, 2018.01.01 22:08

He means that the value "0.69" cannot be exactly represented given the way a floating point number works (based on binary and not decimal representation) - hence, why the value gets represented as "0.68999999..." (see below).

You can never really "normalize" it and it is the main reason why both @whroeder1 and myself contest the use of the NormalizeDouble() function. It should in the very least be renamed to something like "RoundDigits()" because it is more of a "rounding" function and does not "normalize" in any way or fashion.


https://www.h-schmidt.net/FloatConverter/IEEE754.html

EDIT: Please note that the above images are for examples of representation in the 4-byte "float", and not the 8-byte "double" which offers more precision but still cannot represent the value "0.69" exactly due to the "binary" nature of the format.

EDIT2: For future readers that have difficulty understanding (or accepting) this concept, of decimal values not having an exact representation with a "float" or a "double", here is an article worth reading:

Why 0.1 Does Not Exist In Floating-Point

Many new programmers become aware of binary floating-point after seeing their programs give odd results: “Why does my program print 0.10000000000000001 when I enter 0.1?”; “Why does 0.3 + 0.6 = 0.89999999999999991?”; “Why does 6 * 0.1 not equal 0.6?” Questions like these are asked every day, on online forums like stackoverflow.com.

The answer is that most decimals have infinite representations in binary. Take 0.1 for example. It’s one of the simplest decimals you can think of, and yet it looks so complicated in binary:


Decimal 0.1 In Binary ( To 1369 Places

The bits go on forever; no matter how many of those bits you store in a computer, you will never end up with the binary equivalent of decimal 0.1.

... Read the rest of the article at: http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

 
void OnStart()
{
   //Double to int back to double based on the chart symbol's digits
   double double_bid = Bid;
   Print(DoubleToString(double_bid, _Digits)); 
   int int_bid = int(round(double_bid / _Point));
   Print(int_bid);
   double_bid = int_bid * _Point;
   Print(DoubleToString(double_bid, _Digits)); 
}
 
nicholi shen:

yah that still will not work though do to bit resilion but the DoubleToString() works should have thought of that sooner my bad 



if any one has a answer to my other question i tried not drawing the buffers but they still show up on the indicator 


SetIndexDrawBegin(1,InpRSIPeriod);
SetIndexDrawBegin(2,InpRSIPeriod);

right now i change the number of indicators to 1 so they don't show up

#property indicator_buffers    3
 

damn! such this problem i havd sloved ,

just by using the same code showed at the first post.

i know the issus about the float/double,why it is so difficult for you?