Download MetaTrader 5
To add comments, please log in or register
Improve your rating. Execute orders in Freelance service!
whroeder1
14457
whroeder1 2016.11.29 21:24  
  1. Yes they use it heavily. All those were written when there were only currencies. Now there are metals and if tick size != point it is flat wrong.
  2. 02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
    The OP keeps printing out a double to 15 digits and can't understand why it is not 0.07 exactly. Because some number can't be represented exactly 1/8. can 1/10. can not.
Max Enrik
816
Max Enrik 2016.11.29 23:38  
honest_knave:
double LotCalculator(double lots)
  {
   ...
   return(NormalizeDouble(lots,2));
  }

This comment really help me a lot, and this is useful but that gives me more decimals.
( more decimals is normal - because I already read about it )

I still worry about 'NormalizeDouble' and I am looking for another way, which one it is better then 'NormalizeDouble'

Thanks!

Max Enrik
816
Max Enrik 2016.11.30 00:11  

Big thanks who were wrote comments.

@whroeder1 - I will widely research your comment (/ links) big thanks.
@Marco - I will use it after LotSize LotStep issue. Thanks!

honest_knave
Moderator
2149
honest_knave 2016.11.30 00:19  
Max Enrik:

This comment really help me a lot, and this is useful but that gives me more decimals.
( more decimals is normal - because I already read about it )

I still worry about 'NormalizeDouble' and I am looking for another way, which one it is better then 'NormalizeDouble'

Thanks!

Perhaps it would be best to establish exactly what you are seeking to achieve.

If you want a function to return a valid lot size for placing an order, you don't need to use NormalizeDouble(). My original code snippet or WHRoeder's will achieve that for you. There are subtle differences between them which will be a matter of personal preference.

But, if you do a straight Print() of that lot value you may get some "odd" results... like your 0.07000000000000001

This won't be a problem for OrderSend() but it may not be what you expect to see.

If you want to see the numbers displayed in a "normal" manner, you have 2 choices:

1. You can use NormalizeDouble() in the function. For a standard print out, the value will be as you expect it. But if you (manually) print enough decimal places, you will eventually see that the number is not exactly what you think it is. This is the point WHRoeder is trying to make (I think). This solution isn't the most elegant, but it is the simplest. Or...

2. You can leave the lot size as it is (i.e. not use NormalizeDouble) and then adjust the value for display purposes when needed. You could use DoubleToStr() or StringFormat() or printf() to achieve this, depending on what you need. This is a more flexible approach.

Remember that the actual value and how that value gets displayed do not have to be the same. You will never be able to store exactly 0.07:

   double myVal=0.07;
   printf("%.24f",myVal);

Result: 0.070000000000000006661338

But you can certainly display 0.07 if you need to. 
Max Enrik
816
Max Enrik 2016.11.30 00:29  
honest_knave:

Perhaps it would be best to establish exactly what you are seeking to achieve.
... 

Wow, nice to you wrote it, I almost understand like your comment.
So I will write new comment, soon.

//--- second times edited

As I mentioned I do not need LotSize and LotStep shows right just in display, I need LotSize and LotStep could shows same thing everywhere.
Just I worry about that.

Marco vd Heijden
Moderator
4680
Marco vd Heijden 2016.11.30 00:55  

Well if it's about dynamic lotsizing you can always plug in a simple gearbox.

//Gearbox//
double Lots;
Balance=AccountInfoDouble(ACCOUNT_BALANCE);

if(Balance>10000)
{Lots=10;Print(" Gear Two");}
if(Balance>100000)
{Lots=100;Print(" Gear Three");}
if(Balance>1000000)
{Lots=1000;Print(" Gear Four");}
if(Balance>10000000)
{Lots=10000;Print(" Gear Five");}

