Why does calculation result in ZERO

 

I just couldn't track an error down then found a very basic calculation not performing as expected - I've subsequently tried various combinations and reduced it to the following (comments / spacing removed).

Variables are read from a file which is created in Excel (then copied & pasted). I believe the 2 files to be almost identical except that the variable My_MaxLevels (passed through at the time of sub routine call) and others like Take_Profit would vary but not used here.

using <Test_Variables.mqh> the following is output to file

MaxLevels = 6 mcd1 = 32 H_Lot_Increase_PC = 25 H_Lot_Increase_PC / 100 = 0.00 <<<<<<<<<<<<<<<< should be .25 or 25% ..eventually leading to a Lot Increase of 8 i.e. 25% of 32

using different data

using <K9_Variables.mqh> the following is output to file

My_Log_for GBPCHF
MaxLevels = 3 mcd1 = 4 H_Lot_Increase_PC = 25 H_Lot_Increase_PC / 100 = 0.25 <<<<<<<<<<<<<<<< correct .25 or 25% ..eventually leading to a Lot Increase of 1 i.e. 25% of 4
#include <stdlib.mqh>
#include <stderror.mqh>
#include <WinUser32.mqh>
//#include <K9_Variables.mqh> 
#include <Test_Variables.mqh>                //  variables defined - this include must be included before the rest of 'own routines'
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{  My_Handle = FileOpen("Test_Get_H_Lots"+Symbol()+".txt", FILE_CSV|FILE_WRITE, '|'); 
   if (My_Handle > 0) FileWrite(My_Handle, "My_Log_for "+Symbol());
   H_Lot_Increase = Get_H_Lot_Increase(My_MaxLevels);    
   return(0);
}
int deinit() // expert deinitialization function    
{  FileClose(My_Handle);
   return(0);
}
int start() //| expert start function
{   return(0);
}
double Get_H_Lot_Increase(int MaxLevels)
   {  mcd1=1;
      double Lot_Increase = 0;
      for (int i1 = MaxLevels; i1 > 1; i1--) mcd1 = mcd1 * My_Multiplier;
      temp1 = H_Lot_Increase_PC / 100;
      string t1="MaxLevels = "+MaxLevels+" mcd1 = "+DoubleToStr(mcd1,0)+
         " H_Lot_Increase_PC  = "+DoubleToStr(H_Lot_Increase_PC,0)+" H_Lot_Increase_PC / 100 = "+DoubleToStr(temp1,2);
      FileWrite(My_Handle,t1);
      FileFlush(My_Handle);
      return(Lot_Increase);
   }

I can find a way round easily enough but just no idea what this problem may result from.

Any ideas / suggestions appreciated ?

 

Maybe I am missing what your issue is . . . but . . .

double Lot_Increase = 0;
    
      return(Lot_Increase);
 
RaptorUK:

Maybe I am missing what your issue is . . . but . . .

Sorry - tried to simplify the routine to it's simplest - I would calculate Lot_Increase but my multiplier ' H_Lot_Increase_PC / 100 = 0.00 ' fails to calculate with one example

H_Lot_Increase_PC / 100 = 0.00 - should always give a number > 0 if H_Lot_Increase_PC is > 0.

it is 25 in both cases one answer is .25 the other is zero

 
Where is H_Lot_Increase_PC defined ?
 
RaptorUK:
Where is H_Lot_Increase_PC defined ?

H_Lot_Increase_PC is defined in the 'variable' file loaded with the include statement.

K9_variables.mqh was the one I had been using then created a separate file Test_variables.mqh for this test.

I had 2 instances of MetaTrader running the full EA with different values for My_MaxLevels (i.e. 3 and 6 as shown above). After much error checking I found the error that I described above.

