Example #1
0
 def __init__(self, name, settings={}):
     self.events_pool = EventsPool()
     self.blotter = SimpleBlotter(name, self.events_pool, settings)
     self.exchange = Exchange(name, self.events_pool, strict=True)
     self.name = name
     self._orders = []
     self._datetime = None
Example #2
0
 def __init__(self, name, settings={ }):
     self.events_pool = EventsPool()
     self.blotter = SimpleBlotter(name, self.events_pool, settings)
     self.exchange = Exchange(name, self.events_pool, strict=True)
     self.name = name
     self._orders = []
     self._datetime = None
     self._cancel_now = False # 是当根bar还是下一根bar撤单成功。
Example #3
0
 def __init__(self, name, settings={}):
     self.events_pool = EventsPool()
     # @TODO merge blotter and exchange
     self.blotter = SimpleBlotter(name, self.events_pool, settings)
     self.exchange = Exchange(name, self.events_pool, strict=True)
     self.name = name
     # 0: line_marks, 1: text_marks
     self.marks = [{}, {}]
     self._entry_orders = []
     self._exit_orders = []
     self._datetime = None
     self._cancel_now = False  # 是当根bar还是下一根bar撤单成功。
Example #4
0
 def __init__(self, name, settings={ }):
     self.events_pool = EventsPool()
     self.blotter = SimpleBlotter(name, self.events_pool, settings)
     self.exchange = Exchange(self.events_pool, strict=False)
     self.name = name
     self._orders = []
     self._datetime = None
Example #5
0
 def __init__(self, name, settings={ }):
     self.events_pool = EventsPool()
     self.blotter = SimpleBlotter(name, self.events_pool, settings)
     self.exchange = Exchange(name, self.events_pool, strict=True)
     self.name = name
     self._orders = []
     self._datetime = None
     self._cancel_now = False # 是当根bar还是下一根bar撤单成功。
Example #6
0
 def __init__(self, name, settings={}):
     self.events_pool = EventsPool()
     # @TODO merge blotter and exchange
     self.blotter = SimpleBlotter(name, self.events_pool, settings)
     self.exchange = Exchange(name, self.events_pool, strict=True)
     self.name = name
     # 0: line_marks, 1: text_marks
     self.marks = [{}, {}]
     self._entry_orders = []
     self._exit_orders = []
     self._datetime = None
     self._cancel_now = False  # 是当根bar还是下一根bar撤单成功。
