Skip to content

Commit 99411cd

Browse files
shinny-hongyanshinny-chenli
authored andcommitted
Update Version 3.7.8
1 parent 1adf688 commit 99411cd

22 files changed

+103
-133
lines changed

PKG-INFO

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 2.1
22
Name: tqsdk
3-
Version: 3.7.6
3+
Version: 3.7.8
44
Summary: TianQin SDK
55
Home-page: https://www.shinnytech.com/tqsdk
66
Author: TianQin

doc/advanced/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@
1717
unanttended.rst
1818
targetpostask2.rst
1919
scheduler.rst
20-
tqsdk2ctptest.rst

doc/conf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@
4040

4141
# General information about the project.
4242
project = u'TianQin Python SDK'
43-
copyright = u'2018-2024, TianQin'
43+
copyright = u'2018-2025, TianQin'
4444
author = u'TianQin'
4545

4646
# The version info for the project you're documenting, acts as replacement for
4747
# |version| and |release|, also used in various other places throughout the
4848
# built documents.
4949
#
5050
# The short X.Y version.
51-
version = u'3.7.6'
51+
version = u'3.7.8'
5252
# The full version, including alpha/beta/rc tags.
53-
release = u'3.7.6'
53+
release = u'3.7.8'
5454

5555
# The language for content autogenerated by Sphinx. Refer to documentation
5656
# for a list of supported languages.

doc/profession.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ TqSdk 中大部分功能是供用户免费使用的, 同时我们也提供了专
2020

2121
.. figure:: images/how-grafana04.gif
2222

23+
2324
`快期专业版官网地址 <https://www.shinnytech.com/qpro>`_
2425

2526
`快期专业版文档地址 <https://publish2.shinnytech.com/doc/qpro/latest/quickstart.html>`_

doc/quickstart.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,6 @@ klines是一个pandas.DataFrame对象. 跟 api.get_quote() 一样, api.get_kline
107107

108108
这部分的完整示例程序请见 :ref:`tutorial-t30` .
109109

110-
我们也可以通过传入一个合约列表作为参数,来获取包含多个合约数据的K线::
111-
112-
klines = api.get_kline_serial(["SHFE.au1912", "SHFE.au2006"], 5) # 获取SHFE.au2006向SHFE.au1912对齐的K线
113-
114-
详细使用方法及说明请见 :py:meth:`~tqsdk.TqApi.get_kline_serial` 函数说明。
115-
116110
到这里为止, 你已经知道了如何获取实时行情和K线数据, 下面一段将介绍如何访问你的交易账户并发送交易指令
117111

118112
.. _quickstart_2_web_gui:

doc/usage/backtest.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
策略程序回测
44
=================================================
5-
策略程序回测是 TqSdk 专业版中的功能,能让用户在不改变代码的情况下去回测自己的策略在历史行情的表现
5+
策略程序回测能让用户在不改变代码的情况下去回测自己的策略在历史行情的表现
66

7-
如果想使用策略回测该功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk-buy/>`_ 申请使用或购买
8-
9-
用户也可以申请模拟账户后模拟运行来检验策略 :ref:`sim_trading`
7+
用户也可以使用快期模拟账户来模拟运行来检验策略 :ref:`sim_trading`
108

119
执行策略回测
1210
-------------------------------------------------

doc/usage/option_trade.rst

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
期权交易 & 交易所官方组合
44
====================================================
5-
TqSdk 中期权交易(商品期权、金融期权和 ETF 期权)和交易所官方组合交易,均是 TqSdk 专业版中的功能
6-
7-
用户如果想在 TqSdk 中进行上述操作,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk-buy/>`_ 申请使用或购买
8-
95
TqSdk 中期权合和交易所官方组合的约代码格式参考如下::
106

117
DCE.m1807-C-2450 - 大商所豆粕期权
@@ -20,7 +16,7 @@ TqSdk 中期权合和交易所官方组合的约代码格式参考如下::
2016

2117

2218

23-
对于交易所官方组合,目前 TqSdk 中只支持交易所官方组合进行实盘交易
19+
对于交易所官方组合,目前 TqSdk 中只支持交易所官方组合进行实盘交易,不支持在模拟中进行交易所官方组合交易
2420

