CTP期货行情接口使用笔记

CTP开发文档


期货行情订阅


使用流程

  • 创建继承自 CThostFtdcMdSpi 的类
  • 通过 CThostFtdcMdApi::CreateFtdcMdApi() 创建api对象
  • 将spi对象通过 RegisterSpi() 注册给api对象
  • 通过 RegisterFront() 函数向api对象注册行情前置地址
  • 调用api对象的 init() 接口完成初始化
  • 当与行情前置连接成功后,可以使用api对象的 ReqUserLogin() 接口来进行登录
  • 登录成功后即可通过api对象的 SubscribeMarketData() 接口进行订阅操作
  • 使用api对象的 ReqUserLogout() 函数来退出登录
  • 使用api对象的 Release() 函数来释放CTP资源
  • 使用api对象的 join() 函数等待线程退出

Demo开发注意事项

  1. 实现spi接口类

    继承类 CThostFtdcMdSpi 中的虚函数,我们可以根据具体需要来选择实现

    • OnFrontConnected 客户端到行情前置的无身份验证连接建立之后,这个函数会被调用,用于说明连接已经建立。连接建立之后,才能请求登录
    • OnFrontDisconnected 如果客户端到行情前置的无身份验证连接建立失败,这个函数被调用,其中的参数说明连接失败的原因
    • OnRspUserLogin 交易系统对客户端的请求登录消息作出的响应
    • OnRspSubMarketData 交易核心对客户端请求订阅行情的消息处理结果回应,包含错误代码及原因
    • OnRspUnSubMarketData 交易核心对客户端请求退订行情的消息处理结果回应,包含错误代码及原因
    • OnRtnDepthMarketData 通过这个函数返回行情信息,频率是每秒两次
    • OnRspError 如果交易系统无法识别客户端发送的请求消息,就通过这个函数返回错误信息
    • OnHeartBeatWarning 如果超过一定时间在客户端和系统之间没有任何消息交换发生,这个函数会发送心跳用来说明客户端到系统服务器之间的连接是活跃的
  2. 行情接口的初始化

    // 创建api对象
    CThostFtdcMdApi *api = CThostFtdcMdApi::CreateFtdcMdApi();
    // 创建spi对象,CMySpi继承自CThostFtdcMdSpi
    CMySpi *spi = new CMySpi();
    // 将spi注册给api
    api->RegisterSpi(spi);
    注册期货行情前置地址
    api->RegisterFront("tcp://127.0.0.1:17001");
    // 初始化,并向期货行情前置发起无身份验证连接
    api->init();
  3. 登录系统

    // 上面调用api的 `init()` 后,会想前置发起连接
    // 连接成功后,会回调 `OnFrontConnected()`
    // 如果连接失败,则回调 `OnFrontDisconnected`
    // 连接成功后,就可以进行登录
    
    CThostFtdcReqUserLoginField field;
    memset(&field, 0, sizeof(field));
    // BROKER_ID 是期货公司的会员号
    strcpy(field.BrokerID, BROKER_ID);
    // INVESTOR_ID 是投资者在该期货公司的客户号
    strcpy(field.UserID, INVESTOR_ID);
    // PASSWORD 是该投资者密码
    strcpy(field.Password, PASSWORD);
    strcpy(field.UserProductInfo, UserProductInfo);
    // 该函数返回一个整数值,标志请求是否被发送出去,而不是是否已经被服务端处理
    // 0 发送成功
    // -1 因网络原因发送失败
    // -2 未处理请求队列总数量超限
    // -3 每秒发送请求数量超限
    int ret = api->ReqUserLogin(&field, 0);

    服务器通过 OnRspUserLogin() 对该登录请求做出响应

    virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin,
        CThostFtdcRspInfoField *pRspInfo, /*该结构中的ErrorID为0表示登录成功,否则失败;ErrorMsg表示错误信息*/
        int nRequestID,
        bool bIsLast);
  4. 订阅行情

    // 登录成功才可以订阅
    // nameArray 合约名称数组
    // count 数组大小
    int ret = SubscribeMarketData(nameArray, count);

    发送订阅后,回调spi的 OnRspSubMarketData 进行处理响应

    ///订阅行情应答
    virtual void OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument,
        CThostFtdcRspInfoField *pRspInfo, /*服务端给的错误响应信息,如果没有错误,ErrorMsg内容为 "CTP:No Error" */
        int nRequestID,
        bool bIsLast);

    成功订阅的行情数据,通过回调spi的 OnRtnDepthMarketData 来返回

    ///深度行情通知
    ///频率是每秒两次
    virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData);
  5. 退出登录及取消订阅

    ///退订行情。
    /// ppInstrumentID 合约ID  
    /// nCount 要订阅/退订行情的合约个数
    virtual int UnSubscribeMarketData(char *ppInstrumentID[], int nCount) = 0;
    ///登出请求
    virtual int ReqUserLogout(CThostFtdcUserLogoutField *pUserLogout, int nRequestID) = 0;

    退订行情和取消登录的处理与上述的类似,也是回调相应spi的虚函数接口

    注意:目前,通过ReqUserLogout登出系统的话,会先将现有的连接断开。客户端重新登录后系统会再重新建立一个新的连接,而SessionID会被重置,因此MaxOrderRef一般也会重新从0计数。

  6. 断线重连

    客户端与服务端断开连接时,函数 OnFrontDisconnected 被调用,其中的参数nReason描述了断线的原因。

    • 0x1001 网络读失败
    • 0x1002 网络写失败
    • 0x2001 读心跳超时
    • 0x2002 发送心跳超时
    • 0x2003 收到不能识别的错误消息

    客户端与服务端的连接断开有两种情况

    • 网络原因导致连接断开
    • 服务端主动断开连接

    服务器主动断开连接有两种可能

    • 客户端长时间没有从服务端接收报文,时间超时
    • 客户端建立的连接数超过限制

    超时

    • 网络超时会导致服务端主动与客户端断开连接
    • 默认的读超时为:120 秒,写超时为:60 秒,心跳超时为:80 秒
    • 客户端与服务端连接断开后,交易接口会自动尝试重新连接,频率是每5 秒一次

你可能感兴趣的:(金融开发库)