from tqsdk import TqApi, TqAuth
from public_module.tqz_extern.tools.pandas_operator.pandas_operator import pandas # noqa
from server_api.tqz_object import BarData, Exchange
TIME_GAP = 8 * 60 * 60 * 1000000000
class TQZTianQinClient:
"""
天勤接口 每次只能拉取单一合约的数据!
"""
__tq_symbols = None
def __init__(self, account: str = "账号", pass_word: str = "密码"):
self.api = TqApi(auth=TqAuth(account, pass_word))
if TQZTianQinClient.__tq_symbols is None:
TQZTianQinClient.__tq_symbols = self.api.query_quotes(ins_class="FUTURE", expired=False)
def query_history_bars(self, tq_symbol: str, tq_duration_seconds: int, tq_data_length=8964) -> list:
assert tq_symbol in TQZTianQinClient.__tq_symbols, f'Bad tq_symbol: {tq_symbol}'
tq_result = self.api.get_kline_serial(symbol=tq_symbol, duration_seconds=tq_duration_seconds, data_length=tq_data_length)
self.api.close()
tq_result["datetime"] = pandas.to_datetime(tq_result["datetime"] + TIME_GAP)
tq_result['datetime'] = tq_result['datetime'].apply(lambda x: x.strftime('%Y-%m-%d %H:%M:%S')) # %f是毫秒
symbol, exchange = TQZTianQinClient.__get_symbol_exchange(tq_symbol=tq_symbol)
history_bars = []
if tq_result is not None:
for ix, row in tq_result.loc[tq_result["id"] >= 0].iterrows():
history_bars.append(
BarData(
symbol=symbol,
exchange=exchange,
interval='any_interval', # noqa
datetime=row["datetime"],
open_price=row["open"],
high_price=row["high"],
low_price=row["low"],
close_price=row["close"],
volume=row["volume"],
open_interest=row.get("open_oi", 0),
gateway_name="TQ",
)
)
return history_bars
def load_all_tq_symbols(self):
self.api.close()
return TQZTianQinClient.__tq_symbols
# --- private part ---
@classmethod
def __get_symbol_exchange(cls, tq_symbol: str) -> (str, Exchange):
exchange_str, symbol = tq_symbol.split('.')[0], tq_symbol.split('.')[1]
if exchange_str in [Exchange.SHFE.value]:
exchange = Exchange.SHFE
elif exchange_str in [Exchange.INE.value]:
exchange = Exchange.INE
elif exchange_str in [Exchange.DCE.value]:
exchange = Exchange.DCE
elif exchange_str in [Exchange.CZCE.value]:
exchange = Exchange.CZCE
elif exchange_str in [Exchange.CFFEX.value]:
exchange = Exchange.CFFEX
else:
assert False, f'Bad exchange_str: {exchange_str}'
return symbol, exchange
class TQZTianQinDataManager:
__load_history_bars_map: dict = None
@classmethod
def load_history_bars_map(cls, tq_symbols: list, tq_duration_seconds: int) -> dict:
"""
Load history bars of multi symbols from tianqin, and only load once time before back tester.
:param tq_symbols: list of multi symbols
:param tq_duration_seconds: just tq_duration_seconds
:return: history bars map
"""
load_history_bars_map = {}
if cls.__load_history_bars_map is None:
for tq_symbol in tq_symbols:
if tq_symbol not in load_history_bars_map.keys():
load_history_bars_map[tq_symbol] = TQZTianQinClient().query_history_bars(tq_symbol=tq_symbol, tq_duration_seconds=tq_duration_seconds)
cls.__load_history_bars_map = load_history_bars_map
return cls.__load_history_bars_map
if __name__ == '__main__':
TQZTianQinDataManager.load_history_bars_map(tq_symbols=["CZCE.SM206", "SHFE.rb2205"], tq_duration_seconds=60 * 60)