# CTP 账户与交易数据

交易凭据仅在本地使用。先从期货公司获取交易前置、AppID 和 AuthCode，再创建 `CtpAccount`。SDK 登录后会自动确认当日结算。

## 创建账户并等待同步

```python
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(os.environ["EXSDK_TOKEN"], 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 账户同步未在预期时间内完成")
    print("可用资金", funds.data().available)
    print("持仓映射", positions.data())
```

六个账户字段均必填、非空、不能包含 NUL。前置地址必须以 `tcp://` 开头；不要填入行情前置代替交易前置。

## 交易状态

| 状态 | 含义与操作 |
| --- | --- |
| `SYNCING` | 首次登录或重连后同步中，尚不能提交委托 |
| `READY` | 登录及一致性同步完成，可提交委托，但不保证资金或行情是即时值 |
| `DISCONNECTED` | CTP 连接中断，旧快照仍保留，不作为当前状态 |
| `ERROR` | 无法自动恢复，需要处理错误并新建 ExApi |

`trading_status()` 读取最近发布状态，不主动查询。资金默认每 5 秒安排刷新，实际到达可能更晚。一次成交引起的订单成交量、成交和持仓更新会在同一轮发布，资金更新可能在后续轮次才到达。

## 只读映射的正确访问

```python
positions = api.watch_position(symbol)
orders = api.watch_order(symbol)
trades = api.watch_trade(symbol)

# 上述创建动作放在循环之前。
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)
```

持仓按合约代码索引，订单按本地 `order_id` 索引，成交按 CTP `TradeID` 索引。即使指定单个合约，`data()` 仍返回 Mapping。可提前观察尚无持仓的合约；持仓归零后仍保留对象。

订单与成交只包含当前交易日普通投机记录，包括同一账户其他客户端产生的记录。字段含义、未知值和单位详见 [数据字典](./data-reference.md)。

## 断线与同步

重连期间不发布部分查询结果；恢复 `READY` 后提交一致快照。`data()` 不会因断线自动清空，但旧数据不能表示当前账户状态。在非 READY 时本地下单拒绝通过返回结果说明，不改写订单快照。
