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 __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 __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撤单成功。
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
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
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
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
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
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
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
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