2521

2622
期权指标计算&序列计算函数

doc/usage/shinny_account.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
-------------------------------------------------
2222
对于 TqSdk 免费版,每个快期账户支持最多绑定一个实盘账户,而天勤量化专业版支持一个快期账户绑定任意多个实盘账户
2323

24-
快期账户会在用户使用实盘账户时自动进行绑定,直到该快期账户没有能绑定实盘账户的名额(自动绑定功能需要 TqSdk 版本> 1.8.3)::
24+
快期账户会在用户使用实盘账户时自动进行绑定,直到该快期账户没有能绑定实盘账户的名额::
2525

2626
from tqsdk import TqApi, TqAccount, TqAuth, TqKq
2727
api = TqApi(TqAccount("H海通期货", "320102", "123456"), auth=TqAuth("快期账户", "账户密码"))

doc/usage/targetpostask.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,3 @@
7272

7373

7474

75-
:py:class:`~tqsdk.InsertOrderUntilAllTradedTask` 是追价下单task, 该task会在行情变化后自动撤单重下,直到全部成交.
76-

doc/version.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
版本变更
44
=============================
5+
3.7.8 (2025/01/23)
6+
7+
* docs: 修正部分文档
8+
* 修复: 因郑商所三位合约导致合约信息中部分字段错误的问题
9+
10+
11+
3.7.7 (2025/01/14)
12+
13+
* docs: 修正部分文档,补充 wait_update 的 deadline 参数说明
14+
* 自该版本起不再支持使用 api._data['quotes'] 获取全部合约
15+
16+
517
3.7.6 (2024/11/14)
618

