def _init_main_data(self): # 预留了历史和当天的数据空间。 self.open = NumberSeries(self, self._data.open, True) self.close = NumberSeries(self, self._data.close, True) self.high = NumberSeries(self, self._data.high, True) self.low = NumberSeries(self, self._data.low, True) self.volume = NumberSeries(self, self._data.volume, True) self.datetime = DateTimeSeries(self, self._data.index, True) self.curbar = 0
class OriginalData(object): """ A DataContext expose data should be visited by multiple strategie. which including bars of specific PContract. """ def __init__(self, pcontract, raw_data): self.open = NumberSeries(raw_data.open.values, 'open') self.close = NumberSeries(raw_data.close.values, 'close') self.high = NumberSeries(raw_data.high.values, 'high') self.low = NumberSeries(raw_data.low.values, 'low') self.volume = NumberSeries(raw_data.volume.values, 'volume') self.datetime = DateTimeSeries(raw_data.index, 'datetime') self.bar = Bar(None, None, None, None, None, None) self.has_pending_data = False self.next_datetime = datetime.datetime(2100, 1, 1) self.size = len(raw_data.close) self.pcontract = pcontract self._curbar = -1 self._helper = RollingHelper(len(raw_data)) self._raw_data = raw_data @property def raw_data(self): return self._helper.data @property def curbar(self): return self._curbar + 1 @property def contract(self): return self.pcontract.contract def update_vars(self): self._curbar = self._next_bar self.open.update_curbar(self._curbar) self.close.update_curbar(self._curbar) self.high.update_curbar(self._curbar) self.low.update_curbar(self._curbar) self.volume.update_curbar(self._curbar) self.datetime.update_curbar(self._curbar) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) def rolling_forward(self): """ Retrieve data of next step """ self.has_pending_data, self._next_bar = self._helper.rolling_forward() if not self.has_pending_data: return False, None self.next_datetime = self._raw_data.index[self._next_bar] if self.datetime[0] >= self.next_datetime and self.curbar != 0: log.error('合约[%s] 数据时间逆序或冗余' % self.pcontract) raise return True, self.has_pending_data def __len__(self): return len(self._helper)
def __init__(self, pcontract, raw_data): self.open = NumberSeries(raw_data.open.values, 'open') self.close = NumberSeries(raw_data.close.values, 'close') self.high = NumberSeries(raw_data.high.values, 'high') self.low = NumberSeries(raw_data.low.values, 'low') self.volume = NumberSeries(raw_data.volume.values, 'volume') self.datetime = DateTimeSeries(raw_data.index, 'datetime') self.bar = Bar(None, None, None, None, None, None) self.has_pending_data = False self.next_datetime = datetime.datetime(2100, 1, 1) self.size = len(raw_data.close) self.pcontract = pcontract self._curbar = -1 self._helper = RollingHelper(len(raw_data)) self._raw_data = raw_data
def on_init(self, ctx): """初始化数据""" ctx.ma3 = MA(ctx.close, 3) ctx.svar = NumberSeries() ctx.numseries = NumberSeries() ctx.dtseries = DateTimeSeries() ctx.dlist = [] return
def __init__(self, wrapper, window_size): """ window_size: 滚动窗口大小 """ self.wrapper = wrapper self.series = [[{ }]] self.indicators = [[{ }]] self.variables = [[{ }]] data = self.wrapper.data self.window_size = window_size self.open = NumberSeries(data.open.values, self.window_size, 'open') self.close = NumberSeries(data.close.values, self.window_size, 'close') self.high = NumberSeries(data.high.values, self.window_size, 'high') self.low = NumberSeries(data.low.values, self.window_size, 'low') self.volume = NumberSeries(data.volume.values, self.window_size, 'volume') self.datetime = DateTimeSeries(data.index, self.window_size, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self._curbar = -1 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100,1,1)
def __init__(self, Helper): data = Helper.data self.open = NumberSeries(data.open.values, 'open') self.close = NumberSeries(data.close.values, 'close') self.high = NumberSeries(data.high.values, 'high') self.low = NumberSeries(data.low.values, 'low') self.volume = NumberSeries(data.volume.values, 'volume') self.datetime = DateTimeSeries(data.index, 'datetime') self.ith_comb = -1 # 第i个组合 self.ith_strategy = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.new_row = False self.next_datetime = datetime.datetime(2100, 1, 1) self.technicals = [[{}]] self._curbar = -1 self._Helper = Helper self._series = [[{}]] self._variables = [[{}]] self._all_variables = [[{}]] self._size = len(data.close)
def __init__(self, wrapper): data = wrapper.data self.open = NumberSeries(data.open.values, 'open') self.close = NumberSeries(data.close.values, 'close') self.high = NumberSeries(data.high.values, 'high') self.low = NumberSeries(data.low.values, 'low') self.volume = NumberSeries(data.volume.values, 'volume') self.datetime = DateTimeSeries(data.index, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100, 1, 1) self.indicators = [[{}]] self._curbar = -1 self._wrapper = wrapper self._series = [[{}]] self._variables = [[{}]] self._all_variables = [[{}]] self._size = len(data.close)
def __init__(self, data: "dict((s_pcon, DataFrame))", name, settings, strategy, max_window): TradingDelegator.__init__(self, name, settings) PlotterDelegator.__init__(self) self.dt_series = DateTimeSeries([MAX_DATETIME] * max_window, 'universal_time') self.aligned_dt = datetime.datetime(2100, 1, 1) self.aligned_bar_index = 0 self.strategy_name = name self.on_bar = False self.strategy = strategy self.data_ref = DataRef(data)
def __init__(self, data, max_window): self.ctx_dt_series = DateTimeSeries([datetime.datetime(2100, 1, 1)] * max_window, 'universal_time') self.ctx_datetime = datetime.datetime(2100, 1, 1) self.on_bar = False self.step = 0 self._data_contexts = {} # str(PContract): DataContext for key, value in data.iteritems(): self._data_contexts[key] = value self._cur_data_context = None self._strategy_contexts = [] self._cur_strategy_context = None self._ticks = {} # Contract: float self._bars = {} # Contract: Bar
def __init__(self, wrapper, window_size): """ window_size: 滚动窗口大小 """ self.wrapper = wrapper self.series = [[{ }]] self.indicators = [[{ }]] self.variables = [[{ }]] data = self.wrapper.data self.window_size = window_size self.open = NumberSeries(data.open.values, self.window_size, 'open') self.close = NumberSeries(data.close.values, self.window_size, 'close') self.high = NumberSeries(data.high.values, self.window_size, 'high') self.low = NumberSeries(data.low.values, self.window_size, 'low') self.volume = NumberSeries(data.volume.values, self.window_size, 'volume') self.datetime = DateTimeSeries(data.index, self.window_size, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self.curbar = 0 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100,1,1)
def __init__(self, data, max_window): self.ctx_dt_series = DateTimeSeries([datetime.datetime(2100, 1, 1)] * max_window, 'universal_time') self.ctx_datetime = datetime.datetime(2100, 1, 1) self.ctx_curbar = 0 # update by ExecuteUnit self.on_bar = False # pass to on_bar function or on_symbol function self._strategy_contexts = [] self._cur_strategy_context = None self._cur_data_context = None self._data_contexts = {} # str(PContract): DataContext for key, value in data.iteritems(): self._data_contexts[key] = value self._data_contexts[key.split('-')[0]] = value self._data_contexts[key.split('.')[0]] = value # latest price data # Contract -> float # Contract -> Bar self._ticks = {} self._bars = {}
def __init__(self, wrapper): data = wrapper.data self.open = NumberSeries(data.open.values, "open") self.close = NumberSeries(data.close.values, "close") self.high = NumberSeries(data.high.values, "high") self.low = NumberSeries(data.low.values, "low") self.volume = NumberSeries(data.volume.values, "volume") self.datetime = DateTimeSeries(data.index, "datetime") self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100, 1, 1) self.indicators = [[{}]] self._curbar = -1 self._wrapper = wrapper self._series = [[{}]] self._variables = [[{}]] self._size = len(data.close)
class DataContext(object): """ A DataContext expose data should be visited by multiple strategie. which including bars of specific PContract, technicals and series of strategie. """ def __init__(self, Helper): data = Helper.data self.open = NumberSeries(data.open.values, 'open') self.close = NumberSeries(data.close.values, 'close') self.high = NumberSeries(data.high.values, 'high') self.low = NumberSeries(data.low.values, 'low') self.volume = NumberSeries(data.volume.values, 'volume') self.datetime = DateTimeSeries(data.index, 'datetime') self.ith_comb = -1 # 第i个组合 self.ith_strategy = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.new_row = False self.next_datetime = datetime.datetime(2100, 1, 1) self.technicals = [[{}]] self._curbar = -1 self._Helper = Helper self._series = [[{}]] self._variables = [[{}]] self._all_variables = [[{}]] self._size = len(data.close) @property def raw_data(self): return self._Helper.data @property def curbar(self): return self._curbar + 1 @property def pcontract(self): return self._Helper.pcontract @property def contract(self): return self._Helper.pcontract.contract def __getattr__(self, name): return self.get_item(name) def update_system_vars(self): # self.data = np.append(data, tracker.container_day) self._curbar = self.last_curbar self.open.update_curbar(self._curbar) self.close.update_curbar(self._curbar) self.high.update_curbar(self._curbar) self.low.update_curbar(self._curbar) self.volume.update_curbar(self._curbar) self.datetime.update_curbar(self._curbar) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) self.new_row = False def update_user_vars(self): # Update series defined by user if exist. try: series = self._series[self.ith_comb][self.ith_strategy].values() except IndexError: pass else: for s in series: s.update_curbar(self._curbar) s.duplicate_last_element() # Update technicals if exist. try: technicals = self.technicals[self.ith_comb][self.ith_strategy].values() except IndexError: pass else: for tec in technicals: if tec.is_multiple: for s in six.itervalues(tec.series): s.update_curbar(self._curbar) else: for s in tec.series: s.update_curbar(self._curbar) def rolling_forward(self): """ 滚动读取下一步的数据。 """ self.new_row, self.last_curbar = self._Helper.rolling_forward() if not self.new_row: self.last_curbar -= 1 return False, None self.next_datetime = self._Helper.data.index[self.last_curbar] if self.datetime[0] >= self.next_datetime and self.curbar != 0: logger.error('合约[%s] 数据时间逆序或冗余' % self.pcontract) raise return True, self.new_row def __len__(self): return len(self._Helper) def get_item(self, name): """ 获取用户在策略on_init函数中初始化的变量 """ return self._all_variables[self.ith_comb][self.ith_strategy][name] def add_item(self, name, value): """ 添加用户初始化的变量。 """ # @TODO ... if self.ith_comb < len(self._all_variables): if self.ith_strategy < len(self._all_variables[self.ith_comb]): self._all_variables[self.ith_comb][self.ith_strategy][name] = value else: self._all_variables[self.ith_comb].append({name: value}) else: self._all_variables.append([{name: value}]) if isinstance(value, SeriesBase): self.add_series(name, value) elif isinstance(value, TechnicalBase): self.add_indicator(name, value) else: self.add_variable(name, value) def add_series(self, attr, s): """ 添加on_init中初始化的序列变量 Args: attr (str): 属性名 s (Series): 序列变量 """ s.reset_data([], self._size) if self.ith_comb < len(self._series): if self.ith_strategy < len(self._series[self.ith_comb]): self._series[self.ith_comb][self.ith_strategy][attr] = s else: self._series[self.ith_comb].append({attr: s}) else: self._series.append([{attr: s}]) def add_indicator(self, attr, indic): if self.ith_comb < len(self.technicals): if self.ith_strategy < len(self.technicals[self.ith_comb]): self.technicals[self.ith_comb][self.ith_strategy][attr] = indic else: self.technicals[self.ith_comb].append({attr: indic}) else: self.technicals.append([{attr: indic}]) def add_variable(self, attr, var): if self.ith_comb < len(self._variables): if self.ith_strategy < len(self._variables[self.ith_comb]): self._variables[self.ith_comb][self.ith_strategy][attr] = var else: self._variables[self.ith_comb].append({attr: var}) else: self._variables.append([{attr: var}])
class DataContext(object): def __init__(self, wrapper): data = wrapper.data self.open = NumberSeries(data.open.values, 'open') self.close = NumberSeries(data.close.values, 'close') self.high = NumberSeries(data.high.values, 'high') self.low = NumberSeries(data.low.values, 'low') self.volume = NumberSeries(data.volume.values, 'volume') self.datetime = DateTimeSeries(data.index, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100, 1, 1) self.indicators = [[{}]] self._curbar = -1 self._wrapper = wrapper self._series = [[{}]] self._variables = [[{}]] self._all_variables = [[{}]] self._size = len(data.close) @property def raw_data(self): return self._wrapper.data @property def curbar(self): return self._curbar + 1 @property def pcontract(self): return self._wrapper.pcontract @property def contract(self): return self._wrapper.pcontract.contract def __getattr__(self, name): return self.get_item(name) def update_system_vars(self): # self.data = np.append(data, tracker.container_day) self._curbar = self.last_curbar self.open.update_curbar(self._curbar) self.close.update_curbar(self._curbar) self.high.update_curbar(self._curbar) self.low.update_curbar(self._curbar) self.volume.update_curbar(self._curbar) self.datetime.update_curbar(self._curbar) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) self.last_row = [] return def rolling_forward(self): """ 滚动读取下一步的数据。 """ new_row, self.last_curbar = self._wrapper.rolling_forward() if not new_row: self.last_curbar -= 1 return False, None self.last_row = [1] # mark self.last_date = self._wrapper.data.index[self.last_curbar] if self.datetime[0] >= self.last_date and self.curbar != 0: logger.error('合约[%s] 数据时间逆序或冗余' % self.pcontract) assert (False) return True, new_row def update_user_vars(self): """ 更新用户定义的变量。 """ try: siter = self._series[self.i][self.j].iteritems() except IndexError: # The strategy doesn't have user defined series. pass else: for key, s in siter: s.update_curbar(self._curbar) s.duplicate_last_element() try: indic_iter = self.indicators[self.i][self.j].iteritems() except IndexError: # The strategy doesn't use indicators. pass else: for key, indic in indic_iter: if indic.is_multiple: for key, value in indic.series.iteritems(): value.update_curbar(self._curbar) else: for s in indic.series: s.update_curbar(self._curbar) def __len__(self): return len(self._wrapper) def get_item(self, name): """ 获取用户在策略on_init函数中初始化的变量 """ return self._all_variables[self.i][self.j][name] def add_item(self, name, value): """ 添加用户初始化的变量。 """ # @TODO ... if self.i < len(self._all_variables): if self.j < len(self._all_variables[self.i]): self._all_variables[self.i][self.j][name] = value else: self._all_variables[self.i].append({name: value}) else: self._all_variables.append([{name: value}]) if isinstance(value, SeriesBase): self.add_series(name, value) elif isinstance(value, TechnicalBase): self.add_indicator(name, value) else: self.add_variable(name, value) def add_series(self, attr, s): """ 添加on_init中初始化的序列变量 Args: attr (str): 属性名 s (Series): 序列变量 """ s.reset_data([], self._size) if self.i < len(self._series): if self.j < len(self._series[self.i]): self._series[self.i][self.j][attr] = s else: self._series[self.i].append({attr: s}) else: self._series.append([{attr: s}]) return def add_indicator(self, attr, indic): if self.i < len(self.indicators): if self.j < len(self.indicators[self.i]): self.indicators[self.i][self.j][attr] = indic else: self.indicators[self.i].append({attr: indic}) else: self.indicators.append([{attr: indic}]) def add_variable(self, attr, var): if self.i < len(self._variables): if self.j < len(self._variables[self.i]): self._variables[self.i][self.j][attr] = var else: self._variables[self.i].append({attr: var}) else: self._variables.append([{attr: var}])
class BarTracker(object): """ 跟踪器,可能是策略,策略用到的非主合约数据,独立指标。 :ivar events_pool: 事件池。 :ivar blotter: 订单本地处理器。 :ivar exchange: 模拟交易所。 :ivar _excution: 最小执行单元。 :ivar _series: 当前跟踪器负责维护的时间序列变量集合。 :ivar _main_pcontract: 主合约。即self.open等指向的合约。 :ivar open: 主合约当前Bar的开盘价。 :ivar close: 主合约当前Bar的收盘价。 :ivar high: 主合约当前Bar的最高价。 :ivar low: 主合约当前Bar的最低价。 :ivar volume: 主合约当前Bar的成交量。 :ivar datetime: 主合约当前Bar的开盘时间。 :ivar curbar: 当前Bar索引。 """ def __init__(self, exe_unit, pcontract=None): """ 初始化数据列表 Args: pcontract (PContract): 周期合约, 空表示仅是跟踪器,非策略。 """ self.events_pool = EventsPool() self.blotter = SimpleBlotter(None, self.events_pool) self.exchange = Exchange(self.events_pool, strict=False) self._excution = exe_unit # tracker中用到的时间序列 self._series = [] try: if pcontract: self._main_pcontract = pcontract exe_unit.add_tracker(self) else: self._main_pcontract = exe_unit.pcontracts[0] exe_unit.add_strategy(self) self._main_contract = self._main_pcontract.contract self._data = exe_unit.data[self._main_pcontract] self._container_day = np.zeros(shape=(self.length_day( self._main_pcontract), ), dtype=float) self._init_main_data() except KeyError: ## @todo 提醒用户用法。 raise KeyError def length_day(self, pcontract): """ 计算当天的数据量 """ ## @todo local_data return 4 @property def container_day(self): """ 为当天数据预留的空间 """ return self._container_day def _init_main_data(self): # 预留了历史和当天的数据空间。 self.open = NumberSeries(self, self._data.open, True) self.close = NumberSeries(self, self._data.close, True) self.high = NumberSeries(self, self._data.high, True) self.low = NumberSeries(self, self._data.low, True) self.volume = NumberSeries(self, self._data.volume, True) self.datetime = DateTimeSeries(self, self._data.index, True) self.curbar = 0 def on_tick(self): """ tick数据到达时候触发。 """ pass def on_bar(self): """ Bar数据到达时候触发。""" pass def execute_strategy(self): self.on_tick() self.on_bar() def add_series(self, series): """ 添加时间序列变量。 每个跟踪器都要维护策略使用的时间序列变量,当新的Bar数据 到达后,通过BarTracker.update_curbar函数更新时间序列变量的最 后一个值。 """ self._series.append(series) def update_curbar(self, index): """ 新的bar数据到达时,更新相关信息, 如其负责维护的时间序列对象变量的最新值。 :param int index: 当前bar索引。 :return: 最新的Bar对象。 :rtype: Bar """ self.curbar = index self.open.update_curbar(index) self.close.update_curbar(index) self.high.update_curbar(index) self.low.update_curbar(index) self.volume.update_curbar(index) self.datetime.update_curbar(index) for serie in self._series: serie.update_curbar(index) serie.duplicate_last_element() return Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0])
class DataContext(object): def __init__(self, wrapper, window_size): """ window_size: 滚动窗口大小 """ self.wrapper = wrapper self.series = [[{ }]] self.indicators = [[{ }]] self.variables = [[{ }]] data = self.wrapper.data self.window_size = window_size self.open = NumberSeries(data.open.values, self.window_size, 'open') self.close = NumberSeries(data.close.values, self.window_size, 'close') self.high = NumberSeries(data.high.values, self.window_size, 'high') self.low = NumberSeries(data.low.values, self.window_size, 'low') self.volume = NumberSeries(data.volume.values, self.window_size, 'volume') self.datetime = DateTimeSeries(data.index, self.window_size, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self.curbar = 0 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100,1,1) @property def raw_data(self): if series.g_rolling: assert(False and '逐步运算不存在历史数据') return self.wrapper.data @property def pcontract(self): return self.wrapper.pcontract @property def contract(self): return self.wrapper.pcontract.contract def update_system_vars(self): # 为当天数据预留空间, 改变g_window或者一次性分配 #self.data = np.append(data, tracker.container_day) self.curbar = self.last_curbar self.open.update_curbar(self.curbar) self.close.update_curbar(self.curbar) self.high.update_curbar(self.curbar) self.low.update_curbar(self.curbar) self.volume.update_curbar(self.curbar) self.datetime.update_curbar(self.curbar) # 更新数据源 if series.g_rolling: self.datetime.update(self.last_row[0]) self.open.update(self.last_row[1]) self.close.update(self.last_row[2]) self.high.update(self.last_row[3]) self.low.update(self.last_row[4]) self.volume.update(self.last_row[5]) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) self.last_row = [] return def rolling_foward(self): ## @todo next """ 滚动读取下一步的数据。 """ new_row, self.last_curbar = self.wrapper.rolling_foward() if not new_row: self.last_curbar -= 1 return False, None if series.g_rolling: self.last_row = new_row self.last_date = self.last_row[0] else: self.last_row = [1] # mark self.last_date = self.wrapper.data.index[self.last_curbar] return True, new_row def update_user_vars(self): """ 更新用户定义的变量。 """ try: siter = self.series[self.i][self.j].iteritems() except Exception: pass else: for key, s in siter: s.update_curbar(self.curbar) s.duplicate_last_element() try: indic_iter = self.indicators[self.i][self.j].iteritems() except Exception: pass else: for key, indic in indic_iter: if indic.multi_value: for key, value in indic.series.iteritems(): value.update_curbar(self.curbar) else: for s in indic.series: s.update_curbar(self.curbar) def add_series(self, key, s): """ 添加on_init中初始化的序列变量 Args: key (str): 属性名 s (Series): 序列变量 """ s.reset_data([], self.window_size + 1) if self.i < len(self.series): if self.j < len(self.series[self.i]): self.series[self.i][self.j][key] = s else: self.series[self.i].append({ key: s }) else: self.series.append([{ key:s }]) return def add_indicator(self, key, indic): if self.i < len(self.indicators): if self.j < len(self.indicators[self.i]): self.indicators[self.i][self.j][key] = indic else: self.indicators[self.i].append({ key: indic }) else: self.indicators.append([{ key: indic }]) def add_variable(self, key, var): if self.i < len(self.variables): if self.j < len(self.variables[self.i]): self.variables[self.i][self.j][key] = var else: self.variables[self.i].append({ key: var }) else: self.variables.append([{ key: var }]) def __len__(self): return len(self.wrapper) def get_item(self, name): """ 获取用户在策略on_init函数中初始化的变量 Args: name (str): 变量名 """ try: return self.indicators[self.i][self.j][name] except KeyError: try: return self.series[self.i][self.j][name] except KeyError: return self.variables[self.i][self.j][name] def add_item(self, name, value): """ 添加用户初始化的变量。 """ if isinstance(value, series.SeriesBase): self.add_series(name, value) elif isinstance(value, IndicatorBase): self.add_indicator(name, value) else: self.add_variable(name, value) def __getattr__(self, name): return self.get_item(name)
class DataContext(object): def __init__(self, wrapper, window_size): """ window_size: 滚动窗口大小 """ self.wrapper = wrapper self.series = [[{}]] self.indicators = [[{}]] self.variables = [[{}]] data = self.wrapper.data self.window_size = window_size self.open = NumberSeries(data.open.values, self.window_size, 'open') self.close = NumberSeries(data.close.values, self.window_size, 'close') self.high = NumberSeries(data.high.values, self.window_size, 'high') self.low = NumberSeries(data.low.values, self.window_size, 'low') self.volume = NumberSeries(data.volume.values, self.window_size, 'volume') self.datetime = DateTimeSeries(data.index, self.window_size, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self._curbar = -1 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100, 1, 1) @property def raw_data(self): if series.g_rolling: assert (False and '逐步运算不存在历史数据') return self.wrapper.data @property def curbar(self): return self._curbar + 1 @property def pcontract(self): return self.wrapper.pcontract @property def contract(self): return self.wrapper.pcontract.contract def update_system_vars(self): # 为当天数据预留空间, 改变g_window或者一次性分配 #self.data = np.append(data, tracker.container_day) self._curbar = self.last_curbar self.open.update_curbar(self._curbar) self.close.update_curbar(self._curbar) self.high.update_curbar(self._curbar) self.low.update_curbar(self._curbar) self.volume.update_curbar(self._curbar) self.datetime.update_curbar(self._curbar) # 更新数据源 if series.g_rolling: self.datetime.update(self.last_row[0]) self.open.update(self.last_row[1]) self.close.update(self.last_row[2]) self.high.update(self.last_row[3]) self.low.update(self.last_row[4]) self.volume.update(self.last_row[5]) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) self.last_row = [] return def rolling_foward(self): ## @todo next """ 滚动读取下一步的数据。 """ new_row, self.last_curbar = self.wrapper.rolling_foward() if not new_row: self.last_curbar -= 1 return False, None if series.g_rolling: self.last_row = new_row self.last_date = self.last_row[0] else: self.last_row = [1] # mark self.last_date = self.wrapper.data.index[self.last_curbar] if self.datetime[0] >= self.last_date and self.curbar != 0: logger.error('合约[%s] 数据时间逆序或冗余' % self.pcontract) assert (False) return True, new_row def update_user_vars(self): """ 更新用户定义的变量。 """ try: siter = self.series[self.i][self.j].iteritems() except Exception: pass else: for key, s in siter: s.update_curbar(self._curbar) s.duplicate_last_element() try: indic_iter = self.indicators[self.i][self.j].iteritems() except Exception: pass else: for key, indic in indic_iter: if indic.multi_value: for key, value in indic.series.iteritems(): value.update_curbar(self._curbar) else: for s in indic.series: s.update_curbar(self._curbar) def add_series(self, key, s): """ 添加on_init中初始化的序列变量 Args: key (str): 属性名 s (Series): 序列变量 """ s.reset_data([], self.window_size + 1) if self.i < len(self.series): if self.j < len(self.series[self.i]): self.series[self.i][self.j][key] = s else: self.series[self.i].append({key: s}) else: self.series.append([{key: s}]) return def add_indicator(self, key, indic): if self.i < len(self.indicators): if self.j < len(self.indicators[self.i]): self.indicators[self.i][self.j][key] = indic else: self.indicators[self.i].append({key: indic}) else: self.indicators.append([{key: indic}]) def add_variable(self, key, var): if self.i < len(self.variables): if self.j < len(self.variables[self.i]): self.variables[self.i][self.j][key] = var else: self.variables[self.i].append({key: var}) else: self.variables.append([{key: var}]) def __len__(self): return len(self.wrapper) def get_item(self, name): """ 获取用户在策略on_init函数中初始化的变量 Args: name (str): 变量名 """ try: return self.indicators[self.i][self.j][name] except KeyError: try: return self.series[self.i][self.j][name] except KeyError: return self.variables[self.i][self.j][name] def add_item(self, name, value): """ 添加用户初始化的变量。 """ if isinstance(value, series.SeriesBase): self.add_series(name, value) elif isinstance(value, IndicatorBase): self.add_indicator(name, value) else: self.add_variable(name, value) def __getattr__(self, name): return self.get_item(name)
class DataContext(object): def __init__(self, wrapper): data = wrapper.data self.open = NumberSeries(data.open.values, 'open') self.close = NumberSeries(data.close.values, 'close') self.high = NumberSeries(data.high.values, 'high') self.low = NumberSeries(data.low.values, 'low') self.volume = NumberSeries(data.volume.values, 'volume') self.datetime = DateTimeSeries(data.index, 'datetime') self.i = -1 # 第i个组合 self.j = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.last_row = [] self.last_date = datetime.datetime(2100, 1, 1) self.indicators = [[{}]] self._curbar = -1 self._wrapper = wrapper self._series = [[{}]] self._variables = [[{}]] self._all_variables = [[{}]] self._size = len(data.close) @property def raw_data(self): return self._wrapper.data @property def curbar(self): return self._curbar + 1 @property def pcontract(self): return self._wrapper.pcontract @property def contract(self): return self._wrapper.pcontract.contract def __getattr__(self, name): return self.get_item(name) def update_system_vars(self): # self.data = np.append(data, tracker.container_day) self._curbar = self.last_curbar self.open.update_curbar(self._curbar) self.close.update_curbar(self._curbar) self.high.update_curbar(self._curbar) self.low.update_curbar(self._curbar) self.volume.update_curbar(self._curbar) self.datetime.update_curbar(self._curbar) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) self.last_row = [] return def rolling_forward(self): """ 滚动读取下一步的数据。 """ new_row, self.last_curbar = self._wrapper.rolling_forward() if not new_row: self.last_curbar -= 1 return False, None self.last_row = [1] # mark self.last_date = self._wrapper.data.index[self.last_curbar] if self.datetime[0] >= self.last_date and self.curbar != 0: logger.error('合约[%s] 数据时间逆序或冗余' % self.pcontract) assert(False) return True, new_row def update_user_vars(self): """ 更新用户定义的变量。 """ try: siter = self._series[self.i][self.j].iteritems() except IndexError: # The strategy doesn't have user defined series. pass else: for key, s in siter: s.update_curbar(self._curbar) s.duplicate_last_element() try: indic_iter = self.indicators[self.i][self.j].iteritems() except IndexError: # The strategy doesn't use indicators. pass else: for key, indic in indic_iter: if indic.is_multiple: for key, value in indic.series.iteritems(): value.update_curbar(self._curbar) else: for s in indic.series: s.update_curbar(self._curbar) def __len__(self): return len(self._wrapper) def get_item(self, name): """ 获取用户在策略on_init函数中初始化的变量 """ return self._all_variables[self.i][self.j][name] def add_item(self, name, value): """ 添加用户初始化的变量。 """ # @TODO ... if self.i < len(self._all_variables): if self.j < len(self._all_variables[self.i]): self._all_variables[self.i][self.j][name] = value else: self._all_variables[self.i].append({name: value}) else: self._all_variables.append([{name: value}]) if isinstance(value, SeriesBase): self.add_series(name, value) elif isinstance(value, TechnicalBase): self.add_indicator(name, value) else: self.add_variable(name, value) def add_series(self, attr, s): """ 添加on_init中初始化的序列变量 Args: attr (str): 属性名 s (Series): 序列变量 """ s.reset_data([], self._size) if self.i < len(self._series): if self.j < len(self._series[self.i]): self._series[self.i][self.j][attr] = s else: self._series[self.i].append({attr: s}) else: self._series.append([{attr: s}]) return def add_indicator(self, attr, indic): if self.i < len(self.indicators): if self.j < len(self.indicators[self.i]): self.indicators[self.i][self.j][attr] = indic else: self.indicators[self.i].append({attr: indic}) else: self.indicators.append([{attr: indic}]) def add_variable(self, attr, var): if self.i < len(self._variables): if self.j < len(self._variables[self.i]): self._variables[self.i][self.j][attr] = var else: self._variables[self.i].append({attr: var}) else: self._variables.append([{attr: var}])
class BarTracker(object): """ 跟踪器,可能是策略,策略用到的非主合约数据,独立指标。 :ivar events_pool: 事件池。 :ivar blotter: 订单本地处理器。 :ivar exchange: 模拟交易所。 :ivar _excution: 最小执行单元。 :ivar _series: 当前跟踪器负责维护的时间序列变量集合。 :ivar _main_pcontract: 主合约。即self.open等指向的合约。 :ivar open: 主合约当前Bar的开盘价。 :ivar close: 主合约当前Bar的收盘价。 :ivar high: 主合约当前Bar的最高价。 :ivar low: 主合约当前Bar的最低价。 :ivar volume: 主合约当前Bar的成交量。 :ivar datetime: 主合约当前Bar的开盘时间。 :ivar curbar: 当前Bar索引。 """ def __init__(self, exe_unit, pcontract=None): """ 初始化数据列表 Args: pcontract (PContract): 周期合约, 空表示仅是跟踪器,非策略。 """ self.events_pool = EventsPool() self.blotter = SimpleBlotter(None, self.events_pool) self.exchange = Exchange(self.events_pool, strict=False) self._excution = exe_unit # tracker中用到的时间序列 self._series = [] try: if pcontract: self._main_pcontract = pcontract exe_unit.add_tracker(self) else: self._main_pcontract = exe_unit.pcontracts[0] exe_unit.add_strategy(self) self._main_contract = self._main_pcontract.contract self._data = exe_unit.data[self._main_pcontract] self._container_day = np.zeros(shape=(self.length_day(self._main_pcontract), ), dtype = float) self._init_main_data() except KeyError: ## @todo 提醒用户用法。 raise KeyError def length_day(self, pcontract): """ 计算当天的数据量 """ ## @todo local_data return 4 @property def container_day(self): """ 为当天数据预留的空间 """ return self._container_day def _init_main_data(self): # 预留了历史和当天的数据空间。 self.open = NumberSeries(self, self._data.open, True) self.close = NumberSeries(self, self._data.close, True) self.high = NumberSeries(self, self._data.high, True) self.low = NumberSeries(self, self._data.low, True) self.volume = NumberSeries(self, self._data.volume, True) self.datetime = DateTimeSeries(self, self._data.index, True) self.curbar = 0 def on_tick(self): """ tick数据到达时候触发。 """ pass def on_bar(self): """ Bar数据到达时候触发。""" pass def execute_strategy(self): self.on_tick() self.on_bar() def add_series(self, series): """ 添加时间序列变量。 每个跟踪器都要维护策略使用的时间序列变量,当新的Bar数据 到达后,通过BarTracker.update_curbar函数更新时间序列变量的最 后一个值。 """ self._series.append(series) def update_curbar(self, index): """ 新的bar数据到达时,更新相关信息, 如其负责维护的时间序列对象变量的最新值。 :param int index: 当前bar索引。 :return: 最新的Bar对象。 :rtype: Bar """ self.curbar = index self.open.update_curbar(index) self.close.update_curbar(index) self.high.update_curbar(index) self.low.update_curbar(index) self.volume.update_curbar(index) self.datetime.update_curbar(index) for serie in self._series: serie.update_curbar(index) serie.duplicate_last_element() return Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0])
class DataContext(object): """ A DataContext expose data should be visited by multiple strategie. which including bars of specific PContract, technicals and series of strategie. """ def __init__(self, Helper): data = Helper.data self.open = NumberSeries(data.open.values, 'open') self.close = NumberSeries(data.close.values, 'close') self.high = NumberSeries(data.high.values, 'high') self.low = NumberSeries(data.low.values, 'low') self.volume = NumberSeries(data.volume.values, 'volume') self.datetime = DateTimeSeries(data.index, 'datetime') self.ith_comb = -1 # 第i个组合 self.ith_strategy = -1 # 第j个策略 self.bar = Bar(None, None, None, None, None, None) self.new_row = False self.next_datetime = datetime.datetime(2100, 1, 1) self.technicals = [[{}]] self._curbar = -1 self._Helper = Helper self._series = [[{}]] self._variables = [[{}]] self._all_variables = [[{}]] self._size = len(data.close) @property def raw_data(self): return self._Helper.data @property def curbar(self): return self._curbar + 1 @property def pcontract(self): return self._Helper.pcontract @property def contract(self): return self._Helper.pcontract.contract def __getattr__(self, name): return self.get_item(name) def update_system_vars(self): # self.data = np.append(data, tracker.container_day) self._curbar = self.last_curbar self.open.update_curbar(self._curbar) self.close.update_curbar(self._curbar) self.high.update_curbar(self._curbar) self.low.update_curbar(self._curbar) self.volume.update_curbar(self._curbar) self.datetime.update_curbar(self._curbar) self.bar = Bar(self.datetime[0], self.open[0], self.close[0], self.high[0], self.low[0], self.volume[0]) self.new_row = False def update_user_vars(self): # Update series defined by user if exist. try: series = self._series[self.ith_comb][self.ith_strategy].values() except IndexError: pass else: for s in series: s.update_curbar(self._curbar) s.duplicate_last_element() # Update technicals if exist. try: technicals = self.technicals[self.ith_comb][ self.ith_strategy].values() except IndexError: pass else: for tec in technicals: if tec.is_multiple: for s in six.itervalues(tec.series): s.update_curbar(self._curbar) else: for s in tec.series: s.update_curbar(self._curbar) def rolling_forward(self): """ 滚动读取下一步的数据。 """ self.new_row, self.last_curbar = self._Helper.rolling_forward() if not self.new_row: self.last_curbar -= 1 return False, None self.next_datetime = self._Helper.data.index[self.last_curbar] if self.datetime[0] >= self.next_datetime and self.curbar != 0: logger.error('合约[%s] 数据时间逆序或冗余' % self.pcontract) raise return True, self.new_row def __len__(self): return len(self._Helper) def get_item(self, name): """ 获取用户在策略on_init函数中初始化的变量 """ return self._all_variables[self.ith_comb][self.ith_strategy][name] def add_item(self, name, value): """ 添加用户初始化的变量。 """ # @TODO ... if self.ith_comb < len(self._all_variables): if self.ith_strategy < len(self._all_variables[self.ith_comb]): self._all_variables[self.ith_comb][ self.ith_strategy][name] = value else: self._all_variables[self.ith_comb].append({name: value}) else: self._all_variables.append([{name: value}]) if isinstance(value, SeriesBase): self.add_series(name, value) elif isinstance(value, TechnicalBase): self.add_indicator(name, value) else: self.add_variable(name, value) def add_series(self, attr, s): """ 添加on_init中初始化的序列变量 Args: attr (str): 属性名 s (Series): 序列变量 """ s.reset_data([], self._size) if self.ith_comb < len(self._series): if self.ith_strategy < len(self._series[self.ith_comb]): self._series[self.ith_comb][self.ith_strategy][attr] = s else: self._series[self.ith_comb].append({attr: s}) else: self._series.append([{attr: s}]) def add_indicator(self, attr, indic): if self.ith_comb < len(self.technicals): if self.ith_strategy < len(self.technicals[self.ith_comb]): self.technicals[self.ith_comb][self.ith_strategy][attr] = indic else: self.technicals[self.ith_comb].append({attr: indic}) else: self.technicals.append([{attr: indic}]) def add_variable(self, attr, var): if self.ith_comb < len(self._variables): if self.ith_strategy < len(self._variables[self.ith_comb]): self._variables[self.ith_comb][self.ith_strategy][attr] = var else: self._variables[self.ith_comb].append({attr: var}) else: self._variables.append([{attr: var}])