async def update_trade(self, trade): """ 逐笔成交更新 """ newMinute = False #默认不是新的一分钟 #尚未创建对象 if not self.bar: self.bar = Kline() newMinute = True #新的一分钟 elif int(self.bar.timestamp//ONE_MINUTE) != int(trade.timestamp//ONE_MINUTE): #生成上一分钟K线的时间戳 self.bar.timestamp = int(self.bar.timestamp//ONE_MINUTE)*ONE_MINUTE #推送已经结束的上一分钟K线 await self.onBar(self.bar) #创建新的K线对象 self.bar = Kline() newMinute = True #初始化新一分钟的K线数据 if newMinute: self.bar.platform = trade.platform self.bar.symbol = trade.symbol self.bar.open = trade.price self.bar.high = trade.price self.bar.low = trade.price self.bar.kline_type = const.MARKET_TYPE_KLINE self.bar.volume = 0 #累加更新老一分钟的K线数据 else: self.bar.high = max(self.bar.high, trade.price) self.bar.low = min(self.bar.low, trade.price) #通用更新部分 self.bar.close = trade.price self.bar.timestamp = trade.timestamp self.bar.volume += trade.quantity
async def on_kline_update_callback(self, kline: Kline): """ 市场K线更新 """ if self.native_to_system: kline.symbol = self.native_to_system[ kline.symbol] #'交易所原始符号'转换成'量化平台通用符号' await self._original_on_kline_update_callback(kline)
def _update_kline(self, kline_info, symbol): """ kline update. Args: kline_info: kline information. Returns: None. """ info = { "platform": self._platform, "symbol": symbol, "open": kline_info["open"], "high": kline_info["high"], "low": kline_info["low"], "close": kline_info["close"], "volume": kline_info["volume"], "timestamp": tools.utctime_str_to_mts(kline_info["startTime"], "%Y-%m-%dT%H:%M:%S+00:00"), "kline_type": MARKET_TYPE_KLINE } kline = Kline(**info) SingleTask.run(self.cb.on_kline_update_callback, kline)
async def update_bar(self, bar): """ 1分钟K线更新 """ #尚未创建对象 if not self.xminBar: self.xminBar = Kline() self.xminBar.kline_type = self.bar_type self.xminBar.platform = bar.platform self.xminBar.symbol = bar.symbol self.xminBar.open = bar.open self.xminBar.high = bar.high self.xminBar.low = bar.low self.xminBar.timestamp = bar.timestamp #以第一根分钟K线的开始时间戳作为X分钟线的时间戳 self.xminBar.volume = 0 #累加老K线 else: self.xminBar.high = max(self.xminBar.high, bar.high) self.xminBar.low = min(self.xminBar.low, bar.low) #通用部分 self.xminBar.close = bar.close self.xminBar.volume += bar.volume #X分钟已经走完 minute = int(bar.timestamp//ONE_MINUTE) if not (minute + 1) % self.xmin: #可以用X整除 #推送 await self.onXminBar(self.xminBar) #清空老K线缓存对象 self.xminBar = None
async def on_kline_update_callback(self, kline: Kline): """ 市场K线更新 """ #logger.info("kline:", kline, caller=self) self.last_kline = kline #如果收到的是'交易所提供的K线'而不是'自合成K线'的话就直接忽略 if not kline.is_custom_and_usable(): return await super(CTAMultiTimeframeStrategy, self).on_kline_update_callback(kline)
async def on_kline_update_callback(self, kline: Kline): """ 市场K线更新 """ #logger.info("kline:", kline, caller=self) self.last_kline = kline #历史数据还没准备好 if not self.init_history_data: return #如果收到的是'交易所提供的K线'而不是'自合成K线'的话就直接忽略 if not kline.is_custom_and_usable(): return await super(CTAStrategy, self).on_kline_update_callback(kline)
async def load_history_data(self, platform, symbol): """ 加载历史数据 """ now = ModelAPI.current_milli_timestamp() prev = now - 4 * 24 * 60 * 60 * 1000 #四天的数据 ks = await ModelAPI.get_klines_between(platform, symbol, prev, now) for k in ks: kwargs = { "platform": platform, "symbol": symbol, "timestamp": k["begin_dt"], "kline_type": const.MARKET_TYPE_KLINE } kwargs.update(k) #填充剩余字段 kline = Kline(**kwargs) for model in self.models: model.on_history_kline(kline)
async def feed(self, row): """ 通过历史数据驱动策略进行回测 """ drive_type = row["drive_type"] #数据驱动方式 if drive_type == "kline" and self.cb.on_kline_update_callback: kw = row.to_dict() del kw["drive_type"] del kw["gw"] del kw["dt"] kw["platform"] = self._platform kw["timestamp"] = int(kw["begin_dt"]) kw["kline_type"] = MARKET_TYPE_KLINE kline = Kline(**kw) await self.cb.on_kline_update_callback(kline) elif drive_type == "trade" and self.cb.on_trade_update_callback: kw = { "platform": self._platform, "symbol": row["symbol"], "action": row["direction"], "price": row["tradeprice"], "quantity": row["volume"], "timestamp": int(row["tradedt"]) } trade = Trade(**kw) await self.cb.on_trade_update_callback(trade) elif drive_type == "orderbook" and self.cb.on_orderbook_update_callback: asks = [] bids = [] for i in range(1, 20 + 1): asks.append([row[f'askprice{i}'], row[f'asksize{i}']]) bids.append([row[f'bidprice{i}'], row[f'bidsize{i}']]) kw = { "platform": self._platform, "symbol": row["symbol"], "asks": asks, "bids": bids, "timestamp": int(row["pubdt"]) } ob = Orderbook(**kw) await self.cb.on_orderbook_update_callback(ob)
async def process_kline(self, data): symbol = data["instrument_id"] if symbol not in self._symbols: return cur_kline = data["candle"] if self._prev_kline_map[symbol]: #如果存在前一根k线 prev_kline = self._prev_kline_map[symbol] prev_timestamp = tools.utctime_str_to_mts(prev_kline[0]) cur_timestamp = tools.utctime_str_to_mts(cur_kline[0]) if prev_timestamp != cur_timestamp: #前一根k线的开始时间与当前k线开始时间不同,意味着前一根k线已经统计完毕,通知上层策略 info = { "platform": self._platform, "symbol": symbol, "open": float(prev_kline[1]), "high": float(prev_kline[2]), "low": float(prev_kline[3]), "close": float(prev_kline[4]), "volume": float(prev_kline[5]), "timestamp": prev_timestamp, "kline_type": MARKET_TYPE_KLINE } kline = Kline(**info) SingleTask.run(self.cb.on_kline_update_callback, kline) self._prev_kline_map[symbol] = cur_kline
def parse(self): kline = Kline(**self.data) return kline
def parse(self): """ 解析self._data数据 """ kline = Kline(**self.data) return kline