719
* 修复: 增加依赖库 packaging

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setuptools.setup(
1010
name='tqsdk',
11-
version="3.7.6",
11+
version="3.7.8",
1212
description='TianQin SDK',
1313
author='TianQin',
1414
author_email='[email protected]',

tqsdk/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.7.6'
1+
__version__ = '3.7.8'

tqsdk/api.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
from tqsdk.entity import Entity
6565
from tqsdk.exceptions import TqTimeoutError
6666
from tqsdk.log import _clear_logs, _get_log_name, _get_disk_free
67-
from tqsdk.objs import Quote, TradingStatus, Kline, Tick, Account, Position, Order, Trade, QuotesEntity, RiskManagementRule, RiskManagementData
67+
from tqsdk.objs import Quote, TradingStatus, Kline, Tick, Account, Position, Order, Trade, RiskManagementRule, RiskManagementData
6868
from tqsdk.objs import SecurityAccount, SecurityOrder, SecurityTrade, SecurityPosition
6969
from tqsdk.objs_not_entity import QuoteList, TqDataFrame, TqSymbolDataFrame, SymbolList, SymbolLevelList, \
7070
TqSymbolRankingDataFrame, TqOptionGreeksDataFrame, TqMdSettlementDataFrame
@@ -276,8 +276,6 @@ def __init__(self, account: Optional[Union[TqMultiAccount, UnionTradeable]] = No
276276
self._klines_update_range = {}
277277
self._data = Entity() # 数据存储
278278
self._data._instance_entity([])
279-
self._data["quotes"] = QuotesEntity(self)
280-
self._data["quotes"]._instance_entity(["quotes"])
281279
self._diffs = [] # 自上次wait_update返回后收到更新数据的数组 (异步代码)
282280
self._sync_diffs = [] # 自上次wait_update返回后收到更新数据的数组 (同步代码)
283281
self._pending_diffs = [] # 从网络上收到的待处理的 diffs, 只在 wait_update 函数执行过程中才可能为非空
@@ -287,6 +285,7 @@ def __init__(self, account: Optional[Union[TqMultiAccount, UnionTradeable]] = No
287285
self._dividend_cache = {} # 缓存合约对应的复权系数矩阵,每个合约只计算一次
288286
self._send_chan, self._recv_chan = TqChan(self), TqChan(self) # 消息收发队列
289287
self._ws_md_recv_chan = None # 记录 ws_md_recv_chan 引用
288+
self._pre20_ins_info = {} # 20年9月份之前的合约信息
290289

291290
# slave模式的api不需要完整初始化流程
292291
self._is_slave = isinstance(account, TqApi)
@@ -542,19 +541,20 @@ async def _ensure_symbol_async(self, symbol: Union[str, List[str]]):
542541
if self._stock is False:
543542
raise Exception("代码 %s 不存在, 请检查合约代码是否填写正确" % symbol_list)
544543
else:
545-
query_pack = _query_for_quote(symbol_list)
546-
self._send_pack(query_pack)
544+
for query in _query_for_quote(symbol_list, self._pre20_ins_info.keys()):
545+
self._send_pack(query)
547546
async with self.register_update_notify() as update_chan:
548547
async for _ in update_chan:
548+
# 这里用 price_tick 判断是否已经收到了合约信息,是为了兼容 2020年9月份之前上市的合约
549+
# 合约服务没有提供这些合约,tqsdk 是通过预先加载本地缓存文件的方式提供这些合约的信息
550+
# 理想的判断标准是 basktest 模块中的 _ensure_query 函数
549551
if all([self._data.get("quotes", {}).get(symbol, {}).get('price_tick', float('nan')) > 0 for symbol in symbol_list]):
550552
break
551553

552554
# ----------------------------------------------------------------------
553555
def get_trading_status(self, symbol: str) -> TradingStatus:
554556
"""
555-
获取指定合约的交易状态. 此接口为 TqSdk 专业版提供,便于实现开盘抢单功能。
556-
557-
如果想使用此功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk-buy/>`_ 申请试用或购买
557+
获取指定合约的交易状态,便于实现开盘抢单功能。
558558
559559
Args:
560560
symbol (str): 合约代码
@@ -1012,7 +1012,7 @@ def _get_data_series(self, call_func: str, symbol_list: Union[str, List[str]], d
10121012
# ----------------------------------------------------------------------
10131013
def get_trading_calendar(self, start_dt: Union[date, datetime], end_dt: Union[date, datetime]) -> pd.DataFrame:
10141014
"""
1015-
获取一段时间内的交易日历信息,交易日历可以处理的范围为 2003-01-01 ~ 2024-12-31。
1015+
获取一段时间内的交易日历信息,每年的交易日历将在交易所新一年的节假日安排后更新
10161016
10171017
Args:
10181018
start_dt (date/datetime): 起始时间
@@ -1068,7 +1068,7 @@ def get_trading_calendar(self, start_dt: Union[date, datetime], end_dt: Union[da
10681068
# ----------------------------------------------------------------------
10691069
def query_his_cont_quotes(self, symbol: Union[str, List[str]], n: int = 200) -> pd.DataFrame:
10701070
"""
1071-
获取指定的主连合约最近 n 天的标的,可以处理的范围为 2003-01-01 ~ 2022-12-31
1071+
获取指定的主连合约最近 n 天的标的。
10721072
10731073
Args:
10741074
symbol (str/list of str): 指定主连合约代码或主连合约代码列表.
@@ -1126,9 +1126,7 @@ def query_his_cont_quotes(self, symbol: Union[str, List[str]], n: int = 200) ->
11261126
# ----------------------------------------------------------------------
11271127
def add_risk_rule(self, rule: TqRiskRule) -> None:
11281128
"""
1129-
添加一项风控规则实例,此接口为 TqSdk 专业版提供。
1130-
1131-
如需使用此功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk-buy/>`_ 申请试用或购买
1129+
添加一项风控规则实例。
11321130
11331131
Args:
11341132
rule (TqRiskRule): 风控规则实例,必须是 TqRiskRule 的子类型
@@ -1142,9 +1140,7 @@ def add_risk_rule(self, rule: TqRiskRule) -> None:
11421140

11431141
def delete_risk_rule(self, rule: TqRiskRule) -> None:
11441142
"""
1145-
删除一项风控规则实例,此接口为 TqSdk 专业版提供。
1146-
1147-
如需使用此功能,可以点击 `天勤量化专业版 <https://www.shinnytech.com/tqsdk-buy/>`_ 申请试用或购买
1143+
删除一项风控规则实例。
11481144
11491145
Args:
11501146
rule (TqRiskRule): 风控规则实例,必须是 TqRiskRule 的子类型
@@ -1884,7 +1880,7 @@ def wait_update(self, deadline: Optional[float] = None, _task: Union[asyncio.Tas
18841880
* 如果没有收到数据包,则挂起等待.
18851881
18861882
Args:
1887-
deadline (float): [可选]指定截止时间,自unix epoch(1970-01-01 00:00:00 GMT)以来的秒数(time.time())。默认没有超时(无限等待)
1883+
deadline (float): [可选]指定截止时间,自unix epoch(1970-01-01 00:00:00 GMT)以来的秒数(time.time())。默认没有超时(无限等待), 当 wait_update 有数据更新或者任务执行时会返回为 True,否则会陷入阻塞,使用 deadline 参数会让 wait_update 函数在当前时间大于 deadline 参数后返回 False ,避免长时间阻塞。非简单用法,如果设置的 deadline 过小,而计算任务过多,可能会导致处理任务堆积,引发潜在问题。
18881884
18891885
Returns:
18901886
bool: 如果收到业务数据更新则返回 True, 如果到截止时间依然没有收到业务数据更新则返回 False
@@ -3348,10 +3344,13 @@ def _setup_connection(self):
33483344
if quote["ins_class"] == "FUTURE_OPTION":
33493345
quote["exercise_year"] = _timestamp_nano_to_datetime(int(quote["expire_datetime"] * 1000000) * 1000).year
33503346
quote["exercise_month"] = _timestamp_nano_to_datetime(int(quote["expire_datetime"] * 1000000) * 1000).month
3351-
ws_md_recv_chan.send_nowait({
3352-
"aid": "rtn_data",
3353-
"data": [{"quotes": quotes}]
3354-
}) # 获取合约信息
3347+
if self._stock is False:
3348+
ws_md_recv_chan.send_nowait({
3349+
"aid": "rtn_data",
3350+
"data": [{"quotes": quotes}]
3351+
}) # 获取合约信息
3352+
else:
3353+
self._pre20_ins_info = quotes
33553354

33563355
self._ws_md_recv_chan = ws_md_recv_chan # 记录 ws_md_recv_chan 引用
33573356

tqsdk/backtest/backtest.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ async def _run(self, api, sim_send_chan, sim_recv_chan, md_send_chan, md_recv_ch
160160
self._diffs.append({
161161
"ins_list": pack["ins_list"]
162162
})
163+
await self._ensure_symbols(pack["ins_list"].split(","))
163164
for ins in pack["ins_list"].split(","):
164165
await self._ensure_quote(ins)
165166
await self._send_diff() # 处理上一次未处理的 peek_message
@@ -451,16 +452,21 @@ async def _ensure_query(self, pack):
451452
while not query_pack.items() <= self._data.get("symbols", {}).get(pack["query_id"], {}).items():
452453
await update_chan.recv()
453454

454-
async def _ensure_quote(self, symbol):
455+
async def _ensure_symbols(self, symbols):
455456
# 在接新版合约服务器后,合约信息程序运行过程中查询得到的,这里不再能保证合约一定存在,需要添加 quote 默认值
456-
quote = _get_obj(self._data, ["quotes", symbol], BtQuote(self._api))
457-
if math.isnan(quote.get("price_tick")):
458-
query_pack = _query_for_quote(symbol)
457+
quotes = [_get_obj(self._data, ["quotes", symbol], BtQuote(self._api)) for symbol in symbols]
458+
quotes = [q for q in quotes if math.isnan(q.get("price_tick"))]
459+
if not quotes:
460+
return
461+
for query_pack in _query_for_quote([q._path[-1] for q in quotes], self._api._pre20_ins_info.keys()):
459462
await self._md_send_chan.send(query_pack)
460-
async with TqChan(self._api, last_only=True) as update_chan:
461-
quote["_listener"].add(update_chan)
462-
while math.isnan(quote.get("price_tick")):
463-
await update_chan.recv()
463+
async with TqChan(self._api, last_only=True) as update_chan:
464+
for q in quotes:
465+
q["_listener"].add(update_chan)
466+
while any([math.isnan(q.get("price_tick")) for q in quotes]):
467+
await update_chan.recv()
468+
469+
async def _ensure_quote(self, symbol):
464470
if symbol not in self._quotes or self._quotes[symbol]["min_duration"] > 60000000000:
465471
await self._ensure_serial(symbol, 60000000000)
466472

tqsdk/objs.py

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,10 @@
44

55
import copy
66
import json
7-
import warnings
87
from typing import List
98

109
from tqsdk.diff import _get_obj
1110
from tqsdk.entity import Entity
12-
from tqsdk.utils import _query_for_init, _generate_uuid
13-
14-
15-
class QuotesEntity(Entity):
16-
17-
def __init__(self, api):
18-
self._api = api
19-
self._not_send_init_query = True
20-
21-
def __iter__(self):
22-
message = """
23-
不推荐使用 api._data['quotes'] 获取全部合约,该使用方法会在 20201101 之后的版本中放弃维护。
24-
需要注意:
25-
* 在同步代码中,初次使用 api._data['quotes'] 获取全部合约会产生一个耗时很长的查询。
26-
* 在协程中,api._data['quotes'] 这种用法不支持使用。
27-
请尽快修改使用新的接口,参考链接 http://doc.shinnytech.com/tqsdk/reference/tqsdk.api.html#tqsdk.api.TqApi.query_quotes
28-
"""
29-
warnings.warn(message, DeprecationWarning, stacklevel=3)
30-
self._api._logger.warning("deprecation", content="Deprecation Warning in api._data['quotes']")
31-
32-
# 兼容旧版 tqsdk 所做的修改,来支持用户使用 for k,v in api._data.quotes.items() 类似的用法
33-
# 从 api._init_() 最后 3 行移到这里
34-
if self._not_send_init_query and self._api._stock:
35-
self._not_send_init_query = False
36-
q = _query_for_init()
37-
self._api.query_graphql(q, {}, _generate_uuid("PYSDK_quote"))
38-
return super().__iter__()
3911

4012

4113
class Quote(Entity):
@@ -143,7 +115,7 @@ def __init__(self, api):
143115
self.strike_price: float = float("nan")
144116
#: 合约类型
145117
self.ins_class: str = ""
146-
#: 交易所内的合约代码
118+
#: 合约代码,包含了交易所代码
147119
self.instrument_id: str = ""
148120
#: 合约中文名
149121
self.instrument_name: str = ""

tqsdk/objs_not_entity.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from tqsdk.ins_schema import ins_schema, _add_all_frags
1616
from tqsdk.objs import Quote
1717
from tqsdk.diff import _get_obj
18-
from tqsdk.utils import _query_for_quote, _generate_uuid
18+
from tqsdk.utils import _generate_uuid
1919
from tqsdk.tafunc import _get_t_series, get_impv, _get_d1, get_delta, get_theta, get_gamma, get_vega, get_rho
2020

2121
"""
@@ -54,22 +54,8 @@ def __init__(self, api, quotes):
5454
if not hasattr(quote, '_task'):
5555
quote._task = api.create_task(ensure_quote_with_underlying(api, quote), _caller_api=True)
5656

57-
async def _ensure_symbols(self):
58-
if all([q.price_tick > 0 for q in self]):
59-
return
60-
query_symbols = [q._path[-1] for q in self if not q.price_tick > 0]
61-
query_pack = _query_for_quote(query_symbols)
62-
self._api._send_pack(query_pack)
63-
async with self._api.register_update_notify(self) as update_chan:
64-
async for _ in update_chan:
65-
# 这里用 price_tick 判断是否已经收到了合约信息,是为了兼容 2020年9月份之前上市的合约
66-
# 合约服务没有提供这些合约,tqsdk 是通过预先加载本地缓存文件的方式提供这些合约的信息
67-
# 理想的判断标准是 basktest 模块中的 _ensure_query 函数
68-
if all([q.price_tick > 0 for q in self]):
69-
return
70-
7157
async def _ensure_quotes(self):
72-
await self._ensure_symbols()
58+
await self._api._ensure_symbol_async([q._path[-1] for q in self])
7359
self._api._auth._has_md_grants([q._path[-1] for q in self]) # 权限检查
7460
# 发送的请求会请求到所有字段,如果是期权也会请求标的的合约信息
7561
underlying_symbols = set([q.underlying_symbol for q in self if q.underlying_symbol])

0 commit comments

Comments
 (0)