def cross_limit_order(self) -> None: """ Cross limit order with last bar/tick data. """ for order in list(self.active_limit_orders.values()): bar = self.bars[order.vt_symbol] long_cross_price = bar.low_price short_cross_price = bar.high_price long_best_price = bar.open_price short_best_price = bar.open_price # Push order update with status "not traded" (pending). if order.status == Status.SUBMITTING: order.status = Status.NOTTRADED self.strategy.update_order(order) # Check whether limit orders can be filled. long_cross = (order.direction == Direction.LONG and order.price >= long_cross_price and long_cross_price > 0) short_cross = (order.direction == Direction.SHORT and order.price <= short_cross_price and short_cross_price > 0) if not long_cross and not short_cross: continue # Push order update with status "all traded" (filled). order.traded = order.volume order.status = Status.ALLTRADED self.strategy.update_order(order) self.active_limit_orders.pop(order.vt_orderid) # Push trade update self.trade_count += 1 if long_cross: trade_price = min(order.price, long_best_price) else: trade_price = max(order.price, short_best_price) trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime self.strategy.update_trade(trade) self.trades[trade.vt_tradeid] = trade
def cross_algo(self): """ Cross limit order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.close_price short_cross_price = self.bar.close_price else: long_cross_price = self.tick.ask_price_1 short_cross_price = self.tick.bid_price_1 for algo in list(self.active_algos.values()): # Check whether limit orders can be filled. long_cross = (algo.direction == Direction.LONG and algo.price >= long_cross_price and long_cross_price > 0) short_cross = (algo.direction == Direction.SHORT and algo.price <= short_cross_price and short_cross_price > 0) if not long_cross and not short_cross: continue # Push order udpate with status "all traded" (filled). algo.traded = algo.volume algo.status = Status.ALLTRADED self.strategy.update_spread_algo(algo) self.active_algos.pop(algo.algoid) # Push trade update self.trade_count += 1 if long_cross: trade_price = long_cross_price pos_change = algo.volume else: trade_price = short_cross_price pos_change = -algo.volume trade = TradeData( symbol=self.spread.name, exchange=Exchange.LOCAL, orderid=algo.algoid, tradeid=str(self.trade_count), direction=algo.direction, offset=algo.offset, price=trade_price, volume=algo.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime self.spread.net_pos += pos_change self.strategy.on_spread_pos() self.trades[trade.vt_tradeid] = trade
def cross_stop_order(self): """ Cross stop order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.high_price short_cross_price = self.bar.low_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.last_price short_cross_price = self.tick.last_price long_best_price = long_cross_price short_best_price = short_cross_price for stop_order in list(self.active_stop_orders.values()): # Check whether stop order can be triggered. long_cross = (stop_order.direction == Direction.LONG and stop_order.price <= long_cross_price) short_cross = (stop_order.direction == Direction.SHORT and stop_order.price >= short_cross_price) if not long_cross and not short_cross: continue # Create order data. self.limit_order_count += 1 order = OrderData( symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=stop_order.direction, offset=stop_order.offset, price=stop_order.price, volume=stop_order.volume, status=Status.ALLTRADED, gateway_name=self.gateway_name, ) order.datetime = self.datetime self.limit_orders[order.vt_orderid] = order # Create trade data. if long_cross: trade_price = max(stop_order.price, long_best_price) pos_change = order.volume else: trade_price = min(stop_order.price, short_best_price) pos_change = -order.volume self.trade_count += 1 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime self.trades[trade.vt_tradeid] = trade # Update stop order. stop_order.vt_orderid = order.vt_orderid stop_order.status = StopOrderStatus.TRIGGERED self.active_stop_orders.pop(stop_order.stop_orderid) # Push update to strategy. self.strategy.on_stop_order(stop_order) self.strategy.on_order(order) self.strategy.pos += pos_change self.strategy.on_trade(trade)
def cross_limit_order(self): """ Cross limit order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.low_price short_cross_price = self.bar.high_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.ask_price_1 short_cross_price = self.tick.bid_price_1 long_best_price = long_cross_price short_best_price = short_cross_price for order in list(self.active_limit_orders.values()): # Push order update with status "not traded" (pending). if order.status == Status.SUBMITTING: order.status = Status.NOTTRADED self.strategy.on_order(order) order: OrderData = order pos_change = 0 trade_price = 0 if order.type == OrderType.LIMIT: # Check whether limit orders can be filled. long_cross = (order.direction == Direction.LONG and order.price >= long_cross_price and long_cross_price > 0) short_cross = (order.direction == Direction.SHORT and order.price <= short_cross_price and short_cross_price > 0) if not long_cross and not short_cross: continue if long_cross: trade_price = min(order.price, long_best_price) pos_change = order.volume else: trade_price = max(order.price, short_best_price) pos_change = -order.volume else: if order.direction == Direction.LONG: trade_price = self.bar.high_price pos_change = order.volume else: trade_price = self.bar.low_price pos_change = -order.volume # Push order udpate with status "all traded" (filled). order.traded = order.volume order.status = Status.ALLTRADED self.strategy.on_order(order) self.active_limit_orders.pop(order.vt_orderid) # Push trade update self.trade_count += 1 trade = TradeData(symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, extra=order.extra) trade.datetime = self.datetime self.strategy.pos += pos_change self.strategy.on_trade(trade) self.trades[trade.vt_tradeid] = trade
def cross_stop_order(self): """ Cross stop order with last bar/tick data. T时刻内,价格上下波动,形成T日K线; T时刻走完,基于T日以及之前数据计算通道上下轨 T+1时刻开盘,基于上一步的通道上下轨挂出对应的停止单 T+1时刻内,价格突破通道是触发停止单,立即发出市价单成交 """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.high_price short_cross_price = self.bar.low_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.last_price short_cross_price = self.tick.last_price long_best_price = long_cross_price short_best_price = short_cross_price for stop_order in list(self.active_stop_orders.values()): # Check whether stop order can be triggered. # self.active_stop_orders.values里面的数据结构是一个类,这里面使用类来保存数据。 long_cross = (stop_order.direction == Direction.LONG and stop_order.price <= long_cross_price) short_cross = (stop_order.direction == Direction.SHORT and stop_order.price >= short_cross_price) if not long_cross and not short_cross: continue # Create order data. # 停止单最后还是要转化为限价单 self.limit_order_count += 1 order = OrderData(symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=stop_order.direction, offset=stop_order.offset, price=stop_order.price, volume=stop_order.volume, status=Status.ALLTRADED, gateway_name=self.gateway_name, time=self.datetime.strftime("%H:%M:%S")) """ symbol表示交易品种,如IF88,在最开始传入 exchange表示交易所,在set_parameters中传入的 self.limit_order_count表示限价单的数量 stop_order表示在发送停止单时的一些信息 stop_order.direction的方向在上面 offset表示开或平 status: Status = Status.SUBMITTING这个是默认值, getway_name是在BacktestingEngine中确定的 """ order.datetime = self.datetime # 这个地方和可能是直接给这个类添加属性,这个有什么用呢,为什么不直接放进OrderData里面去,self.datetime= bar.datetime self.limit_orders[order.vt_orderid] = order # 没有把这笔交易推给策略,没有搞懂为什么,这个不是active,因为一旦发出即成交了,两种情况,一种是t时刻就已经把单子挂在交易所那边,另一种是挂在自己的系统上面只要满足条件就提交订单,并不一定需要t+1的K线形成才可以 # Create trade data. if long_cross: trade_price = max(stop_order.price, long_best_price) pos_change = order.volume else: trade_price = min(stop_order.price, short_best_price) pos_change = -order.volume self.trade_count += 1 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime # direction表示方向,offset表示经常模式,一手多两手空,会平掉多仓空仓,然后开 # 一个空仓 # 这个time是一个字符串 self.trades[trade.vt_tradeid] = trade # Update stop order. stop_order.vt_orderids.append(order.vt_orderid) stop_order.status = StopOrderStatus.TRIGGERED if stop_order.stop_orderid in self.active_stop_orders: self.active_stop_orders.pop(stop_order.stop_orderid) # Push update to strategy. self.strategy.on_stop_order(stop_order) self.strategy.on_order(order) # 这个地方把停止单推给了策略 self.strategy.pos += pos_change self.strategy.on_trade(trade)
def cross_limit_order(self): """ Cross limit order with last bar/tick data. 此处的回测只用了bar进行了回测,没有用tick进行相应的回测 次函数的作用就是在T时刻,把T-1时刻之前所有的委托都进行一遍撮合 """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.low_price short_cross_price = self.bar.high_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.ask_price_1 short_cross_price = self.tick.bid_price_1 long_best_price = long_cross_price short_best_price = short_cross_price """long_cross_price表示多头可能成交价格""" # long_best_price多头有机会最好的成交价格 for order in list(self.active_limit_orders.values()): # 如果list是空的,不会进入到循环里面来,也不会报错 # come from backtesting.send_stop_order # Push order update with status "not traded" (pending).key是委托号,value是委托对象 # 此处的order是一个类 if order.status == Status.SUBMITTING: order.status = Status.NOTTRADED self.strategy.on_order(order) # 这个on_order是当状态有更新的时候推送给策略,需要自己去定义 # //TODO:很有可能order里面还有很多的列,其中一个是status # status这个属性是从哪来的,很可能跟object中的BaseData有关系 # Check whether limit orders can be filled. long_cross = (order.direction == Direction.LONG and order.price >= long_cross_price and long_cross_price > 0) short_cross = (order.direction == Direction.SHORT and order.price <= short_cross_price and short_cross_price > 0) if not long_cross and not short_cross: continue # 这个if continue是过滤掉没有成交的单子 # Push order udpate with status "all traded" (filled). order.traded = order.volume # 表示已经完成的成交数量 order.status = Status.ALLTRADED # 变更状态 self.strategy.on_order(order) # 订单的状态发生变化后,把订单发给策略 self.active_limit_orders.pop(order.vt_orderid) # Push trade update self.trade_count += 1 # 这个是在init中定义的变量 if long_cross: trade_price = min(order.price, long_best_price) pos_change = order.volume else: trade_price = max(order.price, short_best_price) pos_change = -order.volume if self.trade_count != 0: trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%Y:%m:%d %H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime # 这个self.datetime是在传bar数据的时候确定的日期,为什么这个交易时间不直接放进去 self.strategy.pos += pos_change # pos是外部引擎处理的 self.strategy.on_trade(trade) # 把这笔交易推送出去交易 self.trades[trade.vt_tradeid] = trade
def cross_stop_order(self): """ Cross stop order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.high_price short_cross_price = self.bar.low_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.last_price short_cross_price = self.tick.last_price long_best_price = long_cross_price short_best_price = short_cross_price for stop_order in list(self.active_stop_orders.values()): # Check whether stop order can be triggered. long_cross = ( stop_order.direction == Direction.LONG and stop_order.price <= long_cross_price ) short_cross = ( stop_order.direction == Direction.SHORT and stop_order.price >= short_cross_price ) if not long_cross and not short_cross: continue # Create order data. self.limit_order_count += 1 order = OrderData( symbol=self.symbol, exchange=self.exchange, orderid=str(self.limit_order_count), direction=stop_order.direction, offset=stop_order.offset, price=stop_order.price, volume=stop_order.volume, status=Status.ALLTRADED, gateway_name=self.gateway_name, ) self.limit_orders[order.vt_orderid] = order # Create trade data. if long_cross: trade_price = max(stop_order.price, long_best_price) pos_change = order.volume else: trade_price = min(stop_order.price, short_best_price) pos_change = -order.volume self.trade_count += 1 trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime self.trades[trade.vt_tradeid] = trade # Update stop order. stop_order.vt_orderid = order.vt_orderid stop_order.status = StopOrderStatus.TRIGGERED self.active_stop_orders.pop(stop_order.stop_orderid) # Push update to strategy. self.strategy.on_stop_order(stop_order) self.strategy.on_order(order) self.strategy.pos += pos_change self.strategy.on_trade(trade)
def cross_limit_order(self): """ Cross limit order with last bar/tick data. """ if self.mode == BacktestingMode.BAR: long_cross_price = self.bar.low_price short_cross_price = self.bar.high_price long_best_price = self.bar.open_price short_best_price = self.bar.open_price else: long_cross_price = self.tick.ask_price_1 short_cross_price = self.tick.bid_price_1 long_best_price = long_cross_price short_best_price = short_cross_price for order in list(self.active_limit_orders.values()): # Push order update with status "not traded" (pending). if order.status == Status.SUBMITTING: order.status = Status.NOTTRADED self.strategy.on_order(order) # Check whether limit orders can be filled. long_cross = ( order.direction == Direction.LONG and order.price >= long_cross_price and long_cross_price > 0 ) short_cross = ( order.direction == Direction.SHORT and order.price <= short_cross_price and short_cross_price > 0 ) if not long_cross and not short_cross: continue # Push order udpate with status "all traded" (filled). order.traded = order.volume order.status = Status.ALLTRADED self.strategy.on_order(order) self.active_limit_orders.pop(order.vt_orderid) # Push trade update self.trade_count += 1 if long_cross: trade_price = min(order.price, long_best_price) pos_change = order.volume else: trade_price = max(order.price, short_best_price) pos_change = -order.volume trade = TradeData( symbol=order.symbol, exchange=order.exchange, orderid=order.orderid, tradeid=str(self.trade_count), direction=order.direction, offset=order.offset, price=trade_price, volume=order.volume, time=self.datetime.strftime("%H:%M:%S"), gateway_name=self.gateway_name, ) trade.datetime = self.datetime self.strategy.pos += pos_change self.strategy.on_trade(trade) self.trades[trade.vt_tradeid] = trade