Hi Kwan, on_bulkdatafeed would be more appropriate for your case. The 'bd' object in on_bulkdatafeed is a dictionary containing the latest price info for all your chosen instruments.
For the example in TechDoc, you can revise the data type for 'arr_close', 'arr_fastMA', and 'arr_slowMA' to dictionary. Then, you can loop all instruments and append the observations under on_bulkdatafeed later.
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 | from AlgoAPI import AlgoAPIUtil, AlgoAPI_Backtest from datetime import datetime, timedelta import talib, numpy class AlgoEvent: def __init__(self): self.lasttradetime = datetime(2000,1,1) self.arr_close = {} self.arr_fastMA = {} self.arr_slowMA = {} self.fastperiod = 7 self.slowperiod = 14 def start(self, mEvt): self.instrument_1 = mEvt['subscribeList'][0] self.evt = AlgoAPI_Backtest.AlgoEvtHandler(self, mEvt) self.evt.start() def on_bulkdatafeed(self, isSync, bd, ab): if isSync and bd[self.instrument_1]['timestamp'] >= self.lasttradetime + timedelta(hours=24): self.lasttradetime = bd[self.instrument_1]['timestamp'] for instrument in bd: # initialize array if instrument not in self.arr_close: self.arr_close[instrument] = [] self.arr_fastMA[instrument] = [] self.arr_slowMA[instrument] = [] lastprice = bd[instrument]['lastPrice'] self.arr_close[instrument] = numpy.append(self.arr_close[instrument], lastprice) # keep the most recent observations if len(self.arr_close[instrument])>int(self.fastperiod+self.slowperiod): self.arr_close[instrument] = self.arr_close[instrument][-int(self.fastperiod+self.slowperiod):] # fit SMA line self.arr_fastMA[instrument] = talib.SMA(self.arr_close[instrument], timeperiod=int(self.fastperiod)) self.arr_slowMA[instrument] = talib.SMA(self.arr_close[instrument], timeperiod=int(self.slowperiod)) # debug print result self.evt.consoleLog("arr_fastMA=", instrument, self.arr_fastMA[instrument]) self.evt.consoleLog("arr_slowMA=", instrument, self.arr_slowMA[instrument]) # check number of record is at least greater than both self.fastperiod, self.slowperiod if not numpy.isnan(self.arr_fastMA[instrument][-1]) and not numpy.isnan(self.arr_fastMA[instrument][-2]) and not numpy.isnan(self.arr_slowMA[instrument][-1]) and not numpy.isnan(self.arr_slowMA[instrument][-2]): # send a buy order for Golden Cross if self.arr_fastMA[instrument][-1] > self.arr_slowMA[instrument][-1] and self.arr_fastMA[instrument][-2] < self.arr_slowMA[instrument][-2]: self.place_order(lastprice, 1, 'open', instrument) # send a sell order for Death Cross if self.arr_fastMA[instrument][-1] < self.arr_slowMA[instrument][-1] and self.arr_fastMA[instrument][-2] > self.arr_slowMA[instrument][-2]: self.place_order(lastprice, -1, 'open', instrument) def place_order(self, lastprice, buysell, openclose, instrument): order = AlgoAPIUtil.OrderObject() order.instrument = instrument if buysell==1: order.takeProfitLevel = lastprice*1.1 order.stopLossLevel = lastprice*0.9 elif buysell==-1: order.takeProfitLevel = lastprice*0.9 order.stopLossLevel = lastprice*1.1 order.volume = 0.01 order.openclose = openclose order.buysell = buysell order.ordertype = 0 #0=market_order, 1=limit_order self.evt.sendOrder(order) |
Original Posted by - b'tony lam':Hi Kwan, on_bulkdatafeed would be more appropriate for your case. The 'bd' object in on_bulkdatafeed is a dictionary containing the latest price info for all your chosen instruments.
For the example in TechDoc, you can revise the data type for 'arr_close', 'arr_fastMA', and 'arr_slowMA' to dictionary. Then, you can loop all instruments and append the observations under on_bulkdatafeed later.
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 from AlgoAPI import AlgoAPIUtil, AlgoAPI_Backtest from datetime import datetime, timedelta import talib, numpy class AlgoEvent: def __init__(self): self.lasttradetime = datetime(2000,1,1) self.arr_close = {} self.arr_fastMA = {} self.arr_slowMA = {} self.fastperiod = 7 self.slowperiod = 14 def start(self, mEvt): self.instrument_1 = mEvt['subscribeList'][0] self.evt = AlgoAPI_Backtest.AlgoEvtHandler(self, mEvt) self.evt.start() def on_bulkdatafeed(self, isSync, bd, ab): if isSync and bd[self.instrument_1]['timestamp'] >= self.lasttradetime + timedelta(hours=24): self.lasttradetime = bd[self.instrument_1]['timestamp'] for instrument in bd: # initialize array if instrument not in self.arr_close: self.arr_close[instrument] = [] self.arr_fastMA[instrument] = [] self.arr_slowMA[instrument] = [] lastprice = bd[instrument]['lastPrice'] self.arr_close[instrument] = numpy.append(self.arr_close[instrument], lastprice) # keep the most recent observations if len(self.arr_close[instrument])>int(self.fastperiod+self.slowperiod): self.arr_close[instrument] = self.arr_close[instrument][-int(self.fastperiod+self.slowperiod):] # fit SMA line self.arr_fastMA[instrument] = talib.SMA(self.arr_close[instrument], timeperiod=int(self.fastperiod)) self.arr_slowMA[instrument] = talib.SMA(self.arr_close[instrument], timeperiod=int(self.slowperiod)) # debug print result self.evt.consoleLog("arr_fastMA=", instrument, self.arr_fastMA[instrument]) self.evt.consoleLog("arr_slowMA=", instrument, self.arr_slowMA[instrument]) # check number of record is at least greater than both self.fastperiod, self.slowperiod if not numpy.isnan(self.arr_fastMA[instrument][-1]) and not numpy.isnan(self.arr_fastMA[instrument][-2]) and not numpy.isnan(self.arr_slowMA[instrument][-1]) and not numpy.isnan(self.arr_slowMA[instrument][-2]): # send a buy order for Golden Cross if self.arr_fastMA[instrument][-1] > self.arr_slowMA[instrument][-1] and self.arr_fastMA[instrument][-2] < self.arr_slowMA[instrument][-2]: self.place_order(lastprice, 1, 'open', instrument) # send a sell order for Death Cross if self.arr_fastMA[instrument][-1] < self.arr_slowMA[instrument][-1] and self.arr_fastMA[instrument][-2] > self.arr_slowMA[instrument][-2]: self.place_order(lastprice, -1, 'open', instrument) def place_order(self, lastprice, buysell, openclose, instrument): order = AlgoAPIUtil.OrderObject() order.instrument = instrument if buysell==1: order.takeProfitLevel = lastprice*1.1 order.stopLossLevel = lastprice*0.9 elif buysell==-1: order.takeProfitLevel = lastprice*0.9 order.stopLossLevel = lastprice*1.1 order.volume = 0.01 order.openclose = openclose order.buysell = buysell order.ordertype = 0 #0=market_order, 1=limit_order self.evt.sendOrder(order)
Original Posted by - b'Kwan Chi Yeung': Hi Tony, thank you so much for your reply. I have followed the above code while developing my crypto trading strategy. However, my programme would not trade during the backtest even I just directly copy all functions above. May I know if I have missed any code in the "place_order" part? Additionally, is there a maximum value of the "order.volume". Thank you for your valuable time.