用C++手把手教你连接SimNow期货模拟盘:从CTP API封装到第一个订单(附完整代码)

张开发
2026/4/20 9:41:01 15 分钟阅读

分享文章

用C++手把手教你连接SimNow期货模拟盘:从CTP API封装到第一个订单(附完整代码)
从零构建C期货交易系统SimNow连接与订单实战指南1. CTP API基础架构解析现代期货交易系统的核心在于稳定高效的API连接。CTPComprehensive Transaction Platform作为国内期货行业标准接口其C实现方案尤其值得深入探讨。让我们先解剖API的核心结构// 典型CTP接口类继承关系 class MyTraderSpi : public CThostFtdcTraderSpi { public: // 必须重写的回调接口 virtual void OnFrontConnected(); virtual void OnRspUserLogin(...); // ...其他回调方法 }; class MyMdSpi : public CThostFtdcMdSpi { public: // 行情回调接口 virtual void OnRtnDepthMarketData(...); };关键设计要点双通道设计交易接口(TraderApi)与行情接口(MdApi)物理分离工厂模式必须使用CreateFtdcTraderApi()而非直接new实例化事件驱动所有响应通过虚函数回调机制处理内存管理陷阱示例// 错误做法手动管理API实例 CThostFtdcTraderApi* api new CThostFtdcTraderApi(); // 正确做法使用工厂方法 CThostFtdcTraderApi* api CThostFtdcTraderApi::CreateFtdcTraderApi();2. SimNow环境配置详解SimNow作为官方模拟环境其配置参数与实盘存在关键差异参数项测试环境值生产环境值BrokerID9999各期货公司代码TradeFronttcp://180.168.146.187:10130期货公司提供MarketFronttcp://180.168.146.187:10131期货公司提供AuthCode0000000000000000公司专属认证码连接时序图要点交易时段09:00-15:00, 21:00-02:30使用主地址非交易时段自动切换历史行情回放模式每周五下午结算时段不可用3. 交易通道完整实现3.1 连接与认证流程分步骤实现可靠连接void TraderAdapter::Connect() { // 1. 创建API实例 m_api CThostFtdcTraderApi::CreateFtdcTraderApi(); // 2. 注册事件处理器 m_api-RegisterSpi(this); // 3. 设置前置地址 std::string frontAddr tcp:// config.tradeFront; m_api-RegisterFront(const_castchar*(frontAddr.c_str())); // 4. 订阅公私主题 m_api-SubscribePublicTopic(THOST_TERT_QUICK); m_api-SubscribePrivateTopic(THOST_TERT_QUICK); // 5. 初始化连接 m_api-Init(); }认证响应处理示例void TraderAdapter::OnRspAuthenticate(...) { if (pRspInfo pRspInfo-ErrorID ! 0) { // 认证失败处理 return; } // 构造登录请求 CThostFtdcReqUserLoginField req{}; strcpy(req.BrokerID, m_config.brokerId.c_str()); strcpy(req.UserID, m_config.userId.c_str()); strcpy(req.Password, m_config.password.c_str()); // 发送登录请求 int ret m_api-ReqUserLogin(req, m_requestId); }3.2 订单管理核心逻辑限价单实现示例int TraderAdapter::PlaceLimitOrder(const std::string instrument, double price, int volume, char direction) { CThostFtdcInputOrderField order{}; // 基础订单参数 strcpy(order.InstrumentID, instrument.c_str()); order.LimitPrice price; order.VolumeTotalOriginal volume; order.Direction direction; // 订单类型配置 order.OrderPriceType THOST_FTDC_OPT_LimitPrice; order.TimeCondition THOST_FTDC_TC_GFD; // 当日有效 order.VolumeCondition THOST_FTDC_VC_AV; // 任意数量 // 生成唯一订单引用 std::string orderRef GenerateOrderRef(); strcpy(order.OrderRef, orderRef.c_str()); return m_api-ReqOrderInsert(order, m_requestId); }订单状态机处理void TraderAdapter::OnRtnOrder(CThostFtdcOrderField *pOrder) { switch(pOrder-OrderStatus) { case THOST_FTDC_OST_AllTraded: // 全部成交处理 break; case THOST_FTDC_OST_PartTradedQueueing: // 部分成交处理 break; case THOST_FTDC_OST_Canceled: // 已撤单处理 break; // ...其他状态处理 } }4. 行情接收与处理4.1 行情订阅机制多合约订阅实现void MdAdapter::SubscribeInstruments( const std::vectorstd::string instruments) { // 转换CTP要求的格式 char** ppInstruments new char*[instruments.size()]; for(size_t i0; iinstruments.size(); i) { ppInstruments[i] const_castchar*(instruments[i].c_str()); } // 批量订阅 int ret m_api-SubscribeMarketData( ppInstruments, instruments.size()); delete[] ppInstruments; }4.2 深度行情解析典型行情数据结构处理void MdAdapter::OnRtnDepthMarketData( CThostFtdcDepthMarketDataField *pData) { MarketTick tick; tick.instrument pData-InstrumentID; tick.lastPrice pData-LastPrice; tick.volume pData-Volume; tick.openInterest pData-OpenInterest; // 买卖盘处理 for(int i0; i5; i) { tick.bid[i] pData-BidPrice[i]; tick.ask[i] pData-AskPrice[i]; tick.bidVolume[i] pData-BidVolume[i]; tick.askVolume[i] pData-AskVolume[i]; } // 触发行情事件 m_handler-OnMarketData(tick); }5. 实战问题排查指南常见连接问题及解决方案连接超时检查网络防火墙设置验证前置地址是否变更测试telnet端口连通性认证失败确认AuthCode与AppID匹配检查SIMNow账户状态验证系统时间同步订单被拒void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, ...) { if(pRspInfo pRspInfo-ErrorID ! 0) { // 记录错误详情 LOG_ERROR(Order rejected: pRspInfo-ErrorMsg); } }性能优化建议使用单独线程处理行情回调实现请求ID的原子性管理建立本地订单映射表// 线程安全的请求ID生成 std::atomicint requestId{0}; int GetNextRequestId() { return requestId; }实际开发中建议采用RAII管理API生命周期class CTraderApiWrapper { public: CTraderApiWrapper() { m_api CThostFtdcTraderApi::CreateFtdcTraderApi(); } ~CTraderApiWrapper() { m_api-RegisterSpi(nullptr); m_api-Release(); } private: CThostFtdcTraderApi* m_api; };

更多文章