API 参考

天勤接口的PYTHON封装, 提供以下功能

class tqsdk.api.TqApi(account, url=None, backtest=None, debug=None, loop=None)

天勤接口及数据管理类.

通常情况下, 一个线程中应该只有一个TqApi的实例, 它负责维护网络连接, 接收行情及账户数据, 并在内存中维护业务数据截面

创建天勤接口实例

Args:
account (TqAccount/TqSim/str): 交易账号:
  • TqAccount: 使用实盘帐号, 直连行情和交易服务器(不通过天勤终端), 需提供期货公司/帐号/密码
  • TqSim: 使用 Api 自带的模拟功能, 直连行情服务器或连接天勤终端(例如使用历史复盘进行测试)接收行情数据
  • str: 连接天勤终端, 实盘交易填写期货公司提供的帐号, 使用天勤终端内置的模拟交易填写”SIM”, 需先在天勤终端内登录交易
url (str): [可选]指定服务器的地址
  • 当 account 为 TqAccount 类型时, 可以通过该参数指定交易服务器地址, 默认使用 opemtd.shinnytech.com. 行情始终使用 openmd.shinnytech.com
  • 当 account 为 TqSim 类型时, 可以通过该参数指定行情服务器地址, 默认使用 openmd.shinnytech.com, 可以指定为天勤终端的地址
  • 当 account 为 str 类型时, 可以通过该参数指定天勤终端的地址, 默认本机

backtest (TqBacktest): [可选]传入 TqBacktest 对象将进入回测模式, 回测模式下会将帐号转为 TqSim 并只连接 openmd.shinnytech.com 接收行情数据

debug(str): [可选]将调试信息输出到指定文件, 默认不输出.

loop(asyncio.AbstractEventLoop): [可选]使用指定的 IOLoop, 默认创建一个新的.

Example:

# 使用实盘帐号直连行情和交易服务器
from tqsdk import TqApi, TqAccount
api = TqApi(TqAccount("H海通期货", "022631", "123456"))

# 使用实盘帐号连接天勤终端(需先在天勤终端内登录交易)
from tqsdk import TqApi
api = TqApi("022631")

# 使用模拟帐号直连行情和交易服务器
from tqsdk import TqApi, TqSim
api = TqApi(TqSim())

# 进行策略回测
from datetime import date
from tqsdk import TqApi, TqSim, TqBacktest
api = TqApi(TqSim(), backtest=TqBacktest(start_dt=date(2018, 5, 1), end_dt=date(2018, 10, 1)))
close()

关闭天勤接口实例并释放相应资源

Example:

# m1901开多3手
from tqsdk import TqApi, TqSim
from contextlib import closing

with closing(TqApi(TqSim())) as api:
    api.insert_order(symbol="DCE.m1901", direction="BUY", offset="OPEN", volume=3)
get_quote(symbol)

获取指定合约的盘口行情.

Args:
symbol (str): 指定合约代码。注意:天勤接口从0.8版本开始,合约代码格式变更为 交易所代码.合约代码 的格式. 可用的交易所代码如下:
  • CFFEX: 中金所
  • SHFE: 上期所
  • DCE: 大商所
  • CZCE: 郑商所
  • INE: 能源交易所(原油)
Returns:

dict: 返回一个如下结构所示的 dict 对象的引用, 当行情更新时, 此对象的内容会被自动更新

