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._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._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: 价格撮合器
    :ivar marks: 绘图标志集合
    """

    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._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):
        """ 提交订单,撮合,更新持仓 """
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        if not self._orders:
            # 没有交易信号,确保至少运行一次
            self.events_pool.put(OnceEvent())
        self._process_trading_events(at_baropen)
        self._orders = []

    def _process_trading_events(self, at_baropen):
        """"""
        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.route == Event.SIGNAL:
                    assert not at_baropen
                    self.blotter.update_signal(event)
                elif event.route == Event.ORDER:
                    assert not at_baropen
                    self.exchange.insert_order(event)
                elif event.route == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            # @TODO tick 回测不一样
            if event.route == Event.ONCE or event.route == Event.ORDER:
                self.exchange.make_market(self.blotter._bars, at_baropen)
        self.blotter.update_status(self._datetime, at_baropen)

    def plot_line(self, name, ith_window, x, y, styles, lw=1, ms=10, twinx=False):
        """ 绘制曲线

        Args:
            name (str): 标志名称
            ith_window (int): 在第几个窗口显示,从1开始。
            x (datetime): 时间坐标
            y (float): y坐标
            styles (str): 控制颜色,线的风格,点的风格
            lw (int): 线宽
            ms (int): 点的大小
        """
        mark = self.marks[0].setdefault(name, [])
        mark.append((ith_window, twinx, x, y, styles, lw, ms))

    def plot_text(self, name, ith_window, x, y, text, color="black", size=15, rotation=0):
        """ 绘制文本

        Args:
            name (str): 标志名称
            ith_window (int): 在第几个窗口显示,从1开始。
            x (float): x坐标
            y (float): y坐标
            text (str): 文本内容
            color (str): 颜色
            size (int): 字体大小
            rotation (float): 旋转角度
        """
        mark = self.marks[1].setdefault(name, [])
        mark.append((ith_window, x, y, text, color, size, rotation))

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

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

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

    def cover(self, price, quantity, price_type, contract):
        self._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收盘处处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                # @TODO or self._orders ?
                # 结合实盘考虑, 实盘可能自动撤单。
                self._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):
    """ 策略组合

    :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 #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(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 #13
