class TqsdkClient(LocalClient): def __init__(self, **kwargs): super().__init__() self.p = Thread(target=self.init_api, args=()) self.p.start() self.api = None def init_api(self): self.api = TqApi() while True: self.api.wait_update() def get(self, *argsm, **params): """ 调用他们的历史数据 """ # tick数据 if params.get("level") == "tick": del params['level'] temp = self.api.get_tick_serial(*argsm, **params) return temp # 分钟线数据 if params.get("level") != "tick": return self.api.get_kline_serial(*argsm, **params) def set(self): pass
class TqSdkClient(LocalClient): def __init__(self, **kwargs): self.api = TqApi() def get(self, **params): """ 调用他们的历史数据 """ if params.get("level") == "tick": return self.api.get_tick_serial(*self._parse_params(params)) if params.get("level") != "tick": return self.api.get_kline_serial(*self._parse_params(params)) def _parse_params(self, params): """ 将参数解析为tq可以理解的方式 都需要返回一个*args """ level = params.get("level") local_symbol = params.get("local_symbol") length = params.get("length") if level != "tick": return [local_symbol, self.get_seconds(level), length] return [local_symbol, length] @staticmethod def get_seconds(level) -> int: """ 将level转换到秒 * level: 数据等级 """ min_r = r"(\d{1,2})min" hour_r = r"(\d{1,2})h" day_r = r"(\d{1,2})day" if "min" in level: try: return int(re.match(min_r, level).group(1)) * 60 except Exception: raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1min这样的格式") if "h" in level: try: return int(re.match(hour_r, level).group(1)) * 3600 except Exception: raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1min这样的格式") if "day" in level: try: return int(re.match(day_r, level).group(1)) * 3600 * 24 except Exception: raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1day这样的格式")
def test_get_tick_serial(self): """ 获取tick数据 """ # 预设服务器端响应 dir_path = os.path.dirname(os.path.realpath(__file__)) self.mock.run( os.path.join(dir_path, "log_file", "test_md_basic_get_tick_serial.script.lzma")) # 测试: 获取tick数据 utils.RD = random.Random(2) api = TqApi(_ins_url=self.ins_url_2019_07_03, _td_url=self.td_url, _md_url=self.md_url) ticks = api.get_tick_serial("SHFE.cu1909") self.assertEqual(ticks.iloc[-1].id, 2822951.0) self.assertEqual(ticks.iloc[-1].datetime, 1.5686171999995e+18) self.assertEqual(ticks.iloc[-1].last_price, 47580) self.assertEqual(ticks.iloc[-1].average, 47732.3516) self.assertEqual(ticks.iloc[-1].highest, 47860) self.assertEqual(ticks.iloc[-1].lowest, 47580) self.assertEqual(ticks.iloc[-1].ask_price1, 47650) self.assertEqual(ticks.iloc[-1].ask_volume1, 10) self.assertEqual(ticks.iloc[-1].bid_price1, 47570) self.assertEqual(ticks.iloc[-1].bid_volume1, 5) self.assertEqual(ticks.iloc[-1].volume, 9020) self.assertEqual(ticks.iloc[-1].amount, 2152729000.0) self.assertEqual(ticks.iloc[-1].open_interest, 6940) self.assertEqual(ticks.iloc[-1].duration, 0) # 其他调用方式 self.assertEqual(ticks.open_interest.iloc[-1], 6940) self.assertEqual(ticks["open_interest"].iloc[-2], 6940) self.assertEqual(ticks.iloc[-1]["ask_price1"], 47650) # 报错测试 self.assertRaises(Exception, api.get_tick_serial, "SHFE.au1999") self.assertRaises(AttributeError, ticks.iloc[-1].__getattribute__, "dur") self.assertRaises(KeyError, ticks.iloc[-1].__getitem__, "dur") api.close()
class CuatroStrategy(Process): '''''' author = 'XIAO LI' boll_window = 20 boll_dev = 1.8 rsi_window = 14 rsi_signal = 20 fast_window = 4 slow_window = 26 trailing_long = 0.5 trailing_short = 0.3 vol = 1 boll_up = float('nan') boll_down = float('nan') rsi_value = float('nan') rsi_long = float('nan') rsi_short = float('nan') fast_ma = float('nan') slow_ma = float('nan') ma_trend = float('nan') intra_trade_high = float('nan') intra_trade_low = float('nan') long_stop = float('nan') short_stop = float('nan') parameters = [ 'boll_window' 'boll_dev' 'rsi_window' 'rsi_signal' 'fast_window' 'slow_window' 'trailing_long' 'trailing_short' 'vol' ] variables = [ 'boll_up' 'boll_down' 'rsi_value' 'rsi_long' 'rsi_short' 'fast_ma' 'slow_ma' 'ma_trend' 'intra_trade_high' 'intra_trade_low ' 'long_stop' 'short_stop' ] def __init__(self, symbol): Process.__init__(self) self.symbol = symbol self.rsi_long = 50 + self.rsi_signal self.rsi_short = 50 - self.rsi_signal self.api = TqApi(TqSim(init_balance=50000)) self.now = datetime.now() self.target_pos = TargetPosTask(self.api, self.symbol) self.ticks = self.api.get_tick_serial(self.symbol) self.klines5 = self.api.get_kline_serial(self.symbol, 60 * 5) self.klines15 = self.api.get_kline_serial(self.symbol, 60 * 15) self.position = self.api.get_position(self.symbol) def on_init(self): print(self.now, '策略初始化') def on_start(self): print(self.now, '策略启动') def on_stop(self): print(self.now, '策略停止') def on_tick(self, ticks): if self.api.is_changing(ticks, 'datetime'): if self.position.pos_long == 0 and self.position.pos_short == 0: if self.ma_trend > 0 and self.rsi_value >= self.rsi_long and ticks.iloc[-1].last_price > self.boll_up: self.target_pos.set_target_volume(self.vol) self.intra_trade_high = ticks.iloc[-1].last_price if self.ma_trend < 0 and self.rsi_value <= self.rsi_short and ticks.iloc[ -1].last_price < self.boll_down: self.target_pos.set_target_volume(-self.vol) self.intra_trade_low = ticks.iloc[-1].last_price elif self.position.pos_long > 0: self.intra_trade_high = max(self.intra_trade_high, ticks.iloc[-1].last_price) self.long_stop = (self.intra_trade_high - self.trailing_long * (self.boll_up - self.boll_down)) if ticks.iloc[-1].last_price < self.long_stop: self.target_pos.set_target_volume(0) self.intra_trade_high = float('nan') else: self.intra_trade_low = min(self.intra_trade_low, ticks.iloc[-1].last_price) self.short_stop = (self.intra_trade_low + self.trailing_short * (self.boll_up - self.boll_down)) if ticks.iloc[-1].last_price > self.short_stop: self.target_pos.set_target_volume(0) self.intra_trade_low = float('nan') def on_5minbar(self, klines5): if self.api.is_changing(klines5, 'datetime'): boll = ta.BOLL(klines5.iloc[:-1], self.boll_window, self.boll_dev).iloc[-1] self.boll_up = boll['top'] self.boll_down = boll['bottom'] self.rsi_value = ta.RSI(klines5.iloc[:-1], self.rsi_window).iloc[-1]['rsi'] def on_15minbar(self, klines15): if self.api.is_changing(klines15, 'datetime'): self.fast_ma = ta.SMA(klines15.iloc[:-1], self.fast_window, 2) self.slow_ma = ta.SMA(klines15.iloc[:-1], self.slow_window, 2) if self.fast_ma > self.slow_ma: self.ma_trend = 1 elif self.fast_ma < self.slow_ma: self.ma_trend = -1 else: self.ma_trend = 0 def on_order(self): if self.api.is_changing(self.api.get_order()): pass def on_trade(self): if self.api.is_changing(self.api.get_trade()): pass def run(self): self.on_init() self.on_start() while True: self.api.wait_update() self.on_tick(self.ticks) self.on_5minbar(self.klines5) self.on_15minbar(self.klines15) self.on_order() self.on_trade() self.on_stop()
################################################################################# from tqsdk import TqApi from tqsdk.tafunc import time_to_datetime from datetime import datetime import pandas as pd import numpy as np from functools import reduce ################################################################################# api = TqApi(web_gui=True) symbol = "SHFE.rb2010" close = "CLOSETODAY" # 平今方式 quote = api.get_quote(symbol) ticks = api.get_tick_serial(symbol) position = api.get_position(symbol) GRID_AMOUNT = 10 grid_region_long = [1 * quote.price_tick] * GRID_AMOUNT # 多头每格价格跌幅(网格密度) grid_region_short = [1 * quote.price_tick] * GRID_AMOUNT # 空头每格价格涨幅(网格密度) grid_volume_long = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] # 多头每格持仓手数 grid_volume_short = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] # 空头每格持仓手数 profit_long = 1 * quote.price_tick # 多头利润 profit_short = 1 * quote.price_tick # 空头利润 is_clear_all1 = False is_clear_all2 = False ################################################################################# def reset_df_long(quote, GRID_AMOUNT, grid_region_long, grid_volume_long):
#自然灾害(5),趋势影响(4),政策影响(3) # 止损区间,突破HH2和LL2,如果持仓方向不对,坚决出厂 # LL1 和 HH 2 安全区间 BAR_LENGTH = 380 #************************ var **************************** #/************************init***********************************/ mylog.info("walkswing", "game begin") SYMBOL = "SHFE.rb2010" api = TqApi(TqSim()) klines = api.get_kline_serial(SYMBOL, 60, BAR_LENGTH) day_klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60) serial = api.get_tick_serial(SYMBOL) # 账户情况 account = api.get_account() print(account) # 运行时记录 avg_recorder = AvgRecorder("AvgRecord", 60) pos_manage = PositionManger(api, SYMBOL) strage_manager = StrategyManager(pos_manage, SYMBOL) mc_indictor = McIndictors(SYMBOL, strage_manager) mc_indictor.set_avg_recorder(avg_recorder) strage_manager.set_indictor(mc_indictor) strage_manager.set_avg_record(avg_recorder) pos_manage.set_logger(mylog) strage_manager.set_logger(mylog)
log.logger.info('初始账户权益:{0}'.format(account.balance)) log.logger.info('初始浮动盈亏:{0}'.format(account.float_profit)) SEC_LIST = [] for g_sec in g_security: ls = api.get_quote('KQ.m@%s' % g_sec) SEC_LIST.append(ls.underlying_symbol) log.logger.info('品种集合:{0}'.format(SEC_LIST)) # 获取主力合约 # domain = api.get_quote("[email protected]") # 获取主力合约的K线引用 for sec in SEC_LIST: positions[sec] = api.get_position(sec) klines_dict[sec] = api.get_kline_serial(sec, para['BAR_UNIT'], para['BAR_NUM']) quotes[sec] = api.get_quote(sec) ticks[sec] = api.get_tick_serial(sec) un_buy_open[sec] = [] un_sell_open[sec] = [] un_buy_close[sec] = [] un_sell_close[sec] = [] g_HS[sec] = [] g_LS[sec] = [] g_ZS[sec] = [] OPEN_DICT[sec] = open_num_list[SEC_LIST.index(sec)] orders = api.get_order() for order_id, val in orders.items(): secid = val['exchange_id'] + '.' + val['instrument_id'] if val['direction'] == 'BUY' and ( val['offset'] == 'OPEN') and val['status'] != 'FINISHED': un_buy_open[secid].append(order_id) elif val['direction'] == 'SELL' and (
from tqsdk import TqApi import datetime api = TqApi() # 获得 cu2001 tick序列的引用 ticks = api.get_tick_serial("SHFE.cu2001", 200) print(ticks) # 获得 cu2001 10秒K线的引用 # klines = api.get_kline_serial("SHFE.cu2001", 10) # print(datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) # # while True: # api.wait_update() # # 判断整个tick序列是否有变化 # if api.is_changing(ticks): # # ticks.iloc[-1]返回序列中最后一个tick # print("tick变化", ticks.iloc[-1]) # # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线 # if api.is_changing(klines.iloc[-1], "datetime"): # # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数 # print("新K线", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) # # 判断最后一根K线的收盘价是否有变化 # if api.is_changing(klines.iloc[-1], "close"): # # klines.close返回收盘价序列 # print("K线变化", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9), klines.close.iloc[-1])
''' klines ''' from tqsdk import TqApi, TqSim, tafunc from tqsdk.tafunc import time_to_datetime api = TqApi() klines = api.get_kline_serial("SHFE.rb2005", 60) serial = api.get_tick_serial("SHFE.rb2005") #print(time_to_datetime(serial.iloc[-1].datetime)) #llv = tafunc.llv(klines.low, 5) # 求5根k线最低点(包含当前k线) #print(list(llv)) while True: api.wait_update() print(serial.iloc[-1].bid_price1)
print('波动太大平仓') 当前状态 = '寻求开仓机会' def 平仓检测(行情, tick序列): global 当前状态 if 当前状态 == '等待平仓': 持仓检测模块(行情, tick序列) 固定止损止盈(行情, tick序列) 一分钟检测(行情, tick序列) try: api = TqApi(acc, backtest=TqBacktest(start_dt=date(2019, 11, 1), end_dt=date(2019, 11, 8))) 行情 = api.get_kline_serial(品种, 60, 100) tick序列 = api.get_tick_serial(品种, 检测最近多少tick序列) while True: api.wait_update() 开仓判断(行情, tick序列) 检测委托(行情, tick序列) 平仓检测(行情, tick序列) except BacktestFinished as e: # 回测结束时会执行这里的代码 print(acc.trade_log) pass api.close()
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'chengzhi' from tqsdk import TqApi, TqSim import datetime api = TqApi() # 获得cu1906 tick序列的引用 ticks = api.get_tick_serial("SHFE.cu1906") # 获得cu1906 10秒K线的引用 klines = api.get_kline_serial("SHFE.cu1906", 10) print(datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) while True: api.wait_update() # 判断整个tick序列是否有变化 if api.is_changing(ticks): # ticks.iloc[-1]返回序列中最后一个tick print("tick变化", ticks.iloc[-1]) # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线 if api.is_changing(klines.iloc[-1], "datetime"): # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数 print( "新K线", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) # 判断最后一根K线的收盘价是否有变化 if api.is_changing(klines.iloc[-1], "close"): # klines.close返回收盘价序列 print( "K线变化",
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'chengzhi' from tqsdk import TqApi import datetime api = TqApi("SIM") # 获得cu1812 tick序列的引用 ticks = api.get_tick_serial("SHFE.cu1812") # 获得cu1812 10秒K线的引用 klines = api.get_kline_serial("SHFE.cu1812", 10) while True: api.wait_update() # 判断整个tick序列是否有变化 if api.is_changing(ticks): # ticks[-1]返回序列中最后一个tick print("tick变化", ticks[-1]) # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线 if api.is_changing(klines[-1], "datetime"): # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数 print("新K线", datetime.datetime.fromtimestamp(klines[-1]["datetime"]/1e9)) # 判断最后一根K线的收盘价是否有变化 if api.is_changing(klines[-1], "close"): # klines.close返回收盘价序列 print("K线变化", datetime.datetime.fromtimestamp(klines[-1]["datetime"]/1e9), klines.close[-1])
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'chengzhi' from tqsdk import TqApi import datetime api = TqApi() # 获得 cu2003 tick序列的引用 ticks = api.get_tick_serial("SHFE.cu2003") # 获得 cu2003 10秒K线的引用 klines = api.get_kline_serial("SHFE.cu2003", 10) print(datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) while True: api.wait_update() # 判断整个tick序列是否有变化 if api.is_changing(ticks): # ticks.iloc[-1]返回序列中最后一个tick print("tick变化", ticks.iloc[-1]) # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线 if api.is_changing(klines.iloc[-1], "datetime"): # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数 print( "新K线", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) # 判断最后一根K线的收盘价是否有变化 if api.is_changing(klines.iloc[-1], "close"): # klines.close返回收盘价序列 print( "K线变化",
from tqsdk import TqApi api = TqApi( web_gui=True, ) #web_gui="http://172.20.155.135:62964"要将你订阅的K线或策略图形化显示, 只需在 TqApi() 中传入参数 web_gui = True即可: quote = api.get_quote("SHFE.rb2005") print(quote.last_price, quote.volume) klines = api.get_kline_serial("SHFE.rb2005", 1 * 60) # 获取K线 pandas结构 60是秒数 #klines = api.get_kline_serial(["SHFE.rb2005","DCE.i2005", "CZCE.AP005"], 60) # 入一个合约列表作为参数,来获取包含多个合约数据的K线: ticks = api.get_tick_serial( "SHFE.rb2005", data_length=1, ) # for i in klines.iterrows(): # print (i) # while True: api.wait_update() print(ticks.to_dict()) # print("最后一根K线收盘价", klines.close.iloc[-1]) # print (quote.datetime, quote.last_price)
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'chengzhi' from tqsdk import TqApi, TqAuth import datetime api = TqApi(auth=TqAuth("信易账户", "账户密码")) # 获得 i2209 tick序列的引用 ticks = api.get_tick_serial("DCE.i2209") # 获得 i2209 10秒K线的引用 klines = api.get_kline_serial("DCE.i2209", 10) print(datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) while True: api.wait_update() # 判断整个tick序列是否有变化 if api.is_changing(ticks): # ticks.iloc[-1]返回序列中最后一个tick print("tick变化", ticks.iloc[-1]) # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线 if api.is_changing(klines.iloc[-1], "datetime"): # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数 print( "新K线", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) # 判断最后一根K线的收盘价是否有变化 if api.is_changing(klines.iloc[-1], "close"): # klines.close返回收盘价序列 print( "K线变化",
class TqsdkClient(LocalClient): def __init__(self, **kwargs): super().__init__() self.p = Thread(target=self.init_api, args=()) self.p.start() self.api = None def init_api(self): self.api = TqApi() while True: sleep(60) def get(self, *argsm, **params): """ 调用他们的历史数据 """ # tick数据 if params.get("level") == "tick": return self.api.get_tick_serial(*self._parse_params(params)) # 分钟线数据 if params.get("level") != "tick": return self.api.get_kline_serial(*self._parse_params(params)) def set(self): pass def _parse_params(self, params): """ 解析参数 """ level = params.get("level") local_symbol = params.get("local_symbol") length = params.get("length") if level != "tick": return [local_symbol, self.get_seconds(level), length] return [local_symbol, length] @staticmethod def get_seconds(level) -> int: """ 将level转换到秒 * level: 数据等级 """ min_r = r"(\d{1,2})min" hour_r = r"(\d{1,2})h" day_r = r"(\d{1,2})day" if "min" in level: try: return int(re.match(min_r, level).group(1)) * 60 except Exception: raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1min这样的格式") if "h" in level: try: return int(re.match(hour_r, level).group(1)) * 3600 except Exception: raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1min这样的格式") if "day" in level: try: return int(re.match(day_r, level).group(1)) * 3600 * 24 except Exception: raise ValueError("你输入的level数据等级存在问题, 请检查是否符合1day这样的格式")