Following on from a conversation about how to know when to stop an auto-trading strategy in another thread:
https://www.prorealcode.com/topic/when-to-stop-a-live-automated-system/
I decided to try and code something that could automate the whole idea. I also decided to add in some simple money management too. The code below can be added to a strategy and then ‘positionsize’ used for the number of contracts in any buy or sellshort order.
The code works by checking every so many bars how the strategy is performing. It can check the following:
- The win rate (after a minimum number of trades have happened) and then stop the strategy if the win rate is below a minimum desired win rate.
- The draw down. If equity has dropped by a set percentage or more from the maximum profit ever achieved then the strategy is stopped.
- The remaining capital. If the starting capital is reduced by a maximum allowed percentage then the strategy is stopped.
- The percentage profit increase or decrease since the last position size adjustment. If the equity has risen or dropped by the set percentage or more then position size is increased or reduced to stay the same percentage of equity as it was percentage of capital when the strategy was first started.
If using it then you have to be aware that decisions to quit or alter position size are only made on closed trades and only on every ‘barsbeforenextcheck’ bar and so a big losing trade still open is not taken into consideration and a bad losing run between checks can still wipe you out just before the strategy stops itself.
Levels should be set based on your back test performance. For example if your strategy has a win rate of 60% then you might consider having it stop if win rate is halved at 30% as it is most likely under performing and you need to re-optimise it or just decide that it was over fitted and bin it.
Hopefully this code is of use to someone.
// Strategy Stopper and Money Management
// By Vonasi
// 20191011
barsbeforenextcheck = 22 // number of bars between performance checks
drawdownquitting = 1 // drawdown quitting on or off (on=1 off=0)
winratequit = 25 // minimum win rate allowed before quitting (0 = off)
tradesbeforewrquit = 10 // number of trades required before a win rate stop of strategy is allowed to happen
increase = 1 // position size increasing on or off (on=1 off=0)
decrease = 1 // position size decreasing on or off (on=1 off=0)
capital = 10000 // starting capital
startingsize = 1 // starting position size
minpossize = 0.2 // minimum position size allowed
gaintoinc = 5 // % profit rise needed before an increase in position size is made
losstodec = 5 // % loss needed before a decrease in position size is made
maxdrawdown = 25 // maximum % draw down allowed from highest ever equity before stopping strategy
maxcapitaldrop = 60 // maximum % starting capital lost before stopping strategy
once positionsize = startingsize
once psperc = positionsize / capital
if strategyprofit <> strategyprofit[1] then
highestprofit = max(strategyprofit, highestprofit)
if winratequit then
count = count + 1
if strategyprofit > strategyprofit[1] then
win = win + 1
endif
winrate = win/count
if count >= tradesbeforewrquit then
if winrate < winratequit/100 then
quit
endif
endif
endif
endif
if barindex mod barsbeforenextcheck = 0 then
if drawdownquitting then
if highestprofit <> 0 then
if (capital + strategyprofit) <= (capital + highestprofit) - ((capital + highestprofit)*(maxdrawdown/100)) then
quit
endif
endif
if highestprofit = 0 then
if (capital + strategyprofit) <= capital - (capital * (maxcapitaldrop/100)) then
quit
endif
endif
endif
equity = capital + strategyprofit
if increase then
if equity/lastequity >= (1+(gaintoinc/100)) then
positionsize = (max(minpossize,equity*psperc))
lastequity = equity
endif
endif
if decrease then
if equity/lastequity <= (1-(losstodec/100)) then
positionsize = (max(minpossize,equity*psperc))
lastequity = equity
endif
endif
endif
Thanks for the great money management and auto stop strategy snippet. Simple but powerful at the same time.
I also forgot to ask Vonasi, shouldn’t the last if clause on position size be minimum instead of maximum.
if decrease then
if equity/lastequity <= (1-(losstodec/100)) then
positionsize = (MIN(minpossize,equity*psperc))
lastequity = equity
No. It is correct as it is. That line is to ensure that an order is never sent to market and then rejected because it is below the minimum order size allowed for the market.
Set minpossize to whatever your broker allows as the smallest bet size for the instrument that you are trading.
LinkParticipant
Senior
With the Vonasi code. Reconfigure only so, if the average winning trades falls below 75% (example), the following trades are performed at half € pip than the last trade that was above 75% of the average winning trades. And if the average number of winning trades is above 75% again from now on, operate again at the usual € pip. And the same for if the drawdown is higher than 25%. Please!
Serve as an example: The following code is used to operate at half € pip if the maxprofit is less than the maximum.
ELEVEN MaxProfit = 0
MaxProfit = max (MaxProfit, StrategyProfit)
If MaxProfit> StrategyProfit Then
Positionsize = max (1, Positionsize / 2)
ENDIF
LinkParticipant
Senior
That is, I do not want the system to shut down with the “quit” function, but what is specified in the previous post
Firstly you have to tally all trades
Secondly you have to tally winning trades
Thirdly you have to make a percentage of winning trades
Finally you write the instructions to accomplish to get to your goal.
There you go (it won’t be accurate if accumulating positions):
DEFPARAM CumulateOrders = false
ONCE AllTrades = 0
ONCE WinningTrades = 0
ONCE InitialLots = 2
ONCE LotSize = InitialLots
MyGain = StrategyProfit
// tally each trade
t1 = OnMarket AND Not OnMarket[1] //it's a new trade
t2 = Not OnMarket AND Not OnMarket[1] AND MyGain <> MyGain[1] //detect any 1-bar trade
t3 = ShortOnMarket AND LongOnMarket[1] //it's a new trade (S & R)
t4 = ShortOnMarket[1] AND LongOnMarket //it's a new trade (S & R)
AllTrades = AllTrades + ((t1 OR t2 OR t3 OR t4) AND IsLastBarUpdate)
// tally winning trades
IF MyGain > MyGain[1] THEN
WinningTrades = WinningTrades + 1
ENDIF
// calculate % of winning trades
IF AllTrades > 0 THEN
WinPerCent = WinningTrades * 100 / AllTrades
IF WinPerCent < 75 THEN
LotSize = InitialLots * 0.5 //halve lotsize
ELSE
LotSize = InitialLots //restore initial lotsize
ENDIF
ENDIF
IF MyLongConditions THEN
BUY LotSize CONTRACTS AT Market
ELSIF MyShortConditions THEN
SELLSHORT LotSize CONTRACTS AT Market
ENDIF
LinkParticipant
Senior
Ok Roberto, thanks.
And if I have a drawdown of 25%???
What do you want to do in that case?
There you go:
DEFPARAM CumulateOrders = false
DEFPARAM PreLoadBars = 0
ONCE InitialLots = 2
ONCE LotSize = InitialLots
ONCE MaxPoint = 0
ONCE MaxDD = 0
ONCE Capital = 10000
ONCE p = 20
IF BarIndex > p THEN
Equity = Capital + StrategyProfit
MaxPoint = max(MaxPoint,Equity)
DD = MaxPoint - Equity
DDPerCent = DD / MaxPoint * 100
MaxDD = max(MaxDD,DD)
MaxDDPerCent = MaxDD / MaxPoint * 100
Avg = average[p,0](close)
IF DDPerCent > 25 THEN
LotSize = InitialLots * 0.5 //halve lotsize
ELSE
LotSize = InitialLots //restore initial lotsize
ENDIF
IF close CROSSES OVER Avg THEN
buy LotSize CONTRACTS at Market
ELSIF close CROSSES UNDER Avg THEN
SELLSHORT LotSize CONTRACTS AT Market
ENDIF
set target pprofit 100
set stop ploss 150
ENDIF
graph DDPerCent
graph LotSize coloured(255,0,0,255)
LinkParticipant
Senior
Good Code Roberto!
But i use only lines 10 to 15.
Thanks!
LinkParticipant
Senior
ok … a new question.
How would it be if, depending on the% drawdown, I wanted to trade with fractions of position.
That is, if there is no drawdown I operate with € 10 pip …
If the drawdown does not exceed 10% I will operate at € 10 pip.
If the drawdown is between 10%, 30% will operate with € 5 pip.
If the drawdown exceeds 30% I will operate with € 2.5 pip.
You cannot change the value of pips traded, ad this depends on the chosen position instrument (eg.; Dax 25€, Dax 5€ or Dax 1€).
You can change your stop loss (usually not recommended) or lot size.