def on_kline_update_callback(self, kline: Kline): ''' 最新1分钟k线来了,我们需要更新此model的signal''' if self.running_status == 'stopping': #如果是停止状态就不工作了 return if kline.symbol not in self.symbols: return self.last_kline = kline self.last_kline_end_dt = kline.end_dt midnight = ModelAPI.find_last_datetime_by_time_str( self.last_kline_end_dt, reference_time_str='00:00:00.000') if self.last_midnight != midnight: self.last_midnight = midnight #新的一天到了 self.lag_ret_matrix.append([]) self.lag_ret_matrix[-1].append(self.last_kline.lag_ret_fillna) if len( self.lag_ret_matrix ) == self.mode_params['warmup_period'] + 1: #有了三天的数据后,从第四天起就开始工作 self.generate_factor() #产生因子 self.generate_signal() #通过因子生成信号 self.generate_target_position() #通过信号生成仓位 elif len( self.lag_ret_matrix ) > self.mode_params['warmup_period'] + 1: #历史数据超过三天,前四天+'今天'=共五天 self.lag_ret_matrix.pop(0) #前第四天的数据去掉,只需要保存前三天的数据 #策略正式工作以后,每当新的一天到来,都将仓位,信号等都清0,重新开始计算 self.factor = np.nan self.signal = np.nan self.target_position['BTC'] = 0.0
def on_time(self): ''' 每5秒定时被驱动,检查k线是否断连''' if self.running_status == 'stopping': #如果是停止状态就不工作了 return now = ModelAPI.current_milli_timestamp() if self.last_kline_end_dt == None: self.last_kline_end_dt = now if now - self.last_kline_end_dt > self.latency: #超过2分钟 self.factor = np.nan self.signal = np.nan self.target_position['BTC'] = 0.0 self.running_status = 'stopping'
async def init_asset(self): """ 读取回测配置信息中的初始化资产,通知上层策略 """ ts = ModelAPI.current_milli_timestamp() d = config.backtest["feature"][self._platform]["asset"] for (k, v) in d.items(): self._assets[k]["free"] = float(v) self._assets[k]["total"] = float(v) #通知上层策略 ast = Asset(self._platform, self._account, self._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast)
def on_history_kline(self, kline: Kline): ''' 加载历史数据''' if kline.symbol not in self.symbols: return midnight = ModelAPI.find_last_datetime_by_time_str( kline.end_dt, reference_time_str='00:00:00.000') if self.last_midnight != midnight: self.last_midnight = midnight #新的一天来了 self.lag_ret_matrix.append([]) #为新的一天创建一个空列表用于保存相关数据 self.lag_ret_matrix[-1].append(kline.lag_ret_fillna) if len(self.lag_ret_matrix ) > self.mode_params['warmup_period'] + 1: #前三天+'今天'=共四天 self.lag_ret_matrix.pop(0) #只需要前三天的完整数据,把前第四天的去掉
async def get_assets(self): """ 获取交易账户资产信息 Args: None Returns: assets: Asset if successfully, otherwise it's None. error: Error information, otherwise it's None. """ ts = ModelAPI.current_milli_timestamp() ast = Asset(self._platform, self._account, self._assets, ts, True) return ast, None
async def load_history_data(self, platform, symbol): """ 加载历史数据 """ now = ModelAPI.current_milli_timestamp() prev = now - 4 * 24 * 60 * 60 * 1000 #四天的数据 ks = await ModelAPI.get_klines_between(platform, symbol, prev, now) for k in ks: kwargs = { "platform": platform, "symbol": symbol, "timestamp": k["begin_dt"], "kline_type": const.MARKET_TYPE_KLINE } kwargs.update(k) #填充剩余字段 kline = Kline(**kwargs) for model in self.models: model.on_history_kline(kline)
async def on_orderbook_update_callback(self, orderbook: Orderbook): """ 订单薄更新 """ logger.info("orderbook:", orderbook, caller=self) if not (self.ready_main and self.ready_reference): return #必须两个交易所都准备好,才能正常工作 if orderbook.platform == self.platform_reference: #保存[从交易所]的行情 self.last_update_time_reference = ModelAPI.timenow_unix_time() self.last_orderbook_reference = orderbook elif orderbook.platform == self.platform_main: #[主交易所]来行情了 self.last_update_time_main = ModelAPI.timenow_unix_time() self.last_orderbook_main = orderbook #检查策略运行状态 if self.running_status == 1: if self.calc_asset_imbalance(): logger.warn( "Asset imbalance reaches maximum, can not continue !!!", caller=self) return if self.calc_time_diff_delay(): logger.info( "Orderbook time delay is bigger than maximum, can not continue !!!", caller=self) return direction, sell_side_arb_space, buy_side_arb_space = self.check_arb_space( self.volume_frac2) #检查是否有套利空间 if direction != 'empty': if direction == 'sell': #卖方向上有套利机会([主交易所]卖, [从交易所]买) self.limit_order_direction = direction self.limit_order_sell_price = sell_side_arb_space[0] self.limit_order_volume = sell_side_arb_space[1] self.market_order_buy_price = sell_side_arb_space[2] #sell_side_arb_space = [sell_price, sell_volume, buy_price, buy_volume, buy_level] #需要在main标的挂单,sell,价格是sell_price, 数量是sell_volume, 挂单类型是FAK, #即在下单之后,一直监听成交情况,遇到第一笔fill,我们记录main标的成交数量volume_filled, #然后马上对main标的剩余单子,全部撤单,同时,需要在reference标的,市价单提交订单, #buy,数量是volume_filled,价格是self.market_order_buy_price + self.slippage success, error = await self.create_order( self.trader_main, self.symbols_main[0], ORDER_ACTION_SELL, self.limit_order_sell_price, self.limit_order_volume) if error != None: return self.main_order_id = success elif direction == 'buy': #买方向上有套利机会([主交易所]买, [从交易所]卖) self.limit_order_direction = direction self.limit_order_buy_price = buy_side_arb_space[0] self.limit_order_volume = buy_side_arb_space[1] self.market_order_sell_price = buy_side_arb_space[2] #buy_side_arb_space = [buy_price, buy_volume, sell_price, sell_volume, sell_level] #需要在main标的挂单,buy,价格是buy_price, 数量是buy_volume, 挂单类型是FAK, #即在下单之后,一直监听成交情况,遇到第一笔fill,我们记录main标的成交数量volume_filled, #然后马上对main标的剩余单子,全部撤单,同时,需要在reference标的,市价单提交订单, #sell,数量是volume_filled, 价格是self.market_order_sell_price - self.slippage success, error = await self.create_order( self.trader_main, self.symbols_main[0], ORDER_ACTION_BUY, self.limit_order_buy_price, self.limit_order_volume) if error != None: return self.main_order_id = success #更新策略运行状态 self.running_status = 2 #因为我前面下单采用的是ioc类型的订单,这种类型订单的特点就是提交订单后如果不能马上(部分)成交就会立刻撤销订单 #所以不需要下面的代码去执行撤单逻辑, 所以暂时先注释掉 elif self.running_status == 2: _, sell_side_arb_space, buy_side_arb_space = self.check_arb_space( self.volume_frac1) if self.limit_order_direction == 'sell': cond1 = sell_side_arb_space[0] is None #套利空间已经消失 cond2 = sell_side_arb_space[ 0] is not None and sell_side_arb_space[ 1] < self.limit_order_volume #实际挂单数量已经大于可套利数量 cond3 = self.last_orderbook_main.asks[0][ 0] < self.limit_order_sell_price #挂单已经不是第一档位 if cond1 or cond2 or cond3: #接下来需要对main标的撤单, 并对策略状态相关参数归位 await self.revoke_order(self.trader_main, self.symbols_main[0], self.main_order_id) self.running_status = 1 elif self.limit_order_direction == 'buy': cond1 = buy_side_arb_space[0] is None #套利空间已经消失 cond2 = buy_side_arb_space[ 0] is not None and buy_side_arb_space[ 1] < self.limit_order_volume #实际挂单数量已经大于可套利数量 cond3 = self.last_orderbook_main.bids[0][ 0] > self.limit_order_buy_price #挂单已经不是第一档位 if cond1 or cond2 or cond3: #接下来需要对main标的撤单, 并对策略状态相关参数归位 await self.revoke_order(self.trader_main, self.symbols_main[0], self.main_order_id) self.running_status = 1
async def create_order(self, action, price, quantity, order_type=ORDER_TYPE_LIMIT): """ 下单 """ if not self._last_kline or not self._last_kline.usable: return None, "无法创建订单" #获取符号相关信息 syminfo = config.backtest["feature"][self._platform]["syminfo"][self._symbol] price_tick = syminfo["price_tick"] #价格变动最小精度 size_tick = syminfo["size_tick"] #下单数量变动最小精度 size_limit = syminfo["size_limit"] #下单数量最小限制 value_tick = syminfo["value_tick"] #下单金额变动最小精度 value_limit = syminfo["value_limit"] #下单金额最小限制 base_currency = syminfo["base_currency"] #基础币种,交易标的,或者说就是'货' settlement_currency = syminfo["settlement_currency"] #结算币种,或者说就是'钱' #输入参数验证 if order_type == ORDER_TYPE_MARKET: if price: return None, "无法创建订单,市价单价格必须填0" if action == ORDER_ACTION_BUY: #市价买单quantity代表的是下单金额 if quantity < value_limit: return None, "无法创建订单,下单金额太少" if not self.precision_verify(quantity, value_tick): return None, "无法创建订单,下单金额精度错误" else: if quantity < size_limit: return None, "无法创建订单,下单数量太少" if not self.precision_verify(quantity, size_tick): return None, "无法创建订单,下单数量精度错误" else: if price <= 0: return None, "无法创建订单,价格必须大于0" if not self.precision_verify(price, price_tick): return None, "无法创建订单,价格精度错误" if quantity < size_limit: return None, "无法创建订单,下单数量太少" if not self.precision_verify(quantity, size_tick): return None, "无法创建订单,下单数量精度错误" #获取当前时间 ts = ModelAPI.current_milli_timestamp() # if order_type == ORDER_TYPE_MARKET: #市价单 if action == ORDER_ACTION_BUY: #买 bc = self._trader._assets[base_currency] sc = self._trader._assets[settlement_currency] if quantity > sc['free']: return None, "账户余额不够" #收盘均价模拟成交价 tradeprice = tools.nearest(self._last_kline.close_avg_fillna, price_tick) #市价买单quantity指的是'钱',逼真模拟 tradevolmue, left_money = self.market_buy_order_cross(quantity, tradeprice, size_tick) #市价买单quantity指的是'钱' #tradevolmue = quantity/tradeprice #对于现货交易,手续费是从接收币种里面扣除 fee = tradevolmue*self.taker_commission_rate #订单通知 order_no = self.next_order_no() o = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "order_no": order_no, "action": action, "symbol": self._symbol, "price": 0, "quantity": tools.nearest(quantity, value_tick), "remain": tools.nearest(left_money, value_tick), "status": ORDER_STATUS_FILLED, "order_type": order_type, "ctime": ts, "utime": ts #avg_price #trade_type } order = Order(**o) if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(order) #成交通知 fill_no = self.next_fill_no() f = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "fill_no": fill_no, "order_no": order_no, "side": action, #成交方向,买还是卖 "symbol": self._symbol, "price": tools.nearest(tradeprice, price_tick), #成交价格 "quantity": tools.nearest(tradevolmue, size_tick), #成交数量 "liquidity": LIQUIDITY_TYPE_TAKER, #maker成交还是taker成交 "fee": tools.nearest(fee, size_tick), "ctime": ts } fill = Fill(**f) if self.cb.on_fill_update_callback: await self.cb.on_fill_update_callback(fill) #账户资产通知 #'货'增加 bc['free'] += (tradevolmue-fee) bc['free'] = tools.nearest(bc['free'], size_tick) bc['total'] = bc['free'] + bc['locked'] bc['total'] = tools.nearest(bc['total'], size_tick) #'钱'减少 sc['free'] -= quantity #市价买单quantity指的是'钱' sc['free'] = tools.nearest(sc['free'], value_tick) sc['total'] = sc['free'] + sc['locked'] sc['total'] = tools.nearest(sc['total'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) elif action == ORDER_ACTION_SELL: #卖 bc = self._trader._assets[base_currency] sc = self._trader._assets[settlement_currency] if quantity > bc['free']: return None, "账户币不足" #收盘均价模拟成交价 tradeprice = tools.nearest(self._last_kline.close_avg_fillna, price_tick) trademoney = quantity*tradeprice #对于现货交易,手续费是从接收币种里面扣除 fee = trademoney*self.taker_commission_rate trademoney -= fee #订单通知 order_no = self.next_order_no() o = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "order_no": order_no, "action": action, "symbol": self._symbol, "price": 0, "quantity": tools.nearest(quantity, size_tick), "remain": 0, "status": ORDER_STATUS_FILLED, "order_type": order_type, "ctime": ts, "utime": ts #avg_price #trade_type } order = Order(**o) if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(order) #成交通知 fill_no = self.next_fill_no() f = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "fill_no": fill_no, "order_no": order_no, "side": action, #成交方向,买还是卖 "symbol": self._symbol, "price": tools.nearest(tradeprice, price_tick), #成交价格 "quantity": tools.nearest(quantity, size_tick), #成交数量 "liquidity": LIQUIDITY_TYPE_TAKER, #maker成交还是taker成交 "fee": tools.nearest(fee, value_tick), "ctime": ts } fill = Fill(**f) if self.cb.on_fill_update_callback: await self.cb.on_fill_update_callback(fill) #账户资产通知 #'货'减少 bc['free'] -= quantity bc['free'] = tools.nearest(bc['free'], size_tick) bc['total'] = bc['free'] + bc['locked'] bc['total'] = tools.nearest(bc['total'], size_tick) #'钱'增加 sc['free'] += trademoney sc['free'] = tools.nearest(sc['free'], value_tick) sc['total'] = sc['free'] + sc['locked'] sc['total'] = tools.nearest(sc['total'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) elif order_type == ORDER_TYPE_LIMIT: #限价单 if action == ORDER_ACTION_BUY: #买 bc = self._trader._assets[base_currency] sc = self._trader._assets[settlement_currency] if quantity*price > sc['free']: return None, "账户余额不够" #如果下单价格小于当前价格,那意味着无法成交,订单将进入订单薄挂着 if price < self._last_kline.close_avg_fillna: #订单通知 order_no = self.next_order_no() o = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "order_no": order_no, "action": action, "symbol": self._symbol, "price": tools.nearest(price, price_tick), "quantity": tools.nearest(quantity, size_tick), "remain": tools.nearest(quantity, size_tick), "status": ORDER_STATUS_SUBMITTED, "order_type": order_type, "ctime": ts, "utime": ts #avg_price #trade_type } order = Order(**o) self._orders[order_no] = order #进入订单簿 if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(order) #账户资产通知 #'钱'需要被锁定一部分 sc['locked'] += quantity*price #挂单部分所占用的资金需要被锁定 sc['locked'] = tools.nearest(sc['locked'], value_tick) sc['free'] = sc['total'] - sc['locked'] sc['free'] = tools.nearest(sc['free'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) else: #直接成交 #收盘均价模拟成交价 tradeprice = tools.nearest(self._last_kline.close_avg_fillna, price_tick) tradevolmue = quantity #直接模拟全部成交 trademoney = tradeprice*tradevolmue #成交金额 #对于现货交易,手续费是从接收币种里面扣除 fee = tradevolmue*self.taker_commission_rate #订单通知 order_no = self.next_order_no() o = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "order_no": order_no, "action": action, "symbol": self._symbol, "price": tools.nearest(price, price_tick), "quantity": tools.nearest(quantity, size_tick), "remain": 0, "status": ORDER_STATUS_FILLED, "order_type": order_type, "ctime": ts, "utime": ts #avg_price #trade_type } order = Order(**o) if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(order) #成交通知 fill_no = self.next_fill_no() f = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "fill_no": fill_no, "order_no": order_no, "side": action, #成交方向,买还是卖 "symbol": self._symbol, "price": tools.nearest(tradeprice, price_tick), #成交价格 "quantity": tools.nearest(tradevolmue, size_tick), #成交数量 "liquidity": LIQUIDITY_TYPE_TAKER, #maker成交还是taker成交 "fee": tools.nearest(fee, size_tick), "ctime": ts } fill = Fill(**f) if self.cb.on_fill_update_callback: await self.cb.on_fill_update_callback(fill) #账户资产通知 #'货'增加 bc['free'] += (tradevolmue-fee) bc['free'] = tools.nearest(bc['free'], size_tick) bc['total'] = bc['free'] + bc['locked'] bc['total'] = tools.nearest(bc['total'], size_tick) #'钱'减少 sc['free'] -= trademoney sc['free'] = tools.nearest(sc['free'], value_tick) sc['total'] = sc['free'] + sc['locked'] sc['total'] = tools.nearest(sc['total'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) elif action == ORDER_ACTION_SELL: #卖 bc = self._trader._assets[base_currency] sc = self._trader._assets[settlement_currency] if quantity > bc['free']: return None, "账户币不足" #如果下单价格大于当前价格,那意味着无法成交,订单将进入订单薄挂着 if price > self._last_kline.close_avg_fillna: #订单通知 order_no = self.next_order_no() o = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "order_no": order_no, "action": action, "symbol": self._symbol, "price": tools.nearest(price, price_tick), "quantity": tools.nearest(quantity, size_tick), "remain": tools.nearest(quantity, size_tick), "status": ORDER_STATUS_SUBMITTED, "order_type": order_type, "ctime": ts, "utime": ts #avg_price #trade_type } order = Order(**o) self._orders[order_no] = order #进入订单簿 if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(order) #账户资产通知 #'货'需要被锁定一部分 bc['locked'] += quantity #挂单部分所占用的'货'需要被锁定 bc['locked'] = tools.nearest(bc['locked'], size_tick) bc['free'] = bc['total'] - bc['locked'] bc['free'] = tools.nearest(bc['free'], size_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) else: #直接成交 #收盘均价模拟成交价 tradeprice = tools.nearest(self._last_kline.close_avg_fillna, price_tick) trademoney = quantity*tradeprice #对于现货交易,手续费是从接收币种里面扣除 fee = trademoney*self.taker_commission_rate trademoney -= fee #订单通知 order_no = self.next_order_no() o = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "order_no": order_no, "action": action, "symbol": self._symbol, "price": tools.nearest(price, price_tick), "quantity": tools.nearest(quantity, size_tick), "remain": 0, "status": ORDER_STATUS_FILLED, "order_type": order_type, "ctime": ts, "utime": ts #avg_price #trade_type } order = Order(**o) if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(order) #成交通知 fill_no = self.next_fill_no() f = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "fill_no": fill_no, "order_no": order_no, "side": action, #成交方向,买还是卖 "symbol": self._symbol, "price": tools.nearest(tradeprice, price_tick), #成交价格 "quantity": tools.nearest(quantity, size_tick), #成交数量 "liquidity": LIQUIDITY_TYPE_TAKER, #maker成交还是taker成交 "fee": tools.nearest(fee, value_tick), "ctime": ts } fill = Fill(**f) if self.cb.on_fill_update_callback: await self.cb.on_fill_update_callback(fill) #账户资产通知 #'货'减少 bc['free'] -= quantity bc['free'] = tools.nearest(bc['free'], size_tick) bc['total'] = bc['free'] + bc['locked'] bc['total'] = tools.nearest(bc['total'], size_tick) #'钱'增加 sc['free'] += trademoney sc['free'] = tools.nearest(sc['free'], value_tick) sc['total'] = sc['free'] + sc['locked'] sc['total'] = tools.nearest(sc['total'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) elif order_type == ORDER_TYPE_IOC: raise NotImplementedError #返回订单号 return order_no, None
async def make_trade(self): """ 尝试和订单列表中的订单进行撮合成交 """ #遍历订单簿里面所有挂单 os = copy.copy(self._orders) for (k, o) in os.items(): syminfo = config.backtest["feature"][self._platform]["syminfo"][self._symbol] price_tick = syminfo["price_tick"] #价格变动最小精度 size_tick = syminfo["size_tick"] #下单数量变动最小精度 value_tick = syminfo["value_tick"] #下单金额变动最小精度 base_currency = syminfo["base_currency"] #基础币种,交易标的,或者说就是'货' settlement_currency = syminfo["settlement_currency"] #结算币种,或者说就是'钱' bc = self._trader._assets[base_currency] sc = self._trader._assets[settlement_currency] if o.action == ORDER_ACTION_BUY: #买单 if o.price >= self._last_kline.close_avg_fillna: #当前价格可以成交 ts = ModelAPI.current_milli_timestamp() #收盘均价模拟成交价 tradeprice = tools.nearest(self._last_kline.close_avg_fillna, price_tick) tradevolmue = o.quantity #直接模拟全部成交 trademoney = tradeprice*tradevolmue #成交金额 #对于现货交易,手续费是从接收币种里面扣除 fee = tradevolmue*self.maker_commission_rate #订单通知 o.remain = 0 o.status = ORDER_STATUS_FILLED o.utime = ts if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(o) #成交通知 fill_no = self.next_fill_no() f = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "fill_no": fill_no, "order_no": o.order_no, "side": o.action, #成交方向,买还是卖 "symbol": self._symbol, "price": tools.nearest(tradeprice, price_tick), #成交价格 "quantity": tools.nearest(tradevolmue, size_tick), #成交数量 "liquidity": LIQUIDITY_TYPE_MAKER, #maker成交还是taker成交 "fee": tools.nearest(fee, size_tick), "ctime": ts } fill = Fill(**f) if self.cb.on_fill_update_callback: await self.cb.on_fill_update_callback(fill) #账户资产通知 #'货'增加 bc['free'] += (tradevolmue-fee) bc['free'] = tools.nearest(bc['free'], size_tick) bc['total'] = bc['free'] + bc['locked'] bc['total'] = tools.nearest(bc['total'], size_tick) #释放挂单占用的'钱' sc['locked'] -= o.quantity*o.price sc['locked'] = tools.nearest(sc['locked'], value_tick) sc['free'] = sc['total'] - sc['locked'] #'钱'减少 sc['free'] -= trademoney sc['free'] = tools.nearest(sc['free'], value_tick) sc['total'] = sc['free'] + sc['locked'] sc['total'] = tools.nearest(sc['total'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) #删除订单簿中的订单 del self._orders[o.order_no] elif o.action == ORDER_ACTION_SELL: #卖单 if o.price <= self._last_kline.close_avg_fillna: #当前价格可以成交 ts = ModelAPI.current_milli_timestamp() #收盘均价模拟成交价 tradeprice = tools.nearest(self._last_kline.close_avg_fillna, price_tick) trademoney = o.quantity*tradeprice #模拟全部成交 #对于现货交易,手续费是从接收币种里面扣除 fee = trademoney*self.maker_commission_rate trademoney -= fee #订单通知 o.remain = 0 o.status = ORDER_STATUS_FILLED o.utime = ts if self.cb.on_order_update_callback: await self.cb.on_order_update_callback(o) #成交通知 fill_no = self.next_fill_no() f = { "platform": self._platform, "account": self._account, "strategy": self._strategy, "fill_no": fill_no, "order_no": o.order_no, "side": o.action, #成交方向,买还是卖 "symbol": self._symbol, "price": tools.nearest(tradeprice, price_tick), #成交价格 "quantity": tools.nearest(o.quantity, size_tick), #成交数量 "liquidity": LIQUIDITY_TYPE_MAKER, #maker成交还是taker成交 "fee": tools.nearest(fee, value_tick), "ctime": ts } fill = Fill(**f) if self.cb.on_fill_update_callback: await self.cb.on_fill_update_callback(fill) #账户资产通知 #释放挂单占用的'货' bc['locked'] -= o.quantity bc['locked'] = tools.nearest(bc['locked'], size_tick) bc['free'] = bc['total'] - bc['locked'] #'货'减少 bc['free'] -= o.quantity bc['free'] = tools.nearest(bc['free'], size_tick) bc['total'] = bc['free'] + bc['locked'] bc['total'] = tools.nearest(bc['total'], size_tick) #'钱'增加 sc['free'] += trademoney sc['free'] = tools.nearest(sc['free'], value_tick) sc['total'] = sc['free'] + sc['locked'] sc['total'] = tools.nearest(sc['total'], value_tick) # ast = Asset(self._platform, self._account, self._trader._assets, ts, True) if self.cb.on_asset_update_callback: await self.cb.on_asset_update_callback(ast) #删除订单簿中的订单 del self._orders[o.order_no]