Example #7
0
class StrategyContext(object):
    """ 策略组合

    :ivar name: 策略名
    :ivar blotter: 订单管理
    :ivar exchange: 价格撮合器
    """
    def __init__(self, name, settings={}):
        self.events_pool = EventsPool()
        # @TODO merge blotter and exchange
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(name, self.events_pool, strict=True)
        self.name = name
        self._entry_orders = []
        self._exit_orders = []
        self._datetime = None
        self._cancel_now = False  # 是当根bar还是下一根bar撤单成功。

    def update_environment(self, dt, ticks, bars):
        """ 更新模拟交易所和订单管理器的数据,时间,持仓 """
        self.blotter.update_datetime(dt)
        self.exchange.update_datetime(dt)
        self.blotter.update_data(ticks, bars)
        self._datetime = dt
        return

    def process_trading_events(self, at_baropen):
        """ 提交订单,撮合,更新持仓 """
        append = at_baropen
        entry_flag = True
        exit_flag = True
        if self._exit_orders:
            self.events_pool.put(SignalEvent(self._exit_orders))
            self._process_trading_events(at_baropen, at_baropen)
            self._exit_orders = []
            exit_flag = False
            append = False
        if self._entry_orders:
            self.events_pool.put(SignalEvent(self._entry_orders))
            self._process_trading_events(at_baropen, append)
            self._entry_orders = []
            entry_flag = False
            append = False
        # 没有交易信号,确保至少运行一次
        if exit_flag and entry_flag:
            self.events_pool.put(OnceEvent())
            self._process_trading_events(at_baropen, append)

    def _process_trading_events(self, at_baropen, append):
        """"""
        while True:
            # 事件处理。
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                assert (False)
            except IndexError:
                break
            else:
                #if event.type == 'MARKET':
                ##strategy.calculate_signals(event)
                #port.update_timeindex(event)
                if event.type == Event.SIGNAL:
                    assert (not at_baropen)
                    self.blotter.update_signal(event)
                elif event.type == Event.ORDER:
                    assert (not at_baropen)
                    self.exchange.insert_order(event)
                elif event.type == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            # @TODO tick 回测不一样
            if event.type == Event.ONCE or event.type == Event.ORDER:
                self.exchange.make_market(self.blotter._bars, at_baropen)
        self.blotter.update_status(self._datetime, at_baropen, append)
        return

    def buy(self, price, quantity, price_type, contract):
        self._entry_orders.append(
            Order(None, contract, price_type, TradeSide.KAI, Direction.LONG,
                  float(price), quantity))

    def sell(self, price, quantity, price_type, contract):
        self._exit_orders.append(
            Order(None, contract, price_type, TradeSide.PING, Direction.LONG,
                  float(price), quantity))

    def short(self, price, quantity, price_type, contract):
        self._entry_orders.append(
            Order(None, contract, price_type, TradeSide.KAI, Direction.SHORT,
                  float(price), quantity))

    def cover(self, price, quantity, price_type, contract):
        self._exit_orders.append(
            Order(None, contract, price_type, TradeSide.PING, Direction.SHORT,
                  float(price), quantity))

    def cancel(self, orders):
        """ 撤单

        Args:
            orders (list/Order): 撤单,参数为list表示撤多个单。
        """
        orders = orders if isinstance(orders, list) else [orders]
        if not self._cancel_now:
            # bar close点处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                # @TODO or self._exit_orders ?
                # 结合实盘考虑, 实盘可能自动撤单。
                self._entry_orders.append(norder)
            return
        ## 立即处理撤单
        #temp = copy.deepcopy(self._orders)
        #self._orders = []
        #for order in orders:
        #order.side = TradeSide.CANCEL
        #self._orders.append(order)
        #self.process_trading_events(False)
        #self._orders = temp

    @property
    def open_orders(self):
        """ 未成交的订单 """
        return self.blotter.open_orders

    def all_positions(self):
        return self.blotter.positions.values()

    def position(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey]
        except KeyError:
            return None

    def pos(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey].closable
        except KeyError:
            return 0

    def cash(self):
        return self.blotter.holding['cash']

    def equity(self):
        return self.blotter.holding['equity']

    def profit(self, contract):
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """
        pass
Example #8
0
class StrategyContext(object):
    """ 策略组合"""
    def __init__(self, name, settings={ }):
        self.events_pool = EventsPool()
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(self.events_pool, strict=False)
        self.name = name
        self._orders = []
        self._datetime = None

    def update_environment(self, dt, ticks, bars):
        """ 更新模拟交易所和订单管理器的环境。
        
        Args:
            dt (datetime): 时间戳

            ticks (dict): 所有订阅合约的最新价格
        
        """
        self.exchange.update_datetime(dt)
        self.blotter.update_datetime(dt)
        self.blotter.update_data(ticks, bars)
        self._datetime = dt
        return

    def process_trading_events(self):
        # 一次策略循环可能产生多个委托单。
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        self._orders = []
        maked = False # 保证至少一次价格撮合。
        while True:
           # 事件处理。 
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                if maked:
                    break
            except IndexError:
                break
            else:
                if event is not None:
                    #if event.type == 'MARKET':
                        #strategy.calculate_signals(event)
                        #port.update_timeindex(event)
                    if event.type == Event.SIGNAL:
                        self.blotter.update_signal(event)

                    elif event.type == Event.ORDER:
                        self.exchange.insert_order(event)

                    elif event.type == Event.FILL:
                        # 模拟交易接口收到报单成交
                        self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            self.exchange.make_market(self.blotter._bars)
            maked = True

    def buy(self, direction, price, quantity, price_type, contract):
        self._orders.append(Order(
                ## @todo 时间放到blotter中设置
                self._datetime,
                contract,
                PriceType.arg_to_type(price_type),
                TradeSide.KAI,
                Direction.arg_to_type(direction),
                float(price),
                quantity
        ))

    def sell(self, direction, price, quantity, price_type, contract):
        self._orders.append(Order(
                self._datetime,
                contract,
                PriceType.arg_to_type(price_type),
                TradeSide.PING,
                Direction.arg_to_type(direction),
                float(price),
                quantity
        ))

    def position(self, contract):
        try:
            return self.blotter.current_positions[contract].quantity
        except KeyError:
            return 0

    def cash(self):
        return self.blotter.current_holdings['cash']

    def equity(self):
        return self.blotter.current_holdings['equity']

    def profit(self, contract):
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """ 
        pass
