Normalize Volume to VolStep

 

Hello!

If I use this function

double NormVol(double vol)
  {

   return (MathFloor(vol/SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP))*
           SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP));
  }

and to normalize a double of 0.1294, it will result in 0.12 for a volume step of 0.01

If I use this function:

double NormalizeVolume2(double vol)
  {
   double lotstep=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   int lenght=StringLen(DoubleToString(lotstep))-8;
   double x=NormalizeDouble(vol,lenght);
   return x;
  }

For the same double  0.1294 and the same step of 0.01, it will result in 0.13, which is much closer to reality.

What do you guys think?

Thanks

 
double NormVol( const double Vol )
{
  static const double Step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
 
  return ((int)(Vol / Step + 0.5) * Step);
}
 
Daniel Cioca: If I use this function:

For the same double  0.1294 and the same step of 0.01, it will result in 0.13, which is much closer to reality.

What do you guys think?

The function fails if the Step is not a power of ten (e.g. 0.5 for DE30 ).

 
Daniel Cioca:

Hello!

If I use this function

and to normalize a double of 0.1294, it will result in 0.12 for a volume step of 0.01

If I use this function:

For the same double  0.1294 and the same step of 0.01, it will result in 0.13, which is much closer to reality.

What do you guys think?

Thanks

What reality ?

It's your choice, you can use the conservative value 0.12 (less risk with rounding down), or allow an increase in risk with a rounding up scheme (0.13).

EDIT: Funnily the automatic link (in green) to "rounding up" leads to MathFloor() which is doing the exact opposite (rounding down).

 
Thank you al! As William observed, it fails if step is not power of ten… so I have to think again … thanks 
 

Here is some of my own code to serve as an example. Use at your own discretion ...

// Calculation method for risk
   enum ERiskCalc {
      ERiskCalc_Moderate,     // Moderate calculation using "round"
      ERiskCalc_Conservative, // Conservative calculation using "floor"
      ERiskCalc_Aggressive    // Aggressive calculation using "ceiling"
   };

// Input for type of risk calculation method
   input ERiskCalc i_eRiskCalcMethod = ERiskCalc_Moderate;   // Risk calculation method

// Define macro for error status
   #define MReportError( _text )                   \
      PrintFormat( "Error %d: %s (%s,%d)",         \
         _LastError, _text, __FUNCTION__, __LINE__ )

// Function to normalise volume
   bool NormaliseVolume( const bool bValidMinimum, double &dbVolume ) {
      double dbVolumeStep = WRONG_VALUE;
      ResetLastError();
      if( SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP, dbVolumeStep ) && dbVolumeStep > DBL_EPSILON ) {
         dbVolume /= dbVolumeStep;
         switch( i_eRiskCalcMethod ) {
            case ERiskCalc_Conservative:  dbVolume = floor( dbVolume ); break;
            case ERiskCalc_Aggressive:    dbVolume = ceil(  dbVolume ); break;
            case ERiskCalc_Moderate:
            default:                      dbVolume = round( dbVolume );
         };
         dbVolume *= dbVolumeStep;
         double dbVolumeMax = WRONG_VALUE;
         ResetLastError();
         if( SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX, dbVolumeMax ) ) {
            if( dbVolumeMax > DBL_EPSILON ) dbVolume = fmin( dbVolume, dbVolumeMax );
            double dbVolumeMin = WRONG_VALUE;
            ResetLastError();
            if( SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN, dbVolumeMin ) ) {
               if( dbVolumeMin > DBL_EPSILON ) {
                  if( dbVolume < dbVolumeMin ) dbVolume = bValidMinimum ? dbVolumeMin : WRONG_VALUE;
               };
               return true;
            } else MReportError( "Unable to get volume minimum" );
         } else MReportError( "Unable to get volume maximum" );
      } else MReportError( "Unable to get volume step" );
      return false;
   };
 
Fernando Carreiro #:

Here is some of my own code to serve as an example. Use at your own discretion ...

Thank You!