Overview
It is common that a trading algorithm involves a number of user defined trading parameters. To optimize the algorithm's trading performance, developers usually need to tweet the parameters, re-run backtest, and compare the results manually.
ALGOGENE is excited to announce a new system feature to support such parameter optimization process!
Preparation
Before going into the Strategy Optimization function, all we need to do is to develop a backtest script as usual. Let's borrow the code from this article [A simple RSI strategy].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | from AlgoAPI import AlgoAPIUtil, AlgoAPI_Backtest from datetime import datetime, timedelta from talib import RSI import numpy as np class AlgoEvent: def __init__(self): self.timer = datetime(1970,1,1) self.rsi_period = 14 self.rsi_overbought = 70 self.rsi_oversold = 30 self.position = 0 self.last_tradeID = "" self.instrument = "USDJPY" def start(self, mEvt): self.evt = AlgoAPI_Backtest.AlgoEvtHandler(self, mEvt) self.evt.start() def on_marketdatafeed(self, md, ab): # execute stratey every 24 hours if md.timestamp >= self.timer+timedelta(hours=24): # get last 14 closing price res = self.evt.getHistoricalBar({"instrument":self.instrument}, self.rsi_period+1, "D") arr = [res[t]['c'] for t in res] # calculate the current RSI value RSI_cur = RSI(np.array(arr), self.rsi_period)[-1] # print out RSI value to console self.evt.consoleLog("RSI_cur = ", RSI_cur) # open an order if we have no outstanding position if self.position==0: # open a sell order if it is overbought if RSI_cur>self.rsi_overbought: self.open_order(-1) # open a buy order if it is oversold elif RSI_cur<self.rsi_oversold: self.open_order(1) # check condition to close an order else: # close a position if we have previously open a buy order and RSI now reverse above 50 if self.position>0 and RSI_cur>50: self.close_order() # close a position if we have previously open a sell order and RSI now reverse below 50 elif self.position<0 and RSI_cur<50: self.close_order() # update timer self.timer = md.timestamp def open_order(self, buysell): order = AlgoAPIUtil.OrderObject() order.instrument = self.instrument order.openclose = 'open' order.buysell = buysell #1=buy, -1=sell order.ordertype = 0 #0=market, 1=limit order.volume = 0.01 self.evt.sendOrder(order) def close_order(self): order = AlgoAPIUtil.OrderObject() order.openclose = 'close' order.tradeID = self.last_tradeID self.evt.sendOrder(order) def on_bulkdatafeed(self, isSync, bd, ab): pass def on_newsdatafeed(self, nd): pass def on_weatherdatafeed(self, wd): pass def on_econsdatafeed(self, ed): pass def on_orderfeed(self, of): # when system confirm an order, update last_tradeID and position if of.status=="success": self.position += of.fill_volume*of.buysell if self.position==0: self.last_tradeID = "" else: self.last_tradeID = of.tradeID def on_dailyPLfeed(self, pl): pass def on_openPositionfeed(self, op, oo, uo): pass |
Optimization
- First of all, we need to backtest our strategy script to create a "finished" backtest record. It is to ensure that our base strategy is bug-free.
- Go to [My History] > [Finished Backtest], under your base strategy, click "Optimize"
- It will load our base strategy in left panel, we then need to set the following, and click "Optimize"
- Optimization objective
- Optimization method
- The parameters set to optimize
- from a starting value to the end value inclusively, with an incremental step size
- 'Value' specifies the initial estimate for the optimization problem
- It will take some time for the engine to generate the backtest results. Depending on the complexity of our base strategy and the grid size of our parameter sets, the overall optimization process may ranging from a few minutes to a couple of days.
- Upon the optimization process finished, we can obtain the
- performance summary
- visualization charts
- cummulative returns
Load optimization results
When we reload [My History] page, the optimization results can be found under the same group ID. We can load to see the backtest result, or compare with other optimization results.
Demo Video
Now, we got a new tool for speed up the algo development process! Happy Trading!