Example #9
0
class StrategyContext(object):
    """ 策略组合"""
    def __init__(self, name, settings={}):
        self.events_pool = EventsPool()
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(name, self.events_pool, strict=True)
        self.name = name
        self._orders = []
        self._datetime = None

    def update_environment(self, dt, ticks, bars):
        """ 更新模拟交易所和订单管理器的数据,时间,持仓 """
        self.blotter.update_datetime(dt)
        self.exchange.update_datetime(dt)
        self.blotter.update_data(ticks, bars)
        self._datetime = dt
        return

    def process_trading_events(self, append):
        """ 提交订单,撮合,更新持仓 """
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        self._orders = []
        new_signal = False  # 保证至少一次价格撮合。
        event = None
        while True:
            # 事件处理。
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                assert (False)
            except IndexError:
                if new_signal:
                    break
            else:
                #if event.type == 'MARKET':
                #strategy.calculate_signals(event)
                #port.update_timeindex(event)
                if event.type == Event.SIGNAL:
                    try:
                        self.blotter.update_signal(event)
                    except TradingError as e:
                        logger.debug(e)
                        return
                elif event.type == Event.ORDER:
                    self.exchange.insert_order(event)
                elif event.type == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            if event == None or event.type == Event.ORDER:
                self.exchange.make_market(self.blotter._bars)
                new_signal = True
        self.blotter.update_status(self._datetime, append)

    def buy(self, direction, price, quantity, price_type, contract):
        self._orders.append(
            Order(None, contract, price_type, TradeSide.KAI, direction,
                  float(price), quantity))

    def sell(self, direction, price, quantity, price_type, contract):
        self._orders.append(
            Order(None, contract, price_type, TradeSide.PING, direction,
                  float(price), quantity))

    def position(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey].quantity
        except KeyError:
            return 0

    def cash(self):
        return self.blotter.holding['cash']

    def equity(self):
        return self.blotter.holding['equity']

    def profit(self, contract):
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """
        pass
Example #10
0
class StrategyContext(object):
    """ 策略组合

    :ivar name: 策略名
    :ivar blotter: 订单管理
    :ivar exchange: 价格撮合器
    """
    def __init__(self, name, settings={}):
        self.events_pool = EventsPool()
        # @TODO merge blotter and exchange
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(name, self.events_pool, strict=True)
        self.name = name
        self._entry_orders = []
        self._exit_orders = []
        self._datetime = None
        self._cancel_now = False  # 是当根bar还是下一根bar撤单成功。

    def update_environment(self, dt, ticks, bars):
        """ 更新模拟交易所和订单管理器的数据,时间,持仓 """
        self.blotter.update_datetime(dt)
        self.exchange.update_datetime(dt)
        self.blotter.update_data(ticks, bars)
        self._datetime = dt
        return

    def process_trading_events(self, at_baropen):
        """ 提交订单,撮合,更新持仓 """
        append = at_baropen
        entry_flag = True
        exit_flag = True
        if self._exit_orders:
            self.events_pool.put(SignalEvent(self._exit_orders))
            self._process_trading_events(at_baropen, at_baropen)
            self._exit_orders = []
            exit_flag = False
            append = False
        if self._entry_orders:
            self.events_pool.put(SignalEvent(self._entry_orders))
            self._process_trading_events(at_baropen, append)
            self._entry_orders = []
            entry_flag = False
            append = False
        # 没有交易信号,确保至少运行一次
        if exit_flag and entry_flag:
            self.events_pool.put(OnceEvent())
            self._process_trading_events(at_baropen, append)

    def _process_trading_events(self, at_baropen, append):
        """"""
        while True:
            # 事件处理。
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                assert(False)
            except IndexError:
                break
            else:
                #if event.type == 'MARKET':
                    ##strategy.calculate_signals(event)
                    #port.update_timeindex(event)
                if event.type == Event.SIGNAL:
                    assert(not at_baropen)
                    self.blotter.update_signal(event)
                elif event.type == Event.ORDER:
                    assert(not at_baropen)
                    self.exchange.insert_order(event)
                elif event.type == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            # @TODO tick 回测不一样
            if event.type == Event.ONCE or event.type == Event.ORDER:
                self.exchange.make_market(self.blotter._bars, at_baropen)
        self.blotter.update_status(self._datetime, at_baropen, append)
        return

    def buy(self, price, quantity, price_type, contract):
        self._entry_orders.append(Order(
            None,
            contract,
            price_type,
            TradeSide.KAI,
            Direction.LONG,
            float(price),
            quantity
        ))

    def sell(self, price, quantity, price_type, contract):
        self._exit_orders.append(Order(
            None,
            contract,
            price_type,
            TradeSide.PING,
            Direction.LONG,
            float(price),
            quantity
        ))

    def short(self, price, quantity, price_type, contract):
        self._entry_orders.append(Order(
            None,
            contract,
            price_type,
            TradeSide.KAI,
            Direction.SHORT,
            float(price),
            quantity
        ))

    def cover(self, price, quantity, price_type, contract):
        self._exit_orders.append(Order(
            None,
            contract,
            price_type,
            TradeSide.PING,
            Direction.SHORT,
            float(price),
            quantity
        ))

    def cancel(self, orders):
        """ 撤单

        Args:
            orders (list/Order): 撤单,参数为list表示撤多个单。
        """
        orders = orders if isinstance(orders, list) else [orders]
        if not self._cancel_now:
            # bar close点处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                # @TODO or self._exit_orders ?
                # 结合实盘考虑, 实盘可能自动撤单。
                self._entry_orders.append(norder)
            return
        ## 立即处理撤单
        #temp = copy.deepcopy(self._orders)
        #self._orders = []
        #for order in orders:
            #order.side = TradeSide.CANCEL
            #self._orders.append(order)
        #self.process_trading_events(False)
        #self._orders = temp

    @property
    def open_orders(self):
        """ 未成交的订单 """
        return self.blotter.open_orders

    def all_positions(self):
        return self.blotter.positions.values()

    def position(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey]
        except KeyError:
            return None

    def pos(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey].closable
        except KeyError:
            return 0

    def cash(self):
        return self.blotter.holding['cash']

    def equity(self):
        return self.blotter.holding['equity']

    def profit(self, contract):
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """
        pass