if(Balance<10000000)
{Lots=1000;Print(" Gear Four");}
if(Balance<1000000)
{Lots=100;Print(" Gear Three");}
if(Balance<100000)
{Lots=10;Print(" Gear Two");}
if(Balance<10000)
{Lots=1;Print(" Gear One");}
if(Balance>1000000000)
{Lots=0;}
Max Enrik
816
Max Enrik 2016.11.30 01:06  

I need to post part of my EA's with you, so I hope it will help you more clearly understand me.
So, I need to know is that good code or what?

Please give me good (clearly) advice or help, thanks in advance.

void OnChartEvent(const int      id     , // Event ID
                  const long   & lparam , // Parameter of type long event
                  const double & dparam , // Parameter of type double event
                  const string & sparam   // Parameter of type string events
                  )
{

    _lotCalc();
    //-------Process Button---------------------------------------------------------|
    if ( sparam == _btnLotMinus )
    {
        ObjectSetInteger( 0, _btnLotMinus, OBJPROP_STATE, false );
        _lotSize -= _lotStep;

        if ( NormalizeDouble( _lotSize, 2 ) <= 0 ) _lotSize = _lotMin;
        _calcUpdade( CALC_CHANGE_LOT );

        Print( " | Lot:   ", _lotSize );
        return;
    }   //---if Close
    //                          ...
}

double _lotCalc()
{
    //---
    _lotMin  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  );
    _lotMax  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  );
    _lotStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );

    //---
    return( NormalizeDouble( _lotSize, 2 ) );
}
honest_knave
Moderator
2149
honest_knave 2016.11.30 01:28  
Max Enrik:

I need to post part of my EA's with you, so I hope it will help you more clearly understand me.
So, I need to know is that good code or what?

Please give me good (clearly) advice or help, thanks in advance.

Late at night, uncompiled, untested.

We can't see where you first set _lotSize... remember you will need to make sure that _lotSize is always a multiple of _lotStep.

IMHO it would be better if you kept all your lot calculations together, rather than splitting them between OnChartEvent() and _lotCalc(). One function that checks min / max / step and does the increment / decrement.

 

void OnChartEvent(const int      id     , // Event ID
                  const long   & lparam , // Parameter of type long event
                  const double & dparam , // Parameter of type double event
                  const string & sparam   // Parameter of type string events
                  )
{
    _lotCalc();
    //-------Process Button---------------------------------------------------------|
    if ( sparam == _btnLotMinus )
    {
        ObjectSetInteger( 0, sparam, OBJPROP_STATE, false );
        _lotSize = fmax(_lotMin, _lotSize-_lotStep);
        _calcUpdade( CALC_CHANGE_LOT );
        printf( " | Lot: %.2f  ", _lotSize );
        return;
    }   //---if Close
    //                          ...
}

void _lotCalc()
{
    //---
    _lotMin  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  );
    _lotMax  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  );
    _lotStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );

    //---
}
Max Enrik
816
Max Enrik 2016.11.30 18:40  
honest_knave:

Late at night, uncompiled, untested.
We can't see where you first set _lotSize... remember you will need to make sure that _lotSize is always a multiple of _lotStep.
IMHO it would be better if you kept all your lot calculations together, rather than splitting them between OnChartEvent() and _lotCalc(). One function that checks min / max / step and does the increment / decrement.

That helped me a lot, that mean that solved my lotSize and losStep issues.
Huge thanks man.

#Lot 0 (zero) & (between solved Lot Size and Lot Step issue)- Closed

Max Enrik
816
Max Enrik 2016.11.30 21:35  

Yeah I forgot lotSize code, so I use it in init function.
Is it good place for _lotSize?

Thanks! 

int OnInit()
{
    _pip = Point;
    if( Digits == 0 || Digits == 2 || Digits == 3 || Digits == 5 ) _pip = 10 * Point;
    _lotSize = _lotValue * MarketInfo( Symbol(), MODE_MINLOT );

    //...
}
/ /1234567891011...36
To add comments, please log in or register