Position Sizing Calac... Need a little help

 
I'm building a Position Sizing calculator as a function based on the "Kelly Formula"

(Win Rate-((1-Win Rate)/(Avg Win/Avg Loss)

I've got the over all code and calculations working with manual inputs (extern) for the required variables and am now trying to get the function working dynamically by calling certain account information (namely I want to calculate the Winning consistency rate (%), the avg # pips per winning trade, and the avg # pips per lossing trade)

I could use any and all help getting the three functions (WinRate AvgWin & AvgLoss) operating. I have been using the manual input variation for months and it works great. Here is the complete code for this (automated) version to this point... in testing I am getting no dynamic output, everything goes back to the default setting (50, 40, 20). I have this set up as it's own EA for testing and easy modularization into any existing EA. once attached to any chart, the output is printed in the log/expert tab. the use of fractals is intentional so that maximum account growth (or minimal loss) is exploited. as a note most Brokers offering the MT trader platform allow fractal trading for either mini or std lots. This will prove use full in the future with money management that can take off partial lot positions (ie: remove 25% of 1 Lot). anyway...

in order to collect the real time account info I need I am trying to...
1. count all trades
2. count trades that are profitable
etc. etc.

I may or may not be going about this the right way.


Thanks in advance for all the help...
SeaWolf







//+------------------------------------------------------------------+
//| KellyFormula.mq4 |
//+------------------------------------------------------------------+
#property copyright "seawolf"
#property link "seawolf"
//+------------------------------------------------------------------+
//| EXTERNAL INFORMATION INPUT |
//+------------------------------------------------------------------+
extern int MyAccount = 1001; //------>>>> Account ID
extern int ExpertID = 500001; //------>>>> Magic Number for this EA

extern double PipValue= 1.00; //------>>>> use for ALL calc's
extern double LotCost= 50.0; //------>>>> use for ALL calc's
extern double PercentMax= 24.0; //------>>>> max % account leveraged @ one time
extern int TradesMax= 3; //------>>>> max simultaniouse trades (example: 24%/3 trades = 8% per trade)

extern bool UseKelly= true; //------>>>> Manual overide toggle
extern double ManualLots= 1.0; //------>>>> # lots if "UseKelly" is false
extern double mWinRate= 50.00; //------>>>> winning consistancy in % (manual overide)
extern int mAvgWin= 40; //------>>>> avg # pips per winning trade (manual overide)
extern int mAvgLoss= 20; //------>>>> avg # pips per lossing trade (manual overide)


//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----

PositionSize();
{
Print("Lots=",PositionSize()," WinRate=",WinRate()," AvgWin=",AvgWin()," AvgLoss=",AvgLoss());
}

Comment("Current Time is ",TimeToStr(TimeCurrent(),TIME_MINUTES)," GMT ",TimeToStr(TimeCurrent(),TIME_DATE)," ... Win Rate= ",WinRate()," Avg Win= ",AvgWin()," Avg Loss= ",AvgLoss());

//----
return(0);
}
//----
//+------------------------------------------------------------------+
//| CALCULATE POSITION SIZE FOR ALL NEW TRADES |
//+------------------------------------------------------------------+
//------------------------>>>>
double PositionSize()
{
//------------------------>>>> DO NOT USE KELLY FORMULA, USE FLAT RATE
if(UseKelly == true)
{
double KelyForm = WinRate()-((1-WinRate())/(AvgWin()/AvgLoss()));
double PerTrade;
double Lots;

if(KelyForm > PercentMax)
{
PerTrade = (PercentMax/10)/TradesMax;
}
else if(KelyForm < PercentMax)
{
PerTrade = (KelyForm/10)/TradesMax;
}
else if(KelyForm == PercentMax)
{
PerTrade = (KelyForm/10)/TradesMax;
}
Lots = (PerTrade * AccountBalance()/LotCost);
return(MathRound(Lots)/10);
}
}

//+------------------------------------------------------------------+
//| COLLECT REAL TIME ACCOUNT INFO |
//+------------------------------------------------------------------+
//------------------------>>>>
double WinRate()
{
double Ticket;
double CountWins = 0;

for(Ticket=0;Ticket<OrdersTotal();Ticket++)
{
OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
{
//------>>>>
if(OrderType()==OP_BUY)
{
if(OrderClosePrice() >= OrderOpenPrice())
CountWins++;
}
else if(OrderType()==OP_SELL)
{
if(OrderClosePrice() <= OrderOpenPrice())
CountWins++;
}
}
}
if(CountWins > 0)
return(MathRound(CountWins/OrdersHistoryTotal())*10);
else
Print("Real Time WinRate not Available");
return(mWinRate);
}
//------>>>>
//------------------------>>>>
double AvgWin()
{
double Ticket;
double CountTrades = 0;
double CountPips = 0;

for(Ticket=0;Ticket<OrdersTotal();Ticket++)
{
OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
{
//------>>>>
if(OrderType()==OP_BUY && OrderClosePrice()>=OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() >= 0)
CountPips++;
}
if(OrderType()==OP_SELL && OrderClosePrice()<=OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() >= 0)
CountPips++;
}
}
}
if(CountPips > 0)
return(MathRound(CountPips/CountTrades)*10);
else
Print("Real Time AvgWin not Available");
return(mAvgWin);
}

