2. 衍生品与CTP基础
在进入行情接入与标准化实战之前,必须先建立两个基础认知:一是“衍生品到底是什么、它的价格从哪里来”,二是“CTP在整条链路中扮演什么角色、交易接口与行情接口各自负责什么”。很多接入问题表面上是代码或网络问题,本质上是对合约属性、接口定位理解不清导致的。
一、核心原理:衍生品的价值来自标的,合约是标准化的载体
衍生品(Derivative)是一类价值依附于标的资产(Underlying)的金融合约。期货与期权是最典型的两类。期货是双方约定在未来某一时间、以约定价格买卖一定数量标的的义务型合约;期权则是买方支付权利金后获得在未来买入或卖出标的的权利,卖方承担对应义务。理解这一点,对行情接入非常关键:你订阅的不是“一个价格”,而是一个带有合约乘数、交割月份、行权价、涨跌停等属性的结构化对象。
- 期货合约要素:合约代码、交易所、标的、合约乘数、最小变动价位、交割月份、最后交易日、保证金比例。
- 期权合约要素:在期货要素基础上,增加看涨/看跌方向(Call/Put)、行权价(Strike)、行权方式(美式/欧式)、到期日。
- 价格形成:期货价格由标的现货、持有成本、市场预期共同决定;期权价格还受波动率、剩余期限、无风险利率影响。
因此,行情接入的第一件事不是连服务器,而是把“合约元数据”与“实时行情”分开管理。合约元数据决定字段含义,实时行情决定字段取值,两者混在一起会导致后续标准化极其混乱。
二、CTP系统架构:行情与交易是两条并行的通道
CTP(Comprehensive Transaction Platform)是国内期货公司广泛使用的交易与行情接入平台。它对外提供两类核心接口:交易接口(Trader API)与行情接口(Md API)。很多初学者误以为“登录一次就能同时拿行情和下单”,实际上二者是独立的前置、独立的会话、独立的心跳与重连逻辑。
从架构上看,行情接口连接的是行情前置,交易接口连接的是交易前置。行情前置通常按交易所分片,提供快照与增量;交易前置则负责报单、撤单、查询与成交回报。二者共享的只有“经纪商代码、用户名、密码”等认证信息,但会话、心跳、重连、流控完全独立。
三、方法流程:从合约识别到行情落地的标准动作
接入CTP行情时,建议按以下顺序推进,避免“先连上再说”的混乱:
- 确认环境:区分生产、仿真、7×24测试环境,前置地址与经纪商代码不同。
- 登录行情:调用登录接口,成功后订阅行情。注意行情登录不校验资金账户。
- 订阅合约:按交易所+合约代码订阅,例如上期所螺纹钢
rb2510、大商所豆粕m2509。 - 接收快照:处理
OnRtnDepthMarketData回调,提取最新价、买卖盘、成交量、持仓量、时间戳。 - 标准化映射:将CTP字段映射到内部统一行情模型,补齐合约乘数、交易所、品种等元数据。
- 异常处理:断线重连、订阅恢复、时间戳乱序、涨跌停与空值处理。
下面是一段典型的行情登录与订阅伪代码,重点观察“登录”和“订阅”是两个独立动作:
// 行情API初始化
MdApi->RegisterFront("tcp://md.front.ctp.example.com:41213");
MdApi->Init();
// 登录请求
CThostFtdcReqUserLoginField req;
strcpy(req.BrokerID, "9999");
strcpy(req.UserID, "investor01");
strcpy(req.Password, "******");
MdApi->ReqUserLogin(&req, ++requestId);
// 登录成功后订阅
char* instruments[] = {"rb2510", "m2509", "cu2509"};
MdApi->SubscribeMarketData(instruments, 3);
// 行情回调
void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* p) {
// p->InstrumentID, p->LastPrice, p->BidPrice1, p->AskPrice1
// p->Volume, p->OpenInterest, p->UpdateTime, p->UpdateMillisec
}
四、案例与场景:期权行情接入的特殊性
以某商品期权为例,投资者需要同时订阅标的期货与对应期权合约。期权行情除了价格,还必须关注行权价、看涨看跌方向、隐含波动率、希腊值等字段。CTP行情接口本身不直接提供希腊值,需要接入方基于标的与期权价格自行计算或从其他数据源补充。这就体现了“行情接入”与“行情标准化”的分工:接口负责传输原始字段,标准化层负责补齐衍生指标与统一口径。
| 对比维度 | 行情接口 Md API | 交易接口 Trader API |
|---|---|---|
| 核心职责 | 推送行情快照与增量 | 报单、撤单、查询、回报 |
| 数据方向 | 服务端 → 客户端(只读) | 双向,含请求与回报 |
| 是否涉及资金 | 否 | 是,需资金账户认证 |
| 会话与心跳 | 独立会话,独立心跳 | 独立会话,独立心跳 |
| 典型回调 | OnRtnDepthMarketData | OnRtnOrder、OnRtnTrade |
| 断线影响 | 行情中断,需重新订阅 | 报单状态需查询确认 |
五、误区与复盘:三个高频错误
误区一:用交易接口拿行情。交易接口不推送行情快照,混淆二者会导致订阅失败或数据缺失。
误区二:忽略合约乘数与最小变动价位。不同品种乘数不同,直接拿价格做盈亏计算会放大或缩小真实风险。
误区三:断线后只重连不重订阅。行情会话恢复后,原有订阅关系通常不会自动恢复,必须重新调用订阅接口。
复盘建议:每次接入新环境,先做“最小闭环”——登录行情、订阅一个主力合约、打印一条完整快照、核对字段与交易所公布数据是否一致。这个动作能在十分钟内暴露大部分配置与理解问题。
理解衍生品的合约属性、CTP的双通道架构,以及交易接口与行情接口的定位差异,是后续行情标准化、字段映射与异常处理的前提。把“接口职责”与“数据职责”分开,接入工作会清晰很多。