接入前准备:
- 向期货公司获取交易前置、AppID 和 AuthCode;交易密码及这些配置仅在本地使用。
- 在个人中心绑定与
CtpAccount.user_id一致的期货账号。仅使用行情无需绑定。 - 创建
CtpAccount,通过更新循环等待账户同步。SDK 登录后会自动确认当日结算。
创建账户并等待同步#
示例从本地环境变量读取六项 CTP 配置,将 YOUR_TOKEN 替换为自己的令牌后运行:
import os
import time
from exsdk import ExApi, CtpAccount
account = CtpAccount(
broker_id=os.environ["CTP_BROKER_ID"],
user_id=os.environ["CTP_USER_ID"],
password=os.environ["CTP_PASSWORD"],
front_url=os.environ["CTP_FRONT_URL"],
app_id=os.environ["CTP_APP_ID"],
auth_code=os.environ["CTP_AUTH_CODE"],
)
with ExApi(token="YOUR_TOKEN", account=account) as api:
funds = api.watch_account()
positions = api.watch_position()
orders = api.watch_order()
trades = api.watch_trade()
deadline = time.time() + 60
while api.trading_status() != "READY":
if not api.wait_update(deadline=deadline):
raise TimeoutError("CTP synchronization timed out")
print("可用资金", funds.data().available)
print("持仓映射", positions.data())前置地址必须以 tcp:// 开头,不能用行情前置代替交易前置。账户字段约束见 CtpAccount。
交易状态#
| 状态 | 含义与操作 |
|---|---|
SYNCING | 首次登录或重连后同步中,尚不能提交委托 |
READY | 登录及一致性同步完成,可提交委托,但不保证资金或行情是即时值 |
DISCONNECTED | CTP 连接中断,旧快照仍保留,不作为当前状态 |
ERROR | 无法自动恢复,需要处理错误并新建 ExApi |
trading_status() 读取最近发布状态,不主动查询。
- 资金刷新:默认每 5 秒安排一次,实际到达可能更晚。
- 成交发布:同一笔成交引起的订单成交量、成交和持仓更新在同一轮发布,资金更新可能在后续轮次才到达。
判断资金是否刷新#
金额不变时,funds.is_changing() 可能为 False。要知道是否完成了新一次资金查询,检查查询完成时间:
while api.wait_update():
if api.trading_status() != "READY":
continue
if funds.is_changing("updated_at"):
current = funds.data()
print("查询完成时间", current.updated_at, "可用资金", current.available)此循环沿用已创建的 funds,替换其他更新循环。updated_at 是本地完成查询的 Unix 毫秒时间,不是行情时间或柜台保证的资金变动时刻;使用资金前仍应检查字段是否为 None。
只读映射的正确访问#
positions = api.watch_position(symbol)
orders = api.watch_order(symbol)
trades = api.watch_trade(symbol)
# Create watches before entering the update loop.
while api.wait_update():
if api.trading_status() != "READY":
continue
position = positions.data().get(symbol)
if position is not None:
print(position.pos_long, position.available_long)
for order_id, order in orders.data().items():
print(order_id, order.status)
for trade_id, trade in trades.data().items():
print(trade_id, trade.price, trade.volume)| 观察数据 | Mapping 索引 |
|---|---|
| 持仓 | 合约代码 |
| 订单 | 本地 order_id |
| 成交 | CTP TradeID |
即使指定单个合约,data() 仍返回 Mapping。可提前观察尚无持仓的合约;持仓归零后仍保留对象。
数据范围与策略归属#
订单与成交只包含当前交易日普通投机记录,包括同一账户其他客户端产生的记录。按合约筛选不能区分策略;本策略应跟踪自己的订单号及业务关联,见 订单跟踪与重启。
SDK 不另行持久化订单、成交与持仓,不提供跨交易日历史交易账本。应用需要留存交易记录时自行保存。字段含义、未知值和单位详见 数据字典。
断线与同步#
重连期间不发布部分查询结果;恢复 READY 后提交一致快照。
data()不会因断线自动清空,但旧数据不能表示当前账户状态。- 恢复
READY后重新读取订单、成交和持仓,核对未结束委托,再恢复交易决策。断线和同步期间旧快照不能作为新交易的依据。
无法恢复时按 错误处理 检查配置和异常;不要把重建实例当作委托未提交或已撤销的证明。