Skip to content

Commit

Permalink
Update Version 3.6.1
Browse files Browse the repository at this point in the history
  • Loading branch information
shinny-pack authored and shinny-mayanqiong committed Aug 16, 2024
1 parent 53f7aaf commit 5cc39d4
Show file tree
Hide file tree
Showing 27 changed files with 9,621 additions and 32 deletions.
2 changes: 1 addition & 1 deletion PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: tqsdk
Version: 3.6.0
Version: 3.6.1
Summary: TianQin SDK
Home-page: https://www.shinnytech.com/tqsdk
Author: TianQin
Expand Down
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
version = u'3.6.0'
version = u'3.6.1'
# The full version, including alpha/beta/rc tags.
release = u'3.6.0'
release = u'3.6.1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
4 changes: 2 additions & 2 deletions doc/demo/jupyter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Jupyter 示例

.. toctree::
:maxdepth: 2
:caption: Contents:
:caption: 目录:

notebooks/demo

notebooks/factor
9,376 changes: 9,376 additions & 0 deletions doc/demo/notebooks/factor.ipynb

Large diffs are not rendered by default.

Binary file added doc/images/llm_pic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/llm_pic2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/llm_pic3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/llm_pic4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/llm_pic5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/llm_pic6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/llm_pic7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ TianQin Python Sdk User Guide
dev/index.rst
profession.rst
enterprise.rst
tqsdk_llm.rst
qa.rst
version.rst

37 changes: 37 additions & 0 deletions doc/tqsdk_llm.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.. _tqsdk_llm:

天勤量化机器人助手
-----------------------------------------------
在使用天勤的过程中,用户往往会遇到各种问题,尤其是初学者,他们可能会关心以下几点:

* 天勤量化可以实现哪些功能?
* 如何编写实现这些功能的大致代码?
* 文档中某些函数的具体参数是什么意思?

当度过初学者的阶段后,用户可能会遇到以下情况:

* 如何解决天勤或 Python 报错?
* 如何优化策略代码逻辑?
* 某个特定功能在天勤中如何实现?

这些问题都会成为用户使用天勤量化时的障碍。

为了帮助用户解决这些问题,我们结合了国内先进的大语言模型,推出了专门的智能机器人助手,旨在解答以下问题:

* 具体函数的详细介绍
* 根据具体需求或策略提供天勤实现的示例
* 天勤或 Python 报错的可能解决方案

点击即刻尝试 `使用智能机器人! <https://udify.app/chat/im02prcHNEOVbPAx/>`_

下图是具体的使用示例 demo

.. figure:: images/llm_pic1.png
.. figure:: images/llm_pic2.png
.. figure:: images/llm_pic3.png
.. figure:: images/llm_pic4.png
.. figure:: images/llm_pic5.png
.. figure:: images/llm_pic6.png
.. figure:: images/llm_pic7.png


19 changes: 18 additions & 1 deletion doc/usage/jupyter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

在 Jupyter Notebook 中使用 TqSdk
====================================================
本文档将介绍如何在 Jupyter Notebook 中使用 TqSdk。

本文档将介绍如何在 Jupyter Notebook 中使用 TqSdk。与普通代码类似,直接导入 TqSdk 并使用即可。
当您的主要是希望使用 TqSdk 来进行行情分析和研究,并不涉及到交易时使用 Jupyter Notebook 可以带来一些潜在优势

1. 交互式编程
Jupyter Notebook 提供了一个交互式的环境,可以逐步执行代码块并立即查看输出结果。这种特性特别适合数据分析和探索性编程,使得用户可以实时查看数据处理和可视化的效果。

2. 内嵌可视化
Jupyter Notebook 支持在单元格中嵌入图表和图像,使得数据可视化变得非常方便。用户可以在一个文档中同时编写代码、生成图表和撰写分析报告,无需切换到其他工具或窗口。

安装 Jupyter Notebook
----------------------------------------------------
Expand Down Expand Up @@ -33,3 +40,13 @@ pip install jupyter

请参考 :ref:`示例 <demo_jupyter>` 。


注意事项
----------------------------------------------------

* **不建议用户在 jupyter 里使用 tqsdk 的交易功能,因为 TqSdk 行情只有在调用 wait_update() 之后才会更新,但是在 jupyter 交互运行的环境中,无法及时调用 wait_update(),可能会导致行情延时**