"datetime": "",  # "2017-07-26 23:04:21.000001" (行情从交易所发出的时间(北京时间))
"ask_price1": float("nan"),  # 6122.0 (卖一价)
"ask_volume1": 0,  # 3 (卖一量)
"bid_price1": float("nan"),  # 6121.0 (买一价)
"bid_volume1": 0,  # 7 (买一量)
"last_price": float("nan"),  # 6122.0 (最新价)
"highest": float("nan"),  # 6129.0 (当日最高价)
"lowest": float("nan"),  # 6101.0 (当日最低价)
"open": float("nan"),  # 6102.0 (开盘价)
"close": float("nan"),  # nan (收盘价)
"average": float("nan"),  # 6119.0 (当日均价)
"volume": 0,  # 89252 (成交量)
"amount": float("nan"),  # 5461329880.0 (成交额)
"open_interest": 0,  # 616424 (持仓量)
"settlement": float("nan"),  # nan (结算价)
"upper_limit": float("nan"),  # 6388.0 (涨停价)
"lower_limit": float("nan"),  # 5896.0 (跌停价)
"pre_open_interest": 0,  # 616620 (昨持仓量)
"pre_settlement": float("nan"),  # 6142.0 (昨结算价)
"pre_close": float("nan"),  # 6106.0 (昨收盘价)
"price_tick": float("nan"),  # 10.0 (合约价格单位)
"price_decs": 0,  # 0 (合约价格小数位数)
"volume_multiple": 0,  # 10 (合约乘数)
"max_limit_order_volume": 0,  # 500 (最大限价单手数)
"max_market_order_volume": 0,  # 0 (最大市价单手数)
"min_limit_order_volume": 0,  # 1 (最小限价单手数)
"min_market_order_volume": 0,  # 0 (最小市价单手数)
"underlying_symbol": "",  # SHFE.rb1901 (标的合约)
"strike_price": float("nan"),  # nan (行权价)
"change": float("nan"),  # −20.0 (涨跌)
"change_percent": float("nan"),  # −0.00325 (涨跌幅)
"expired": False,  # False (合约是否已下市)

注意: 在 tqsdk 还没有收到行情数据包时, 此对象中各项内容为 NaN 或 0

Example:

# 获取 SHFE.cu1812 合约的报价
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
quote = api.get_quote("SHFE.cu1812")
while True:
    api.wait_update()
    print(quote["last_price"])

#以上代码将输出
nan
nan
24575.0
24575.0
...
get_kline_serial(symbol, duration_seconds, data_length=200, chart_id=None)

获取k线序列数据

请求指定合约及周期的K线数据. 序列数据会随着时间推进自动更新

Args:

symbol (str): 指定合约代码.

duration_seconds (int): K线数据周期,以秒为单位。例如: 1分钟线为60,1小时线为3600,日线为86400

data_length (int): 需要获取的序列长度。每个序列最大支持请求 8964 个数据

chart_id (str): [可选]指定序列id, 默认由 api 自动生成

Returns:

KlineSerialDataProxy: 本函数总是返回一个 KlineSerialDataProxy 的实例. 其中每个数据项的格式如下

"datetime": 0,  # 1501080715000000000 (K线起点时间(按北京时间),自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数)
"open": float("nan"),  # 51450.0 (K线起始时刻的最新价)
"high": float("nan"),  # 51450.0 (K线时间范围内的最高价)
"low": float("nan"),  # 51450.0 (K线时间范围内的最低价)
"close": float("nan"),  # 51450.0 (K线结束时刻的最新价)
"volume": 0,  # 11 (K线时间范围内的成交量)
"open_oi": 0,  # 27354 (K线起始时刻的持仓量)
"close_oi": 0,  # 27355 (K线结束时刻的持仓量)

Example:

# 获取 SHFE.cu1812 的1分钟线
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
k_serial = api.get_kline_serial("SHFE.cu1812", 60)
while True:
    api.wait_update()
    print(k_serial[-1]["close"])

# 预计的输出是这样的:
50970.0
50970.0
50960.0
...
get_tick_serial(symbol, data_length=200, chart_id=None)

获取tick序列数据

请求指定合约的Tick序列数据. 序列数据会随着时间推进自动更新

Args:

symbol (str): 指定合约代码.

data_length (int): 需要获取的序列长度。每个序列最大支持请求 8964 个数据

chart_id (str): [可选]指定序列id, 默认由 api 自动生成

Returns:

TickSerialDataProxy: 本函数总是返回一个 TickSerialDataProxy 的实例. 其中每个数据项的格式如下

"datetime": 0,  # 1501074872000000000 (tick从交易所发出的时间(按北京时间),自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数)
"last_price": float("nan"),  # 3887.0 (最新价)
"average": float("nan"),  # 3820.0 (当日均价)
"highest": float("nan"),  # 3897.0 (当日最高价)
"lowest": float("nan"),  # 3806.0 (当日最低价)
"ask_price1": float("nan"),  # 3886.0 (卖一价)
"ask_volume1": 0,  # 3 (卖一量)
"bid_price1": float("nan"),  # 3881.0 (买一价)
"bid_volume1": 0,  # 18 (买一量)
"volume": 0,  # 7823 (当日成交量)
"amount": float("nan"),  # 19237841.0 (成交额)
"open_interest": 0,  # 1941 (持仓量)