//------>>>>
//------------------------>>>>
double AvgLoss()
{
double Ticket;
double CountTrades = 0;
double CountPips = 0;

for(Ticket=0;Ticket<OrdersTotal();Ticket++)
{
OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
{
//------>>>>
if(OrderType()==OP_BUY && OrderClosePrice()<OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() < 0)
CountPips++;
}
if(OrderType()==OP_SELL && OrderClosePrice()>OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() < 0)
CountPips++;
}
}
}
if(CountPips > 0)
return(MathRound(CountPips/CountTrades)*10);
else
Print("Real Time AvgLoss not Available");
return(mAvgLoss);
}

//---------------------------------------------------------------------+
 

could you please enter your formatted code by using the SRC button on the input form.

unless of course your code is all left justified as above

thanks

if not know what I am on about go here please - How to insert MQL4 code into message

"I'm building a Position Sizing calculator as a function based on the "Kelly Formula" "

could you supply references detailing data which you are working with - that way help is on same wave length as you ;)

 

Here is a little info on the Kelly Formula...

http://en.wikipedia.org/wiki/Kelly_criterion



here is the code;

//+------------------------------------------------------------------+
//|                                                 KellyFormula.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Kevin"
#property link      " "
//+------------------------------------------------------------------+
//| EXTERNAL INFORMATION INPUT                                       |
//+------------------------------------------------------------------+
extern int     MyAccount   =     1001;    //------>>>>   Account ID
extern int     ExpertID    =   500001;    //------>>>>   Magic Number for this EA
 
extern double  PipValue=        1.00;     //------>>>>   use for ALL calc's
extern double  LotCost=         50.0;     //------>>>>   use for ALL calc's
extern double  PercentMax=      24.0;     //------>>>>   max % account leveraged @ one time
extern int     TradesMax=          3;     //------>>>>   max simultaniouse trades (example: 24%/3 trades = 8% per trade)
 
extern bool    UseKelly=        true;     //------>>>>   Manual overide toggle
extern double  ManualLots=       1.0;     //------>>>>   # lots if "UseKelly" is false
extern double  mWinRate=       50.00;     //------>>>>   winning consistancy in %     (manual overide)
extern int     mAvgWin=           40;     //------>>>>   avg # pips per winning trade (manual overide)
extern int     mAvgLoss=          20;     //------>>>>   avg # pips per lossing trade (manual overide)
 
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
//----
   return(0);
  }
int deinit()
  {
//----
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----
//------>>>> for testing
PositionSize();
{
   Print("Lots=",PositionSize()," WinRate=",WinRate()," AvgWin=",AvgWin()," AvgLoss=",AvgLoss());
}
 
Comment("Current Time is ",TimeToStr(TimeCurrent(),TIME_MINUTES)," GMT ",TimeToStr(TimeCurrent(),TIME_DATE)," ... Win Rate= ",WinRate(),"  Avg Win= ",AvgWin(),"  Avg Loss= ",AvgLoss());
 
//----
return(0);
}
//----
//+------------------------------------------------------------------+
//| CALCULATE POSITION SIZE FOR ALL NEW TRADES                       |
//+------------------------------------------------------------------+
//------------------------>>>> 
double PositionSize()
{
//------------------------>>>> DO NOT USE KELLY FORMULA, USE FLAT RATE
   if(UseKelly == true)
   {
      double   KelyForm    =  WinRate()-((1-WinRate())/(AvgWin()/AvgLoss()));
      double   PerTrade;
      double   Lots;
   
      if(KelyForm > PercentMax)
      {
         PerTrade = (PercentMax/10)/TradesMax;
      }
      else if(KelyForm < PercentMax)
      {
         PerTrade = (KelyForm/10)/TradesMax;
      }
      else if(KelyForm == PercentMax)
      {
         PerTrade = (KelyForm/10)/TradesMax;
      }   
      Lots = (PerTrade * AccountBalance()/LotCost);
      return(MathRound(Lots)/10); 
   } 
}
 