* **不能在 jupyter 中异步的使用 tqsdk,jupyter 只能用 TqSdk 的同步代码的写法**

* **在 jupyter 中使用 wait_update() 时,建议增加 deadline 参数在函数里,避免长时间的阻塞**

6 changes: 6 additions & 0 deletions doc/version.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

版本变更
=============================
3.6.1 (2024/08/16)

* 优化:仅在发送过订阅请求后,才会发送退订请求
* docs:添加天勤量化智能机器人介绍文档,详情参考 :ref:`tqsdk_llm`


3.6.0 (2024/06/21)

* 增加:支持在 Jupyter 中使用 Tqsdk,详情参考 :ref:`jupyter`
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setuptools.setup(
name='tqsdk',
version="3.6.0",
version="3.6.1",
description='TianQin SDK',
author='TianQin',
author_email='[email protected]',
Expand All @@ -18,7 +18,7 @@
packages=setuptools.find_packages(exclude=["tqsdk.test", "tqsdk.test.*"]),
python_requires='>=3.6.4',
install_requires=["websockets>=8.1", "requests", "numpy", "pandas>=1.1.0", "scipy", "simplejson", "aiohttp",
"certifi", "pyjwt", "psutil", "shinny_structlog", "sgqlc", "filelock", "tqsdk_ctpse", "tqsdk_sm"],
"certifi", "pyjwt", "psutil", "shinny_structlog", "sgqlc", "filelock", "tqsdk_ctpse", "tqsdk_sm", "tqsdk_zq_otg==1.0.1"],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
Expand Down
2 changes: 1 addition & 1 deletion tqsdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name = "tqsdk"

from tqsdk.api import TqApi
from tqsdk.tradeable import TqAccount, TqZq, TqKq, TqKqStock, TqSim, TqSimStock
from tqsdk.tradeable import TqAccount, TqZq, TqKq, TqKqStock, TqSim, TqSimStock, TqCtp
from tqsdk.auth import TqAuth
from tqsdk.channel import TqChan
from tqsdk.backtest import TqBacktest, TqReplay
Expand Down
2 changes: 1 addition & 1 deletion tqsdk/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.6.0'
__version__ = '3.6.1'
10 changes: 6 additions & 4 deletions tqsdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
from tqsdk.risk_rule import TqRiskRule
from tqsdk.ins_schema import ins_schema, basic, derivative, future, option
from tqsdk.symbols import TqSymbols
from tqsdk.tradeable import TqAccount, TqZq, TqKq, TqKqStock, TqSim, TqSimStock, BaseSim, BaseOtg
from tqsdk.tradeable import TqAccount, TqZq, TqKq, TqKqStock, TqSim, TqSimStock, BaseSim, BaseOtg, TqCtp
from tqsdk.trading_status import TqTradingStatus
from tqsdk.tqwebhelper import TqWebHelper
from tqsdk.utils import _generate_uuid, _query_for_quote, BlockManagerUnconsolidated, _quotes_add_night, _bisect_value, \
Expand All @@ -82,7 +82,7 @@
from .__version__ import __version__


UnionTradeable = Union[TqAccount, TqKq, TqZq, TqKqStock, TqSim, TqSimStock]
UnionTradeable = Union[TqAccount, TqKq, TqZq, TqKqStock, TqSim, TqSimStock, TqCtp]


