Ejemplo n.º 1
0
    async def on_event_orderbook_update(self):
        """订单薄更新"""
        await asyncio.sleep(0.1)

        bid1_price = self.exchange.bids[0]  # 买一价格
        bid5_price = self.exchange.bids[4]  # 买五价格

        # 如果已有挂单,且在价格区间内,就不需要执行任何操作
        if self.order_no and bid5_price < self.exchange.open_orders(clOrdID="")[0]["price"] < bid1_price:
            return

        # 如果存在挂单但不在价格区间内,就撤单;如果没有挂单也执行挂单操作
        else:
            if self.order_no:
                self.exchange.revoke_order(self.order_no)
                logger.info("撤销订单:{}".format(self.order_no))
            # 创建新订单
            new_price = (bid1_price + bid5_price) / 2
            price = round(new_price)  # bitmex的XBTUSD合约价格精度限制为下单价格必须是例如10000.0 或10000.5,此处简化处理为取整数
            quantity = 5  # 假设委托数量为5
            # 限价订单
            order_no = self.exchange.generate_uuid()  # 生成机器码作为自己维护的client order id
            self.exchange.buy(price, quantity, clOrdID=order_no)
            logger.info("创建订单:{}".format(order_no))
            sleep(0.5)  # 下单后等待一下,因为websocket获取当前挂单信息也有延迟,防止重复挂单
 async def on_event_asset_update(self):
     """资产更新"""
     while True:
         if self.exchange.asset != self.asset:  # 如果资产有变化就打印变化后的资产信息
             logger.info("asset:{}".format(self.exchange.asset))
             self.asset = self.exchange.asset
         await asyncio.sleep(0.1)
Ejemplo n.º 3
0
 async def on_event_order_update(self):
     """订单状态更新"""
     await asyncio.sleep(0.1)
     if not self.exchange.open_orders(clOrdID=""):  # 如果订单失败、订单取消、订单完成交易,即当前无挂单
         self.order_no = None
     elif self.exchange.open_orders(clOrdID="") and self.exchange.open_orders(clOrdID="")[0]['clOrdID'] != self.order_no:  # 有挂单且订单有变化
         logger.info("订单更新:{}".format(self.exchange.open_orders(clOrdID="")))  # 订单变动时打印最新的订单信息
         self.order_no = self.exchange.open_orders(clOrdID="")[0]['clOrdID']
 async def on_event_order_update(self):
     """订单状态更新"""
     while True:
         if not self.exchange.open_orders(clOrdID=""):  # 如果当前无挂单
             self.order_no = ""
         elif self.exchange.open_orders(
                 clOrdID=""
         ) and self.exchange.open_orders(
                 clOrdID="")[0]['clOrdID'] != self.order_no:  # 有挂单且订单有变化
             logger.info("order update:{}".format(
                 self.exchange.open_orders(clOrdID="")))  # 订单变动时打印最新的订单信息
             self.order_no = self.exchange.open_orders(
                 clOrdID="")[0]['clOrdID']
         await asyncio.sleep(0.1)