Example #11
0
class StrategyContext(object):
    """ 策略组合"""
    def __init__(self, name, settings={ }):
        self.events_pool = EventsPool()
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(name, self.events_pool, strict=True)
        self.name = name
        self._orders = []
        self._datetime = None
        self._cancel_now = False # 是当根bar还是下一根bar撤单成功。

    def update_environment(self, dt, ticks, bars):
        """ 更新模拟交易所和订单管理器的数据,时间,持仓 """ 
        self.blotter.update_datetime(dt)
        self.exchange.update_datetime(dt)
        self.blotter.update_data(ticks, bars)
        self._datetime = dt
        return

    def process_trading_events(self, append):
        """ 提交订单,撮合,更新持仓 """
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        self._orders = []
        new_signal = False # 保证至少一次价格撮合。
        event = None
        while True:
           # 事件处理。 
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                assert(False)
            except IndexError:
                if new_signal:
                    break
            else:
                #if event.type == 'MARKET':
                    #strategy.calculate_signals(event)
                    #port.update_timeindex(event)
                if event.type == Event.SIGNAL:
                    try:
                        self.blotter.update_signal(event)
                    except TradingError as e:
                        new_signal = True
                        logger.warn(e)
                        return
                elif event.type == Event.ORDER:
                    self.exchange.insert_order(event)
                elif event.type == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            if event == None or event.type == Event.ORDER:
                self.exchange.make_market(self.blotter._bars)
                new_signal = True
        self.blotter.update_status(self._datetime, append)

    def buy(self, direction, price, quantity, price_type, contract):
        self._orders.append(Order(
                None,
                contract,
                price_type,
                TradeSide.KAI,
                direction,
                float(price),
                quantity
        ))

    def sell(self, direction, price, quantity, price_type, contract):
        self._orders.append(Order(
                None,
                contract,
                price_type,
                TradeSide.PING,
                direction,
                float(price),
                quantity
        ))

    def cancel(self, orders):
        """ 撤单
        
        Args:
            orders (list/Order): 撤单,参数为list表示撤多个单。
        
        """
        orders = orders if isinstance(orders, list) else [orders]
        if not self._cancel_now:
            # 下一根bar处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                self._orders.append(norder)
            return
        assert(False)
        temp = copy.deepcopy(self._orders)
        self._orders = []
        for order in orders:
            order.side = TradeSide.CANCEL
            self._orders.append(order)
        # 立即处理撤单
        self.process_trading_events(False)
        self._orders = temp
    
    @property
    def open_orders(self):
        """ 未成交的订单 """ 
        return self.blotter.open_orders

    def position(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction) 
            return self.blotter.positions[poskey]
        except KeyError:
            return 0

    def pos(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction) 
            return self.blotter.positions[poskey].closable
        except KeyError:
            return 0

    def cash(self):
        return self.blotter.holding['cash']

    def equity(self):
        return self.blotter.holding['equity']

    def profit(self, contract):
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """ 
        pass
Example #12
0
class StrategyContext(object):
    """ 策略组合"""

    def __init__(self, name, settings={}):
        self.events_pool = EventsPool()
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(self.events_pool, strict=False)
        self.name = name
        self._orders = []
        self._datetime = None

    def update(self, dt, ticks):
        """ 更新模拟交易所和订单管理器的环境。
        
        Args:
            dt (datetime): 时间戳

            ticks (dict): 所有订阅合约的最新价格
        
        """
        self.exchange.update_datetime(dt)
        self.blotter.update_datetime(dt)
        self.blotter.update_ticks(ticks)
        self._datetime = dt
        return

    def process_signals(self, latest_bar):
        # 一次策略循环可能产生多个委托单。
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        self._orders = []
        while True:
            # 事件处理。
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                break
            except IndexError:
                break
            else:
                if event is not None:
                    # if event.type == 'MARKET':
                    # strategy.calculate_signals(event)
                    # port.update_timeindex(event)
                    if event.type == Event.SIGNAL:
                        self.blotter.update_signal(event)

                    elif event.type == Event.ORDER:
                        self.exchange.insert_order(event)

                    elif event.type == Event.FILL:
                        # 模拟交易接口收到报单成交
                        self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            self.exchange.make_market(latest_bar)

    def buy(self, direction, price, quantity, price_type, contract):
        """ 开仓    
        
        Args:
            direction (str/int): 下单方向。多头 - 'long' / 1 ;空头 - 'short'  / 2

            price (float): 价格。

            quantity (int): 数量。

            price_type (str/int): 下单价格类型。限价单 - 'lmt' / 1;市价单 - 'mkt' / 2

            contract (Contract): 合约
        """
        self._orders.append(
            Order(
                ## @todo 时间放到blotter中设置
                self._datetime,
                contract,
                PriceType.arg_to_type(price_type),
                TradeSide.KAI,
                Direction.arg_to_type(direction),
                float(price),
                quantity,
            )
        )

    def sell(self, direction, price, quantity, price_type, contract):
        """ 平仓。
        
        Args:
           direction (str/int): 下单方向。多头 - 'long' / 1 ;空头 - 'short'  / 2

           price (float): 价格。

           quantity (int): 数量。

           price_type (str/int): 下单价格类型。限价单 - 'lmt' / 1;市价单 - 'mkt' / 2

           contract (Contract): 合约
        """
        self._orders.append(
            Order(
                self._datetime,
                contract,
                PriceType.arg_to_type(price_type),
                TradeSide.PING,
                Direction.arg_to_type(direction),
                float(price),
                quantity,
            )
        )

    def position(self, contract):
        """ 当前仓位。
       
        Args:
            contract (Contract): 字符串合约,默认为None表示主合约。
        
        Returns:
            int. 该合约的持仓数目。
        """
        try:
            return self.blotter.current_positions[contract].quantity
        except KeyError:
            return 0

    def cash(self):
        """ 现金。 """
        return self.blotter.current_holdings["cash"]

    def equity(self):
        """ 当前权益 """
        return self.blotter.current_holdings["equity"]

    def profit(self, contract):
        """ 当前持仓的历史盈亏 """
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """
        pass