0
class StrategyContext(object):
    """ 策略组合

    :ivar name: 策略名
    :ivar blotter: 订单管理
    :ivar exchange: 价格撮合器
    :ivar marks: 绘图标志集合
    """
    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._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):
        """ 提交订单,撮合,更新持仓 """
        if self._orders:
            self.events_pool.put(SignalEvent(self._orders))
        if not self._orders:
            # 没有交易信号,确保至少运行一次
            self.events_pool.put(OnceEvent())
        self._process_trading_events(at_baropen)
        self._orders = []

    def _process_trading_events(self, at_baropen):
        """"""
        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.route == Event.SIGNAL:
                    assert (not at_baropen)
                    self.blotter.update_signal(event)
                elif event.route == Event.ORDER:
                    assert (not at_baropen)
                    self.exchange.insert_order(event)
                elif event.route == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            # @TODO tick 回测不一样
            if event.route == Event.ONCE or event.route == Event.ORDER:
                self.exchange.make_market(self.blotter._bars, at_baropen)
        self.blotter.update_status(self._datetime, at_baropen)

    def plot_line(self,
                  name,
                  ith_window,
                  x,
                  y,
                  styles,
                  lw=1,
                  ms=10,
                  twinx=False):
        """ 绘制曲线

        Args:
            name (str): 标志名称
            ith_window (int): 在第几个窗口显示,从1开始。
            x (datetime): 时间坐标
            y (float): y坐标
            styles (str): 控制颜色,线的风格,点的风格
            lw (int): 线宽
            ms (int): 点的大小
        """
        mark = self.marks[0].setdefault(name, [])
        mark.append((ith_window, twinx, x, y, styles, lw, ms))

    def plot_text(self,
                  name,
                  ith_window,
                  x,
                  y,
                  text,
                  color='black',
                  size=15,
                  rotation=0):
        """ 绘制文本

        Args:
            name (str): 标志名称
            ith_window (int): 在第几个窗口显示,从1开始。
            x (float): x坐标
            y (float): y坐标
            text (str): 文本内容
            color (str): 颜色
            size (int): 字体大小
            rotation (float): 旋转角度
        """
        mark = self.marks[1].setdefault(name, [])
        mark.append((ith_window, x, y, text, color, size, rotation))

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

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

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

    def cover(self, price, quantity, price_type, contract):
        self._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收盘处处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                # @TODO or self._orders ?
                # 结合实盘考虑, 实盘可能自动撤单。
                self._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 #14
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 #15
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
Example #16
0
class TradingDelegator(object):
    """"""
    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._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

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

    def _process_trading_events(self, at_baropen):
        """"""
        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.route == Event.SIGNAL:
                    assert (not at_baropen)
                    self.blotter.update_signal(event)
                elif event.route == Event.ORDER:
                    assert (not at_baropen)
                    self.exchange.insert_order(event)
                elif event.route == Event.FILL:
                    # 模拟交易接口收到报单成交
                    self.blotter.api.on_transaction(event)
            # 价格撮合。note: bar价格撮合要求撮合置于运算后面。
            # @TODO tick 回测不一样
            if event.route == Event.ONCE or event.route == Event.ORDER:
                self.exchange.make_market(self.blotter._bars, at_baropen)
        self.blotter.update_status(self._datetime, at_baropen)

    def buy(self, price, quantity, symbol=None):
        """ 开多仓

        Args:
            price (float): 价格, 0表市价。
            quantity (int): 数量。
            symbol (str): 合约
        """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能下单!')
        if symbol:
            contract = Contract(symbol) if isinstance(symbol, str) else symbol
        else:
            contract = self.contract
        price_type = PriceType.MKT if price == 0 else PriceType.LMT
        self._orders.append(
            Order(None, contract, price_type, TradeSide.OPEN, Direction.LONG,
                  float(price), quantity))

    def sell(self, price, quantity, symbol=None):
        """ 平多仓。

        Args:
           price (float): 价格, 0表市价。
           quantity (int): 数量。
           symbol (str): 合约
        """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能下单!')
        if symbol:
            contract = Contract(symbol) if isinstance(symbol, str) else symbol
        else:
            contract = self.contract
        price_type = PriceType.MKT if price == 0 else PriceType.LMT
        self._orders.append(
            Order(None, contract, price_type, TradeSide.CLOSE, Direction.LONG,
                  float(price), quantity))

    def short(self, price, quantity, symbol=None):
        """ 开空仓

        Args:
            price (float): 价格, 0表市价。
            quantity (int): 数量。
            symbol (str): 合约
        """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能下单!')
        if symbol:
            contract = Contract(symbol) if isinstance(symbol, str) else symbol
        else:
            contract = self.contract
        price_type = PriceType.MKT if price == 0 else PriceType.LMT
        self._orders.append(
            Order(None, contract, price_type, TradeSide.OPEN, Direction.SHORT,
                  float(price), quantity))

    def cover(self, price, quantity, symbol=None):
        """ 平空仓。

        Args:
           price (float): 价格, 0表市价。
           quantity (int): 数量。
           symbol (str): 合约
        """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能下单!')
        if symbol:
            contract = Contract(symbol) if isinstance(symbol, str) else symbol
        else:
            contract = self.contract
        price_type = PriceType.MKT if price == 0 else PriceType.LMT
        self._orders.append(
            Order(None, contract, price_type, TradeSide.CLOSE, 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收盘处处理撤单
            for order in orders:
                norder = copy.deepcopy(order)
                norder.side = TradeSide.CANCEL
                # @TODO or self._orders ?
                # 结合实盘考虑, 实盘可能自动撤单。
                self._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 list(self.blotter.open_orders)

    def all_positions(self):
        """ 返回所有持仓列表 [Position] """
        return list(six.itervalues(self.blotter.positions))

    def position(self, direction='long', symbol=None):
        """ 合约当前持仓仓位。

        Args:
            direction (str/int): 持仓方向。多头 - 'long' / 1 ;空头 - 'short'  / 2
            , 默认为多头。

            symbol (str): 字符串合约,默认为None表示主合约。

        Returns:
            Position. 该合约的持仓
        """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能查询当前持仓!')
        direction = Direction.arg_to_type(direction)
        contract = Contract(symbol) if symbol else \
            self.contract
        # @TODO assert direction
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey]
        except KeyError:
            return None

    def pos(self, direction='long', symbol=None):
        """  合约的当前可平仓位。

        Args:
            direction (str/int): 持仓方向。多头 - 'long' / 1 ;空头 - 'short'  / 2
            , 默认为多头。

            symbol (str): 字符串合约,默认为None表示主合约。

        Returns:
            int. 该合约的持仓数目。
        """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能查询当前持仓!')
        direction = Direction.arg_to_type(direction)
        # @TODO symbol xxxxx
        contract = Contract(symbol) if symbol else \
            self.contract
        # @TODO assert direction
        try:
            poskey = PositionKey(contract, direction)
            return self.blotter.positions[poskey].closable
        except KeyError:
            return 0

    def cash(self):
        """ 现金。 """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能查询可用资金!')
        return self.blotter.holding['cash']

    def equity(self):
        """ 当前权益 """
        if not self.on_bar:
            raise Exception('只有on_bar函数内能查询当前权益!')
        return self.blotter.holding['equity']

    def profit(self, contract=None):
        """ 当前持仓的历史盈亏 """
        # if not self.on_bar:
        # log.warn('只有on_bar函数内能查询总盈亏!')
        # return
        pass

    def day_profit(self, contract=None):
        """ 当前持仓的浮动盈亏 """
        #if not self.on_bar:
        #log.warn('只有on_bar函数内能查询浮动盈亏!')
        #return
        pass

    def test_cash(self):
        """  当根bar时间终点撮合后的可用资金,用于测试。 """
        self.process_trading_events(at_baropen=False)
        return self.cash()

    def test_equity(self):
        """  当根bar时间终点撮合后的权益,用于测试。 """
        self.process_trading_events(at_baropen=False)
        return self.equity()