//+------------------------------------------------------------------+
//| COLLECT REAL TIME ACCOUNT INFO                                   |
//+------------------------------------------------------------------+
//------------------------>>>> 
double   WinRate()
{
   double   Ticket;
   double   CountWins    =  0;
    
   for(Ticket=0;Ticket<OrdersTotal();Ticket++)
   {
      OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
      if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
      {
//------>>>>
         if(OrderType()==OP_BUY)
         {
            if(OrderClosePrice() >= OrderOpenPrice())
            CountWins++;
         }
         else if(OrderType()==OP_SELL) 
         {
            if(OrderClosePrice() <= OrderOpenPrice())
            CountWins++;  
         }
      }        
   }
   if(CountWins > 0)
   return(MathRound(CountWins/OrdersHistoryTotal())*10);
   else 
   Print("Real Time WinRate not Available");
   return(mWinRate);
}
//------>>>>
//------------------------>>>> 
double   AvgWin()
{
   double   Ticket;
   double   CountTrades =  0;
   double   CountPips =  0;
    
   for(Ticket=0;Ticket<OrdersTotal();Ticket++)
   {
      OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
      if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
      {
//------>>>> 
         if(OrderType()==OP_BUY && OrderClosePrice()>=OrderOpenPrice())
         CountTrades++;
         {
            if(OrderProfit() >= 0)
            CountPips++;
         }
         if(OrderType()==OP_SELL && OrderClosePrice()<=OrderOpenPrice())
         CountTrades++;
         {
            if(OrderProfit() >= 0)
            CountPips++;
         }  
      }
   }
   if(CountPips > 0)
   return(MathRound(CountPips/CountTrades)*10);         
   else 
   Print("Real Time AvgWin not Available");
   return(mAvgWin);   
}
 
//------>>>>
//------------------------>>>> 
double   AvgLoss()
{
   double   Ticket;
   double   CountTrades =  0;
   double   CountPips =  0;
    
   for(Ticket=0;Ticket<OrdersTotal();Ticket++)
   {
      OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
      if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
      {
//------>>>>
         if(OrderType()==OP_BUY && OrderClosePrice()<OrderOpenPrice())
         CountTrades++;
         {
            if(OrderProfit() < 0)
            CountPips++;
         }
         if(OrderType()==OP_SELL && OrderClosePrice()>OrderOpenPrice())
         CountTrades++;
         {
            if(OrderProfit() < 0)
            CountPips++;
         }  
      }
   }
   if(CountPips > 0)
   return(MathRound(CountPips/CountTrades)*10);         
   else 
   Print("Real Time AvgLoss not Available");
   return(mAvgLoss);
}
 
//---------------------------------------------------------------------+
 

seawolf - vkind of you, man... total ease at reading code now, yes?

off to read wiki now - btw, great site wiki is it not?

back soon

;o)

like it... any Bell Systems Tech Journal is vInteresting to me.

 
ukt wrote >>

seawolf - vkind of you, man... total ease at reading code now, yes?

off to read wiki now - btw, great site wiki is it not?

back soon

;o)

like it... any Bell Systems Tech Journal is vInteresting to me.

Has there been any progress on this code

 
seawolf wrote >>
I'm building a Position Sizing calculator as a function based on the "Kelly Formula"

