Ejemplo n.º 1
0
    def update_signal(self, event):
        """ 处理策略函数产生的下单事件。

        可能产生一系列order事件,在bar的开盘时间交易。
        """
        assert event.route == Event.SIGNAL
        new_orders = []
        for order in event.orders:
            errmsg = self._valid_order(order)
            if errmsg == '':
                order.datetime = self._datetime
                new_orders.append(order)
                if order.side == TradeSide.KAI:
                    self.holding['cash'] -= \
                        order.order_margin(self._bars[order.contract].open)
            else:
                logger.warn(errmsg)
                # print len(event.orders), len(new_orders)
                continue
        self.open_orders.update(new_orders)  # 改变对象的值,不改变对象地址。
        self._all_orders.extend(new_orders)
        for order in new_orders:
            self.api.order(copy.deepcopy(order))
        for order in new_orders:
            if order.side == TradeSide.PING:
                pos = self.positions[PositionKey(order.contract,
                                                 order.direction)]
                pos.closable -= order.quantity
Ejemplo n.º 2
0
 def _update_holding(self, trans):
     """ 更新佣金和平仓盈亏。 """
     if trans.side == TradeSide.CANCEL:
         return
     self.holding['commission'] += trans.commission
     # 平仓,更新历史持仓盈亏。
     if trans.side == TradeSide.PING:
         poskey = PositionKey(trans.contract, trans.direction)
         flag = 1 if trans.direction == Direction.LONG else -1
         profit = (trans.price-self.positions[poskey].cost) * \
             trans.quantity * flag * trans.volume_multiple
         self.holding['history_profit'] += profit
     self._all_transactions.append(trans)
Ejemplo n.º 3
0
 def update_datetime(self, dt):
     """ 在新的价格数据来的时候触发。 """
     if self._datetime is None:
         self._datetime = dt
         self._start_date = dt
         self._init_state()
     elif self._datetime.date() != dt.date():
         for order in self.open_orders:
             if order.side == TradeSide.PING:
                 pos = self.positions[PositionKey(order.contract,
                                                  order.direction)]
                 pos.closable += order.quantity
         self.open_orders.clear()
         for key, pos in self.positions.iteritems():
             pos.closable += pos.today
             pos.today = 0
     self._datetime = dt
Ejemplo n.º 4
0
 def _update_positions(self, trans):
     """ 更新持仓 """
     poskey = PositionKey(trans.contract, trans.direction)
     if trans.side == TradeSide.CANCEL:
         pos = self.positions.get(poskey, None)
         if pos:
             pos.closable += trans.quantity
         return
     pos = self.positions.setdefault(poskey, Position(trans))
     if trans.side == TradeSide.KAI:
         pos.cost = (pos.cost*pos.quantity + trans.price*trans.quantity) / \
                     (pos.quantity+trans.quantity)
         pos.quantity += trans.quantity
         if trans.contract.is_stock:
             pos.today += trans.quantity
         else:
             pos.closable += trans.quantity
         assert (pos.quantity == pos.today + pos.closable)
     elif trans.side == TradeSide.PING:
         pos.quantity -= trans.quantity
         if pos.quantity == 0:
             del self.positions[poskey]
Ejemplo n.º 5
0
 def _valid_order(self, order):
     """ 判断订单是否合法。 """
     if order.quantity <= 0:
         return "交易数量要大于0"
     # 撤单
     if order.side == TradeSide.CANCEL:
         if order not in self.open_orders:
             return '撤销失败: 不存在该订单!'
     if order.side == TradeSide.PING:
         try:
             poskey = PositionKey(order.contract, order.direction)
             pos = self.positions[poskey]
             if pos.closable < order.quantity:
                 return '可平仓位不足'
         except KeyError:
             # 没有持有该合约
             # logger.warn("不存在合约[%s]" % order.contract)
             return "不存在合约[%s]" % order.contract
     elif order.side == TradeSide.KAI:
         new_price = self._bars[order.contract].open
         if self.holding['cash'] < order.order_margin(new_price):
             # print self.holding['cash'], new_price * order.quantity
             return '没有足够的资金开仓'
     return ''
Ejemplo n.º 6
0
 def pos(self, contract, direction):
     try:
         poskey = PositionKey(contract, direction)
         return self.blotter.positions[poskey].closable
     except KeyError:
         return 0
Ejemplo n.º 7
0
    def _update_positions(self, current_positions, deal_positions, trans):
        """ 根据交易明细计算开平仓对。 """
        class PositionsDetail(object):
            """ 当前相同合约持仓集合(可能不同时间段下单)。

            :ivar cost: 持仓成本。
            :ivar total: 持仓总数。
            :ivar positions: 持仓集合。
            :vartype positions: list
            """
            def __init__(self):
                self.total = 0
                self.positions = []
                self.cost = 0

        assert trans.quantity > 0
        poskey = PositionKey(trans.contract, trans.direction)
        p = current_positions.setdefault(poskey, PositionsDetail())
        if trans.side == TradeSide.KAI:
            # 开仓
            p.positions.append(trans)
            p.total += trans.quantity

        elif trans.side == TradeSide.PING:
            # 平仓
            assert (len(p.positions) > 0 and '所平合约没有持仓')
            left_vol = trans.quantity
            last_index = 0
            search_index = 0
            p.total -= trans.quantity
            if trans.contract.is_stock:
                for position in reversed(p.positions):
                    # 开仓日期小于平仓时间
                    if position.datetime.date() < trans.datetime.date():
                        break
                    search_index -= 1
            if search_index != 0:
                positions = p.positions[:search_index]
                left_positions = p.positions[search_index:]
            else:
                positions = p.positions
            for position in reversed(positions):
                if position.quantity < left_vol:
                    # 还需从之前的仓位中平。
                    left_vol -= position.quantity
                    last_index -= 1
                    deal_positions.append(
                        OneDeal(position, trans, position.quantity))
                elif position.quantity == left_vol:
                    left_vol -= position.quantity
                    last_index -= 1
                    deal_positions.append(
                        OneDeal(position, trans, position.quantity))
                    break
                else:
                    position.quantity -= left_vol
                    left_vol = 0
                    deal_positions.append(OneDeal(position, trans, left_vol))
                    break
            if last_index != 0 and search_index != 0:
                p.positions = positions[0:last_index] + left_positions
            elif last_index != 0:
                p.positions = positions[0:last_index]
            # last_index == 0, 表示没找到可平的的开仓对,最后一根强平
            # 可以被catch捕获 AssertError
            assert (left_vol == 0 or last_index == 0)