tgsdk-python 1.0.1__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tgsdk/DISCLAIMER.md +9 -0
- tgsdk/__init__.py +20 -0
- tgsdk/_ctp.cp313-win_amd64.pyd +0 -0
- tgsdk/api.cp313-win_amd64.pyd +0 -0
- tgsdk/api.pyi +139 -0
- tgsdk/data.cp313-win_amd64.pyd +0 -0
- tgsdk/data.pyi +96 -0
- tgsdk/py.typed +0 -0
- tgsdk/thosttraderapi_se.dll +0 -0
- tgsdk/trading.cp313-win_amd64.pyd +0 -0
- tgsdk/trading.pyi +62 -0
- tgsdk/trading_data.cp313-win_amd64.pyd +0 -0
- tgsdk/trading_data.pyi +170 -0
- tgsdk/transport.cp313-win_amd64.pyd +0 -0
- tgsdk/transport.pyi +36 -0
- tgsdk_python-1.0.1.dist-info/DELVEWHEEL +2 -0
- tgsdk_python-1.0.1.dist-info/METADATA +107 -0
- tgsdk_python-1.0.1.dist-info/RECORD +21 -0
- tgsdk_python-1.0.1.dist-info/WHEEL +5 -0
- tgsdk_python-1.0.1.dist-info/top_level.txt +1 -0
- tgsdk_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
tgsdk/DISCLAIMER.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 免责声明
|
|
2
|
+
|
|
3
|
+
tgsdk 仅提供期货行情访问与交易接口工具,不构成投资建议、收益承诺或交易结果保证。
|
|
4
|
+
|
|
5
|
+
期货交易具有较高风险。因网络中断、行情延迟、交易柜台异常、交易所规则变化、程序错误、用户策略或操作等原因造成的委托失败、重复委托、成交差异、资金损失及其他直接或间接损失,由用户自行承担。
|
|
6
|
+
|
|
7
|
+
用户应在充分测试并理解接口行为后使用本软件,并自行遵守适用的法律法规、交易所规则及期货公司要求。
|
|
8
|
+
|
|
9
|
+
本软件及其安装包为闭源软件。除权利人明确书面授权外,不授予复制、修改、反向工程、再发布、转售或以其他方式处置本软件的权利。
|
tgsdk/__init__.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""期货行情与直连 CTP 交易 SDK。"""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# start delvewheel patch
|
|
5
|
+
def _delvewheel_patch_1_13_1():
|
|
6
|
+
import os
|
|
7
|
+
if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'tgsdk_python.libs'))):
|
|
8
|
+
os.add_dll_directory(libs_dir)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_delvewheel_patch_1_13_1()
|
|
12
|
+
del _delvewheel_patch_1_13_1
|
|
13
|
+
# end delvewheel patch
|
|
14
|
+
|
|
15
|
+
from .api import TgApi
|
|
16
|
+
from .data import KlinePeriod, Quote, TgError
|
|
17
|
+
from .trading_data import CtpAccount, Account, Position, Order, Trade
|
|
18
|
+
|
|
19
|
+
__all__ = ["TgApi", "KlinePeriod", "Quote", "TgError", "CtpAccount", "Account", "Position", "Order", "Trade"]
|
|
20
|
+
__version__ = "1.0.1"
|
|
Binary file
|
|
Binary file
|
tgsdk/api.pyi
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import types
|
|
4
|
+
from .data import BAR_COLUMNS as BAR_COLUMNS, KlinePeriod as KlinePeriod, Quote as Quote, Serial as Serial, TgError as TgError, check_symbol as check_symbol, decode as decode, different as different
|
|
5
|
+
from .trading import Trading as Trading
|
|
6
|
+
from .trading_data import Account as Account, CtpAccount as CtpAccount, LiveMap as LiveMap, LiveObject as LiveObject, Order as Order, Position as Position, Trade as Trade
|
|
7
|
+
from .transport import Transport as Transport
|
|
8
|
+
from collections.abc import Mapping
|
|
9
|
+
from datetime import date, datetime
|
|
10
|
+
from typing import Literal, overload
|
|
11
|
+
|
|
12
|
+
class TgApi:
|
|
13
|
+
"""期货行情与交易接口,须在创建实例的线程中使用。
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
account: CTP 账户配置;不传时仅使用行情功能。
|
|
17
|
+
timeout: 连接和请求的超时秒数,默认 30 秒。
|
|
18
|
+
|
|
19
|
+
推荐通过 ``with TgApi(...) as api:`` 自动关闭连接。
|
|
20
|
+
实时数据统一在 ``wait_update()`` 中更新。
|
|
21
|
+
"""
|
|
22
|
+
def __init__(self, account: CtpAccount | None = None, *, timeout: float = 30.0) -> None:
|
|
23
|
+
"""创建 SDK 实例。account 不传时仅启用行情;timeout 为超时秒数。"""
|
|
24
|
+
def get_account(self) -> Account:
|
|
25
|
+
"""获取持续更新的只读资金对象,不发起查询。
|
|
26
|
+
|
|
27
|
+
金额来自最近一次完整柜台查询;未知字段为 None。
|
|
28
|
+
使用 wait_update() 更新,未配置 CtpAccount 时抛出 RuntimeError。
|
|
29
|
+
"""
|
|
30
|
+
@overload
|
|
31
|
+
def get_position(self, symbol: str) -> Position:
|
|
32
|
+
"""获取指定合约的持续更新持仓对象,symbol 如 SHFE.rb2610。"""
|
|
33
|
+
@overload
|
|
34
|
+
def get_position(self, symbol: None = None) -> Mapping[str, Position]:
|
|
35
|
+
"""获取全部持仓的持续更新只读集合,以合约代码为键。"""
|
|
36
|
+
@overload
|
|
37
|
+
def get_order(self, order_id: str) -> Order:
|
|
38
|
+
"""按本地订单号获取持续更新的订单;未知 ID 抛出 KeyError。"""
|
|
39
|
+
@overload
|
|
40
|
+
def get_order(self, order_id: None = None) -> Mapping[str, Order]:
|
|
41
|
+
"""获取当前连接订单的持续更新只读集合,以本地订单号为键。"""
|
|
42
|
+
def get_trade(self) -> Mapping[str, Trade]:
|
|
43
|
+
"""获取当前连接全部真实成交的持续更新只读集合,不发起查询。
|
|
44
|
+
|
|
45
|
+
断线后集合原位清空,旧成交对象失效。
|
|
46
|
+
"""
|
|
47
|
+
def insert_order(self, symbol: str, direction: Literal['BUY', 'SELL'], offset: Literal['OPEN', 'CLOSE', 'CLOSE_TODAY', 'CLOSE_YESTERDAY'], volume: int, limit_price: float) -> str:
|
|
48
|
+
"""提交一笔限价委托,返回本地订单号。账户须已同步为 READY。
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
symbol: 合约代码,如 SHFE.rb2610。
|
|
52
|
+
direction: BUY 买入,SELL 卖出。
|
|
53
|
+
offset: OPEN 开仓,CLOSE 普通平仓,CLOSE_TODAY 平今,
|
|
54
|
+
CLOSE_YESTERDAY 平昨。
|
|
55
|
+
volume: 委托数量,单位为手,须为正整数。
|
|
56
|
+
limit_price: 委托价格,须符合合约最小变动价位。
|
|
57
|
+
|
|
58
|
+
每次调用只发送一笔 CTP 委托,不会自动拆分;柜台结果由 wait_update() 更新。
|
|
59
|
+
"""
|
|
60
|
+
def cancel_order(self, order_id: str) -> None:
|
|
61
|
+
"""撤销本地订单号对应的委托。
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
order_id: ``FrontID:SessionID:OrderRef`` 格式的本地订单号。
|
|
65
|
+
|
|
66
|
+
尚无交易所订单号时等待回报再发送。返回不表示撤单成功,
|
|
67
|
+
请通过 wait_update() 查看订单状态;断线会清除待发送的撤单。
|
|
68
|
+
"""
|
|
69
|
+
def query_symbols(self, exchange_id: str | None = None, product_id: str | None = None, is_main: bool | None = None) -> list[str]:
|
|
70
|
+
"""查询合约代码列表,返回一次性查询结果。
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
exchange_id: 交易所代码,如 SHFE;None 表示不限。
|
|
74
|
+
product_id: 品种代码,如 rb;None 表示不限。
|
|
75
|
+
is_main: True 仅主力,False 仅非主力,None 表示不限。
|
|
76
|
+
"""
|
|
77
|
+
def query_symbol_info(self, symbol: str) -> dict:
|
|
78
|
+
"""查询合约详细信息,返回一次性字典结果。
|
|
79
|
+
|
|
80
|
+
symbol 为交易所.合约,如 SHFE.rb2610。结果包含 symbol、
|
|
81
|
+
exchange_id、product_id、is_main,以及详细信息字典 data。
|
|
82
|
+
"""
|
|
83
|
+
def get_quote(self, symbol: str) -> Quote:
|
|
84
|
+
"""订阅合约行情,立即返回持续更新的 Quote 对象。
|
|
85
|
+
|
|
86
|
+
symbol 如 SHFE.rb2610。同一合约返回同一对象,
|
|
87
|
+
通过 wait_update() 接收行情,SDK 字段应视为只读。
|
|
88
|
+
"""
|
|
89
|
+
def get_kline_serial(self, symbol: str, period: KlinePeriod, data_length: int = 200) -> pd.DataFrame:
|
|
90
|
+
"""获取最近历史 K 线并订阅更新,返回固定长度的 DataFrame。
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
symbol: 合约代码,如 SHFE.rb2610。
|
|
94
|
+
period: KlinePeriod 周期常量,如 KlinePeriod.MIN_1。
|
|
95
|
+
data_length: K 线数量,范围 1–10000,默认 200。
|
|
96
|
+
|
|
97
|
+
后续数据在 wait_update() 中原位更新。可添加指标列,
|
|
98
|
+
不要修改 SDK 列、索引或行数。timestamp 为 K 线结束时间的 Unix 毫秒。
|
|
99
|
+
"""
|
|
100
|
+
def download_kline_data(self, symbol: str, period: KlinePeriod, start_dt: date | datetime, end_dt: date | datetime, csv_file_name: str | os.PathLike) -> int:
|
|
101
|
+
"""下载指定时间范围的 K 线到 CSV,返回写入的数据行数。
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
symbol: 合约代码,如 SHFE.rb2610。
|
|
105
|
+
period: KlinePeriod 周期常量,如 KlinePeriod.MIN_1。
|
|
106
|
+
start_dt: 起始日期或时间,包含边界;日期从当天零点起算。
|
|
107
|
+
end_dt: 结束日期或时间,包含边界;日期包含当天全天。
|
|
108
|
+
csv_file_name: CSV 文件路径,父目录须已存在。
|
|
109
|
+
|
|
110
|
+
无时区的时间按北京时间解释。成功后覆盖同名文件,失败保留原文件。
|
|
111
|
+
CSV 使用 UTF-8 BOM 编码,不含索引;无数据时仅写表头并返回 0。
|
|
112
|
+
此方法同步完成,无需调用 wait_update()。
|
|
113
|
+
"""
|
|
114
|
+
def wait_update(self, deadline: float | None = None) -> bool:
|
|
115
|
+
"""等待并提交一批行情或交易更新,有更新返回 True,截止超时返回 False。
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
deadline: Unix 秒绝对截止时间,如 time.time() + 10;None 表示持续等待。
|
|
119
|
+
|
|
120
|
+
同一笔成交对应的成交、订单成交量和持仓会同时提交;
|
|
121
|
+
资金来自独立查询,不保证同时更新。可仅用于交易账户。
|
|
122
|
+
"""
|
|
123
|
+
def is_changing(self, obj: Quote | pd.DataFrame | LiveObject | Mapping[str, LiveObject], key: str | list[str] | None = None) -> bool:
|
|
124
|
+
"""判断对象或指定字段在本次 wait_update() 中是否变化。
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
obj: 本实例返回的行情、K 线、交易对象或实时集合。
|
|
128
|
+
key: 字段名、字段名列表;None 表示检查业务字段。
|
|
129
|
+
|
|
130
|
+
K 线仅比较最新一行;检查 timestamp 可判断是否出现新 K 线。
|
|
131
|
+
交易对象默认忽略 updated_at,显式传入该字段才检查刷新时间。
|
|
132
|
+
"""
|
|
133
|
+
def close(self) -> None:
|
|
134
|
+
"""关闭连接并释放资源,可重复调用;不会撤销已提交的订单。
|
|
135
|
+
|
|
136
|
+
程序正常退出时会自动关闭,仍推荐使用 with 或主动调用 close()。
|
|
137
|
+
"""
|
|
138
|
+
def __enter__(self) -> TgApi: ...
|
|
139
|
+
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: types.TracebackType | None) -> None: ...
|
|
Binary file
|
tgsdk/data.pyi
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
class TgError(Exception):
|
|
6
|
+
"""SDK 数据或交易服务异常,status 为可选的响应状态码。"""
|
|
7
|
+
status: Incomplete
|
|
8
|
+
def __init__(self, message: str, *, status: int | None = None) -> None: ...
|
|
9
|
+
|
|
10
|
+
class KlinePeriod(Enum):
|
|
11
|
+
"""K 线周期:MIN_1/5/10/15/30 为分钟,HOUR_1/4 为小时,DAY_1 为日线。"""
|
|
12
|
+
MIN_1 = '1m'
|
|
13
|
+
MIN_5 = '5m'
|
|
14
|
+
MIN_10 = '10m'
|
|
15
|
+
MIN_15 = '15m'
|
|
16
|
+
MIN_30 = '30m'
|
|
17
|
+
HOUR_1 = '1h'
|
|
18
|
+
HOUR_4 = '4h'
|
|
19
|
+
DAY_1 = '1d'
|
|
20
|
+
|
|
21
|
+
@dataclass(eq=False)
|
|
22
|
+
class Quote:
|
|
23
|
+
"""持续更新的合约行情,通过 wait_update() 更新,SDK 字段应视为只读。
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
symbol: 合约代码,如 SHFE.rb2610。
|
|
27
|
+
trading_day: 交易日,格式 YYYYMMDD。
|
|
28
|
+
timestamp: 行情时间,Unix 毫秒。
|
|
29
|
+
open: 开盘价。
|
|
30
|
+
highest: 最高价。
|
|
31
|
+
lowest: 最低价。
|
|
32
|
+
last_price: 最新价。
|
|
33
|
+
pre_settlement: 昨结算价。
|
|
34
|
+
pre_close: 昨收盘价。
|
|
35
|
+
upper_limit: 涨停价。
|
|
36
|
+
lower_limit: 跌停价。
|
|
37
|
+
volume: 成交量。
|
|
38
|
+
turnover: 成交额。
|
|
39
|
+
open_interest: 持仓量。
|
|
40
|
+
bids: 买盘档位,每档为(价格,数量)。
|
|
41
|
+
asks: 卖盘档位,每档为(价格,数量)。
|
|
42
|
+
"""
|
|
43
|
+
symbol: str
|
|
44
|
+
'合约代码,如 SHFE.rb2610。'
|
|
45
|
+
trading_day: str = ...
|
|
46
|
+
'交易日,格式 YYYYMMDD。'
|
|
47
|
+
timestamp: int = ...
|
|
48
|
+
'行情时间,Unix 毫秒。'
|
|
49
|
+
open: float = ...
|
|
50
|
+
'开盘价。'
|
|
51
|
+
highest: float = ...
|
|
52
|
+
'最高价。'
|
|
53
|
+
lowest: float = ...
|
|
54
|
+
'最低价。'
|
|
55
|
+
last_price: float = ...
|
|
56
|
+
'最新价。'
|
|
57
|
+
pre_settlement: float = ...
|
|
58
|
+
'昨结算价。'
|
|
59
|
+
pre_close: float = ...
|
|
60
|
+
'昨收盘价。'
|
|
61
|
+
upper_limit: float = ...
|
|
62
|
+
'涨停价。'
|
|
63
|
+
lower_limit: float = ...
|
|
64
|
+
'跌停价。'
|
|
65
|
+
volume: float = ...
|
|
66
|
+
'成交量。'
|
|
67
|
+
turnover: float = ...
|
|
68
|
+
'成交额。'
|
|
69
|
+
open_interest: float = ...
|
|
70
|
+
'持仓量。'
|
|
71
|
+
bids: list = field(default_factory=list)
|
|
72
|
+
'买盘档位,每档为(价格,数量)。'
|
|
73
|
+
asks: list = field(default_factory=list)
|
|
74
|
+
'卖盘档位,每档为(价格,数量)。'
|
|
75
|
+
def __setattr__(self, key, value) -> None: ...
|
|
76
|
+
|
|
77
|
+
BAR_FIELDS: Incomplete
|
|
78
|
+
QUOTE_FIELDS: Incomplete
|
|
79
|
+
BAR_COLUMNS: Incomplete
|
|
80
|
+
|
|
81
|
+
def check_symbol(symbol) -> None: ...
|
|
82
|
+
def number(value): ...
|
|
83
|
+
def decode(data, symbol, *, quote: bool = False):
|
|
84
|
+
"""Validate a complete message before exposing any of its fields."""
|
|
85
|
+
def different(old, new): ...
|
|
86
|
+
|
|
87
|
+
class Serial:
|
|
88
|
+
symbol: Incomplete
|
|
89
|
+
period: Incomplete
|
|
90
|
+
length: Incomplete
|
|
91
|
+
bars: Incomplete
|
|
92
|
+
initial_generation: int
|
|
93
|
+
initial_sequence: int
|
|
94
|
+
frame: Incomplete
|
|
95
|
+
def __init__(self, symbol, period, length) -> None: ...
|
|
96
|
+
def update(self, bars): ...
|
tgsdk/py.typed
ADDED
|
File without changes
|
|
Binary file
|
|
Binary file
|
tgsdk/trading.pyi
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from .data import TgError as TgError, check_symbol as check_symbol, different as different
|
|
2
|
+
from .trading_data import Account as Account, LiveMap as LiveMap, Order as Order, Position as Position, Trade as Trade, empty_position as empty_position
|
|
3
|
+
from _typeshed import Incomplete
|
|
4
|
+
|
|
5
|
+
log: Incomplete
|
|
6
|
+
TZ: Incomplete
|
|
7
|
+
QUERY: Incomplete
|
|
8
|
+
SYNC_STEPS: Incomplete
|
|
9
|
+
ACCOUNT_FIELDS: Incomplete
|
|
10
|
+
OFFSET_BY_FLAG: Incomplete
|
|
11
|
+
FLAG_BY_OFFSET: Incomplete
|
|
12
|
+
|
|
13
|
+
def timestamp(day, clock): ...
|
|
14
|
+
def finite(value): ...
|
|
15
|
+
def local_order_id(front, session, order_ref): ...
|
|
16
|
+
def order_offset(value): ...
|
|
17
|
+
|
|
18
|
+
class Native:
|
|
19
|
+
module: Incomplete
|
|
20
|
+
handle: Incomplete
|
|
21
|
+
def __init__(self, config, directory) -> None: ...
|
|
22
|
+
def request(self, method, data, request_id): ...
|
|
23
|
+
def poll(self): ...
|
|
24
|
+
def close(self) -> None: ...
|
|
25
|
+
|
|
26
|
+
class Trading:
|
|
27
|
+
"""Private protocol state is committed to user objects only by wait_update."""
|
|
28
|
+
factory: Incomplete
|
|
29
|
+
account: Incomplete
|
|
30
|
+
a: Incomplete
|
|
31
|
+
instruments: Incomplete
|
|
32
|
+
live_trade_buffer: Incomplete
|
|
33
|
+
trade_before: Incomplete
|
|
34
|
+
position_candidate: Incomplete
|
|
35
|
+
position_ready: bool
|
|
36
|
+
sync_index: int
|
|
37
|
+
last_query: Incomplete
|
|
38
|
+
last_account_refresh: float
|
|
39
|
+
phase_data: Incomplete
|
|
40
|
+
dirty: bool
|
|
41
|
+
local_changes: Incomplete
|
|
42
|
+
changed: Incomplete
|
|
43
|
+
directory: Incomplete
|
|
44
|
+
reset_pending: bool
|
|
45
|
+
cancel_pending: Incomplete
|
|
46
|
+
published_position_time: Incomplete
|
|
47
|
+
def __init__(self, config, timeout, objects, *, native_factory=...) -> None: ...
|
|
48
|
+
def get_position(self, symbol): ...
|
|
49
|
+
task: Incomplete
|
|
50
|
+
def start(self) -> None: ...
|
|
51
|
+
phase: str
|
|
52
|
+
error: Incomplete
|
|
53
|
+
async def run(self) -> None: ...
|
|
54
|
+
day: Incomplete
|
|
55
|
+
order_ref: Incomplete
|
|
56
|
+
inflight: Incomplete
|
|
57
|
+
def event(self, event) -> None: ...
|
|
58
|
+
def tick(self, now) -> None: ...
|
|
59
|
+
async def insert(self, symbol, direction, offset, volume, limit_price): ...
|
|
60
|
+
def cancel(self, order_id) -> None: ...
|
|
61
|
+
def commit(self, changes): ...
|
|
62
|
+
async def close(self) -> None: ...
|
|
Binary file
|
tgsdk/trading_data.pyi
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from collections.abc import Mapping
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
|
|
5
|
+
@dataclass(frozen=True)
|
|
6
|
+
class CtpAccount:
|
|
7
|
+
"""CTP 直连账户配置,交易凭据不会发送至行情服务。
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
broker_id: 期货公司代码。
|
|
11
|
+
user_id: 资金账号。
|
|
12
|
+
password: 交易密码。
|
|
13
|
+
front_url: 交易前置地址,格式为 tcp://地址:端口。
|
|
14
|
+
app_id: 期货公司提供的客户端标识。
|
|
15
|
+
auth_code: 期货公司提供的客户端授权码。
|
|
16
|
+
"""
|
|
17
|
+
broker_id: str
|
|
18
|
+
'期货公司代码。'
|
|
19
|
+
user_id: str
|
|
20
|
+
'资金账号。'
|
|
21
|
+
password: str = field(repr=False)
|
|
22
|
+
'交易密码。'
|
|
23
|
+
front_url: str
|
|
24
|
+
'交易前置地址,格式为 tcp://地址:端口。'
|
|
25
|
+
app_id: str
|
|
26
|
+
'期货公司提供的客户端标识。'
|
|
27
|
+
auth_code: str = field(repr=False)
|
|
28
|
+
'期货公司提供的客户端授权码。'
|
|
29
|
+
def __post_init__(self) -> None: ...
|
|
30
|
+
|
|
31
|
+
class LiveObject:
|
|
32
|
+
fields: Incomplete
|
|
33
|
+
def __init__(self, **values) -> None: ...
|
|
34
|
+
def __getattr__(self, key): ...
|
|
35
|
+
def __setattr__(self, key, value) -> None: ...
|
|
36
|
+
|
|
37
|
+
class LiveMap(Mapping):
|
|
38
|
+
item_type: Incomplete
|
|
39
|
+
def __init__(self, item_type) -> None: ...
|
|
40
|
+
def __getitem__(self, key): ...
|
|
41
|
+
def __iter__(self): ...
|
|
42
|
+
def __len__(self) -> int: ...
|
|
43
|
+
|
|
44
|
+
class Account(LiveObject):
|
|
45
|
+
"""只读资金快照;金额单位为人民币元,未知字段为 None。
|
|
46
|
+
|
|
47
|
+
仅由完整柜台查询更新,不根据行情或成交估算资金。
|
|
48
|
+
"""
|
|
49
|
+
account_id: str | None
|
|
50
|
+
'资金账号。'
|
|
51
|
+
trading_day: str | None
|
|
52
|
+
'交易日,格式 YYYYMMDD。'
|
|
53
|
+
sync_status: str
|
|
54
|
+
'同步状态:INITIALIZING、READY、DISCONNECTED、RESYNCING 或 ERROR。'
|
|
55
|
+
balance: float | None
|
|
56
|
+
'账户权益。'
|
|
57
|
+
available: float | None
|
|
58
|
+
'可用资金。'
|
|
59
|
+
margin: float | None
|
|
60
|
+
'已占用保证金。'
|
|
61
|
+
frozen_margin: float | None
|
|
62
|
+
'冻结保证金。'
|
|
63
|
+
commission: float | None
|
|
64
|
+
'当日累计实际手续费。'
|
|
65
|
+
frozen_commission: float | None
|
|
66
|
+
'冻结手续费。'
|
|
67
|
+
close_profit: float | None
|
|
68
|
+
'当日平仓盈亏。'
|
|
69
|
+
position_profit: float | None
|
|
70
|
+
'持仓盈亏。'
|
|
71
|
+
deposit: float | None
|
|
72
|
+
'当日入金。'
|
|
73
|
+
withdraw: float | None
|
|
74
|
+
'当日出金。'
|
|
75
|
+
updated_at: int | None
|
|
76
|
+
'最近一次完整查询完成的本地时间,Unix 毫秒。'
|
|
77
|
+
fields: Incomplete
|
|
78
|
+
|
|
79
|
+
class Position(LiveObject):
|
|
80
|
+
"""持续更新的只读持仓;数量单位为手。
|
|
81
|
+
|
|
82
|
+
登录查询建立基线,之后根据真实成交本地更新;未知数量为 None。
|
|
83
|
+
"""
|
|
84
|
+
symbol: str
|
|
85
|
+
'合约代码,如 SHFE.rb2610。'
|
|
86
|
+
pos_long: int | None
|
|
87
|
+
'多头持仓。'
|
|
88
|
+
pos_short: int | None
|
|
89
|
+
'空头持仓。'
|
|
90
|
+
pos: int | None
|
|
91
|
+
'净持仓,多头减空头。'
|
|
92
|
+
pos_long_today: int | None
|
|
93
|
+
'剩余多头今仓。'
|
|
94
|
+
pos_short_today: int | None
|
|
95
|
+
'剩余空头今仓。'
|
|
96
|
+
pos_long_his: int | None
|
|
97
|
+
'剩余多头历史仓。'
|
|
98
|
+
pos_short_his: int | None
|
|
99
|
+
'剩余空头历史仓。'
|
|
100
|
+
frozen_long: int | None
|
|
101
|
+
'卖出平仓冻结的多头持仓。'
|
|
102
|
+
frozen_short: int | None
|
|
103
|
+
'买入平仓冻结的空头持仓。'
|
|
104
|
+
available_long: int | None
|
|
105
|
+
'同一查询快照中的可平多头数量。'
|
|
106
|
+
available_short: int | None
|
|
107
|
+
'同一查询快照中的可平空头数量。'
|
|
108
|
+
updated_at: int | None
|
|
109
|
+
'最近一次持仓数量或冻结状态更新时间,Unix 毫秒。'
|
|
110
|
+
fields: Incomplete
|
|
111
|
+
|
|
112
|
+
class Order(LiveObject):
|
|
113
|
+
"""持续更新的只读订单,断线后失效。"""
|
|
114
|
+
order_id: str
|
|
115
|
+
'FrontID:SessionID:OrderRef 格式的本地订单号。'
|
|
116
|
+
symbol: str
|
|
117
|
+
'合约代码。'
|
|
118
|
+
direction: str | None
|
|
119
|
+
'BUY 买入,SELL 卖出。'
|
|
120
|
+
offset: str | None
|
|
121
|
+
'OPEN 开仓,CLOSE 普通平仓,CLOSE_TODAY 平今,CLOSE_YESTERDAY 平昨。'
|
|
122
|
+
limit_price: float | None
|
|
123
|
+
'委托限价。'
|
|
124
|
+
volume_original: int | None
|
|
125
|
+
'原始委托数量,单位为手。'
|
|
126
|
+
volume_traded: int | None
|
|
127
|
+
'已成交数量,单位为手。'
|
|
128
|
+
volume_left: int | None
|
|
129
|
+
'未成交数量;撤单结束后仍可大于零。'
|
|
130
|
+
status: str | None
|
|
131
|
+
'ALIVE 有效,FINISHED 已结束;失效对象为 None。'
|
|
132
|
+
is_confirmed: bool
|
|
133
|
+
'当前状态是否已确认且同步有效。'
|
|
134
|
+
is_error: bool | None
|
|
135
|
+
'是否存在报单失败。'
|
|
136
|
+
last_msg: str | None
|
|
137
|
+
'最新状态说明。'
|
|
138
|
+
insert_time: int | None
|
|
139
|
+
'委托时间,Unix 毫秒。'
|
|
140
|
+
trade_records: Mapping[str, Trade]
|
|
141
|
+
'此订单的只读成交集合,与全局集合引用相同成交对象。'
|
|
142
|
+
fields: Incomplete
|
|
143
|
+
|
|
144
|
+
class Trade(LiveObject):
|
|
145
|
+
"""只读真实成交记录,不包含估算手续费;断线后对象失效。"""
|
|
146
|
+
trade_id: str
|
|
147
|
+
'SDK 成交 ID。'
|
|
148
|
+
exchange_trade_id: str | None
|
|
149
|
+
'交易所原始成交号。'
|
|
150
|
+
order_id: str
|
|
151
|
+
'关联的本地订单号。'
|
|
152
|
+
symbol: str
|
|
153
|
+
'合约代码。'
|
|
154
|
+
direction: str | None
|
|
155
|
+
'BUY 买入,SELL 卖出。'
|
|
156
|
+
offset: str | None
|
|
157
|
+
'OPEN 开仓,CLOSE 普通平仓,CLOSE_TODAY 平今,CLOSE_YESTERDAY 平昨。'
|
|
158
|
+
close_type: str | None
|
|
159
|
+
'TODAY 平今,HISTORY 平历史仓,UNSPECIFIED 普通平仓,None 开仓或未知。'
|
|
160
|
+
price: float | None
|
|
161
|
+
'实际成交价格。'
|
|
162
|
+
volume: int | None
|
|
163
|
+
'实际成交数量,单位为手。'
|
|
164
|
+
trade_time: int | None
|
|
165
|
+
'成交时间,Unix 毫秒。'
|
|
166
|
+
trading_day: str | None
|
|
167
|
+
'交易日,格式 YYYYMMDD。'
|
|
168
|
+
fields: Incomplete
|
|
169
|
+
|
|
170
|
+
def empty_position(symbol, updated_at=None): ...
|
|
Binary file
|
tgsdk/transport.pyi
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from .data import TgError as TgError, decode as decode
|
|
2
|
+
from _typeshed import Incomplete
|
|
3
|
+
|
|
4
|
+
logger: Incomplete
|
|
5
|
+
|
|
6
|
+
class Transport:
|
|
7
|
+
url: Incomplete
|
|
8
|
+
ws_url: Incomplete
|
|
9
|
+
timeout: Incomplete
|
|
10
|
+
restore: Incomplete
|
|
11
|
+
session: Incomplete
|
|
12
|
+
channels: Incomplete
|
|
13
|
+
acked: Incomplete
|
|
14
|
+
incoming: Incomplete
|
|
15
|
+
changed: Incomplete
|
|
16
|
+
subscriptions_changed: Incomplete
|
|
17
|
+
ack_changed: Incomplete
|
|
18
|
+
task: Incomplete
|
|
19
|
+
generation: int
|
|
20
|
+
sequence: int
|
|
21
|
+
ready: bool
|
|
22
|
+
error: Incomplete
|
|
23
|
+
ws: Incomplete
|
|
24
|
+
def __init__(self, url, timeout, restore) -> None: ...
|
|
25
|
+
async def client(self): ...
|
|
26
|
+
async def get(self, path, params=None): ...
|
|
27
|
+
def subscribe(self, channel) -> None: ...
|
|
28
|
+
def start(self) -> None: ...
|
|
29
|
+
def raise_error(self) -> None: ...
|
|
30
|
+
async def wait_ack(self, channel) -> None: ...
|
|
31
|
+
async def send_subscriptions(self) -> None: ...
|
|
32
|
+
async def receive(self) -> None: ...
|
|
33
|
+
async def bootstrap(self) -> None: ...
|
|
34
|
+
async def run(self) -> None: ...
|
|
35
|
+
async def next_batch(self): ...
|
|
36
|
+
async def close(self) -> None: ...
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Version: 1.13.1
|
|
2
|
+
Arguments: ['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-uigkki2f\\cp313-win_amd64\\build\\venv\\Scripts\\delvewheel', 'repair', '--ignore-existing', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-uigkki2f\\cp313-win_amd64\\repaired_wheel', '-v', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-uigkki2f\\cp313-win_amd64\\built_wheel\\tgsdk_python-1.0.1-cp313-cp313-win_amd64.whl']
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tgsdk-python
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Python futures market data and direct CTP trading SDK
|
|
5
|
+
Requires-Python: >=3.12
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: aiohttp<4,>=3.10
|
|
8
|
+
Requires-Dist: pandas<4,>=2.2
|
|
9
|
+
Dynamic: description
|
|
10
|
+
Dynamic: description-content-type
|
|
11
|
+
Dynamic: requires-dist
|
|
12
|
+
Dynamic: requires-python
|
|
13
|
+
Dynamic: summary
|
|
14
|
+
|
|
15
|
+
# tgsdk-python
|
|
16
|
+
|
|
17
|
+
面向期货策略开发的闭源 Python SDK,提供合约查询、实时行情、持续更新的 K 线和直连 CTP 交易。
|
|
18
|
+
通过简洁的同步接口,策略可以持续读取行情、计算指标并响应数据变化。
|
|
19
|
+
|
|
20
|
+
需要 Python 3.12 及以上版本。CTP 交易支持 64 位 Windows/Linux(x86_64)和 macOS(Apple Silicon),需安装对应平台的发行包。
|
|
21
|
+
发行 wheel 保留包入口 `tgsdk/__init__.py`;其余模块编译为原生扩展,并通过同名 `.pyi` 提供接口提示。
|
|
22
|
+
|
|
23
|
+
## 快速开始
|
|
24
|
+
|
|
25
|
+
安装:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install tgsdk-python
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
获取行情和 K 线:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from tgsdk import TgApi, KlinePeriod
|
|
35
|
+
|
|
36
|
+
with TgApi() as api:
|
|
37
|
+
# 请替换为当前有效的合约代码。
|
|
38
|
+
symbol = "SHFE.au2609"
|
|
39
|
+
quote = api.get_quote(symbol)
|
|
40
|
+
klines = api.get_kline_serial(symbol, KlinePeriod.MIN_1, data_length=200)
|
|
41
|
+
|
|
42
|
+
while api.wait_update():
|
|
43
|
+
if api.is_changing(quote, "last_price"):
|
|
44
|
+
print("最新价", quote.last_price)
|
|
45
|
+
|
|
46
|
+
if api.is_changing(klines, "timestamp"):
|
|
47
|
+
print("新 K 线", klines.iloc[-1].to_dict())
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Quote 和 K 线对象只需获取一次,之后原位更新。对 K 线的变化判断只检查最新一行:
|
|
51
|
+
`timestamp` 变化表示出现新 K 线,`close` 变化表示最新一行收盘价实际改变。
|
|
52
|
+
|
|
53
|
+
连接交易账户并读取资金:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from tgsdk import TgApi, CtpAccount
|
|
57
|
+
|
|
58
|
+
account = CtpAccount(
|
|
59
|
+
broker_id="期货公司代码",
|
|
60
|
+
user_id="资金账号",
|
|
61
|
+
password="交易密码",
|
|
62
|
+
front_url="tcp://期货公司提供的地址:端口",
|
|
63
|
+
app_id="期货公司提供的 AppID",
|
|
64
|
+
auth_code="期货公司提供的授权码",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
with TgApi(account) as api:
|
|
68
|
+
funds = api.get_account()
|
|
69
|
+
positions = api.get_position()
|
|
70
|
+
while api.wait_update():
|
|
71
|
+
if api.is_changing(funds, "available"):
|
|
72
|
+
print("柜台可用资金", funds.available)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
资金通过柜台查询刷新。持仓在登录时查询一次,之后由真实成交回报更新;同一笔成交引起的成交、订单和持仓变化会同时提交。对象只需获取一次,集合也会持续更新。
|
|
76
|
+
|
|
77
|
+
## 系统架构
|
|
78
|
+
|
|
79
|
+
```mermaid
|
|
80
|
+
flowchart TD
|
|
81
|
+
Broker[期货公司交易柜台]
|
|
82
|
+
Market[官方期货行情系统]
|
|
83
|
+
SDK[tgsdk]
|
|
84
|
+
|
|
85
|
+
Broker <-->|直连 CTP| SDK
|
|
86
|
+
Market -->|行情接口| SDK
|
|
87
|
+
|
|
88
|
+
classDef source fill:#f3f4f6,stroke:#9ca3af,color:#111;
|
|
89
|
+
classDef sdk fill:#dbeafe,stroke:#598bea,stroke-width:2px,color:#111;
|
|
90
|
+
|
|
91
|
+
class Broker,Market source;
|
|
92
|
+
class SDK sdk;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- **策略始终运行在用户本地环境中,策略代码与交易信号计算均保留在本地。**
|
|
96
|
+
- **交易连接由本地 SDK 直接建立到期货公司柜台,交易账号、密码和委托不经过行情服务。**
|
|
97
|
+
|
|
98
|
+
## 主要功能
|
|
99
|
+
|
|
100
|
+
- **合约查询**:按交易所、品种、是否主力筛选合约,获取合约详细信息。
|
|
101
|
+
- **实时行情**:通过 Quote 对象读取最新价格、成交量、持仓量和盘口。
|
|
102
|
+
- **K 线序列**:通过 pandas DataFrame 获取历史与实时 K 线,支持八种固定周期。
|
|
103
|
+
- **CTP 交易**:读取资金、持仓、订单与成交,支持限价下单、撤单,以及普通平仓、平今和平昨。
|
|
104
|
+
- **统一更新**:使用 `wait_update()` 推进更新,使用 `is_changing()` 判断关注字段的变化。
|
|
105
|
+
- **连接管理**:自动连接官方数据服务,支持断线重连和订阅恢复。
|
|
106
|
+
|
|
107
|
+
完整接口、周期枚举、数据字段和使用约定见 [SDK 使用指南](docs/usage.md)。使用本软件前请阅读安装包内的 `DISCLAIMER.md`。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
tgsdk/api.cp313-win_amd64.pyd,sha256=6VTbfM9jIilm5gA3UJ50xZONopb9YUbnHI8a7NI2YZY,276992
|
|
2
|
+
tgsdk/api.pyi,sha256=N6ZqbuhOZqtI2BX4q7dDWruNawASjJdVVps4sq-T4hA,7661
|
|
3
|
+
tgsdk/data.cp313-win_amd64.pyd,sha256=KfPQnSNOh_cDKfkals7fZ2ZjGsgkfsdrR-ucO3qtr50,105984
|
|
4
|
+
tgsdk/data.pyi,sha256=jdQfEtUar-h172swCTENXqNy986yNWvzPSTxg7SYQoM,2962
|
|
5
|
+
tgsdk/DISCLAIMER.md,sha256=6kNOTQKd3iRKx2X80XWOF85jwbrJZB0leQGwcwRkhGA,755
|
|
6
|
+
tgsdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
tgsdk/thosttraderapi_se.dll,sha256=q8_3T5OloBcXkYCnxDU9Qig_Yz_7yJRwI_9iVTOv3r4,3400192
|
|
8
|
+
tgsdk/trading.cp313-win_amd64.pyd,sha256=gaSfJa0Nt75A7sCOejuIw7kdBI_ETB8ZnJtq14IfKTM,361472
|
|
9
|
+
tgsdk/trading.pyi,sha256=eg5scomk3oCl0dBfsYbAfXUWCI5sur3PbTcc7Pjl3ek,2066
|
|
10
|
+
tgsdk/trading_data.cp313-win_amd64.pyd,sha256=0Lg2tsJNAoBekNLDyUFvcr1IORaICGn92F1YehjEUx8,73216
|
|
11
|
+
tgsdk/trading_data.pyi,sha256=ugx0S5UtmLO8dlaasNa0mKUlLJVeCcGp6Qs65E6U4Y0,5723
|
|
12
|
+
tgsdk/transport.cp313-win_amd64.pyd,sha256=lNLIBWCZOhs2FQscp3Bs9kIsWDzrMOWBzM6vFTJwC8k,162816
|
|
13
|
+
tgsdk/transport.pyi,sha256=3xnha18kjUYdywG6Jo_LLmouJ0sqpqysRAKvsei8znQ,1111
|
|
14
|
+
tgsdk/_ctp.cp313-win_amd64.pyd,sha256=6sncHVB4hO1uAkyHTciJL4h0flKIgzT_8ceXta-EmE4,64000
|
|
15
|
+
tgsdk/__init__.py,sha256=MmAuH3EMJC5HHxyzT1PEECA-OlyEB2wojDNmSV6MXzw,656
|
|
16
|
+
tgsdk_python-1.0.1.dist-info/DELVEWHEEL,sha256=dXhb4MRoL_CjlPknbrjc_IVDMXYsEPBIBV_Yy4I7874,432
|
|
17
|
+
tgsdk_python-1.0.1.dist-info/METADATA,sha256=ji7NGZ1r-ESoQvkZShbykJ4atMckKgz1yBUbCEcwjRs,4047
|
|
18
|
+
tgsdk_python-1.0.1.dist-info/RECORD,,
|
|
19
|
+
tgsdk_python-1.0.1.dist-info/top_level.txt,sha256=Qa-_dytgV1Q7Lc8P1vadyaZYxLP1ydHzAglWt6cvjtM,6
|
|
20
|
+
tgsdk_python-1.0.1.dist-info/WHEEL,sha256=0LUNoHxLvcpw9db_x0XozE5jW73-_GOAO7fDDJ4Xt4Q,101
|
|
21
|
+
tgsdk_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll,sha256=pMIim9wqKmMKzcCVtNhgCOXD47x3cxdDVPPaT1vrnN4,575056
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tgsdk
|
|
Binary file
|