class StrategyTest(StockStrategy): market_open_count = 0 start_trade_time = None end_trade_time = None final_valid_capital = 0 portfolio: Portfolio = None def __init__(self, ): pass def on_create(self): """ 决策初始化. """ self.market_open_count = 0 self.market = MarketImpl() self.market.addNotice("601318") ##工商银行 if (not self.backtestContext is None): # 从网络上面准备数据。 self.write_log( f"on_create from backtestEngine, start={self.backtestContext.start_date},end={self.backtestContext.end_date}" ) else: self.write_log("on_create") pass def on_destroy(self): """ 决策结束.(被停止之后) """ self.write_log("on_destroy") pass daily_pre_tick: TickData = None def on_market_prepare_open(self, protfolio: Portfolio, toady: datetime): self.portfolio = protfolio """ 市场准备开始(比如:竞价). """ assert is_same_day(toady, self.market.getToday()) if (self.start_trade_time is None): self.start_trade_time = toady self.end_trade_time = toady self.daily_pre_tick = None pass def on_market_open(self, protfolio: Portfolio): """ 市场开市. """ self.market_open_count = self.market_open_count + 1 self.on_bar_per_minute_count = 0 if (is_same_day(datetime(2019, 2, 23), self.market.getToday())): ###刚刚开始,没有任何持仓 assert protfolio.sell("601318", 67.15, 100) == False assert protfolio.cover("601318", 67.15, 100) == False # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15 # 中国平安601318 在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57 # 中国平安601318 在datetime(2019, 2, 28)时刻,9点40分左右到最低点66.8,10:47最高到达68.08,然后14:00后面出现新的第二低点67.2-67.4 self.daily_pre_tick = self.market.getRealTime().getTick("601318") if (is_same_day(datetime(2019, 2, 26, 10, 28), self.market.getToday())): assert protfolio.buy("601318", 67.15, 100) == True assert protfolio.buy("601318", 67.15, 100) == False ##钱不够 assert protfolio.buy("601318", 67.15, 1) == True assert protfolio.buy("601318", 67.10, 1) == True ##价格过低,能委托成功,但没发成交 assert protfolio.buy("601318", 66.10, 1) == True ##价格过低,能委托成功,但没发成交 assert protfolio.buy("601318", 66.10, 1) == True ##价格过低,能委托成功,但没发成交 if (is_same_day(datetime(2019, 2, 27, 9, 48), self.market.getToday())): position = protfolio.getLongPosition("601318") assert position.is_long == True assert position.pos_total == 121 * 100 assert position.getPosAvailable() == 121 * 100 # 昨天买入的,所以今天可用 assert protfolio.sell("601318", 68.54, 500) == False ##持仓数不够 assert protfolio.sell("601318", 68.54, 55) == True assert protfolio.sell("601318", 68.54, 46) == True assert protfolio.short( "601318", 68.54, 10 ) == True ###开始做空买入在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57 assert protfolio.short("601318", 68.70, 1) == True ##价格过低,能委托成功,但没发成交 if (is_same_day(datetime(2019, 2, 28, 10, 48), self.market.getToday())): assert protfolio.buy("601318", 67.40, 120) == True # 4月23日,清空持仓 if (is_same_day(datetime(2019, 4, 23), self.market.getToday())): longPos = protfolio.getLongPosition("601318") shortPos = protfolio.getShortPosition("601318") assert longPos.pos_lock == 0 and shortPos.pos_lock == 0 #这个时间是没有冻结的 #high: 2019 - 04 - 23 13: 47:00: open = 83.77, close = 83.88 #low: 2019 - 04 - 23 09: 31:00: open = 81.38, close = 81.35 protfolio.cover("601318", 83.77, shortPos.pos_total / 100) protfolio.sell("601318", 81.35, longPos.pos_total / 100) pass def on_market_prepare_close(self, protfolio: Portfolio): """ 市场准备关市. """ time = self.market.getToday() assert time.hour == 14 and time.minute == 57 # 最开始datetime(2019, 2, 26, 10, 28)买入100股,由于A股T+1的限制,是不可以当天卖的 if (utils.is_same_day(datetime(2019, 2, 26, 10, 28), time)): assert protfolio.sell("601318", 67.00, 100) == False pass def on_market_close(self, protfolio: Portfolio): """ 市场关市. """ time = self.market.getToday() assert time.hour == 15 and time.minute == 0 assert self.on_bar_per_minute_count > 200 self.final_valid_capital = protfolio.getValidCapital() # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15 if utils.is_same_day(datetime(2019, 2, 26), self.market.getToday()): #当天已经买入121*100股,持有仓位资金不为0 assert protfolio.getTotalHoldCapital() > 810700 position = protfolio.getLongPosition("601318") assert position.is_long == True assert position.pos_total == 121 * 100 assert position.getPosAvailable() == 0 # 因为今天才交易,可用仓位为0 pass sell_time_01_tag = False def on_bar_per_minute(self, time: datetime, protfolio: Portfolio): """ 市场开市后的每分钟。 """ self.on_bar_per_minute_count = self.on_bar_per_minute_count + 1 assert is_same_minitue(time, self.market.getToday()) assert time.hour >= 9 #9点后开市 if (time.hour > 9 or (time.hour == 9 and time.minute > 32)): ##开市之后的实时信息不应该为none bar = self.market.getRealTime().getKBar("601318") assert not bar is None tickData: BarData = self.market.getRealTime().getTick("601318") preTickData: BarData = self.daily_pre_tick assert not tickData is None assert not preTickData is None deltaFloat = preTickData.close_price * 0.015 assert utils.isEqualFloat(preTickData.close_price, tickData.open_price, deltaFloat) self.daily_pre_tick = self.market.getRealTime().getTick("601318") # 中国平安601318 # 2019-03-25 10:35:00:open = 71.03,close=70.96 一天最高点 # 2019-03-25 13:12:00:open = 69.97,close=69.79 下午开盘的一个低点 # 2019-03-25 13:47:00:open = 70.33,close=70.41 下午的一个高点 sell_time_01 = datetime(2019, 3, 25, 13, 12) if not self.sell_time_01_tag: if (utils.is_same_minitue(sell_time_01, time)): protfolio.sell("601318", 70.35, 120) self.sell_time_01_tag = True #self.write_log(f" on_bar_per_minute:{time}" ) # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15 if (utils.is_same_time(datetime(2019, 2, 26, 10, 28), self.market.getToday(), deltaSecond=30)): protfolio.buy("601318", 70.75, 20) ##测试交割价格在67.15附近 # 中国平安601318 在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57 if (utils.is_same_time(datetime(2019, 2, 27, 9, 48), self.market.getToday(), deltaSecond=30)): protfolio.sell("601318", 60.75, 20) ##测试交割价格在68.57附近 ###开始做空买入在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57 # 中国平安601318 在datetime(2019, 2, 28)时刻,9点40分左右到最低点66.8,10:47最高到达68.08,然后14:00后面出现新的第二低点67.2-67.4 if (utils.is_same_time(datetime(2019, 2, 28, 11, 00), self.market.getToday(), deltaSecond=30)): assert protfolio.cover("601318", 67.3, 10) == True ## 11点后开始平仓,以当天第二低价格平仓 # 4月1日 - 20日随机交易 today = self.market.getToday() #today >= datetime(2019,3,2,0) and today <= datetime(2019,3,20,0) or # if today >= datetime(2019,4,1,0) and today <= datetime(2019,4,20,0): # happen = random.random() # if happen <= 0.1: # self.__randomTrade(protfolio) def __randomTrade(self, protfolio: Portfolio): happen = random.random() code = "601318" price = self.market.getRealTime().getTick(code).close_price trade_price = price * random.uniform(0.94, 1.06) volume = random.randint(3, 100) if happen <= 0.25: protfolio.buy(code, trade_price, volume) elif happen <= 0.5: protfolio.sell(code, trade_price, volume) elif happen <= 0.75: protfolio.short(code, trade_price, volume) else: protfolio.cover(code, trade_price, volume) def on_order(self, order: OrderData): print(f"{self.market.getToday()}:onOrder: {order}") sell_at_2019_2_27_9_48 = False buy_at_2019_2_26_10_28 = 0 sell_at_2019_3_25_13_47 = False short_at_2019_2_27_9_48 = False cover_at_2019_2_28_14_more = False def on_trade(self, trade: TradeData): print(f"{self.market.getToday()}:on_trade: {trade}") # 中国平安601318 在datetime(2019, 2, 26, 10, 28)时刻,最低到达 low_price=67.15,到达买入价 # 中国平安601318 在datetime(2019, 2, 27, 9, 48)时刻,最高到达 high_price=68.57,到达卖出价 # 中国平安601318 在datetime(2019, 3, 25, 13, 10)时刻,从最高价71到一个新底69.75, 后面再到一个新的高点。7.38左右 # 中国平安601318 在datetime(2019, 2, 28)时刻,9点40分左右到最低点66.8,10:47最高到达68.08,然后14:00后面出现新的第二低点67.2-67.4 is_buy = trade.direction == Direction.LONG and trade.offset == Offset.OPEN is_sell = trade.direction == Direction.SHORT and trade.offset == Offset.CLOSE is_short = trade.direction == Direction.SHORT and trade.offset == Offset.OPEN is_cover = trade.direction == Direction.LONG and trade.offset == Offset.CLOSE if (utils.is_same_time(datetime(2019, 2, 26, 10, 28), self.market.getToday(), deltaSecond=30)): if is_buy: self.buy_at_2019_2_26_10_28 = self.buy_at_2019_2_26_10_28 + 1 assert utils.isEqualFloat(67.15, trade.price, 0.5) #成交价格在67.15中间 if (utils.is_same_day(datetime(2019, 2, 28), self.market.getToday())): if is_cover: assert self.cover_at_2019_2_28_14_more == False self.cover_at_2019_2_28_14_more = True assert utils.isEqualFloat(67.3, trade.price, 0.5) #成交价格在67.15中间 if (utils.is_same_time(self.market.getToday(), datetime(2019, 2, 27, 9, 48), deltaMinitue=1, deltaSecond=2)): if is_sell: self.sell_at_2019_2_27_9_48 = True assert utils.isEqualFloat(68.57, trade.price, 0.5) # 成交价格在68.57中间 if is_short: self.short_at_2019_2_27_9_48 = True assert utils.isEqualFloat(68.57, trade.price, 0.5) # 成交价格在68.57中间 # 中国平安601318 # 2019-03-25 10:35:00:open = 71.03,close=70.96 一天最高点 # 2019-03-25 13:12:00:open = 69.97,close=69.79 下午开盘的一个低点 # 2019-03-25 13:47:00:open = 70.33,close=70.41 下午的一个高点 if (utils.is_same_time(self.market.getToday(), datetime(2019, 3, 25, 13, 47), deltaMinitue=4, deltaSecond=2)): if is_sell: self.sell_at_2019_3_25_13_47 = True assert utils.isEqualFloat(70.36, trade.price, 0.5) # 成交价格在68.57中间 def on_stop_order(self, stop_order: StopOrder): print(f"{self.market.getToday()}:on_stop_order: {stop_order}")
class Strategy1(StockStrategy): def __init__(self): pass code = "300004" window_size = 30 def on_create(self): """ 决策初始化. """ self.write_log("on_create") self.market = MarketImpl() self.market.addNotice(self.code) pass def on_destroy(self): """ 决策结束.(被停止之后) """ self.write_log("on_destroy") pass def on_market_prepare_open(self, protfolio: Portfolio, today: datetime): """ 市场准备开始(比如:竞价). """ #准备线程池,准备数据。 self.market.setToday(today) self.today_has_buy = False self.today_has_sell = False pass __history_bar100 = None def on_market_open(self, protfolio: Portfolio): """ 市场开市. """ def on_market_prepare_close(self, protfolio: Portfolio): """ 市场准备关市. """ pass def on_market_close(self, protfolio: Portfolio): """ 市场关市. """ pass def on_bar_per_minute(self, time: datetime, protfolio: Portfolio): """ 市场开市后的每分钟。 """ #每天两点半的后尝试去做交易。 if time.hour == 14 and time.minute == 30: self.__history_bar100 = self.market.getHistory().getKbars( self.code, 100) assert len(self.__history_bar100) == 100 bars = self.__history_bar100 todayBar = self.market.getRealTime().getKBar(self.code) indicator = Indicator(40) indicator.update_bar(bars) dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) if (not self.today_has_buy): # 预测金叉 todayBar.close_price = todayBar.close_price * 1.01 indicator.update_bar(todayBar) dif, dea, predict_macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) print( f"[{self.market.getToday()}]:bar={macd_bar[-1]},predic_bar={predict_macd_bar[-1]}" ) if (predict_macd_bar[-1] > 0 and macd_bar[-1] <= 0): targetPrice = todayBar.close_price # 上一个交易日的收盘价作为买如价 print(f" gold cross!!!") if protfolio.buy(self.code, targetPrice, 100): self.today_has_buy = True elif (not self.today_has_sell): todayBar.close_price = todayBar.close_price * 0.99 indicator.update_bar(todayBar) dif, dea, predict_macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) print( f"[{self.market.getToday()}]:bar={macd_bar[-1]},predic_bar={predict_macd_bar[-1]}" ) if (predict_macd_bar[-1] <= 0 and macd_bar[-1] > 0): targetPrice = todayBar.close_price print(f" dead cross!!!") if protfolio.sell(self.code, targetPrice, 100): self.today_has_sell = True
class macd(StockStrategy): def __init__(self): pass codes = ["300004"] activity_long_dict:Dict[str,Long_Item] = {} activity_short_dict:Dict[str,Short_Item] = {} long_datas:Sequence["Long_Item"] = [] short_datas:Sequence["Short_Item"] = [] def on_create(self): """ 决策初始化. """ self.write_log("on_create") self.market = MarketImpl() for code in self.codes: self.market.addNotice(code) pass def on_destroy(self): """ 决策结束.(被停止之后) """ self.write_log("on_destroy") pass def on_market_prepare_open(self,protfolio:Portfolio,today:datetime): """ 市场准备开始(比如:竞价). """ indicator = Indicator(40) for code in self.codes: bars = self.market.getHistory().getKbars(code, 100); indicator.update_bar(bars) dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True); ##金叉出现 if (macd_bar[-1] >= 0 and macd_bar[-2] <= 0): tradePrice = bars[-1].close_price * 1.01 # 上一个交易日的收盘价作为买如价 protfolio.buy(code, tradePrice, 1) protfolio.cover(code,tradePrice,1) ##平仓做空 ##死叉出现 if (macd_bar[-1] <= 0 and macd_bar[-2] >=0): targetPrice = bars[-1].close_price * 0.99 # 上一个交易日的收盘价作为买如价 protfolio.sell(code, targetPrice, 1) protfolio.short(code, targetPrice, 1) ##开仓做空 pass def on_trade(self, trade: TradeData): is_buy = trade.direction == Direction.LONG and trade.offset == Offset.OPEN is_sell = trade.direction == Direction.SHORT and trade.offset == Offset.CLOSE is_short = trade.direction == Direction.SHORT and trade.offset == Offset.OPEN is_cover = trade.direction == Direction.LONG and trade.offset == Offset.CLOSE today = self.market.getToday() if is_buy: long_data = Long_Item(symbol=trade.symbol,start_time=today,start_price=trade.price) self.activity_long_dict[trade.symbol] = long_data self.__update_long_max_price(trade.symbol,trade.price) elif is_sell: self.__update_long_max_price(trade.symbol,trade.price) long_data = self.activity_long_dict.get(trade.symbol) if not long_data is None: long_data.end_time = today long_data.end_price = trade.price long_data.duration_days = (today - long_data.start_time).days self.long_datas.append(long_data) del self.activity_long_dict[trade.symbol] elif is_short: short_data = Short_Item(symbol=trade.symbol, start_time=today, start_price=trade.price) self.activity_short_dict[trade.symbol] = short_data self.__update_short_min_price(trade.symbol,trade.price) elif is_cover: self.__update_short_min_price(trade.symbol,trade.price) short_data = self.activity_short_dict.get(trade.symbol) if not short_data is None: short_data.end_time = today short_data.end_price = trade.price short_data.duration_days = (today - short_data.start_time).days self.short_datas.append(short_data) del self.activity_short_dict[trade.symbol] def __update_long_max_price(self,code:str,max_price:float): data_item = self.activity_long_dict.get(code) if data_item is None: return today = self.market.getToday() delta_day = (today - data_item.start_time).days if max_price > data_item.max_price: data_item.max_price = max_price data_item.max_price_time = today data_item.max_price_day = delta_day delta_pnl = (data_item.max_price - data_item.start_price) / data_item.start_price if (delta_pnl >= 0.03 and data_item.max_pnl_3_day < 0): data_item.max_pnl_3_day = delta_day if (delta_pnl >= 0.05 and data_item.max_pnl_5_day < 0): data_item.max_pnl_5_day = delta_day if (delta_pnl >= 0.07 and data_item.max_pnl_7_day < 0): data_item.max_pnl_7_day = delta_day if (delta_pnl >= 0.09 and data_item.max_pnl_9_day < 0): data_item.max_pnl_9_day = delta_day if (delta_pnl >= 0.11 and data_item.max_pnl_11_day < 0): data_item.max_pnl_11_day = delta_day if (delta_pnl >= 0.13 and data_item.max_pnl_13_day < 0): data_item.max_pnl_13_day = delta_day if (delta_pnl >= 0.15 and data_item.max_pnl_15_day < 0): data_item.max_pnl_15_day = delta_day if (delta_pnl >= 0.17 and data_item.max_pnl_17_day < 0): data_item.max_pnl_17_day = delta_day if (delta_pnl >= 0.19 and data_item.max_pnl_19_day < 0): data_item.max_pnl_19_day = delta_day if (delta_pnl >= 0.21 and data_item.max_pnl_21_more_day < 0): data_item.max_pnl_21_more_day = delta_day def __update_short_min_price(self, code:str, min_price:float): data_item:Short_Item = self.activity_short_dict.get(code) if data_item is None: return today = self.market.getToday() delta_day = (today - data_item.start_time).days if min_price < data_item.min_price: data_item.min_price = min_price data_item.min_price_time = today data_item.min_price_day = delta_day delta_pnl = (data_item.min_price - data_item.start_price) / data_item.start_price if (delta_pnl >= 0.03 and data_item.min_pnl_3_day < 0): data_item.min_pnl_3_day = delta_day if (delta_pnl >= 0.05 and data_item.min_pnl_5_day < 0): data_item.min_pnl_5_day = delta_day if (delta_pnl >= 0.07 and data_item.min_pnl_7_day < 0): data_item.min_pnl_7_day = delta_day if (delta_pnl >= 0.09 and data_item.min_pnl_9_day < 0): data_item.min_pnl_9_day = delta_day if (delta_pnl >= 0.11 and data_item.min_pnl_11_day < 0): data_item.min_pnl_11_day = delta_day if (delta_pnl >= 0.13 and data_item.min_pnl_13_day < 0): data_item.min_pnl_13_day = delta_day if (delta_pnl >= 0.15 and data_item.min_pnl_15_day < 0): data_item.min_pnl_15_day = delta_day if (delta_pnl >= 0.17 and data_item.min_pnl_17_day < 0): data_item.min_pnl_17_day = delta_day if (delta_pnl >= 0.19 and data_item.min_pnl_19_day < 0): data_item.min_pnl_19_day = delta_day if (delta_pnl >= 0.21 and data_item.min_pnl_21_more_day < 0): data_item.min_pnl_21_more_day = delta_day def on_market_open(self,protfolio:Portfolio): """ 市场开市. """ def on_market_prepare_close(self,protfolio:Portfolio): """ 市场准备关市. """ pass def on_market_close(self, protfolio:Portfolio): """ 市场关市. """ for code in self.codes: bar = self.market.getRealTime().getKBar(code) self.__update_long_max_price(code,bar.high_price) self.__update_short_min_price(code,bar.low_price) pass def on_bar_per_minute(self, time: datetime, protfolio:Portfolio): """ 市场开市后的每分钟。 """ pass
def realTimeTest(): market2 = MarketImpl() code = "300004" market2.addNotice(code) has_data_day1 = datetime(year=2020, month=5, day=8, hour=1) market2.setToday(has_data_day1) bar = market2.getRealTime().getKBar(code) assert bar is None market2.setToday( datetime(year=2020, month=5, day=8, hour=9, minute=31, second=30)) bar = market2.getRealTime().getKBar(code) assert not bar is None bar = market2.getRealTime().getKBar(code, hour=9, minute=31, second=31) assert bar is None begin = datetime(year=2020, month=4, day=9, hour=1) for i in range(50): day = begin + timedelta(days=i) market2.setToday( datetime(year=day.year, month=day.month, day=day.day, hour=9, minute=50, second=30)) bar = market2.getRealTime().getKBar(code) todayIsTrade = not bar is None if todayIsTrade: print(f"realTimeTest:test in trad day : {day}") """ 今天是交易日 """ day1 = datetime(year=day.year, month=day.month, day=day.day, hour=9, minute=31, second=30) day2 = datetime(year=day.year, month=day.month, day=day.day, hour=10, minute=31, second=30) day3 = datetime(year=day.year, month=day.month, day=day.day, hour=13, minute=50, second=30) day4 = datetime(year=day.year, month=day.month, day=day.day, hour=15, minute=0, second=30) market2.setToday(day1) bar1 = market2.getRealTime().getKBar(code) market2.setToday(day2) bar2 = market2.getRealTime().getKBar(code) market2.setToday(day3) bar3 = market2.getRealTime().getKBar(code) market2.setToday(day4) bar4 = market2.getRealTime().getKBar(code) assert is_same_day(bar1.datetime, bar2.datetime) and is_same_day( bar3.datetime, bar4.datetime) and is_same_day( bar2.datetime, bar3.datetime) assert bar1.datetime < bar2.datetime and bar2.datetime < bar3.datetime and bar3.datetime < bar4.datetime assert isPostMinitueBar(bar1, bar2) and isPostMinitueBar( bar2, bar3) and isPostMinitueBar( bar3, bar4) and isPostMinitueBar(bar2, bar4)