Ejemplo n.º 5
0
    def begin_trade(self, kline=None):
        try:
            if self.indicators.CurrentBar(kline=kline) < self.slow_length:  # 如果k线数据不够长就返回
                return
            timestamp = ts_to_datetime_str(utctime_str_to_ts(kline[-1][0])) if kline else get_localtime()    # 非回测模式下时间戳就是当前本地时间
            # 计算策略信号
            ma = self.indicators.MA(self.fast_length, self.slow_length, kline=kline)
            fast_ma = ma[0]
            slow_ma = ma[1]
            cross_over = fast_ma[-2] >= slow_ma[-2] and fast_ma[-3] < slow_ma[-3]   # 不用当根k线上的ma来计算信号,防止信号闪烁
            cross_below = slow_ma[-2] >= fast_ma[-2] and slow_ma[-3] < fast_ma[-3]
            if self.indicators.BarUpdate(kline=kline):     # 如果k线更新,计数器归零
                self.counter = 0
            if self.counter < 1:
                # 按照策略信号开平仓
                if cross_over:     # 金叉时
                    if self.position.amount() == 0:     # 若当前无持仓,则买入开多并推送下单结果
                        price = self.market.open(-1, kline=kline)  # 下单价格=此根k线收盘价
                        amount = round(self.total_asset / self.contract_value)   # 数量=总资金/价格/合约面值
                        info = self.exchange.buy(price, amount)
                        push(info)
                        storage.mysql_save_strategy_run_info(self.database, self.datasheet, timestamp, "买入开多",
                                                        price, amount, amount * self.contract_value, price,
                                                        "long", amount, 0, self.total_profit, self.total_asset)     # 将信息保存至数据库
                    if self.position.direction() == 'short':    # 若当前持空头,先平空再开多
                        profit = self.position.covershort_profit(market_type="usd_contract", last=self.market.open(-1, kline=kline))  # 在平空前先计算逻辑盈亏,当前最新成交价为开盘价
                        self.total_profit += profit
                        self.total_asset += profit  # 计算此次盈亏后的总资金
                        cover_short_price = self.market.open(-1, kline=kline)
                        cover_short_amount = self.position.amount()
                        open_long_price = self.market.open(-1, kline=kline)
                        open_long_amount = round(self.total_asset / self.contract_value)
                        info = self.exchange.BUY(cover_short_price, cover_short_amount, open_long_price, open_long_amount)
                        push("此次盈亏:{} 当前总资金:{}".format(profit, self.total_asset) + str(info))   # 需将返回的下单结果info转换为字符串后进行拼接
                        storage.mysql_save_strategy_run_info(self.database, self.datasheet, timestamp, "平空开多",
                                                        open_long_price, open_long_amount, open_long_amount * self.contract_value,
                                                        open_long_price, "long", open_long_amount, profit, self.total_profit, self.total_asset)
                if cross_below:     # 死叉时
                    if self.position.amount() == 0:
                        price = self.market.open(-1, kline=kline)
                        amount = round(self.total_asset / self.contract_value)
                        info = self.exchange.sellshort(price, amount)
                        push(info)
                        storage.mysql_save_strategy_run_info(self.database, self.datasheet, timestamp, "卖出开空",
                                                    price, amount, amount * self.contract_value, price,
                                                    "short", amount, 0, self.total_profit, self.total_asset)
                    if self.position.direction() == 'long':
                        profit = self.position.coverlong_profit(market_type="usd_contract", last=self.market.open(-1, kline=kline))     # 在平多前先计算逻辑盈亏,当前最新成交价为开盘价
                        self.total_profit += profit
                        self.total_asset += profit
                        cover_long_price = self.market.open(-1, kline=kline)
                        cover_long_amount = self.position.amount()
                        open_short_price = self.market.open(-1, kline=kline)
                        open_short_amount = round(self.total_asset / self.contract_value)
                        info = self.exchange.SELL(cover_long_price,
                                                  cover_long_amount,
                                                  open_short_price,
                                                  open_short_amount)
                        push("此次盈亏:{} 当前总资金:{}".format(profit, self.total_asset) + str(info))
                        storage.mysql_save_strategy_run_info(self.database, self.datasheet, timestamp, "平多开空",
                                                        open_short_price, open_short_amount,
                                                        open_short_amount * self.contract_value,
                                                        open_short_price, "short", open_short_amount, profit, self.total_profit,
                                                        self.total_asset)
                # 止损
                if self.position.amount() > 0:
                    if self.position.direction() == 'long' and self.market.low(-1, kline=kline) <= self.position.price() * self.long_stop:    # 多单止损
                        profit = self.position.coverlong_profit(market_type="usd_contract", last=self.position.price() * self.long_stop)    # 在平多前先计算逻辑盈亏,当前最新成交价为止损价
                        self.total_profit += profit
                        self.total_asset += profit
                        price = self.position.price() * self.long_stop
                        amount = self.position.amount()
                        info = self.exchange.sell(price, amount)
                        push("此次盈亏:{} 当前总资金:{}".format(profit, self.total_asset) + str(info))
                        storage.mysql_save_strategy_run_info(self.database, self.datasheet, timestamp,
                                                        "卖出止损", price, amount,
                                                        amount * self.contract_value,
                                                        0, "none", 0, profit, self.total_profit,
                                                        self.total_asset)
                        self.counter += 1   # 计数器加1,控制此根k线上不再下单

                    if self.position.direction() == 'short' and self.market.high(-1, kline=kline) >= self.position.price() * self.short_stop:  # 空头止损
                        profit = self.position.covershort_profit(market_type="usd_contract", last=self.position.price() * self.short_stop)
                        self.total_profit += profit
                        self.total_asset += profit
                        price = self.position.price() * self.short_stop
                        amount = self.position.amount()
                        info = self.exchange.buytocover(price, amount)
                        push("此次盈亏:{} 当前总资金:{}".format(profit, self.total_asset) + str(info))
                        storage.mysql_save_strategy_run_info(self.database, self.datasheet, timestamp,
                                                        "买入止损", price, amount,
                                                        amount * self.contract_value,
                                                        0, "none", 0, profit, self.total_profit,
                                                        self.total_asset)
                        self.counter += 1
        except:
            logger.info()