The code is part of the variable file. [although My_MaxLevels is defined as external I don't as rule change them at run time - I just did and got the expected result].

Must be doing something stupid - I think - just need to keep looking!

//+------------------------------------------------------------------+
//|                                                 K9_Variables.mqh |
//|                      Copyright © 2011, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
//+------------------------------------------------------------------------------------+
//|                       all Variables declared in this routine                       |
//+------------------------------------------------------------------------------------+

string         Data_Set = "901_K91";    //  0  description of data set used     My_Lots 0.01
extern double  My_Lots = 0.01;          //  0           
extern int     My_MaxLevels = 3;        //  0   My_MaxLevels    3
                
double         H_Lot_Increase;          //  6  used in Hedge to multiply lots           
double         H_Lot_Increase_PC = 25;  //  6  percentage used to calculate H_Lot_Increase


 
peterhw1:

Must be doing something stupid - I think - just need to keep looking!


Looks like some corrupted version of MetaTrader installation. I moved the EA and variables across to another installtion and all seems fine.

I'd also started to get an Error 64 Account disabled which suggested something a little more serious.

Thanks for any help - problem gone away !

.
 
peterhw1:

Looks like some corrupted version of MetaTrader installation. I moved the EA and variables across to another installtion and all seems fine.

I'd also started to get an Error 64 Account disabled which suggested something a little more serious.

Thanks for any help - problem gone away !

Looks like I spoke too soon - something really weird appears to be occurring.


This is an extract from a log:


10 mcd1 = 32.00000000 MaxLevels = 6 H_Lot_Increase_PC = 25

20 v1 = 0.00000 v1 = 0.00000 v2 = 0.00000 v3 = 0.00000 v4 = 0.00000

30 H_Lot_Increase = 0.00000000

60 H_Lot_Increase = 0.00000000


The code generating this is below:-


Just doesn't make any sense to me

void Get_H_Lot_Increase(int MaxLevels)
   {  mcd1=1;
      string Local_Test_Flag = "YES";
      for (int i1 = MaxLevels; i1 > 1; i1--) mcd1 = mcd1 * My_Multiplier;
      string t1 = "10 mcd1 = "+mcd1+" MaxLevels = "+MaxLevels+" H_Lot_Increase_PC = "+H_Lot_Increase_PC;
      FileWrite(My_Handle,t1);
      double v1 = H_Lot_Increase_PC / 100;   // eg 25 / 100 = 0.25
      double v2 = v1 * mcd1;                 // 0.25 x 32 = 8
      double v3 = v2 / 100;                  // 8 / 100 = 0.12 (12 microlot)
      double v4 = NormalizeDouble(v3,2);
      t1 = "20  v1 = "+DoubleToStr(v1,5)+" v1 = "+DoubleToStr(v2,5)+" v2 = "+DoubleToStr(v2,5)+" v3 = "+DoubleToStr(v3,5)+" v4 = "+DoubleToStr(v4,5);
      FileWrite(My_Handle,t1);
      H_Lot_Increase = NormalizeDouble((((H_Lot_Increase_PC / 100) * mcd1) / 100),2);
      FileWrite(My_Handle,"30 H_Lot_Increase = "+H_Lot_Increase);
      H_Lot_Increase = v4;
      FileWrite(My_Handle,"60 H_Lot_Increase = "+H_Lot_Increase);
      return(0);
   }
 
peterhw1:

just change H_Lot_Increase_PC from int to double and seems to have cured problem !


 

Humour me . . . try this . .

double v1 = H_Lot_Increase_PC / 100.0;   
 

Your code a few posts above says it's already a double . . .

double         H_Lot_Increase_PC = 25;  //  6  percentage used to calculate H_Lot_Increase
 
RaptorUK:

Your code a few posts above says it's already a double . . .

I've tried several alternatives just trying to understand what has happened.

Defining the integer (for the % age calculation) H_Lot_Increase_PC as a double appears to be doing what I want to do for the time being.

Your logic for 100.0 producing different results appears correct. See results and code below

Line below prints the variables 'as they come' i.e. double with 8 decimal points and integer with no decimal points ( successive extracts from the log file)

10 mcd1 = 32.00000000 H_Lot_Increase_PC = 25.00000000 MaxLevels = 6
20 v1 = 0.25000 v1 = 8.00000 v2 = 8.00000 v3 = 0.08000 v4 = 0.08000
30 H_Lot_Increase = 0.08000000
60 H_Lot_Increase = 0.08000000

I have now changed H_Lot_Increase to integer - seen by no decimal points and the results are the 'rubbish' incurred previously

10 mcd1 = 32.00000000 H_Lot_Increase_PC = 25 MaxLevels = 6
20 v1 = 0.00000 v1 = 0.00000 v2 = 0.00000 v3 = 0.00000 v4 = 0.00000
30 H_Lot_Increase = 0.00000000
60 H_Lot_Increase = 0.00000000

after change 1 with 100 replaced with 100.0

10 mcd1 = 32.00000000 H_Lot_Increase_PC = 25 MaxLevels = 6
20 v1 = 0.25000 v1 = 8.00000 v2 = 8.00000 v3 = 0.08000 v4 = 0.08000
30 H_Lot_Increase = 0.00000000 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< this should be 0.08
60 H_Lot_Increase = 0.08000000

change 2 seems redundant so did not make

change 3 puts decimal point after both occurrences of 100 and returns the required / expected results (H_Lot_Increase_PC remains an integer)

10 mcd1 = 32.00000000 H_Lot_Increase_PC = 25 MaxLevels = 6
20 v1 = 0.25000 v1 = 8.00000 v2 = 8.00000 v3 = 0.08000 v4 = 0.08000
30 H_Lot_Increase = 0.08000000 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< this is correct

60 H_Lot_Increase = 0.08000000

I have now returned to a routine providing a return value rather than void and now works fine.


Thanks very much for your help.

Should this type of problem be reported somewhere for a bug fix (I assume most folk would regard this as a bug)

//==================================Get_H_Lot_Increase START ==========================+
double Get_H_Lot_Increase(int MaxLevels)
   {  mcd1=1;
      double Lot_Increase = 0;
      for (int i1 = MaxLevels; i1 > 1; i1--) mcd1 = mcd1 * My_Multiplier;
      Lot_Increase = NormalizeDouble((((H_Lot_Increase_PC / 100.0) * mcd1) / 100.0),2); // ++++++++++++ change 3 with decimal point after 100 
      return(Lot_Increase);
   }
//==================================Get_H_Lot_Increase END ============================+


//==================================Get_H_Lot_Increase START ==========================+
void Get_H_Lot_Increase(int MaxLevels)
   {  mcd1=1;
      string Local_Test_Flag = "YES";
      //double Lot_Increase = 0;
      for (int i1 = MaxLevels; i1 > 1; i1--) mcd1 = mcd1 * My_Multiplier;
      string t1= "10 mcd1 = "+mcd1+" H_Lot_Increase_PC = "+H_Lot_Increase_PC+" MaxLevels = "+MaxLevels;
      FileWrite(My_Handle,t1);
      double v1 = H_Lot_Increase_PC / 100.0;    // 0.25 = 25 / 100               ++++++++++++ change 1 with decimal point after 100
      double v2 = v1 * mcd1;                    // 8 = 32 * 0.25     
      double v3 = v2 / 100;                     // 0.08 = 8 / 32 for microlots   ++++++++++++ change 2 with decimal point after 100
      double v4 = NormalizeDouble(v3,2);
      t1= "20  v1 = "+DoubleToStr(v1,5)+" v1 = "+DoubleToStr(v2,5)+" v2 = "+DoubleToStr(v2,5)+" v3 = "+DoubleToStr(v3,5)+" v4 = "+DoubleToStr(v4,5);
      FileWrite(My_Handle,t1);
      H_Lot_Increase = NormalizeDouble((((H_Lot_Increase_PC / 100.0) * mcd1) / 100.0),2); // ++++++++++++ change 3 with decimal point after 100
      FileWrite(My_Handle,"30 H_Lot_Increase = "+H_Lot_Increase);
      H_Lot_Increase = v4;
      FileWrite(My_Handle,"60 H_Lot_Increase = "+H_Lot_Increase);
      //temp1 = Lot_Increase;
      //if ( Local_Test_Flag == "YES" ) write_to_log(88888,""); 
      //return(Lot_Increase);
      return(0);
   }
//==================================Get_H_Lot_Increase END ============================+
Reason: