diff --git a/PKG-INFO b/PKG-INFO
index b631f32b..b503cd22 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: tqsdk
-Version: 3.8.7
+Version: 3.8.8
Summary: TianQin SDK
Home-page: https://www.shinnytech.com/tqsdk
Author: TianQin
@@ -10,7 +10,7 @@ Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
-Requires-Python: >=3.7
+Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
@@ -20,7 +20,7 @@ License-File: LICENSE
-
+
@@ -87,7 +87,7 @@ TqSdk提供的功能可以支持从简单到复杂的各类策略程序:
## 安装方法
-TqSdk 仅支持 Python 3.7 及更高版本。要安装 TqSdk,可使用 pip:
+TqSdk 仅支持 Python 3.8 及更高版本。要安装 TqSdk,可使用 pip:
```bash
pip install tqsdk
diff --git a/README.md b/README.md
index 25a83262..bb607ef4 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
-
+
@@ -71,7 +71,7 @@ TqSdk提供的功能可以支持从简单到复杂的各类策略程序:
## 安装方法
-TqSdk 仅支持 Python 3.7 及更高版本。要安装 TqSdk,可使用 pip:
+TqSdk 仅支持 Python 3.8 及更高版本。要安装 TqSdk,可使用 pip:
```bash
pip install tqsdk
diff --git a/doc/advanced/emergency_stop.rst b/doc/advanced/emergency_stop.rst
new file mode 100644
index 00000000..f547007c
--- /dev/null
+++ b/doc/advanced/emergency_stop.rst
@@ -0,0 +1,53 @@
+.. _emergency_stop:
+
+在外出环境下的紧急停止方案
+=================================================
+
+在实际交易中, 难免会遇到人在外面、无法第一时间回到电脑前, 但又需要 **立刻阻止策略继续报单** 的情况。
+对于这类极端场景, 可以准备一套 **从物理链路上阻断报单** 的“最后一道防线”——使用远程遥控插座控制电脑或网络设备的供电。
+
+.. note::
+
+ 如果可以正常远程登录到运行环境, 仍然 **优先通过程序自身的退出/风控逻辑** 来停止策略;
+ 本文介绍的方案只用于“网络中断、远程工具失效、程序卡死/死循环”等, 无法正常操作时的 **兜底紧急手段** 。
+
+
+适用场景
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+下面这些场景都可以考虑使用远程遥控插座作为补充手段:
+
+* 人不在机房/办公室, 无法直接操作运行策略的电脑
+* 远程桌面/VPN 无法连接, 不能登录服务器手动停止程序
+* 运行环境网络异常, 与远程服务器或交易终端的会话建立/恢复失败
+* 程序出现死循环、界面无响应, 无法通过常规方式优雅退出
+* 需要在数秒~数十秒内阻止程序继续发出新的报单
+
+
+推荐做法: 使用远程遥控插座
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+市面上有很多可以通过手机 App 控制的 **远程遥控插座/智能插座** , 一般具备以下能力:
+
+* 支持 4G/5G 或通过家庭/公司网络连接互联网
+* 在手机上安装 App 后, 可以远程开/关插座电源
+* 一键断电, 立刻切断下游设备的供电或网络
+
+对于无人监控环境下运行的策略, 可以从物理链路上做如下配置:
+
+* 将 **运行策略的电脑/服务器电源** 接在远程遥控插座上, 需要紧急停机时, 在手机 App 中关断插座电源, 电脑随之断电, 程序立即停止, 不会再继续报单
+* 或者, 将 **用于联网的路由器/交换机等网络设备电源** 接在远程遥控插座上, 紧急情况下关闭插座, 网络被切断, 程序虽然暂时仍在运行, 但已无法向交易服务器发送新的报单
+
+
+重要提示
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. warning::
+
+ 通过远程遥控插座断电, 对电脑来说相当于“强制断电”, 可能造成未保存数据丢失,
+ 请只在 **确属紧急情况** 时使用。
+
+ 该方案的主要目的在于 **尽快阻止程序继续发送报单** , 而不是优雅关闭系统;
+ 日常风险控制仍应依赖合理的仓位管理、风控规则和监控告警, 远程插座仅作为极端情况下的补充。
+
+
diff --git a/doc/advanced/index.rst b/doc/advanced/index.rst
index 4f2e0a4e..bfd67a7e 100644
--- a/doc/advanced/index.rst
+++ b/doc/advanced/index.rst
@@ -15,5 +15,6 @@
for_vnpy_user.rst
for_ctp_user.rst
unanttended.rst
+ emergency_stop.rst
targetpostask2.rst
scheduler.rst
diff --git a/doc/conf.py b/doc/conf.py
index 15defb47..5326ec2c 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
-version = u'3.8.7'
+version = u'3.8.8'
# The full version, including alpha/beta/rc tags.
-release = u'3.8.7'
+release = u'3.8.8'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/doc/index.rst b/doc/index.rst
index 0ce76957..ea5b735d 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -22,6 +22,7 @@ TianQin Python Sdk User Guide
tq_trading_unit.rst
advanced/index.rst
tqsdk_cursor.rst
+ tqsdk_trae.rst
dev_general.rst
dev_framework.rst
profession.rst
diff --git a/doc/quickstart.rst b/doc/quickstart.rst
index 69633b1b..991ef876 100644
--- a/doc/quickstart.rst
+++ b/doc/quickstart.rst
@@ -24,7 +24,7 @@
-------------------------------------------------
天勤量化的核心是TqSdk开发包, 在安装天勤量化 (TqSdk) 前, 你需要先准备适当的环境和Python包管理工具, 包括:
-* Python >=3.7,3.8,3.9,3.10,3.11,3.12 版本
+* Python >= 3.8 版本
* Windows 7 以上版本, Mac Os, 或 Linux
diff --git a/doc/tq_trading_unit.rst b/doc/tq_trading_unit.rst
index b7a012dc..177eb48e 100644
--- a/doc/tq_trading_unit.rst
+++ b/doc/tq_trading_unit.rst
@@ -113,6 +113,16 @@ TqSdk 多策略使用手册
=========
使用 `pip install -U --upgrade-strategy eager tqsdk-zq` 更新多策略功能所有依赖包
+.. line-block::
+ **2025/12/10**
+ tqsdk-zq: 1.0.3
+ tqsdk-zq-server: 1.0.6
+ tqsdk-zq-history: 1.0.0
+ tqsdk-zq-pgserver: 1.0.0
+ tqsdk-zq-proxy: 1.0.0
+
+* 修复: 撤单失败的问题
+
.. line-block::
**2025/06/16**
tqsdk-zq: 1.0.3
diff --git a/doc/tqsdk_trae.rst b/doc/tqsdk_trae.rst
new file mode 100644
index 00000000..835e6baa
--- /dev/null
+++ b/doc/tqsdk_trae.rst
@@ -0,0 +1,181 @@
+.. _tqsdk_trae:
+
+============================================
+在 Trae 中高效学习和使用 TqSdk
+============================================
+
+
+
+Trae:TqSdk 开发与学习的 AI 助手
+===================================
+
+Trae 简介
+-------------
+
+Trae 是一款 AI 原生的智能开发环境,旨在将大模型的理解、生成与协作能力深度融入日常编码流程。它支持对话式编程(Chat/Agent)、代码补全与多处位点修改、项目级生成(Builder)、实时预览与调试等能力,帮助开发者在同一环境内完成从构思到实现与迭代的闭环。
+
+在 TqSdk 开发中使用 Trae 的好处
+----------------------------------
+
+对于 TqSdk 用户而言,使用 Trae 进行开发与学习具有以下优势:
+
+* **快速理解 TqSdk API 与概念**:
+ * 面向 TqSdk 的类(如 ``TqApi``, ``TqAccount``)、函数或交易概念(如 ``KLine``, ``Backtest``, ``target_pos``)提出问题,获得结构化解释与示例。
+ * 在编辑器内就地查询函数参数、返回值及常见用法。
+* **高效编写与改造策略代码**:
+ * **对话生成**:用自然语言描述策略需求,如“订阅多个合约的 tick 并统计成交量阈值报警”,“基于布林带的简易开平仓框架”。
+ * **智能补全与批量修改**:基于上下文提供更契合的补全,并可对多处代码进行一致性修改与重构建议。
+* **智能辅助调试**:
+ * **错误分析与定位**:粘贴错误堆栈和相关代码,获得原因分析与修复建议。
+* **深入学习与理解源码**:
+ * 将 TqSdk 源码加入工作区后,可让 AI 针对具体模块/函数解释实现思路和设计取舍。
+* **项目级上下文感知**:结合项目代码结构与依赖,回答更贴合当前工程语境。
+
+开始使用 Trae
+================
+
+下载和安装 Trae
+-----------------
+
+1. 访问 Trae 官方下载页面(请根据您组织/渠道提供的地址获取安装包)。
+2. 根据您的操作系统(Windows, macOS, Linux)下载对应安装包。
+3. 按向导完成安装并启动 Trae。
+
+初次启动与界面要点
+-------------------
+
+1. **登录/账户**:根据产品要求完成登录或激活。
+2. **界面区域**:文件资源管理器、编辑器区、终端/调试区与 AI 对话/智能体入口。
+3. **AI 入口**:可通过侧边栏或工具栏打开 Chat/Agent 面板,进行上下文对话与代码指令。
+
+在 Trae 中配置 TqSdk 开发环境
+===============================
+
+创建或打开您的 TqSdk 项目
+----------------------------
+
+1. 在 Trae 中创建新工程或通过“打开文件夹”导入现有的 TqSdk 项目根目录。
+
+配置 Python 解释器
+--------------------
+
+确保 Trae 使用您期望的 Python 解释器/环境来运行 TqSdk 代码。常用做法:
+
+1. 在 Trae 的设置或状态栏中选择目标 Python 解释器(如系统 Python、venv、Conda 环境等)。
+2. 或在 Trae 集成终端中激活虚拟环境(例如 ``venv/Scripts/activate`` 或 ``conda activate ``)。
+
+安装 TqSdk 库
+--------------
+
+在 Trae 的集成终端中(确保已选定正确解释器/已激活环境),执行:::
+
+ pip install tqsdk
+
+可用以下命令验证安装: ``python -c "import tqsdk; print(tqsdk.__version__)"`` 。若提示 ``pip`` 未找到,请使用 ``python -m pip install tqsdk`` 或检查环境变量设置。
+
+让 Trae 深度理解 TqSdk:打开源码 (推荐)
+=========================================
+
+将 TqSdk 源码加入工作区,可显著提升 AI 对实现细节与 API 的理解质量。
+
+操作步骤
+---------
+
+1. **获取 TqSdk 源码**:
+ * **方式一(深入研究推荐)**:从官方仓库克隆:::
+
+ git clone https://github.com/shinnytech/tqsdk-python.git
+
+ 记下其中的 ``tqsdk`` 源码目录。
+ * **方式二(快速查阅已安装版本)**:定位到当前 Python 环境的 ``site-packages`` 目录中的 ``tqsdk`` 包路径(如 Windows 的 ``.../Lib/site-packages/tqsdk``)。
+2. **添加到 Trae 工作区**:
+ * 在已打开的项目中,将上述 ``tqsdk`` 源码文件夹添加到工作区(使用“添加文件夹到工作区”或等效入口)。
+3. **效果**:
+ * 之后可直接在工作区浏览 TqSdk 源码,AI 对应答与代码生成将更贴近真实实现。
+
+在 Trae 中提问和学习 TqSdk
+=============================
+
+如何提问?
+-----------
+
+打开 Trae 的 AI Chat/Agent 面板后,您可以:
+
+* **直接提问**:输入关于 TqSdk 的问题。
+* **选中代码后提问**:选中一段 TqSdk 代码并发起对话,让 AI 以上下文模式进行解释、优化或缺陷分析。
+
+提问示例
+---------
+
+**基础概念与用法:**
+
+* “TqSdk 中 ``TqApi`` 与 ``TqAccount`` 的关系与区别是什么?”
+* “如何获取 ``SHFE.rb2410`` 的 1 分钟 K 线?请给完整示例。”
+* “回测 ``TqBacktest`` 的 ``start_dt`` 和 ``end_dt`` 该如何设置?”
+* “``insert_order`` 的 ``limit_price`` 与 ``offset`` 参数如何使用?”
+
+**结合源码提问(已将源码加入工作区):**
+
+* “``@tqsdk/trade.py`` 中 ``TdApi`` 的 ``_on_rsp_order_insert`` 做了什么?”
+* “我在看 ``@tqsdk/tools/downloader.py``,该下载器支持哪些数据类型?”
+
+**错误排查:**
+
+* “运行以下代码时报错 ``...``(附完整堆栈),可能原因是什么?如何修复?”
+
+利用 AI 进行 TqSdk 代码生成与修改
+---------------------------------
+
+* **生成代码片段**:
+ * “写个函数,输入合约列表,批量订阅这些合约的盘口行情 ``quote``。”
+ * “用 ``TqSim`` 做模拟交易,当资金变化超过 5% 时发送通知的框架。”
+* **修改现有代码(选中后发起)**:
+ * “将这段 TqSdk 代码的 ``datetime`` 格式化为 ``YYYY-MM-DD HH:MM:SS``。”
+ * “为下单逻辑增加条件:只有当最新价大于过去 20 周期均线时才开多。”
+ * “重构策略:将行情处理与交易决策拆成独立函数。”
+
+调试 TqSdk 代码
+----------------
+
+Trae 提供集成调试能力(具体入口与配置以实际版本为准)。
+
+1. **设置断点**:在行号旁点击设置断点。
+2. **启动调试**:在运行/调试面板选择相应 Python 配置(如“Python File”或配置的调试任务)。
+3. **AI 辅助调试**:调试中若遇到异常或变量状态不明,可将相关片段与变量值粘贴到对话中,请求解释或给出下一步排查建议。
+
+高效提问的技巧
+===============
+
+为获得准确与可操作的回答,建议:
+
+* **问题明确具体**:避免过于笼统。
+* **提供上下文**:
+ * 涉及代码时,附上相关片段。
+ * 发生错误时,附完整堆栈与复现步骤。
+ * 若已加入 TqSdk 源码,指明相关模块或符号位置(例如 ``@tqsdk/...`` 风格的文件/符号提示)。
+* **逐步拆解**:复杂问题分步提问。
+* **说明版本**:如 Python 版本、TqSdk 版本、依赖(pandas/NumPy 等)版本。
+* **共享尝试**:说明已尝试方案与结果,便于更精准的建议。
+* **迭代追问**:基于首次回答继续澄清与收敛。
+
+
+使用建议
+--------
+
+1. 在 AI 对话中说明您的需求与版本信息(如 Python 3.11、pandas 2.2、NumPy 2.x)。
+2. 在合适的平台(若支持)启用 Context7 后,配合工作区源码一起提问,获得“规范 + 实现”的双重校对。
+3. 在问题末尾添加“use context7”的提示仅在支持的平台/配置生效;在不支持的平台不会生效。
+
+常见问题(FAQ)
+---------------
+
+* “环境已选但运行用错解释器?”——在设置与集成终端中同时确认:状态栏解释器与终端激活环境需一致。
+* “AI 回答不贴合代码?”——将 TqSdk 源码加入工作区;提问时引用具体模块或函数;粘贴最小可复现片段。
+* “网络/镜像问题导致安装失败?”——优先使用内网镜像或 ``python -m pip`` 方式;必要时手动下载离线包安装。
+
+总结
+=====
+
+Trae 将 AI 深度融入开发流程,对 TqSdk 用户而言,既能加速理解与编写策略,也能在调试与源码学习上提供持续助力。我们建议您将 TqSdk 源码加入工作区,并充分利用对话生成、智能补全与调试能力,配合明确的问题与上下文描述,以获得更高质量、更高效率的开发体验。
+
+
diff --git a/doc/usage/kqd_symbol.rst b/doc/usage/kqd_symbol.rst
index 0251fa3a..6b886bf9 100644
--- a/doc/usage/kqd_symbol.rst
+++ b/doc/usage/kqd_symbol.rst
@@ -4,9 +4,9 @@
==================================================
板块介绍
--------------------------------------------------
-为了满足投资者对全球市场信息的需求,提供更全面、准确的投资决策支持,快期/天勤专业版上线了外盘行情(延时15分钟)
+为了满足投资者对全球市场信息的需求,提供更全面、准确的投资决策支持,快期专业版 / 天勤量化 上线了外盘行情(延时15分钟)
-在快期专业版总添加方式:【添加板块】 - 【系统报价表】 - 【外盘行情(延时)】
+在快期专业版中的添加方式:【添加板块】 - 【系统报价表】 - 【外盘行情(延时)】
.. figure:: /images/foreign01.png
diff --git a/doc/version.rst b/doc/version.rst
index 60dd6f13..ae7cec40 100644
--- a/doc/version.rst
+++ b/doc/version.rst
@@ -2,6 +2,17 @@
版本变更
=============================
+3.8.8 (2025/12/11)
+
+* 修复: :py:meth:`~tqsdk.TqApi.ischanging` 接口无法正确判断 tick 中的字段更新
+* 优化: :py:meth:`~tqsdk.TqApi.query_symbol_settlement` 和 :py:meth:`~tqsdk.TqApi.query_symbol_settlement` 接口复用 tcp 连接
+* 优化: 版本变更信息的通知时机
+* docs: 多策略依赖包升级
+* docs: 修改外盘行情描述
+* docs: 提供 trae IDE 配置方式
+* 自该版本起仅支持 Python >=3.8
+
+
3.8.7 (2025/10/27)
* 修复: 多进程回测触发的超时报错
diff --git a/setup.py b/setup.py
index 6586bcf6..9b5b58c7 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
setuptools.setup(
name='tqsdk',
- version="3.8.7",
+ version="3.8.8",
description='TianQin SDK',
author='TianQin',
author_email='tianqincn@gmail.com',
@@ -16,7 +16,7 @@
long_description_content_type="text/markdown",
url='https://www.shinnytech.com/tqsdk',
packages=setuptools.find_packages(exclude=["tqsdk.test", "tqsdk.test.*"]),
- python_requires='>=3.7',
+ python_requires='>=3.8',
install_requires=["websockets>=10.1", "requests", "numpy", "pandas>=1.1.0", "scipy", "simplejson", "aiohttp",
"certifi", "pyjwt", "psutil>=5.9.6", "shinny_structlog", "sgqlc", "filelock", "tqsdk_ctpse", "tqsdk_sm",
"packaging"],
diff --git a/tqsdk/__version__.py b/tqsdk/__version__.py
index bd03e733..eb4c7bae 100644
--- a/tqsdk/__version__.py
+++ b/tqsdk/__version__.py
@@ -1 +1 @@
-__version__ = '3.8.7'
+__version__ = '3.8.8'
diff --git a/tqsdk/api.py b/tqsdk/api.py
index f8ae64a1..1c4b1829 100644
--- a/tqsdk/api.py
+++ b/tqsdk/api.py
@@ -14,6 +14,7 @@
"""
__author__ = 'chengzhi'
+import aiohttp
import asyncio
import copy
import logging
@@ -201,6 +202,8 @@ def __init__(self, account: Optional[Union[TqMultiAccount, UnionTradeable]] = No
api = TqApi(TqKq(), auth=TqAuth("快期账户", "账户密码")) # 根据填写的快期账户参数连接指定的快期模拟账户
"""
+ # 保证在初始化 TqApi 时打印版本变更与广播信息,并且一个进程内只会打印一次
+ from tqsdk import changelog_notification
# 初始化 logger
self._logger = logging.getLogger("TqApi")
@@ -265,6 +268,7 @@ def __init__(self, account: Optional[Union[TqMultiAccount, UnionTradeable]] = No
self._send_chan, self._recv_chan = TqChan(self), TqChan(self) # 消息收发队列
self._ws_md_recv_chan = None # 记录 ws_md_recv_chan 引用
self._pre20_ins_info = {} # 20年9月份之前的合约信息
+ self._http_session_internal = None # 记录 http 会话
# slave模式的api不需要完整初始化流程
self._is_slave = isinstance(account, TqApi)
@@ -312,6 +316,12 @@ def _print(self, msg: str = "", level: str = "INFO"):
def _base_headers(self):
return self._auth._base_headers
+ @property
+ def _http_session(self):
+ if self._http_session_internal is None or self._http_session_internal.closed:
+ self._http_session_internal = aiohttp.ClientSession(headers=self._base_headers)
+ return self._http_session_internal
+
# ----------------------------------------------------------------------
def copy(self) -> 'TqApi':
"""
@@ -354,7 +364,10 @@ def close(self) -> None:
# 总会发送 serial_extra_array 数据,由 TqWebHelper 处理
for _, serial in self._serials.items():
self._process_serial_extra_array(serial)
- super(TqApi, self)._close()
+ super(TqApi, self)._close_tasks()
+ if self._http_session_internal:
+ self._loop.run_until_complete(self._http_session_internal.close())
+ super(TqApi, self)._close_loop()
mem = psutil.virtual_memory()
self._logger.debug("process end", mem_total=mem.total, mem_free=mem.free)
finally:
@@ -2090,6 +2103,8 @@ def _is_obj_changing(self, obj: Any, diffs: List[Dict[str, Any]], key: List[str]
elif int(m.group(2)) < len(paths):
m_k = int(m.group(2))
k_dict.setdefault(m_k, []).append(m.group(1))
+ else: # 数字 >= len(paths),说明是字段本身的数字(如 tick 盘口字段)
+ k_dict.setdefault(0, []).append(k) # 保留完整字段名
for k_id, v in k_dict.items():
if _is_key_exist(diff, paths[k_id], v):
return True
@@ -4120,18 +4135,5 @@ def _get_current_datetime(self):
print("在使用天勤量化之前,默认您已经知晓并同意以下免责条款,如果不同意请立即停止使用:https://www.shinnytech.com/blog/disclaimer/", file=sys.stderr)
-if platform.python_version().startswith('3.7.'):
- warnings.warn("TqSdk 计划在 20250601 之后放弃支持 Python 3.7 版本,请尽快升级 Python 版本。", FutureWarning, stacklevel=1)
-
-
-try:
- res = requests.get("https://shinny-tqsdk.oss-cn-shanghai.aliyuncs.com/tqsdk_metadata.json", timeout=10)
- tq_metadata = res.json()
- current_version = version.parse(__version__)
- change_version = version.parse(tq_metadata.get('tqsdk_version', '0.0.0'))
- if tq_metadata.get('tqsdk_changelog') and current_version < change_version:
- print(tq_metadata['tqsdk_changelog'], file=sys.stderr)
- if tq_metadata.get('tqsdk_notify'):
- print(tq_metadata['tqsdk_notify'], file=sys.stderr)
-except:
- pass
+if platform.python_version().startswith('3.8.'):
+ warnings.warn("TqSdk 计划在 20260601 之后放弃支持 Python 3.8 版本,请尽快升级 Python 版本。", FutureWarning, stacklevel=1)
\ No newline at end of file
diff --git a/tqsdk/baseApi.py b/tqsdk/baseApi.py
index e51f46d4..7e50109a 100644
--- a/tqsdk/baseApi.py
+++ b/tqsdk/baseApi.py
@@ -37,8 +37,7 @@ def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None) -> None:
def _create_task(self, coro: Coroutine, _caller_api: bool = False) -> asyncio.Task:
task = self._loop.create_task(coro)
- py_ver = sys.version_info
- current_task = asyncio.Task.current_task(loop=self._loop) if (py_ver.major == 3 and py_ver.minor < 7) else asyncio.current_task(loop=self._loop)
+ current_task = asyncio.current_task(loop=self._loop)
if current_task is None or _caller_api: # 由 api 创建的 task,需要 api 主动管理
self._tasks.add(task)
task.add_done_callback(self._on_task_done)
@@ -145,11 +144,13 @@ async def _windows_patch(self):
while True:
await asyncio.sleep(1)
- def _close(self) -> None:
+ def _close_tasks(self) -> None:
self._run_until_idle(async_run=False) # 由于有的处于 ready 状态 task 可能需要报撤单, 因此一直运行到没有 ready 状态的 task
for task in self._tasks:
task.cancel()
while self._tasks: # 等待 task 执行完成
self._run_once()
+
+ def _close_loop(self) -> None:
self._loop.run_until_complete(self._loop.shutdown_asyncgens())
self._loop.close()
diff --git a/tqsdk/changelog_notification.py b/tqsdk/changelog_notification.py
new file mode 100644
index 00000000..5178bb7a
--- /dev/null
+++ b/tqsdk/changelog_notification.py
@@ -0,0 +1,22 @@
+# !usr/bin/env python3
+# -*- coding:utf-8 -*-
+__author__ = 'chenli'
+
+import sys
+from packaging import version
+
+import requests
+
+from tqsdk.__version__ import __version__
+
+try:
+ res = requests.get("https://shinny-tqsdk.oss-cn-shanghai.aliyuncs.com/tqsdk_metadata.json", timeout=10)
+ tq_metadata = res.json()
+ current_version = version.parse(__version__)
+ change_version = version.parse(tq_metadata.get('tqsdk_version', '0.0.0'))
+ if tq_metadata.get('tqsdk_changelog') and current_version < change_version:
+ print(tq_metadata['tqsdk_changelog'], file=sys.stderr)
+ if tq_metadata.get('tqsdk_notify'):
+ print(tq_metadata['tqsdk_notify'], file=sys.stderr)
+except:
+ pass
diff --git a/tqsdk/objs_not_entity.py b/tqsdk/objs_not_entity.py
index 07a7d3a3..0de994e7 100644
--- a/tqsdk/objs_not_entity.py
+++ b/tqsdk/objs_not_entity.py
@@ -321,9 +321,9 @@ def __init__(self, api, symbol, days, start_dt):
async def _get_settlement_data(self, settlement_id):
# 下载结算价数据,并将数据发回到 api.recv_chan
- async with aiohttp.ClientSession(headers=self.__dict__["_api"]._base_headers) as session:
- url = "https://md-settlement-system-fc-api.shinnytech.com/mss"
- async with session.get(url, params=self.__dict__["_params"]) as response:
+ session = self.__dict__["_api"]._http_session
+ url = "https://md-settlement-system-fc-api.shinnytech.com/mss"
+ async with session.get(url, params=self.__dict__["_params"]) as response:
response.raise_for_status()
content = await response.json()
await self.__dict__["_api"]._ws_md_recv_chan.send({
@@ -422,9 +422,9 @@ def __init__(self, api, symbol, ranking_type, days, start_dt, broker):
async def _get_ranking_data(self, ranking_id):
# 下载持仓排名数据,并将数据发回到 api.recv_chan
- async with aiohttp.ClientSession(headers=self.__dict__["_api"]._base_headers) as session:
- url = "https://symbol-ranking-system-fc-api.shinnytech.com/srs"
- async with session.get(url, params=self.__dict__["_params"]) as response:
+ session = self.__dict__["_api"]._http_session
+ url = "https://symbol-ranking-system-fc-api.shinnytech.com/srs"
+ async with session.get(url, params=self.__dict__["_params"]) as response:
response.raise_for_status()
content = await response.json()
await self.__dict__["_api"]._ws_md_recv_chan.send({