Ejemplo n.º 6
0
 def begin_trade(self, kline=None):
     try:
         if self.indicators.CurrentBar(
                 kline=kline) < self.slow_length:  # 如果k线数据不够长就返回
             return
         timestamp = ts_to_datetime_str(utctime_str_to_ts(
             kline[-1]
             [0])) if kline else get_localtime()  # 非回测模式下时间戳就是当前本地时间
         # 计算策略信号
         ma = self.indicators.MA(self.fast_length,
                                 self.slow_length,
                                 kline=kline)
         fast_ma = ma[0]
         slow_ma = ma[1]
         cross_over = fast_ma[-2] >= slow_ma[-2] and fast_ma[-3] < slow_ma[
             -3]  # 不用当根k线上的ma来计算信号,防止信号闪烁
         cross_below = slow_ma[-2] >= fast_ma[-2] and slow_ma[-3] < fast_ma[
             -3]
         if self.indicators.BarUpdate(kline=kline):  # 如果k线更新,计数器归零
             self.counter = 0
         if self.counter < 1:
             # 按照策略信号开平仓
             if cross_over and round(
                     self.position.amount()
             ) < self.precision:  # 金叉时,若当前无持仓,则买入开多并推送下单结果。0.1这个数值根据每个币对的最小交易数量决定
                 price = float(self.market.open(
                     -1, kline=kline))  # 下单价格=此根k线开盘价
                 self.hold_price = price  # 记录开仓价格
                 amount = float(self.total_asset / price)  # 数量=总资金/价格
                 info = self.exchange.buy(price, amount)
                 push(info)
                 storage.mysql_save_strategy_run_info(
                     self.database, self.datasheet, timestamp, "买入开多",
                     price, amount, amount * price, price, "long", amount,
                     0, self.total_profit, self.total_asset)  # 将信息保存至数据库
             if cross_below and round(
                     self.position.amount(), 1
             ) >= self.precision:  # 死叉时,如果当前持多就卖出平多。当前持仓数量根据币对的最小交易数量取小数
                 price = float(self.market.open(-1, kline=kline))
                 amount = float(self.position.amount())
                 profit = (price - self.hold_price) * amount  # 计算逻辑盈亏
                 self.total_profit += profit
                 self.total_asset += profit
                 info = self.exchange.sell(price, amount)
                 push(info)
                 self.hold_price = 0  # 平多后记录持仓价格为0
                 storage.mysql_save_strategy_run_info(
                     self.database, self.datasheet, timestamp, "卖出平多",
                     price, amount, amount * price, 0, "none", 0, profit,
                     self.total_profit, self.total_asset)
             # 如果当前持多且最低价小于等于持仓均价*止损幅度,触发止损,卖出平多止损
             if round(self.position.amount(),
                      1) >= self.precision and self.market.low(
                          -1,
                          kline=kline) <= self.hold_price * self.long_stop:
                 price = float(self.hold_price * self.long_stop)
                 amount = float(self.position.amount())
                 profit = (price - self.hold_price) * amount  # 计算逻辑盈亏
                 self.total_profit += profit
                 self.total_asset += profit
                 info = self.exchange.sell(price, amount)
                 push("此次盈亏:{} 当前总资金:{}".format(profit, self.total_asset) +
                      str(info))
                 self.hold_price = 0  # 平多后记录持仓价格为0
                 storage.mysql_save_strategy_run_info(
                     self.database, self.datasheet, timestamp, "卖出止损",
                     price, amount, amount * price, 0, "none", 0, profit,
                     self.total_profit, self.total_asset)
                 self.counter += 1  # 计数器加1,控制此根k线上不再下单
     except Exception as e:
         logger.info()