Calculate optimal lot size

Version 1
========== 
// setting parameter
input double MaximumRisk = 0.02; // Maximum Risk in percentage
input double DecreaseFactor = 3; // Descrease factor

//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
{
double price=1.0;
double margin=0.1;
//--- select lot size
if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price)) return(0.0);
if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin)) return(0.0);
if(margin<=0.0) return(0.0);

double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
if(DecreaseFactor>0)
{
//--- select history for access
HistorySelect(0,TimeCurrent());
//---
int orders=HistoryDealsTotal(); // total history deals
int losses=0; // number of losses orders without a break

for(int i=orders-1;i>=0;i--)
{
ulong ticket=HistoryDealGetTicket(i);
if(ticket==0)
{
Print("HistoryDealGetTicket failed, no trade history");
break;
}
//--- check symbol
if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol) continue;
//--- check profit
double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
if(profit>0.0) break;
if(profit<0.0) losses++;
}
//---
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//--- normalize and check limits
double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
lot=stepvol*NormalizeDouble(lot/stepvol,0);

double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
if(lot<minvol) lot=minvol;

double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
if(lot>maxvol) lot=maxvol;
//--- return trading volume
return(lot);
}

Version 2
==============

//+------------------------------------------------------------------+
//| Calculation of the lot |
//+------------------------------------------------------------------+
double Calculate_Lot(double lot_value,int type,ENUM_ORDER_TYPE direction)
//+------------------------------------------------------------------+
{
double acc_free_margin=AccountInfoDouble(ACCOUNT_FREEMARGIN);
double calc_margin;
double price=0;

if(direction == ORDER_TYPE_BUY) price = tick.ask;
if(direction == ORDER_TYPE_SELL) price = tick.bid;

switch(type)
{
case fixed:
{
//--- Correction of lot size
if(LOT_CORRECTION)
{
OrderCalcMargin(direction,_Symbol,lot_value,price,calc_margin);
//--- Lot size correction of up to 90% of free margin
if(acc_free_margin<calc_margin)
{
lot_value=lot_value*acc_free_margin*0.9/calc_margin;
printf("Adjusted value of the lot: %f",lot);
}
}
break;
}

case percent:
{
//--- value of free margin for open position
OrderCalcMargin(direction,_Symbol,1,price,calc_margin);
lot_value=acc_free_margin*0.01*LOT/calc_margin;
break;
}
}// end switch

return(NormalizeLot(lot_value));
}

//+------------------------------------------------------------------+
//| Normalization of the lot size |
//+------------------------------------------------------------------+
double NormalizeLot(double lot_value)
//+------------------------------------------------------------------+
{
double lot_min = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double lot_max = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double lot_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
int norm;

if(lot_value <= lot_min ) lot_value = lot_min; // checking for minimum lot
else if(lot_value >= lot_max ) lot_value = lot_max; // checking the maximum lot
else(lot_value = MathFloor(lot_value/ lot_step) * lot_step); // rounding to the nearest

norm=(int)NormalizeDouble(MathCeil(MathLog10(1/lot_step)),0);// coefficient for NormalizeDouble
return(NormalizeDouble(lot_value,norm)); // normalization
}
//+------------------------------------------------------------------+

No comments:

Post a Comment