Skip to content

Commit

Permalink
Update Version 3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
shinny-pack authored and shinny-mayanqiong committed Dec 24, 2021
1 parent 70d0e30 commit b3d1142
Show file tree
Hide file tree
Showing 35 changed files with 2,352 additions and 121 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.0.3
Version: 3.1.0
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.0.3'
version = u'3.1.0'
# The full version, including alpha/beta/rc tags.
release = u'3.0.3'
release = u'3.1.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
3 changes: 2 additions & 1 deletion doc/reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ TqSdk 模块参考
tqsdk.api.rst
tqsdk.auth.rst
tqsdk.account.rst
tqsdk.tqkq.rst
tqsdk.sim.rst
tqsdk.multiaccount.rst
tqsdk.objs.rst
tqsdk.lib.rst
tqsdk.ta.rst
tqsdk.tafunc.rst
tqsdk.sim.rst
tqsdk.backtest.rst
tqsdk.algorithm.rst
tqsdk.risk_rule.rst
Expand Down
6 changes: 3 additions & 3 deletions doc/reference/tqsdk.account.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _tqsdk.account:

tqsdk.account - 账户类
tqsdk.account - 实盘账户类
------------------------------------------------------------------
.. automodule:: tqsdk.account
.. automodule:: tqsdk.tradeable.otg.tqaccount
:members:

:inherited-members:
6 changes: 3 additions & 3 deletions doc/reference/tqsdk.sim.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _tqsdk.sim:

tqsdk.sim - 模拟交易
tqsdk.sim - 本地模拟交易
------------------------------------------------------------------
.. automodule:: tqsdk.sim
.. automodule:: tqsdk.tradeable.sim.tqsim
:members:

:inherited-members:
16 changes: 16 additions & 0 deletions doc/reference/tqsdk.tqkq.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. _tqsdk.tqkq:

tqsdk.tqkq - 快期模拟交易类
------------------------------------------------------------------
.. autoclass:: tqsdk.tradeable.otg.tqkq.TqKq
:members:
:inherited-members:


.. _tqsdk.tqkq_stock:

tqsdk.tqkq_stock - 快期股票模拟交易类
------------------------------------------------------------------
.. autoclass:: tqsdk.tradeable.otg.tqkq.TqKqStock
:members:
:inherited-members:
13 changes: 13 additions & 0 deletions doc/version.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

版本变更
=============================
3.1.0 (2021/12/24)

* 新增:为各种账户类型增加接口调用,支持 IDE 更好的提供代码提示。TqSdk 目前支持以下账户类型 :py:class:`~tqsdk.tradeable.otg.tqaccount.TqAccount`、:py:class:`~tqsdk.tradeable.otg.tqkq.TqKq`、
:py:class:`~tqsdk.tradeable.otg.tqkq.TqKqStock`、:py:class:`~tqsdk.tradeable.sim.tqsim.TqSim`,本次重构为以上账户类型分别添加了
``get_account``、``get_position``、``get_order``、``get_trade`` 几个接口,明确了其返回值的类型。

例如::py:class:`~tqsdk.tradeable.otg.tqkq.TqKq` 实例调用 :py:meth:`~tqsdk.tradeable.otg.tqkq.TqKq.get_account` ,返回 :py:class:`~tqsdk.objs.Account` 类型实例;

:py:class:`~tqsdk.tradeable.otg.tqkq.TqKqStock` 实例调用 :py:meth:`~tqsdk.tradeable.otg.tqkq.TqKqStock.get_account` ,返回 :py:class:`~tqsdk.objs.SecurityAccount` 类型实例。
* 修复::py:class:`~tqsdk.lib.target_pos_task.TargetPosTask` 及 :py:class:`~tqsdk.algorithm.twap` 增加添加红枣期货暂不支持的提示
* docs:更新开盘抢单示例代码


3.0.3 (2021/12/10)

* 修复:从服务器更新节假日表,修复 :py:meth:`~tqsdk.api.TqApi.get_trading_calendar` 接口文档及报错信息
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def get_tag(self):

