Calculate risk based lotsize

 

I have here a function which i find in this forum:

// Function to Determine Pip Point Value in Account Currency

        double dblPipValue( string strSymbol )
        {
                double dblCalcPipValue = MarketInfo( strSymbol, MODE_TICKVALUE );
                switch ( int(MarketInfo( strSymbol, MODE_DIGITS )) )
                {
                        case 3: dblCalcPipValue *= 1;
                        case 5:
                                dblCalcPipValue *= 10;
                                break;
                }
                
                return( dblCalcPipValue );
        }
        

// Calculate Lot Size based on Maximum Risk & Margin

        double dblLotsRisk( string strSymbol, double dblStopLossPips,
                double dblRiskMaxPercent, double dblMarginMaxPercent,
                double dblLotsMin, double dblLotsMax, double dblLotsStep )
        {
                double
                        dblValueAccount = MathMin( AccountEquity(), AccountBalance() )
                ,       dblValueRisk    = dblValueAccount * dblRiskMaxPercent / 100.0
                ,       dblValueMargin  = AccountFreeMargin() * dblMarginMaxPercent / 100.0
                ,       dblLossOrder    = dblStopLossPips * dblPipValue( strSymbol )
                ,       dblMarginOrder  = MarketInfo( strSymbol, MODE_MARGINREQUIRED )
                ,       dblCalcLotMin
                                = MathMax( dblLotsMin, MarketInfo( strSymbol, MODE_MINLOT ) )
                ,       dblCalcLotMax
                                = MathMin( dblLotsMax, MarketInfo( strSymbol, MODE_MAXLOT ) )
                ,       dblModeLotStep  = MarketInfo( strSymbol, MODE_LOTSTEP )
                ,       dblCalcLotStep  = MathCeil( dblLotsStep / dblModeLotStep ) * dblModeLotStep
                ,       dblCalcLotLoss
                                = MathFloor( dblValueRisk / dblLossOrder / dblCalcLotStep ) * dblCalcLotStep
                ,       dblCalcLotMargin
                                = MathFloor( dblValueMargin / dblMarginOrder / dblCalcLotStep ) * dblCalcLotStep
                ,       dblCalcLot = MathMin( dblCalcLotLoss, dblCalcLotMargin )
                ;
                
                if ( dblCalcLot < dblCalcLotMin ) dblCalcLot = dblCalcLotMin;
                if ( dblCalcLot > dblCalcLotMax ) dblCalcLot = dblCalcLotMax;

                return ( dblCalcLot );
        }

if i write some parameters to the function it gives me a lotsize based on a stoploss input parameter:

Alert(dblLotsRisk(Symbol(), 100, 1, 1000, MarketInfo(Symbol(),MODE_MINLOT), MarketInfo(Symbol(),MODE_MAXLOT), MarketInfo(Symbol(),MODE_LOTSTEP) ));

now the stoploss pips which you write int this function is based on pips, but i want to know how i can change it to use ticks and how to get the ticks values correctly, if you for example have a 100 pips stoploss then you write 100 for input parameter to the function and you get the right lotsize but if you have for example bitcoin chart then the number 100 is to smal and not like 100 pips and the functions gives you a to big lotsize, i want to know how i can change this, i want to give the function something like the distance of ticks from stoploss price and current entry price, this distance give to the function instead of pips and then the function give me the lotsize, how can i change this function to work like that?

 

You are looking for _Point . This will give you the smallest price fluctuation possible .

_Point

or

SymbolInfoDouble(_Symbol,SYMBOL_POINT);//you can add any symbol there instead of _Symbol (which is the equivalenvalent of Symbol())

Then you are interested in how much a point (or a tick) costs per lot 

