Exemplo n.º 1
0
 def market_close(self, event: Event, account: AbstractAccount,
                  data_portal: DataPortal):
     account.cancel_all_open_orders()
     for code in account.positions.keys():
         sell_order = MKTOrder(code, OrderDirection.SELL,
                               account.positions[code], event.visible_time)
         account.place_order(sell_order)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
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
Exemplo n.º 4
0
 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
Exemplo n.º 5
0
 def ensure():
     try:
         time.sleep(period)
         logging.info("ensure order filled thread start")
         if order.status == OrderStatus.CREATED or order.status == OrderStatus.PARTIAL_FILLED \
                 or order.status == OrderStatus.SUBMITTED:
             account.cancel_open_order(order)
             # 保证下单的总价值是相同的
             remain_quantity = order.quantity - order.filled_quantity
             cp = data_portal.current_price(
                 [order.code],
                 Timestamp.now(tz='Asia/Shanghai'))[order.code]
             new_quantity = int(remain_quantity * order.limit_price /
                                cp.price)
             now = Timestamp.now(tz='Asia/Shanghai')
             if retry_count > 1:
                 new_order = LimitOrder(order.code, order.direction,
                                        new_quantity, now, cp.price)
             else:
                 new_order = MKTOrder(order.code, order.direction,
                                      new_quantity, now)
             account.place_order(new_order)
             if retry_count > 1:
                 self.ensure_order_filled(account, data_portal,
                                          new_order, period,
                                          retry_count - 1)
         else:
             logging.info("没有还未成交的订单, 不需要ensure")
     except:
         import traceback
         err_msg = "ensure order filled失败:{}".format(
             traceback.format_exc())
         logging.error(err_msg)
         # 显示告警,因为在线程的Runable方法中,不能再抛出异常。
         do_alarm('ensure order filled', AlarmLevel.ERROR, None, None,
                  '{}'.format(traceback.format_exc()))
Exemplo n.º 6
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})

        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
Exemplo n.º 7
0
 def do_ensure():
     try:
         now = Timestamp.now(tz='Asia/Shanghai')
         threshold = now + Timedelta(seconds=duration)
         while now <= threshold:
             if (order.status == OrderStatus.CANCELED) or (
                     order.status == OrderStatus.FILLED
             ) or order.status == OrderStatus.FAILED:
                 logging.info("没有为成交的订单,不需要ensure")
                 break
             bid_ask = None
             try:
                 bid_ask: BidAsk = data_portal.current_bid_ask(
                     [order.code])[order.code]
             except:
                 pass
             if bid_ask:
                 if order.direction == OrderDirection.BUY:
                     target_price = bid_ask.bid_price + delta
                     # 乘以1.1是为了防止跟自己的出价进行比较
                     if abs(target_price -
                            order.limit_price) > delta * 1.1:
                         order.limit_price = target_price
                         update_reason = "当前时间:{}, 订单的限价:{}, 最新的买卖价:{}, 设定的delta:{}".\
                             format(now, order.limit_price, bid_ask.__dict__, delta)
                         account.update_order(order, update_reason)
                 else:
                     target_price = bid_ask.ask_price - delta
                     if abs(target_price -
                            order.limit_price) > delta * 1.1:
                         order.limit_price = target_price
                         update_reason = "当前时间:{}, 订单的限价:{}, 最新的买卖价:{}, 设定的delta:{}". \
                             format(now, order.limit_price, bid_ask.__dict__, delta)
                         new_order = account.update_order(
                             order, update_reason)
                         if new_order:
                             # 针对td的情况,修改订单意味着取消原来的订单,并且创建一个新的订单
                             # 这个时候需要启动监听线程
                             new_duration = (threshold - now).seconds
                             self.ensure_order_filled_v2(
                                 account, data_portal, new_order,
                                 new_duration, delta)
                             pass
             time.sleep(0.1)
             now = Timestamp.now(tz='Asia/Shanghai')
         if order.status == OrderStatus.CREATED or order.status == OrderStatus.SUBMITTED or \
                 order.status == OrderStatus.PARTIAL_FILLED:
             logging.info("订单在规定时间内没有成交,将会使用市价单挂单")
             account.cancel_open_order(order)
             new_order = MKTOrder(
                 order.code, order.direction,
                 int(order.quantity - order.filled_quantity), now)
             account.place_order(new_order)
             # 一般情况下,市价单会立即成交,但是存在某个资产不可卖空的情况,这种情况下,市价单可能会被保留
             # 针对这种情况,需要取消掉,以免在不合适的时候成交
             time.sleep(10)
             if new_order.status == OrderStatus.SUBMITTED or new_order.status == OrderStatus.PARTIAL_FILLED:
                 logging.info(
                     "市价单没有在规定的时间内成交,猜想可能是因为没有资产不可卖空导致的,将会取消订单")
                 account.cancel_open_order(new_order)
     except:
         import traceback
         err_msg = "ensure order filled失败:{}".format(
             traceback.format_exc())
         logging.error(err_msg)
         # 显示告警,因为在线程的Runable方法中,不能再抛出异常。
         do_alarm('ensure order filled', AlarmLevel.ERROR, None, None,
                  '{}'.format(traceback.format_exc()))
Exemplo n.º 8
0
    def _to_order(self, od_model: UserOrderModel) -> Order:
        if od_model.type == "MKTOrder":
            o = MKTOrder(od_model.code, OrderDirection(od_model.direction),
                         od_model.quantity,
                         self._to_timestamp(od_model.place_time))
        elif od_model.type == "LimitOrder":
            o = LimitOrder(od_model.code, OrderDirection(od_model.direction),
                           od_model.quantity,
                           self._to_timestamp(od_model.place_time),
                           od_model.limit_price)
        elif od_model.type == "DelayMKTOrder":
            o = DelayMKTOrder(od_model.code,
                              OrderDirection(od_model.direction),
                              od_model.quantity,
                              self._to_timestamp(od_model.place_time),
                              Timedelta(od_model.delay_time))
        elif od_model.type == 'CrossMKTOrder':
            o = CrossMKTOrder(od_model.code,
                              OrderDirection(od_model.direction),
                              od_model.quantity,
                              self._to_timestamp(od_model.place_time),
                              CrossDirection(od_model.cross_direction),
                              od_model.cross_price)
        else:
            raise RuntimeError("wrong order type")
        new_execution_map = {}
        for exec_id in od_model.execution_map.keys():
            oe_model: UserOrderExecutionModel = od_model.execution_map[exec_id]
            oe = OrderExecution(exec_id, oe_model.version, oe_model.commission,
                                oe_model.filled_quantity,
                                oe_model.filled_avg_price,
                                self._to_timestamp(oe_model.filled_start_time),
                                self._to_timestamp(oe_model.filled_end_time),
                                OrderDirection(oe_model.direction),
                                oe_model.attributes)
            new_execution_map[exec_id] = oe
        o.execution_map = new_execution_map

        o.filled_start_time = self._to_timestamp(od_model.filled_start_time)
        o.filled_end_time = self._to_timestamp(od_model.filled_end_time)
        o.filled_avg_price = od_model.filled_avg_price
        o.filled_quantity = od_model.filled_quantity
        o.status = OrderStatus(od_model.status)
        return o