Example:

# 获取 SHFE.cu1812 的Tick序列
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
serial = api.get_tick_serial("SHFE.cu1812")
while True:
    api.wait_update()
    print(serial[-1]["bid_price1"], serial[-1]["ask_price1"])

# 预计的输出是这样的:
50860.0 51580.0
50860.0 51580.0
50820.0 51580.0
...
insert_order(symbol, direction, offset, volume, limit_price=None, order_id=None)

发送下单指令

Args:

symbol (str): 拟下单的合约symbol, 格式为 交易所代码.合约代码, 例如 “SHFE.cu1801”

direction (str): “BUY” 或 “SELL”

offset (str): “OPEN”, “CLOSE” 或 “CLOSETODAY”

volume (int): 需要下单的手数

limit_price (float): [可选]下单价格, 默认市价单

order_id (str): [可选]指定下单单号, 默认由 api 自动生成

Returns:

dict: 本函数总是返回一个如下结构所示的包含委托单信息的dict的引用. 每当order中信息改变时, 此dict会自动更新.

"order_id": "",  # "123" (委托单ID, 对于一个用户的所有委托单,这个ID都是不重复的)
"exchange_order_id": "",  # "1928341" (交易所单号)
"exchange_id": "",  # "SHFE" (交易所)
"instrument_id": "",  # "rb1901" (交易所内的合约代码)
"direction": "",  # "BUY" (下单方向, BUY=买, SELL=卖)
"offset": "",  # "OPEN" (开平标志, OPEN=开仓, CLOSE=平仓, CLOSETODAY=平今)
"volume_orign": 0,  # 10 (总报单手数)
"volume_left": 0,  # 5 (未成交手数)
"limit_price": float("nan"),  # 4500.0 (委托价格, 仅当 price_type = LIMIT 时有效)
"price_type": "",  # "LIMIT" (价格类型, ANY=市价, LIMIT=限价)
"volume_condition": "",  # "ANY" (手数条件, ANY=任何数量, MIN=最小数量, ALL=全部数量)
"time_condition": "",  # "GFD" (时间条件, IOC=立即完成,否则撤销, GFS=本节有效, GFD=当日有效, GTC=撤销前有效, GFA=集合竞价有效)
"insert_date_time": 0,  # 1501074872000000000 (下单时间(按北京时间),自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数)
"last_msg": "",  # "报单成功" (委托单状态信息)
"status": "",  # "ALIVE" (委托单状态, ALIVE=有效, FINISHED=已完)

Example:

# 市价开3手 DCE.m1809 多仓
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
order = api.insert_order(symbol="DCE.m1809", direction="BUY", offset="OPEN", volume=3)
while True:
    api.wait_update()
    print("单状态: %s, 已成交: %d 手" % (order["status"], order["volume_orign"] - order["volume_left"]))

# 预计的输出是这样的:
单状态: ALIVE, 已成交: 0 
单状态: ALIVE, 已成交: 0 
单状态: FINISHED, 已成交: 3 
...
cancel_order(order_or_order_id)

发送撤单指令

Args:
order_or_order_id (str/dict): 拟撤委托单的 dict 或 单号

Example:

# 挂价开3手 DCE.m1809 多仓, 如果价格变化则撤单重下,直到全部成交
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
quote = api.get_quote("DCE.m1809")
order = {}

while True:
    api.wait_update()
    # 当行情有变化且当前挂单价格不优时,则撤单
    if order and api.is_changing(quote) and order["status"] == "ALIVE" and quote["bid_price1"] > order["limit_price"]:
        print("价格改变,撤单重下")
        api.cancel_order(order)
    # 当委托单已撤或还没有下单时则下单
    if (not order and api.is_changing(quote)) or (api.is_changing(order) and order["volume_left"] != 0 and order["status"] == "FINISHED"):
        print("下单: 价格 %f" % quote["bid_price1"])
        order = api.insert_order(symbol="DCE.m1809", direction="BUY", offset="OPEN", volume=order.get("volume_left", 3), limit_price=quote["bid_price1"])
    if api.is_changing(order):
        print("单状态: %s, 已成交: %d 手" % (order["status"], order["volume_orign"] - order["volume_left"]))