Example #13
0
class StrategyContext(object):
    """ 策略组合"""
    def __init__(self, name, settings={ }):
        self.events_pool = EventsPool()
        self.blotter = SimpleBlotter(name, self.events_pool, settings)
        self.exchange = Exchange(name, self.events_pool, strict=True)
        self.name = name
        self._orders = []
        self._datetime = None
        self._cancel_now = False # 是当根bar还是下一根bar撤单成功。

    def update_environment(self, dt, ticks, bars):
        """ 更新模拟交易所和订单管理器的数据,时间,持仓 """ 
        self.blotter.update_datetime(dt)
        self.exchange.update_datetime(dt)
        self.blotter.update_data(ticks, bars)
        self._datetime = dt
        return

    def process_trading_events(self, append):
        """ 提交订单,撮合,更新持仓 """
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        self._orders = []
        new_signal = False # 保证至少一次价格撮合。
        event = None
        while True:
           # 事件处理。 
            try:
                event = self.events_pool.get()
            except Queue.Empty:
                assert(False)
            except IndexError:
                if new_signal:
                    break
            else:
                #if event.type == 'MARKET':
                    #strategy.calculate_signals(event)
                    #port.update_timeindex(event)
                if event.type == Event.SIGNAL:
                    try:
                        self.blotter.update_signal(event)
                    except TradingError as e:
                        new_signal = True
                        logger.warn(e)
                        return
                elif event.type == Event.ORDER:
                    self.exchange.insert_order(event)
                elif event.type == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            if event == None or event.type == Event.ORDER:
                self.exchange.make_market(self.blotter._bars)
                new_signal = True
        self.blotter.update_status(self._datetime, append)

    def buy(self, direction, price, quantity, price_type, contract):
        self._orders.append(Order(
                None,
                contract,
                price_type,
                TradeSide.KAI,
                direction,
                float(price),
                quantity
        ))

    def sell(self, direction, price, quantity, price_type, contract):
        self._orders.append(Order(
                None,
                contract,
                price_type,
                TradeSide.PING,
                direction,
                float(price),
                quantity
        ))

    def cancel(self, orders):
        """ 撤单
        
        Args:
            orders (list/Order): 撤单,参数为list表示撤多个单。
        
        """
        orders = orders if isinstance(orders, list) else [orders]
        if not self._cancel_now:
            # 下一根bar处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                self._orders.append(norder)
            return
        assert(False)
        temp = copy.deepcopy(self._orders)
        self._orders = []
        for order in orders:
            order.side = TradeSide.CANCEL
            self._orders.append(order)
        # 立即处理撤单
        self.process_trading_events(False)
        self._orders = temp
    
    @property
    def open_orders(self):
        """ 未成交的订单 """ 
        return self.blotter.open_orders

    def position(self, contract, direction):
        try:
            poskey = PositionKey(contract, direction) 
            return self.blotter.positions[poskey].closable
        except KeyError:
            return 0

    def cash(self):
        return self.blotter.holding['cash']

    def equity(self):
        return self.blotter.holding['equity']

    def profit(self, contract):
        pass

    def day_profit(self, contract):
        """ 当前持仓的浮动盈亏 """ 
        pass