class TqApi(TqBaseApi):
Expand Down Expand Up @@ -117,8 +117,10 @@ def __init__(self, account: Optional[Union[TqMultiAccount, UnionTradeable]] = No
* :py:class:`~tqsdk.TqZq` : 使用众期账号
* :py:class:`~tqsdk.TqMultiAccount` : 多账户列表,列表中支持 :py:class:`~tqsdk.TqAccount`、:py:class:`~tqsdk.TqKq`、\
:py:class:`~tqsdk.TqKqStock`、:py:class:`~tqsdk.TqSim` 和 :py:class:`~tqsdk.TqSimStock` 中的 0 至 N 个或者组合
* :py:class:`~tqsdk.TqCtp` : 使用直连 CTP 账号
* :py:class:`~tqsdk.TqMultiAccount` : 多账户列表,列表中支持 :py:class:`~tqsdk.TqAccount`、:py:class:`~tqsdk.TqKq`、:py:class:`~tqsdk.TqKqStock`、\
:py:class:`~tqsdk.TqSim`、:py:class:`~tqsdk.TqSimStock`、:py:class:`~tqsdk.TqZq` 和 :py:class:`~tqsdk.TqCtp` 中的 0 至 N 个或者组合
auth (TqAuth/str): [必填]用户快期账户:
* :py:class:`~tqsdk.TqAuth` : 添加快期账户类,例如:TqAuth("[email protected]", "123456")
Expand Down
6 changes: 5 additions & 1 deletion tqsdk/connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from tqsdk.exceptions import TqBacktestPermissionError
from tqsdk.utils import _generate_uuid
from tqsdk.sm import SMContext, NullContext
from tqsdk.zq_otg import ZqOtgContext

"""
优化代码结构,修改为
Expand Down Expand Up @@ -127,12 +128,15 @@ async def _run(self, api, url, send_chan, recv_chan):
sm_info = url_info.path.split("/", 4)
cm = SMContext(self._logger, self._api, url_info.scheme, sm_info[1], base64.urlsafe_b64decode(sm_info[2]).decode("utf-8"), base64.urlsafe_b64decode(sm_info[3]).decode("utf-8"))
url_info = url_info._replace(scheme="ws", path="/".join(sm_info[:1]+sm_info[4:]))
elif url_info.scheme.startswith("zqotg"):
url_info = url_info._replace(scheme="ws")
cm = ZqOtgContext()

count = 0
async with cm:
while True:
try:
if isinstance(cm, SMContext):
if isinstance(cm, (SMContext, ZqOtgContext)):
addr = await cm.get_addr()
url = url_info._replace(netloc=addr).geturl()
if not self._first_connect:
Expand Down
6 changes: 3 additions & 3 deletions tqsdk/multiaccount.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from shinny_structlog import ShinnyLoggerAdapter

from tqsdk.channel import TqChan
from tqsdk.tradeable import TqAccount, TqKq, TqKqStock, TqSim, TqSimStock, BaseSim, TqZq
from tqsdk.tradeable import TqAccount, TqKq, TqKqStock, TqSim, TqSimStock, BaseSim, TqZq, TqCtp
from tqsdk.tradeable.mixin import StockMixin


Expand All @@ -27,12 +27,12 @@ class TqMultiAccount(object):
"""

def __init__(self, accounts: Optional[List[Union[TqAccount, TqKq, TqZq, TqKqStock, TqSim, TqSimStock, TqZq]]] = None):
def __init__(self, accounts: Optional[List[Union[TqAccount, TqKq, TqZq, TqKqStock, TqSim, TqSimStock, TqZq, TqCtp]]] = None):
"""
创建 TqMultiAccount 实例
Args:
accounts (List[Union[TqAccount, TqKq, TqKqStock, TqSim, TqSimStock, TqZq]]): [可选] 多账户列表, 若未指定任何账户, 则为 [TqSim()]
accounts (List[Union[TqAccount, TqKq, TqKqStock, TqSim, TqSimStock, TqZq, TqCtp]]): [可选] 多账户列表, 若未指定任何账户, 则为 [TqSim()]
Example1::
Expand Down
24 changes: 12 additions & 12 deletions tqsdk/objs_not_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ async def _query_graphql(self):
if query_result is None:
await _query_graphql_async(self._api, self._query_id, self._query)
query_result = symbols.get(self._query_id)
if isinstance(self._api._backtest, TqBacktest): # 回测时,清空缓存的请求
self._api._send_pack({
"aid": "ins_query",
"query_id": self._query_id,
"query": ""
})
self += self._filter(query_result)
if isinstance(self._api._backtest, TqBacktest): # 回测时,清空缓存的请求
self._api._send_pack({
"aid": "ins_query",
"query_id": self._query_id,
"query": ""
})
return self

def __await__(self):
Expand Down Expand Up @@ -164,16 +164,16 @@ async def _query_graphql(self):
if query_result is None:
await _query_graphql_async(self._api, self._query_id, self._query)
query_result = symbols.get(self._query_id)
if isinstance(self._api._backtest, TqBacktest): # 回测时,清空缓存的请求
self._api._send_pack({
"aid": "ins_query",
"query_id": self._query_id,
"query": ""
})
l0, l1, l2 = self._filter(query_result)
self[0].extend(l0)
self[1].extend(l1)
self[2].extend(l2)
if isinstance(self._api._backtest, TqBacktest): # 回测时,清空缓存的请求
self._api._send_pack({
"aid": "ins_query",
"query_id": self._query_id,
"query": ""
})
return self

def __await__(self):
Expand Down
2 changes: 1 addition & 1 deletion tqsdk/tradeable/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@


from tqsdk.tradeable.otg.base_otg import BaseOtg
from tqsdk.tradeable.otg import TqAccount, TqZq, TqKq, TqKqStock
from tqsdk.tradeable.otg import TqAccount, TqZq, TqKq, TqKqStock, TqCtp
from tqsdk.tradeable.sim.basesim import BaseSim
from tqsdk.tradeable.sim import TqSim, TqSimStock
1 change: 1 addition & 0 deletions tqsdk/tradeable/otg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from tqsdk.tradeable.otg.tqaccount import TqAccount
from tqsdk.tradeable.otg.tqzq import TqZq
from tqsdk.tradeable.otg.tqkq import TqKq, TqKqStock
from tqsdk.tradeable.otg.tqctp import TqCtp
71 changes: 71 additions & 0 deletions tqsdk/tradeable/otg/tqctp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!usr/bin/env python3
# -*- coding:utf-8 -*-
__author__ = 'chenli'

import hashlib

from tqsdk.tradeable.otg.base_otg import BaseOtg
from tqsdk.tradeable.mixin import FutureMixin


class TqCtp(BaseOtg, FutureMixin):
"""直连 CTP 账户类"""

def __init__(self, account_id: str, password: str, front_broker: str, front_url: str, app_id: str, auth_code: str) -> None:
"""
创建直连 CTP 账户实例
Args:
account_id (str): 帐号
password (str): 密码
front_broker (str): CTP 柜台代码
front_url (str): CTP 柜台地址
app_id (str): CTP AppID
auth_code (str): CTP AuthCode
Example1::
from tqsdk import TqApi, TqCtp
account = TqCtp(account_id="CTP 账户", password="CTP 密码", front_broker="CTP 柜台代码", "front_url"="CTP 柜台地址", app_id="CTP AppID", auth_code="CTP AuthCode")
api = TqApi(account, auth=TqAuth("快期账户", "账户密码"))
"""
self._account_id = account_id
self._front_broker = front_broker
self._front_url = front_url
self._app_id = app_id
self._auth_code = auth_code
super(TqCtp, self).__init__(broker_id="", account_id=account_id, password=password, td_url="zqotg://127.0.0.1:0/trade")

@property
def _account_auth(self):
return {
"feature": "tq_direct",
"account_id": self._account_id,
"auto_add": True,
}

def _get_account_key(self):
s = self._broker_id + self._account_id
s += self._front_broker if self._front_broker else ""
s += self._front_url if self._front_url else ""
return hashlib.md5(s.encode('utf-8')).hexdigest()

async def _send_login_pack(self):
req = {
"aid": "req_login",
"bid": "tqsdk_zq_otg",
"user_name": self._account_id,
"password": self._password,
"broker_id": self._front_broker,
"front": self._front_url,
"app_id": self._app_id,
"auth_code": self._auth_code,
"backend": "ctp"
}
await self._td_send_chan.send(req)
6 changes: 5 additions & 1 deletion tqsdk/tradeable/sim/basesim.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import asyncio
import time
import os
from abc import abstractmethod
from typing import Type, Union

Expand Down Expand Up @@ -285,7 +286,10 @@ def _md_recv(self, pack):
# 导致前面处理 order 时的 _current_datetime 还是旧的行情时间
self._current_datetime = quote_diff["datetime"] # 最新行情时间
# 更新最新行情时间时的本地时间,回测时不使用时间差
self._local_time_record = (time.time() - 0.005) if not self._tqsdk_backtest else float("nan")
# 在进行测试sim账号时(test_multi_account.py)也不使用时间差,因为会遇到和回测一样的问题:
# 在sim收到行情后记录_local_time_record,然后下发行情到api进行merge_diff(),api需要处理完k线和quote才能结束wait_update(),
# 若处理时间过长,此时下单则在判断下单时间时与测试用例中的预期时间相差较大,导致测试用例无法通过。
self._local_time_record = float("nan") if self._tqsdk_backtest or "TQSDK_RUN_TEST" in os.environ else (time.time() - 0.005)
if self._current_datetime > self._trading_day_end: # 结算
self._settle()
# 若当前行情时间大于交易日的结束时间(切换交易日),则根据此行情时间更新交易日及交易日结束时间
Expand Down
Loading

0 comments on commit 5cc39d4

Please sign in to comment.