# 预计的输出是这样的:
下单: 价格 3117.000000
单状态: ALIVE, 已成交: 0 手
价格改变,撤单重下
下单: 价格 3118.000000
单状态: ALIVE, 已成交: 0 手
单状态: FINISHED, 已成交: 3 手
...
get_account()

获取用户账户资金信息

Returns:

dict: 本函数总是返回一个如下结构所示的包含用户账户资金信息的dict的引用. 每当其中信息改变时, 此dict会自动更新.

"currency": "",  # "CNY" (币种)
"pre_balance": float("nan"),  # 9912934.78 (昨日账户权益)
"static_balance": float("nan"),  # (静态权益)
"balance": float("nan"),  # 9963216.55 (账户权益)
"available": float("nan"),  # 9480176.15 (可用资金)
"float_profit": float("nan"),  # 8910.0 (浮动盈亏)
"position_profit": float("nan"),  # 1120.0(持仓盈亏)
"close_profit": float("nan"),  # -11120.0 (本交易日内平仓盈亏)
"frozen_margin": float("nan"),  # 0.0(冻结保证金)
"margin": float("nan"),  # 11232.23 (保证金占用)
"frozen_commission": float("nan"),  # 0.0 (冻结手续费)
"commission": float("nan"),  # 123.0 (本交易日内交纳的手续费)
"frozen_premium": float("nan"),  # 0.0 (冻结权利金)
"premium": float("nan"),  # 0.0 (本交易日内交纳的权利金)
"deposit": float("nan"),  # 1234.0 (本交易日内的入金金额)
"withdraw": float("nan"),  # 890.0 (本交易日内的出金金额)
"risk_ratio": float("nan"),  # 0.048482375 (风险度)

注意: 在 tqsdk 还没有收到账户数据包时, 此对象中各项内容为NaN

Example:

# 获取当前浮动盈亏
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
account = api.get_account()
while True:
    api.wait_update()
    print(account["float_profit"])

# 预计的输出是这样的:
2180.0
2080.0
2080.0
...
get_position(symbol=None)

获取用户持仓信息

Args:
symbol (str): [可选]合约代码, 默认返回所有持仓
Returns:

dict: 当指定了symbol时, 返回一个如下结构所示的包含指定symbol持仓信息的引用. 每当其中信息改变时, 此dict会自动更新.

"exchange_id": "",  # "SHFE" (交易所)
"instrument_id": "",  # "rb1901" (交易所内的合约代码)
"volume_long_today": 0,  # 10 (多头今仓手数)
"volume_long_his": 0,  # 5 (多头老仓手数)
"volume_long": 0,  # 15 (多头手数)
"volume_long_frozen_today": 0,  # 3 (多头今仓冻结)
"volume_long_frozen_his": 0,  # 2 (多头老仓冻结)
"volume_long_frozen": 0,  # 5 (多头持仓冻结)
"volume_short_today": 0,  # 3 (空头今仓手数)
"volume_short_his": 0,  # 0 (空头老仓手数)
"volume_short": 0,  # 3 (空头手数)
"volume_short_frozen_today": 0,  # 0 (空头今仓冻结)
"volume_short_frozen_his": 0,  # 0 (空头老仓冻结)
"volume_short_frozen": 0,  # 0 (空头持仓冻结)
"open_price_long": float("nan"),  # 3120.0 (多头开仓均价)
"open_price_short": float("nan"),  # 3310.0 (空头开仓均价)
"open_cost_long": float("nan"),  # 468000.0 (多头开仓市值)
"open_cost_short": float("nan"),  # 99300.0 (空头开仓市值)
"position_price_long": float("nan"),  # 3200.0 (多头持仓均价)
"position_price_short": float("nan"),  # 3330.0 (空头持仓均价)
"position_cost_long": float("nan"),  # 480000.0 (多头持仓市值)
"position_cost_short": float("nan"),  # 99900.0 (空头持仓市值)
"float_profit_long": float("nan"),  # 12000.0 (多头浮动盈亏)
"float_profit_short": float("nan"),  # 3300.0 (空头浮动盈亏)
"float_profit": float("nan"),  # 15300.0 (浮动盈亏)
"position_profit_long": float("nan"),  # 0.0 (多头持仓盈亏)
"position_profit_short": float("nan"),  # 3900.0 (空头持仓盈亏)
"position_profit": float("nan"),  # 3900.0 (持仓盈亏)
"margin_long": float("nan"),  # 50000.0 (多头占用保证金)
"margin_short": float("nan"),  # 10000.0 (空头占用保证金)
"margin": float("nan"),  # 60000.0 (占用保证金)