setuptools.setup(
name='tqsdk',
version="3.0.3",
version="3.1.0",
description='TianQin SDK',
author='TianQin',
author_email='[email protected]',
Expand Down
3 changes: 1 addition & 2 deletions tqsdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
name = "tqsdk"

from tqsdk.api import TqApi
from tqsdk.account import TqAccount, TqKq, TqKqStock
from tqsdk.tradeable import TqAccount, TqKq, TqKqStock, TqSim
from tqsdk.auth import TqAuth
from tqsdk.channel import TqChan
from tqsdk.backtest import TqBacktest, TqReplay
from tqsdk.exceptions import BacktestFinished, TqTimeoutError, TqRiskRuleError
from tqsdk.lib import TargetPosScheduler, TargetPosTask, InsertOrderUntilAllTradedTask, InsertOrderTask, TqNotify
from tqsdk.sim import TqSim
from tqsdk.multiaccount import TqMultiAccount
from .__version__ import __version__
2 changes: 1 addition & 1 deletion tqsdk/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.0.3'
__version__ = '3.1.0'
16 changes: 9 additions & 7 deletions tqsdk/algorithm/time_table_generater.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import numpy as np
from pandas import DataFrame

from tqsdk.api import TqApi, TqAccount, TqSim, TqKq
from tqsdk.api import TqApi
from tqsdk import utils
from tqsdk.datetime import _get_trading_timestamp, _get_trade_timestamp, _get_trading_day_from_timestamp
from tqsdk.rangeset import _rangeset_slice, _rangeset_head
from tqsdk.tradeable import TqAccount, TqKq, TqSim


def twap_table(api: TqApi, symbol: str, target_pos: int, duration: int, min_volume_each_step: int, max_volume_each_step: int,
Expand Down Expand Up @@ -145,12 +146,12 @@ def vwap_table(api: TqApi, symbol: str, target_pos: int, duration: float,
调用 vwap_table 函数,根据以下逻辑生成 time_table:
1. 根据 target_pos - 当前合约的净持仓,得到总的需要调整手数
1. 请求 symbol 合约的 ``1min`` K 线
2. 采样取用最近 10 日内,以合约当前行情时间的下一分钟为起点,每日 duration / 60 根 K 线
例如当前合约时间为 14:35:35,那么采样是会使用 14:36:00 开始的分钟线 K 线
3. 按日期分组,分别计算交易日内,每根 K 线成交量占总成交量的比例
4. 计算最近 10 日内相同分钟内的成交量占比的算术平均数,将第 1 步得到的总调整手数按照得到的比例分配
5. 每一分钟,前 58s 以追加价格下单,后 2s 以对价价格下单
2. 请求 symbol 合约的 ``1min`` K 线
3. 采样取用最近 10 日内,以合约当前行情时间的下一分钟为起点,每日 duration / 60 根 K 线, \
例如当前合约时间为 14:35:35,那么采样是会使用 14:36:00 开始的分钟线 K 线
4. 按日期分组,分别计算交易日内,每根 K 线成交量占总成交量的比例
5. 计算最近 10 日内相同分钟内的成交量占比的算术平均数,将第 1 步得到的总调整手数按照得到的比例分配
6. 每一分钟,前 58s 以追加价格下单,后 2s 以对价价格下单
Args:
api (TqApi): TqApi实例,该task依托于指定api下单/撤单
Expand Down Expand Up @@ -189,6 +190,7 @@ def vwap_table(api: TqApi, symbol: str, target_pos: int, duration: float,
api.wait_update()
api.close()
"""
account = api._account._check_valid(account)
if account is None:
Expand Down
6 changes: 4 additions & 2 deletions tqsdk/algorithm/twap.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
from typing import Optional, Union

from tqsdk.algorithm.time_table_generater import _gen_random_list
from tqsdk.api import TqApi, TqAccount, TqSim, TqKq
from tqsdk.api import TqApi
from tqsdk.channel import TqChan
from tqsdk.datetime import _get_trading_timestamp, _get_trade_timestamp
from tqsdk.lib import InsertOrderUntilAllTradedTask
from tqsdk import utils
from tqsdk.tradeable import TqAccount, TqKq, TqSim
from tqsdk.rangeset import _rangeset_slice, _rangeset_head, _rangeset_length


Expand Down Expand Up @@ -117,6 +117,8 @@ def __init__(self, api: TqApi, symbol: str, direction: str, offset: str, volume:
print(target_twap.average_trade_price)
api.close()
"""
if symbol.startswith("CZCE.CJ"):
raise Exception("红枣期货不支持创建 targetpostask、twap、vwap 任务,交易所规定该品种最小开仓手数为大于等于 4 手,这些函数还未支持该规则!")
self._api = api
self._account = api._account._check_valid(account)
if self._account is None:
Expand Down
61 changes: 37 additions & 24 deletions tqsdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
from pandas.core.internals import NumericBlock as FloatBlock

from tqsdk.auth import TqAuth
from tqsdk.account import TqAccount, TqKq, TqKqStock
from tqsdk.baseApi import TqBaseApi
from tqsdk.multiaccount import TqMultiAccount
from tqsdk.backtest import TqBacktest, TqReplay
Expand All @@ -77,9 +76,9 @@
TqSymbolRankingDataFrame, TqOptionGreeksDataFrame
from tqsdk.risk_manager import TqRiskManager
from tqsdk.risk_rule import TqRiskRule
from tqsdk.sim import TqSim
from tqsdk.ins_schema import ins_schema, basic, derivative, future, option
from tqsdk.symbols import TqSymbols
from tqsdk.tradeable import TqAccount, TqKq, TqKqStock, TqSim, BaseOtg
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 @@ -95,26 +94,28 @@ class TqApi(TqBaseApi):
通常情况下, 一个线程中 **应该只有一个** TqApi的实例, 它负责维护网络连接, 接收行情及账户数据, 并在内存中维护业务数据截面
"""

def __init__(self, account: Union[TqMultiAccount, TqAccount, TqSim, None] = None, auth: Union[TqAuth, str, None] = None, url: Optional[str] = None,
def __init__(self, account: Union[TqMultiAccount, TqAccount, TqKq, TqKqStock, TqSim, None] = None, auth: Union[TqAuth, str, None] = None, url: Optional[str] = None,
backtest: Union[TqBacktest, TqReplay, None] = None, web_gui: [bool, str] = False, debug: Union[bool, str, None] = False,
loop: Optional[asyncio.AbstractEventLoop] = None, disable_print: bool = False, _stock: bool = True,
_ins_url=None, _md_url=None, _td_url=None) -> None:
"""
创建天勤接口实例
Args:
account (None/TqAccount/TqSim): [可选]交易账号:
* None: 账号将根据环境变量决定, 默认为 :py:class:`~tqsdk.sim.TqSim`
account (None/TqAccount/TqKq/TqKqStock/TqSim): [可选]交易账号:
* None: 账号将根据环境变量决定, 默认为 :py:class:`~tqsdk.tradeable.sim.tqsim.TqSim`
* :py:class:`~tqsdk.account.TqAccount` : 使用实盘账号, 直连行情和交易服务器, 需提供期货公司/帐号/密码
* :py:class:`~tqsdk.tradeable.account.tqaccount.TqAccount` : 使用实盘账号, 直连行情和交易服务器, 需提供期货公司/帐号/密码
* :py:class:`~tqsdk.account.TqKq` : 使用快期账号登录,直连行情和快期模拟交易服务器, 需提供 auth 参数
* :py:class:`~tqsdk.tradeable.account.tqkq.TqKq` : 使用快期账号登录,直连行情和快期模拟交易服务器
* :py:class:`~tqsdk.sim.TqSim` : 使用 TqApi 自带的内部模拟账号
* :py:class:`~tqsdk.tradeable.account.tqkq.TqKqStock` : 使用快期账号登录,直连行情和快期股票模拟交易服务器
* :py:class:`~tqsdk.tradeable.sim.tqsim.TqSim` : 使用 TqApi 自带的内部模拟账号
* :py:class:`~tqsdk.multiaccount.TqMultiAccount` :\
多账户列表,列表中支持`~tqsdk.account.TqAccount`、`~tqsdk.account.TqKq`\
`~tqsdk.sim.TqSim` 中的 0 至 N 个或者组合
多账户列表,列表中支持`~tqsdk.tradeable.account.tqaccount.TqAccount`、`~tqsdk.tradeable.account.tqkq.TqKq`\
`~tqsdk.tradeable.account.tqkq.TqKqStock` 和 `~tqsdk.tradeable.sim.tqsim.TqSim` 中的 0 至 N 个或者组合
auth (TqAuth/str): [必填]用户信易账户:
* :py:class:`~tqsdk.auth.TqAuth` : 添加信易账户类,例如:TqAuth("[email protected]", "123456")
Expand All @@ -123,12 +124,12 @@ def __init__(self, account: Union[TqMultiAccount, TqAccount, TqSim, None] = None
信易账户注册链接 https://www.shinnytech.com/register-intro/
url (str): [可选]指定服务器的地址
* 当 account 为 :py:class:`~tqsdk.account.TqAccount`、:py:class:`~tqsdk.multiaccount.TqMultiAccount` 类型时, 可以通过该参数指定交易服务器地址,\
* 当 account 为 :py:class:`~tqsdk.tradeable.account.tqaccount.TqAccount`、:py:class:`~tqsdk.multiaccount.TqMultiAccount` 类型时, 可以通过该参数指定交易服务器地址,\
默认使用对应账户的交易服务地址,行情地址该信易账户对应的行情服务地址
* 当 account 为 :py:class:`~tqsdk.sim.TqSim` 类型时, 可以通过该参数指定行情服务器地址, 默认使用该信易账户对应的行情服务地址
* 当 account 为 :py:class:`~tqsdk.tradeable.sim.tqsim.TqSim` 类型时, 可以通过该参数指定行情服务器地址, 默认使用该信易账户对应的行情服务地址
backtest (TqBacktest/TqReplay): [可选] 进入时光机,此时强制要求 account 类型为 :py:class:`~tqsdk.sim.TqSim`
backtest (TqBacktest/TqReplay): [可选] 进入时光机,此时强制要求 account 类型为 :py:class:`~tqsdk.tradeable.sim.tqsim.TqSim`
* :py:class:`~tqsdk.backtest.TqBacktest` : 传入 TqBacktest 对象,进入回测模式 \
在回测模式下, TqBacktest 连接 wss://backtest.shinnytech.com/t/md/front/mobile 接收行情数据, \
由 TqBacktest 内部完成回测时间段内的行情推进和 K 线、Tick 更新.
Expand All @@ -139,9 +140,9 @@ def __init__(self, account: Union[TqMultiAccount, TqAccount, TqSim, None] = None
debug(bool/str): [可选] 是否将调试信息输出到指定文件,默认值为 False。
* None [默认]: 根据账户情况不同,默认值的行为不同。
+ 使用 :py:class:`~tqsdk.account.TqAccount` 或者 :py:class:`~tqsdk.account.TqKq` 实盘账户时,调试信息输出到指定文件夹 `~/.tqsdk/logs`。
+ 使用 :py:class:`~tqsdk.tradeable.account.tqaccount.TqAccount` 或者 :py:class:`~tqsdk.tradeable.account.tqkq.TqKq` 实盘账户时,调试信息输出到指定文件夹 `~/.tqsdk/logs`。
+ 使用 :py:class:`~tqsdk.sim.TqSim` 模拟账户时,调试信息不输出。
+ 使用 :py:class:`~tqsdk.tradeable.sim.tqsim.TqSim` 模拟账户时,调试信息不输出。
* True: 调试信息会输出到指定文件夹 `~/.tqsdk/logs`。
Expand Down Expand Up @@ -1506,8 +1507,8 @@ def get_account(self, account: Optional[Union[TqAccount, TqKq, TqKqStock, TqSim]
account1 = TqAccount("N南华期货", "123456", "123456")
account2 = TqAccount("H宏源期货", "111111", "123456")
api = TqApi(TqMultiAccount([account1, account2]), auth=TqAuth("信易账户", "账户密码"))
account_info1 = api.get_account(account=account1)
account_info2 = api.get_account(account=account2)
account_info1 = account1.get_account()
account_info2 = account2.get_account()
print("账户 1 浮动盈亏 %f, 账户 2 浮动盈亏 %f", account_info1.float_profit, account_info2.float_profit)
api.close()
Expand Down Expand Up @@ -1568,8 +1569,8 @@ def get_position(self, symbol: Optional[str] = None, account: Optional[Union[TqA
account1 = TqAccount("N南华期货", "123456", "123456")
account2 = TqAccount("N宏源期货", "123456", "123456")
api = TqApi(TqMultiAccount([account1, account2]), auth=TqAuth("信易账户", "账户密码"))
position1 = api.get_position("DCE.m2101", account=account1)
position2 = api.get_position("DCE.m2101", account=account2)
position1 = account1.get_position("DCE.m2101")
position2 = account2.get_position("DCE.m2101")
print("账户 1 浮动盈亏 %f, 账户 2 浮动盈亏 %f", position1.float_profit_long + position2.float_profit_short,
position1.float_profit_long + position2.float_profit_short)
api.close()
Expand Down Expand Up @@ -1638,8 +1639,8 @@ def get_order(self, order_id: Optional[str] = None, account: Optional[Union[TqAc
account1 = TqAccount("N南华期货", "123456", "123456")
account2 = TqAccount("N宏源期货", "123456", "123456")
api = TqApi(TqMultiAccount([account1, account2]), auth=TqAuth("信易账户", "账户密码"))
orders1 = api.get_order(account=account1))
order2 = api.get_order(order_id="订单号", account=account2)
orders1 = account1.get_order()
order2 = account2.get_order(order_id="订单号")
print(len(orders1), order2.volume_left)
api.close()
Expand Down Expand Up @@ -1684,9 +1685,9 @@ def get_trade(self, trade_id: Optional[str] = None, account: Optional[Union[TqAc
account1 = TqAccount("N南华期货", "123456", "123456")
account2 = TqAccount("N宏源期货", "123456", "123456")
api = TqApi(TqMultiAccount([account1, account2]), auth=TqAuth("信易账户", "账户密码"))
orders1 = api.get_trade(account=account1))
orders2 = api.get_trade(account=account2)
print(len(orders1), len(orders2))
trades1 = account1.get_trade()
trades2 = account2.get_trade()
print(len(trades1), len(trades2))
api.close()
# 预计的输出是这样的:
Expand Down Expand Up @@ -3113,6 +3114,18 @@ def _setup_connection(self):
else:
self._auth.login() # tqwebhelper 有可能会设置 self._auth

# 在信易账户登录之后,对于账户的基本信息校验及更新
for acc in self._account._account_list:
if isinstance(acc, BaseOtg):
acc._update_otg_info(self) # 获取交易地址;更新模拟账户 _account_id
# TqAccount 需要尝试自动绑定实盘账户
if isinstance(acc, TqAccount):
if not self._auth._has_account(acc._account_id):
self._auth._add_account(acc._account_id)
elif isinstance(acc, TqKqStock):
if not self._auth._has_account(acc._account_id):
raise Exception(f"您的账户不支持快期股票模拟,需要购买专业版本后使用。升级网址:https://account.shinnytech.com")

# 等待复盘服务器启动
if isinstance(self._backtest, TqReplay):
sim = None # 复盘时如果用户传入的 TqSim 实例,则使用用户传入的参数
Expand Down
13 changes: 13 additions & 0 deletions tqsdk/baseModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

__author__ = 'mayanqiong'

import asyncio
from abc import abstractmethod


Expand Down Expand Up @@ -41,8 +42,10 @@ async def _run(self, api, api_send_chan, api_recv_chan, *args):
else:
# 处理下游发送的其他请求
await self._handle_req_data(pack)
await self._send_diff(api_recv_chan)
finally:
[task.cancel() for task in up_handle_tasks]
await asyncio.gather(*up_handle_tasks, return_exceptions=True)

async def _up_handler(self, api_send_chan, recv_chan, chan_index):
async for pack in recv_chan:
Expand All @@ -52,6 +55,7 @@ async def _up_handler(self, api_send_chan, recv_chan, chan_index):
await api_send_chan.send(pack)

async def _send_diff(self, api_recv_chan):
pk = self._pending_peek
if self._pending_peek and self._diffs:
rtn_data = {
"aid": "rtn_data",
Expand All @@ -60,6 +64,7 @@ async def _send_diff(self, api_recv_chan):
self._diffs = []
self._pending_peek = False
await api_recv_chan.send(rtn_data)
await self._on_send_diff(pk)

@abstractmethod
async def _handle_recv_data(self, pack, chan):
Expand All @@ -77,3 +82,11 @@ async def _handle_req_data(self, pack):
这里应该将发送的请求转发到指定的某个上游 channel
"""
pass

async def _on_send_diff(self, peeding_pk):
"""
TqModule 调用 _send_diff 时,最后会执行的回调函数;
TqModule 处理所有 pack 都会调用 self._send_diff(),可以在此处处理额外业务逻辑。
pending_peek 表示调用 _send_diff 时,self._pending_peek 的值
"""
pass
Loading

0 comments on commit b3d1142

Please sign in to comment.