示例#1
0
文件: nr.py 项目: zone21/alphahunter
    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
示例#2
0
文件: nr.py 项目: zone21/alphahunter
 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'
示例#3
0
 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)
示例#4
0
文件: nr.py 项目: zone21/alphahunter
 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)  #只需要前三天的完整数据,把前第四天的去掉
示例#5
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
示例#6
0
 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)
示例#7
0
    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
示例#8
0
 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
示例#9
0
    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]