(Win Rate-((1-Win Rate)/(Avg Win/Avg Loss)

I've got the over all code and calculations working with manual inputs (extern) for the required variables and am now trying to get the function working dynamically by calling certain account information (namely I want to calculate the Winning consistency rate (%), the avg # pips per winning trade, and the avg # pips per lossing trade)

I could use any and all help getting the three functions (WinRate AvgWin & AvgLoss) operating. I have been using the manual input variation for months and it works great. Here is the complete code for this (automated) version to this point... in testing I am getting no dynamic output, everything goes back to the default setting (50, 40, 20). I have this set up as it's own EA for testing and easy modularization into any existing EA. once attached to any chart, the output is printed in the log/expert tab. the use of fractals is intentional so that maximum account growth (or minimal loss) is exploited. as a note most Brokers offering the MT trader platform allow fractal trading for either mini or std lots. This will prove use full in the future with money management that can take off partial lot positions (ie: remove 25% of 1 Lot). anyway...

in order to collect the real time account info I need I am trying to...
1. count all trades
2. count trades that are profitable
etc. etc.

I may or may not be going about this the right way.


Thanks in advance for all the help...
SeaWolf







//+------------------------------------------------------------------+
//| KellyFormula.mq4 |
//+------------------------------------------------------------------+
#property copyright "seawolf"
#property link "seawolf"
//+------------------------------------------------------------------+
//| EXTERNAL INFORMATION INPUT |
//+------------------------------------------------------------------+
extern int MyAccount = 1001; //------>>>> Account ID
extern int ExpertID = 500001; //------>>>> Magic Number for this EA

extern double PipValue= 1.00; //------>>>> use for ALL calc's
extern double LotCost= 50.0; //------>>>> use for ALL calc's
extern double PercentMax= 24.0; //------>>>> max % account leveraged @ one time
extern int TradesMax= 3; //------>>>> max simultaniouse trades (example: 24%/3 trades = 8% per trade)

extern bool UseKelly= true; //------>>>> Manual overide toggle
extern double ManualLots= 1.0; //------>>>> # lots if "UseKelly" is false
extern double mWinRate= 50.00; //------>>>> winning consistancy in % (manual overide)
extern int mAvgWin= 40; //------>>>> avg # pips per winning trade (manual overide)
extern int mAvgLoss= 20; //------>>>> avg # pips per lossing trade (manual overide)


//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----

PositionSize();
{
Print("Lots=",PositionSize()," WinRate=",WinRate()," AvgWin=",AvgWin()," AvgLoss=",AvgLoss());
}

Comment("Current Time is ",TimeToStr(TimeCurrent(),TIME_MINUTES)," GMT ",TimeToStr(TimeCurrent(),TIME_DATE)," ... Win Rate= ",WinRate()," Avg Win= ",AvgWin()," Avg Loss= ",AvgLoss());

//----
return(0);
}
//----
//+------------------------------------------------------------------+
//| CALCULATE POSITION SIZE FOR ALL NEW TRADES |
//+------------------------------------------------------------------+
//------------------------>>>>
double PositionSize()
{
//------------------------>>>> DO NOT USE KELLY FORMULA, USE FLAT RATE
if(UseKelly == true)
{
double KelyForm = WinRate()-((1-WinRate())/(AvgWin()/AvgLoss()));
double PerTrade;
double Lots;

if(KelyForm > PercentMax)
{
PerTrade = (PercentMax/10)/TradesMax;
}
else if(KelyForm < PercentMax)
{
PerTrade = (KelyForm/10)/TradesMax;
}
else if(KelyForm == PercentMax)
{
PerTrade = (KelyForm/10)/TradesMax;
}
Lots = (PerTrade * AccountBalance()/LotCost);
return(MathRound(Lots)/10);
}
}

//+------------------------------------------------------------------+
//| COLLECT REAL TIME ACCOUNT INFO |
//+------------------------------------------------------------------+
//------------------------>>>>
double WinRate()
{
double Ticket;
double CountWins = 0;

for(Ticket=0;Ticket<OrdersTotal();Ticket++)
{
OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
{
//------>>>>
if(OrderType()==OP_BUY)
{
if(OrderClosePrice() >= OrderOpenPrice())
CountWins++;
}
else if(OrderType()==OP_SELL)
{
if(OrderClosePrice() <= OrderOpenPrice())
CountWins++;
}
}
}
if(CountWins > 0)
return(MathRound(CountWins/OrdersHistoryTotal())*10);
else
Print("Real Time WinRate not Available");
return(mWinRate);
}
//------>>>>
//------------------------>>>>
double AvgWin()
{
double Ticket;
double CountTrades = 0;
double CountPips = 0;

for(Ticket=0;Ticket<OrdersTotal();Ticket++)
{
OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
{
//------>>>>
if(OrderType()==OP_BUY && OrderClosePrice()>=OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() >= 0)
CountPips++;
}
if(OrderType()==OP_SELL && OrderClosePrice()<=OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() >= 0)
CountPips++;
}
}
}
if(CountPips > 0)
return(MathRound(CountPips/CountTrades)*10);
else
Print("Real Time AvgWin not Available");
return(mAvgWin);
}

//------>>>>
//------------------------>>>>
double AvgLoss()
{
double Ticket;
double CountTrades = 0;
double CountPips = 0;

for(Ticket=0;Ticket<OrdersTotal();Ticket++)
{
OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);
if(MyAccount==AccountNumber() && OrderSymbol()==Symbol() && OrderMagicNumber() == ExpertID)
{
//------>>>>
if(OrderType()==OP_BUY && OrderClosePrice()<OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() < 0)
CountPips++;
}
if(OrderType()==OP_SELL && OrderClosePrice()>OrderOpenPrice())
CountTrades++;
{
if(OrderProfit() < 0)
CountPips++;
}
}
}
if(CountPips > 0)
return(MathRound(CountPips/CountTrades)*10);
else
Print("Real Time AvgLoss not Available");
return(mAvgLoss);
}

//---------------------------------------------------------------------+

has anyone managed to get this to run using live data

 

@kiwi



this code won't work... it has some problems.



for(Ticket=0;Ticket<OrdersTotal();Ticket++)
   {
      OrderSelect(Ticket,SELECT_BY_TICKET,MODE_HISTORY);

should be:

for(int Position=0;Position<OrdersHistoryTotal();Position++)
   {
      OrderSelect(Position,SELECT_BY_POS,MODE_HISTORY);


didn't look at the rest of the code.


Russell

 
Russell wrote >>

@kiwi



this code won't work... it has some problems.



should be:

didn't look at the rest of the code.

Russell

Thanks for that I have made the changes but still no luck with getting this to work.

 
nope... there are several errors.
Reason: