def market_open(self, event: Event, account: AbstractAccount, data_portal: DataPortal): dest_position = 0 current_position = 0 net_value = None # 等待直到获取到最新的股票价格 current_price = None try: current_price = data_portal.current_price([self.code], event.visible_time)[self.code].price except: logging.error("没有获取到当天的开盘价,code:{}".format(self.code)) if current_price: net_value = account.net_value({self.code: current_price}) current_bid_ask = None try: current_bid_ask = data_portal.current_bid_ask([self.code])[self.code] except: logging.error("没有获取到最新的买卖价, code:{}".format(self.code)) if self.last_close_price and current_price: if np.log(current_price / self.last_close_price) < 0.025: dest_position = int(net_value / current_price) if len(account.positions) > 0: current_position = account.positions[self.code] change = dest_position - current_position if change != 0: direction = OrderDirection.BUY if change > 0 else OrderDirection.SELL reason = "时间:{}, 当前持仓:{}, 总市值:{}, 目标持仓:{}, 昨日收盘价:{}, 今日开盘价:{}, 最新买卖价:{}, strategy:{}" \ .format(event.visible_time, current_position, net_value, dest_position, self.last_close_price, current_price, current_bid_ask.__dict__ if current_bid_ask else None, TestStrategy3.__doc__) if current_bid_ask: delta = 0.01 limit_price = (current_bid_ask.bid_price + delta) if direction == OrderDirection.BUY else ( current_bid_ask.ask_price - delta) order = LimitOrder(self.code, direction, abs(change), event.visible_time, limit_price) order.with_reason(reason) account.place_order(order) # self.ensure_order_filled(account, data_portal, order, period=30, retry_count=3) self.ensure_order_filled_v2(account, data_portal, order, duration=60, delta=delta) else: order = MKTOrder(self.code, direction, abs(change), event.visible_time) order.with_reason(reason) account.place_order(order) else: msg = "不需要下单, 时间:{}, 当前持仓:{}, 总市值:{}, 目标持仓:{}, 昨日收盘价:{}, 今日开盘价:{}". \ format(event.visible_time, current_position, net_value, dest_position, self.last_close_price, current_price) logging.info(msg)
def do_initialize(self, engine: Engine, data_portal: DataPortal): if engine.is_backtest: market_close = EventDefinition(ed_type=EventDefinitionType.TIME, time_rule=MarketClose()) market_open = EventDefinition(ed_type=EventDefinitionType.TIME, time_rule=MarketOpen()) else: market_open = EventDefinition(ed_type=EventDefinitionType.TIME, time_rule=MarketOpen(second_offset=5)) market_close = EventDefinition(ed_type=EventDefinitionType.TIME, time_rule=MarketClose(second_offset=-60)) market_close_set_price = EventDefinition(ed_type=EventDefinitionType.TIME, time_rule=MarketClose()) engine.register_event(market_close_set_price, self.set_close_price) engine.register_event(market_open, self.market_open) engine.register_event(market_close, self.market_close) # 初始化昨日开盘价和收盘价 self.last_open = None self.last_close = None if not engine.is_backtest: command = HistoryDataQueryCommand(None, None, self.scope.codes, window=1) command.with_calendar(trading_calendar=self.scope.trading_calendar) df = data_portal.history_data("ibAdjustedDailyBar", command) if len(df) >= 1: self.last_open = df.iloc[-1]['open'] self.last_close = df.iloc[-1]['close'] logging.info("初始化数据成功,昨日开盘价:{}, 昨日收盘价:{}, bar的开始时间:{}" .format(self.last_open, self.last_close, df.iloc[-1]['start_time'])) else: raise RuntimeError("没有获取到昨日开盘价和收盘价") # self.last_open = 35.17 # self.last_close = 33.77 if len(self.scope.codes) != 1: raise RuntimeError("wrong codes") self.code = self.scope.codes[0]
def market_close(self, event: Event, account: AbstractAccount, data_portal: DataPortal): dest_position = 0 current_position = 0 net_value = None # 等待直到获取到最新的股票价格 current_price = None try: current_price = data_portal.current_price([self.code], event.visible_time)[self.code].price except: logging.error("没有获取到当天的开盘价,code:{}".format(self.code)) if current_price: net_value = account.net_value({self.code: current_price}) if current_price and self.last_close and current_price > self.last_close: dest_position = int(net_value / current_price) if len(account.positions) > 0: current_position = account.positions[self.code] change = dest_position - current_position if change != 0: direction = OrderDirection.BUY if change > 0 else OrderDirection.SELL reason = "时间:{}, 当前持仓:{}, 总市值:{}, 目标持仓:{}, 昨日收盘价:{}, 今日收盘价:{}, strategy:{}".format(event.visible_time, current_position, net_value, dest_position, self.last_close, current_price, TestStrategy2.__doc__) if current_price: order = LimitOrder(self.code, direction, abs(change), event.visible_time, current_price) order.with_reason(reason) account.place_order(order) self.ensure_order_filled(account, data_portal, order, 40, 1) else: order = MKTOrder(self.code, direction, abs(change), event.visible_time) order.with_reason(reason) account.place_order(order) else: logging.info("不需要下单, 时间:{}, 当前持仓:{}, 总市值:{}, 目标持仓:{}, 今日开盘价:{}, 今日收盘价:{}". format(event.visible_time, current_position, net_value, dest_position, self.last_open, current_price)) self.last_close = current_price
def market_open(self, event: Event, account: AbstractAccount, data_portal: DataPortal): if len(account.positions) > 0: raise RuntimeError("错误的账户状态") # 检查最新价格的时间是否是开盘之后的价格 open_time = event.visible_time code = self.scope.codes[0] while True: cp = data_portal.current_price([code], event.visible_time)[code] if cp.time >= open_time: break logging.info("没有获取到最新的价格,将会重试, 获取到的价格是:{}, 事件时间是:{}".format( cp, event.visible_time)) time.sleep(1) quantity = int(account.cash * 0.5 / cp.price) buy_order = MKTOrder(code, OrderDirection.BUY, quantity, event.visible_time) account.place_order(buy_order) self.base_price = cp.price
# contract.multiplier = 5000 contract.lastTradeDateOrContractMonth = "202104" # contract: Contract = Contract() # contract.symbol = '700' # contract.secType = 'STK' # contract.exchange = "SEHK" # contract.currency = "HKD" # # req = Request.new_request() # # client.cli.reqTickByTickData(req.req_id, contract, "AllLast", 0, False) # # client.cli.reqContractDetails(req.req_id, contract) # client.cli.reqMktData(req.req_id, contract, '', False, False, None) code = 'CL_FUT_USD_NYMEX_202104' # code = 'GSX_STK_USD_SMART' dp: DataPortal = DataPortal(is_backtest=False, ts_type_name_for_current_price='ibMarketData', subscribe_codes=[code]) # cp = dp.current_price([code], Timestamp.now(tz='Asia/Shanghai')) # print("cp:{}".format(cp)) class MySub(TimeSeriesSubscriber): def on_data(self, data: TSData): print(str(data.__dict__)) ts_repo: TimeSeriesRepo = BeanContainer.getBean(TimeSeriesRepo) ts: TimeSeries = ts_repo.find_one('ibMarketData') ts.subscribe(MySub(), ['CL_FUT_USD_NYMEX_202104']) while True:
def set_close_price(self, event: Event, account: AbstractAccount, data_portal: DataPortal): current_price = data_portal.current_price([self.code], event.visible_time)[self.code].price self.last_close = current_price logging.info("设置收盘价为:{}".format(current_price))
def market_close(self, event: Event, account: AbstractAccount, data_portal: DataPortal): dest_position = 0 current_position = 0 net_value = None # 等待直到获取到最新的股票价格 current_price = None try: current_price = data_portal.current_price( [self.code], event.visible_time)[self.code].price except: logging.error("没有获取到当天的开盘价,code:{}".format(self.code)) if current_price: net_value = account.net_value({self.code: current_price}) current_bid_ask = None try: current_bid_ask = data_portal.current_bid_ask([self.code ])[self.code] except: logging.error("没有获取到最新的买卖价,code:{}".format(self.code)) # if current_price and self.last_close and current_price > self.last_close: if True: dest_position = int(net_value * self.long_leverage / current_price) if len(account.positions) > 0: current_position = account.positions[self.code] change = dest_position - current_position if change != 0: direction = OrderDirection.BUY if change > 0 else OrderDirection.SELL reason = "时间:{}, 当前持仓:{}, 总市值:{}, 目标持仓:{}, 昨日收盘价:{}, 今日收盘价:{}, " \ "买卖价:{}, strategy:{}".format(event.visible_time, current_position, net_value, dest_position, self.last_close, current_price, current_bid_ask.__dict__ if current_bid_ask else None, SPCEStrategy.__doc__) if current_bid_ask: delta = 0.01 limit_price = (current_bid_ask.bid_price + delta) if direction == OrderDirection.BUY else ( current_bid_ask.ask_price - delta) order = LimitOrder(self.code, direction, abs(change), event.visible_time, limit_price) order.with_reason(reason) account.place_order(order) # self.ensure_order_filled(account, data_portal, order, 40, 1) self.ensure_order_filled_v2(account, data_portal, order, 40, delta) else: order = MKTOrder(self.code, direction, abs(change), event.visible_time) order.with_reason(reason) account.place_order(order) else: logging.info( "不需要下单, 时间:{}, 当前持仓:{}, 总市值:{}, 目标持仓:{}, 今日开盘价:{}, 今日收盘价:{}". format(event.visible_time, current_position, net_value, dest_position, self.last_open, current_price)) self.last_close = current_price