bool get_tick_value_for_one_lot(string symbol,
                                ENUM_ORDER_TYPE type,
                                double &result){
//result will be in account currency !
  result=0.0;
  int errors=0;
  ResetLastError();
//first get the price 
  double price=0.0;
  if(type==ORDER_TYPE_BUY){//if you want to send a buy get the ask price
  price=(double)SymbolInfoDouble(symbol,SYMBOL_ASK);
  errors+=GetLastError();ResetLastError();
  }else if(type==ORDER_TYPE_SELL){//if you want to send a sell get the bid price
  price=(double)SymbolInfoDouble(symbol,SYMBOL_BID);
  errors+=GetLastError();ResetLastError();
  }else{errors=1;}
  //if no errors
  if(errors==0){
  //get the tick or point of the asset
  double point=(double)SymbolInfoDouble(symbol,SYMBOL_POINT);errors+=GetLastError();ResetLastError();
  double close_price=price;
  if(type==ORDER_TYPE_BUY){close_price=price+point;}//assume one tick or one point of profit
  else if(type==ORDER_TYPE_SELL){close_price=price-point;}
  if(errors==0){
  //calculate profit for one tick for one lot
  if(OrderCalcProfit(type,symbol,1.0,price,close_price,result)){
    return(true);
    }
  }
  }
return(false);                            
}

Then you have the tick (or point) value for one lot , and you know the stop loss in ticks (or points) . 

If you also know the $ you are willing to allocate to that stop loss (to those ticks) then you multiply the tick value for one lot with the ticks of the stop loss 

and that gives you the loss you would incur for one lot for that stop loss size in ticks (or points) . 

Then you divide the amount you are willing to lose by the loss for one lot and you get the lot size . 

 
Email Account:

I have here a function which i find in this forum:

if i write some parameters to the function it gives me a lotsize based on a stoploss input parameter:

now the stoploss pips which you write int this function is based on pips, but i want to know how i can change it to use ticks and how to get the ticks values correctly, if you for example have a 100 pips stoploss then you write 100 for input parameter to the function and you get the right lotsize but if you have for example bitcoin chart then the number 100 is to smal and not like 100 pips and the functions gives you a to big lotsize, i want to know how i can change this, i want to give the function something like the distance of ticks from stoploss price and current entry price, this distance give to the function instead of pips and then the function give me the lotsize, how can i change this function to work like that?

That is very old code of mine, and it has some flaws. Please don't use it directly.

Also, when you reference code found on the forum, please supply the link of where you found it.

 
Lorentzos Roussos #:
SymbolInfoDouble(_Symbol,SYMBOL_POINT);

thank you for your examples

 

I have here a simple Lotsize calculation example, it does work when i write for example Stoplos=100 then it means 100 pips stoplos and i get a correct lotsize, but i want to change this calculation to use the ATR Indcator value instead of pips stoploss. But now the ATR value is maybe just 0.001 which is also 100 Pips but in the current calculation the lotsize will be to big.

So i would like to have this calculation to work with ATR indicator stoploss value, how must i change the code to work with that?

double Stoplos=100;//iATR(Symbol(),PERIOD_D1,10,0);
   double Percent=1;
   double ticksize=MarketInfo(Symbol(),MODE_TICKVALUE)*10;
   double AllowLose=(AccountEquity()/100)*Percent;
   double Lotsize=NormalizeDouble((AllowLose/Stoplos)/ticksize,2);
   Alert("Chart "+Symbol()+" AllowLose: "+AllowLose+"  Stoplos: "+Stoplos+"  Lotsize: "+Lotsize);
 
Email Account #:

I have here a simple Lotsize calculation example, it does work when i write for example Stoplos=100 then it means 100 pips stoplos and i get a correct lotsize, but i want to change this calculation to use the ATR Indcator value instead of pips stoploss. But now the ATR value is maybe just 0.001 which is also 100 Pips but in the current calculation the lotsize will be to big.

So i would like to have this calculation to work with ATR indicator stoploss value, how must i change the code to work with that?

I think you should remove the x10 in the tickvalue 

and then get the atr and divide it by _Point in the stop loss .(and error checking of course)

double Stoplos=iATR(Symbol(),PERIOD_D1,10,1)/_Point;
   double Percent=1;
   double ticksize=MarketInfo(Symbol(),MODE_TICKVALUE);
   double AllowLose=(AccountEquity()/100)*Percent;
   double Lotsize=NormalizeDouble((AllowLose/Stoplos)/ticksize,2);
   Alert("Chart "+Symbol()+" AllowLose: "+AllowLose+"  Stoplos: "+Stoplos+"  Lotsize: "+Lotsize);
 
Lorentzos Roussos #:

I think you should remove the x10 in the tickvalue 

and then get the atr and divide it by _Point in the stop loss .(and error checking of course)

Thank you, it looks like your example works.