不带symbol参数调用 get_position 函数, 将返回包含用户所有持仓的一个嵌套dict, 其中每个元素的key为合约代码, value为上述格式的dict

注意: 在 tqsdk 还没有收到持仓信息时, 此对象中各项内容为空或0

Example:

# 获取 DCE.m1809 当前浮动盈亏
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
position = api.get_position("DCE.m1809")
while True:
    api.wait_update()
    print(position["float_profit_long"] + position["float_profit_short"])

# 预计的输出是这样的:
300.0
300.0
330.0
...
get_order(order_id=None)

获取用户委托单信息

Args:
order_id (str): [可选]单号, 默认返回所有委托单
Returns:

dict: 当指定了order_id时, 返回一个如下结构所示的包含指定order_id委托单信息的引用. 每当其中信息改变时, 此dict会自动更新.

"order_id": "",  # "123" (委托单ID, 对于一个用户的所有委托单,这个ID都是不重复的)
"exchange_order_id": "",  # "1928341" (交易所单号)
"exchange_id": "",  # "SHFE" (交易所)
"instrument_id": "",  # "rb1901" (交易所内的合约代码)
"direction": "",  # "BUY" (下单方向, BUY=买, SELL=卖)
"offset": "",  # "OPEN" (开平标志, OPEN=开仓, CLOSE=平仓, CLOSETODAY=平今)
"volume_orign": 0,  # 10 (总报单手数)
"volume_left": 0,  # 5 (未成交手数)
"limit_price": float("nan"),  # 4500.0 (委托价格, 仅当 price_type = LIMIT 时有效)
"price_type": "",  # "LIMIT" (价格类型, ANY=市价, LIMIT=限价)
"volume_condition": "",  # "ANY" (手数条件, ANY=任何数量, MIN=最小数量, ALL=全部数量)
"time_condition": "",  # "GFD" (时间条件, IOC=立即完成,否则撤销, GFS=本节有效, GFD=当日有效, GTC=撤销前有效, GFA=集合竞价有效)
"insert_date_time": 0,  # 1501074872000000000 (下单时间(按北京时间),自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数)
"last_msg": "",  # "报单成功" (委托单状态信息)
"status": "",  # "ALIVE" (委托单状态, ALIVE=有效, FINISHED=已完)

不带order_id参数调用get_order函数, 将返回包含用户所有委托单的一个嵌套dict, 其中每个元素的key为合约代码, value为上述格式的dict

注意: 在 tqsdk 还没有收到委托单信息时, 此对象中各项内容为空

Example:

# 获取当前总挂单手数
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
orders = api.get_order()
while True:
    api.wait_update()
    print(sum(o["volume_left"] for oid, o in orders.items() if not oid.startswith("_") and o["status"] == "ALIVE"))

# 预计的输出是这样的:
3
3
0
...
wait_update(deadline=None)

等待业务数据更新

调用此函数将阻塞当前线程, 等待天勤主进程发送业务数据更新并返回

Args:
deadline (float): [可选]指定截止时间,自unix epoch(1970-01-01 00:00:00 GMT)以来的秒数(time.time())。默认没有超时(无限等待)
Returns:
bool: 如果收到业务数据更新则返回 True, 如果到截止时间依然没有收到业务数据更新则返回 False

注意: 由于存在网络延迟, 因此有数据更新不代表之前发出的所有请求都被处理了, 例如:

from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
quote = api.get_quote("SHFE.cu1812")
api.wait_update()
print(quote["datetime"])

可能输出 ""(空字符串), 表示还没有收到该合约的行情
is_changing(obj, key=None)

判定obj最近是否有更新

当业务数据更新导致 wait_update 返回后可以使用该函数判断本次业务数据更新是否包含特定obj或其中某个字段

Args:

obj (any): 任意业务对象, 包括 get_quote 返回的 quote, get_kline_serial 返回的 k_serial, get_account 返回的 account 等

key (str/list of str): [可选]需要判断的字段,默认不指定
  • 不指定: 当该obj下的任意字段有更新时返回True, 否则返回 False.
  • str: 当该obj下的指定字段有更新时返回True, 否则返回 False.
  • list of str: 当该obj下的指定字段中的任何一个字段有更新时返回True, 否则返回 False.
Returns:
bool: 如果本次业务数据更新包含了待判定的数据则返回 True, 否则返回 False.

Example:

# 追踪 SHFE.cu1812 的最新价更新
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
quote = api.get_quote("SHFE.cu1812")
while True:
    api.wait_update()
    if api.is_changing(quote, "last_price"):
        print(quote["last_price"])

# 以上代码运行后的输出是这样的:
51800.0
51810.0
51800.0
...
create_task(coro)

创建一个task

一个task就是一个协程,task的调度是在 wait_update 函数中完成的,如果代码从来没有调用 wait_update,则task也得不到执行

Args:
coro (coroutine): 需要创建的协程

Example:

# 一个简单的task
import asyncio
from tqsdk import TqApi, TqSim

async def hello():
    await asyncio.sleep(3)
    print("hello world")

api = TqApi(TqSim())
api.create_task(hello())
while True:
    api.wait_update()

#以上代码将在3秒后输出
hello world
register_update_notify(obj=None, chan=None)

注册一个channel以便接受业务数据更新通知

调用此函数将返回一个channel, 当obj更新时会通知该channel

推荐使用 async with api.register_update_notify() as update_chan 来注册更新通知

如果直接调用 update_chan = api.register_update_notify() 则使用完成后需要调用 await update_chan.close() 避免资源泄漏

Args:

obj (any/list of any): [可选]任意业务对象, 包括 get_quote 返回的 quote, get_kline_serial 返回的 k_serial, get_account 返回的 account 等。默认不指定,监控所有业务对象

chan (TqChan): [可选]指定需要注册的channel。默认不指定,由本函数创建

Example:

# 获取 SHFE.cu1812 合约的报价
from tqsdk import TqApi, TqSim

async def demo():
    quote = api.get_quote("SHFE.cu1812")
    async with api.register_update_notify(quote) as update_chan:
        async for _ in update_chan:
            print(quote["last_price"])

api = TqApi(TqSim())
api.create_task(demo())
while True:
    api.wait_update()

#以上代码将输出
nan
51850.0
51850.0
51690.0
...
class tqsdk.api.TqAccount(broker_id, account_id, password)

天勤实盘类

创建天勤实盘实例

Args:

broker_id (str): 期货公司, 可以在天勤终端中查看期货公司名称

account_id (str): 帐号

password (str): 密码

class tqsdk.api.SerialDataProxy(serial_root, width, default)

K线及Tick序列数据包装器, 方便数据读取使用

Examples:

# 获取一个分钟线序列, ks 即是 SerialDataProxy 的实例
ks = api.get_kline_serial("SHFE.cu1812", 60)

# 获取最后一根K线
a = ks[-1]
# 获取倒数第5根K线
a = ks[-5]
# a == {
#     "datetime": ...,
#     "open": ...,
#     "high": ...,
#     "low": ...,
#     ...
# }

# 获取特定字段的序列
cs = ks.close
# cs = [3245, 3421, 3345, ...]

# 将序列转为 pandas.DataFrame
ks.to_dataframe()
is_ready()

判断是否已经从服务器收到了所有订阅的数据

Returns:
bool: 返回 True 表示已经从服务器收到了所有订阅的数据

Example:

# 判断是否已经从服务器收到了最后 3000 根 SHFE.cu1812 的分钟线数据
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
k_serial = api.get_kline_serial("SHFE.cu1812", 60, data_length=3000)
while True:
    api.wait_update()
    print(k_serial.is_ready())

# 预计的输出是这样的:
False
False
True
True
...
to_dataframe()

将当前该序列中的数据转换为 pandas.DataFrame

Returns:

pandas.DataFrame: 每行是一条行情数据

注意: 返回的 DataFrame 反映的是当前的行情数据,不会自动更新,当行情数据有变化后需要重新调用 to_dataframe

Example:

# 判断K线是否为阳线
from tqsdk import TqApi, TqSim

api = TqApi(TqSim())
k_serial = api.get_kline_serial("SHFE.cu1812", 60)
while True:
    api.wait_update()
    df = k_serial.to_dataframe()
    print(df["close"] > df["open"])

# 预计的输出是这样的:
0       True
1       True
2      False
       ...
197    False
198     True
199    False
Length: 200, dtype: bool
...
class tqsdk.api.TqChan(api, last_only=False)

用于协程间通讯的channel

创建channel实例

Args:
last_only (bool): 为True时只存储最后一个发送到channel的对象
send_nowait(item)

尝试立即发送数据到channel中

Args:
item (any): 待发送的对象
Raises:
asyncio.QueueFull: 如果channel已满则会抛出 asyncio.QueueFull
recv_nowait()

尝试立即接收channel中的数据

Returns:
any: 收到的数据,如果channel已被关闭则会立即收到None
Raises:
asyncio.QueueFull: 如果channel中没有数据则会抛出 asyncio.QueueEmpty
close()

关闭channel

关闭后send将不起作用,recv在收完剩余数据后会立即返回None

recv()

异步接收channel中的数据,如果channel中没有数据则一直等待

Returns:
any: 收到的数据,如果channel已被关闭则会立即收到None
recv_latest(latest)

尝试立即接收channel中的最后一个数据

Args:
latest (any): 如果当前channel中没有数据或已关闭则返回该对象
Returns:
any: channel中的最后一个数据
send(item)

异步发送数据到channel中

Args:
item (any): 待发送的对象
class tqsdk.lib.TargetPosTask(api, symbol, price='ACTIVE', init_pos=None, offset_priority='今昨, 开', trade_chan=None)

目标持仓 task, 该 task 可以将指定合约调整到目标头寸

创建目标持仓task实例,负责调整归属于该task的持仓(默认为整个账户的该合约净持仓)

Args:

api (TqApi): TqApi实例,该task依托于指定api下单/撤单

symbol (str): 负责调整的合约代码

price (str): [可选]下单方式, ACTIVE=对价下单, PASSIVE=挂价下单

init_pos (int): [可选]初始持仓,默认整个账户的该合净持仓

offset_priority (str): [可选]开平仓顺序,昨=平昨仓,今=平今仓,开=开仓,逗号=等待之前操作完成

对于下单指令区分平今/昨的交易所(如上期所),按照今/昨仓的数量计算是否能平今/昨仓

对于下单指令不区分平今/昨的交易所(如中金所),按照“先平当日新开仓,再平历史仓”的规则计算是否能平今/昨仓
  • “今昨,开” 表示先平今仓,再平昨仓,等待平仓完成后开仓,对于没有单向大边的品种避免了开仓保证金不足
  • “今昨开” 表示先平今仓,再平昨仓,并开仓,所有指令同时发出,适合有单向大边的品种
  • “昨开” 表示先平昨仓,再开仓,禁止平今仓,适合股指这样平今手续费较高的品种

trade_chan (TqChan): [可选]成交通知channel, 当有成交发生时会将成交手数(多头为正数,空头为负数)发到该channel上

set_target_volume(volume)

设置目标持仓手数

Args:
volume (int): 目标持仓手数,正数表示多头,负数表示空头,0表示空仓

Example:

# 设置 rb1810 持仓为多头5手
from tqsdk import TqApi, TqSim, TargetPosTask

api = TqApi(TqSim())
target_pos = TargetPosTask(api, "SHFE.rb1810")
while True:
    api.wait_update()
    target_pos.set_target_volume(5)
