I recently changed the Money Management code I had been using, mainly because it couldn’t account for the profit accrued when stopping and restarting an algo.
Looking at the existing snippets I could find, I opted for a minor variation of one by Vonasi:
MM = 0 // 0 for optimization
if MM = 0 then
positionsize=0.4
ENDIF
if MM then
Capital = ????
MinSize = 0.2 // IG minimum position size allowed
MaxSize = 550 // IG tier 2 margin limit
ProfitAccrued = 0 // when restarting strategy, enter profit or loss to date
Equity = Capital + ProfitAccrued + StrategyProfit
PositionSize = Max(MinSize, Equity * (MinSize/Capital))
if positionsize > MaxSize then
positionsize = MaxSize
endif
PositionSize = Round(PositionSize*100)
PositionSize = PositionSize/100
ENDIF
This is a nice piece of code and it works well, but as you can see, positionsize is based on the relation between capital and MinSize.
MinSize is a given, so what to enter as a value for Capital? It can’t just be the amount you happen to have in your account, as that could be any arbitrary amount – 5000, 10000, 50000 – and that would be the starting point for any positionsize increase: a 10% increment would occur only after a gain of 500, a gain of 1000 or a gain of 5000.
So how to calculate a useful figure for working capital, as it’s the only variable here with which to alter the speed of increase/decrease ?
My first thought was to use a factor of the margin cost, eg minsize margin * 15 ???
But it could also be related to the value of the stoploss ??
Or the max historical drawdown ??
Any thoughts on this greatly appreciated…
Well… I can post the one I am using (nLots is the Number of Lots to be traded):
ONCE LotManagement = 1 //1=enable LOT size management
ONCE DD = 825 //825 DrawDown
ONCE DDmultiplier = 3.0 //3.0 DD multiplier
ONCE MyMargin = 0.5 //0.5% margin required by the broker
ONCE MyCapital = (DD * DDmultiplier) + (high * MyMargin / 100)
IF IntraDayBarIndex = 0 THEN
MyCapital = (DD * DDmultiplier) + (high * MyMargin / 100)
ENDIF
ONCE MinLots = 1
ONCE InitialSize = 1
ONCE nLots = InitialSize
IF LotManagement THEN
MyEquity = MyCapital + StrategyProfit
MyInvestment = MyEquity / MyCapital
TempLot = InitialSize * MyInvestment
TempLot = round((TempLot * 10) - 0.5) / 10
nLots = max(MinLots,TempLot)
ENDIF
It is based on the DrawDown (write at line 2 the DrawDown showed with LotManagement=0, disabled) with a multipliying factor (DDmultiplier), sort of leverage or risk aversion factor (I always use 3) AND the margin % required by the broker.
At line 7, each new day, the required Capital is updated (considering the fluctuation of price) to affect calculations.
Thanks Roberto, that looks interesting – basing it on DD makes sense.
The only bit I don’t get is
(high * MyMargin / 100)
what does this achieve?
Also, could i add
ProfitAccrued = 0 // when restarting strategy, enter profit or loss to date
IF LotManagement THEN
MyEquity = MyCapital + ProfitAccrued + StrategyProfit
Ok, so (high * MyMargin / 100) just removes the margin cost from your available funds – is that right?
another question: is StrategyProfit calculated in instrument currency or account currency?
The instruments I trade are either $ or € but my account is in GBP … so this would effect the margin calculation
Yes, it’s the margin calculation. I use HIGH, instead of CLOSE, to be more conservative.
Yes, you can either:
- use ProfitAccrued
- increase the InitialSize
STRATEGYPROFIT is in the currency of your account, while the margin is relative to the price of the instrument.
That’s a good point. We could change it to use an exchange rate. So if you trade Nikkei you could enter the GBP/JPY exchange rate. The drawback is that ProOrder won’t let you know what that rate is, so you will have to update it regularly (say each month).
Line 16 is to make sure there’s only 1 decimal. If you want to use 2, just replace 10 with 100, in both multiplication and division.
To use only integers replace 10 with 1 or simply remove both the multiplication and the division.
Out of interest, do you get 0.5% margin in Italy? I thought all of the EU was at 5% ?
My account is in Switzerland and the margin deposit is 0.5%
Sorry, STRATEGYPROFIT is returned according to the involved instrument.
This could be a solution (not tested):
ONCE LotManagement = 1 //1=enable LOT size management
ONCE DD = 825 //825 DrawDown
ONCE DDmultiplier = 3.0 //3.0 DD multiplier
ONCE MyMargin = 0.5 //0.5% margin required by the broker
ONCE ExchangeRate = 1
ONCE ProfitAccrued = 0 * ExchangeRate
ONCE MyCapital = ((DD * DDmultiplier) + (high * MyMargin / 100)) * ExchangeRate
IF IntraDayBarIndex = 0 THEN
MyCapital = ((DD * DDmultiplier) + (high * MyMargin / 100)) * ExchangeRate
ENDIF
ONCE MinLots = 1
ONCE InitialSize = 1
ONCE nLots = InitialSize
IF LotManagement THEN
MyEquity = MyCapital + ProfitAccrued + StrategyProfit
MyInvestment = MyEquity / MyCapital
TempLot = InitialSize * MyInvestment
TempLot = round((TempLot * 10) - 0.5) / 10
nLots = max(MinLots,TempLot)
ENDIF
I’m not sure lines 7 and 9 require ExchangeRate.
I will test it asap.
If you use the Max Drawdown from a backtest (without MM) then that figure will be in instrument currency, so yes I think lines 7 and 9 would need modification for ExchangeRate.
But ProfitAccrued would be in account currency, so I would leave it off there.
Also, if you were going to do a backtest with LotManagement = 1 (not for optimization but just out of curiosity) then you would need to add a limit for MaxSize, otherwise it can go up insanely high…
(high * Margin / 100) would be the margin value of 1 contract, no? … so wouldn’t a proper allowance for margin cost have to be
(nLots*(high * Margin / 100))
??
No, the calculation of lots is at lines 16-17.