class tqsdk.lib.InsertOrderUntilAllTradedTask(api, symbol, direction, offset, volume, price='ACTIVE', trade_chan=None)

追价下单task, 该task会在行情变化后自动撤单重下,直到全部成交

创建追价下单task实例

Args:

api (TqApi): TqApi实例,该task依托于指定api下单/撤单

symbol (str): 拟下单的合约symbol, 格式为 交易所代码.合约代码, 例如 “SHFE.cu1801”

direction (str): “BUY” 或 “SELL”

offset (str): “OPEN”, “CLOSE” 或 “CLOSETODAY”

volume (int): 需要下单的手数

price (str): [可选]下单方式, ACTIVE=对价下单, PASSIVE=挂价下单

trade_chan (TqChan): [可选]成交通知channel, 当有成交发生时会将成交手数(多头为正数,空头为负数)发到该channel上

class tqsdk.lib.InsertOrderTask(api, symbol, direction, offset, volume, limit_price=None, order_chan=None, trade_chan=None)

下单task

创建下单task实例

Args:

api (TqApi): TqApi实例,该task依托于指定api下单/撤单

symbol (str): 拟下单的合约symbol, 格式为 交易所代码.合约代码, 例如 “SHFE.cu1801”

direction (str): “BUY” 或 “SELL”

offset (str): “OPEN”, “CLOSE” 或 “CLOSETODAY”

volume (int): 需要下单的手数

limit_price (float): [可选]下单价格, 默认市价单

order_chan (TqChan): [可选]委托单通知channel, 当委托单状态发生时会将委托单信息发到该channel上

trade_chan (TqChan): [可选]成交通知channel, 当有成交发生时会将成交手数(多头为正数,空头为负数)发到该channel上

class tqsdk.sim.TqSim(init_balance=1000000.0, account_id='TQSIM')

天勤模拟交易类

限价单要求报单价格达到或超过对手盘价格才能成交, 成交价为报单价格, 如果没有对手盘(涨跌停)则无法成交

市价单使用对手盘价格成交, 如果没有对手盘(涨跌停)则自动撤单

模拟交易不会有部分成交的情况, 要成交就是全部成交

创建天勤模拟交易类

Args:

init_balance (float): [可选]初始资金, 默认为一百万

account_id (str): [可选]帐号, 默认为 “TQSIM”

class tqsdk.backtest.TqBacktest(start_dt, end_dt)

天勤回测类

将该类传入 TqApi 的构造函数, 则策略就会进入回测模式

回测模式下 k线会在刚创建出来时和结束时分别更新一次, 在这之间 k线是不会更新的

回测模式下 quote 的更新频率由所订阅的 tick 和 k线周期确定:
  • 只要订阅了 tick, 则对应合约的 quote 就会使用 tick 生成, 更新频率也和 tick 一致, 但只有下字段:
    datetime/ask&bid_price1/ask&bid_volume1/last_price/highest/lowest/average/volume/amount/open_interest/ price_tick/price_decs/volume_multiple/max&min_limit&market_order_volume/underlying_symbol/strike_price
  • 如果没有订阅 tick, 但是订阅了 k线, 则对应合约的 quote 会使用 k线生成, 更新频率和 k线的周期一致, 如果订阅了某个合约的多个周期的 k线, 则任一个周期的 k线有更新时, quote 都会更新. 使用 k线生成的 quote 的盘口由收盘价分别加/减一个最小变动单位, 并且 highest/lowest/average/amount 始终为 nan, volume 始终为0
  • 如果即没有订阅 tick, 也没有订阅 k线或订阅的 k线周期大于分钟线, 则 TqBacktest 会自动订阅分钟线来生成 quote

模拟交易要求报单价格大于等于对手盘价格才会成交, 例如下买单, 要求价格大于等于卖一价才会成交, 如果不能立即成交则会等到下次行情更新再重新判断

回测模式下 wait_update 每次最多推进一个行情时间

回测结束后会抛出 BacktestFinished 例外

创建天勤回测类

Args:

start_dt (date/datetime): 回测起始时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点

end_dt (date/datetime): 回测结束时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点

exception tqsdk.exceptions.BacktestFinished

回测结束会抛出此例外