概述
CTP的接入Demo
详细
代码下载:http://www.demodashi.com/demo/14125.html
本文档不介绍CTP的具体流程,具体流程请参考上海期货交易所文档下载).
一、概述
1.CTP是上期技术,提供的国内期货行情和交易的接口,自推出以来,各大券商均架设了CTP技术的接入,引入策略算法便可以初步形成一个自动交易的系统,这也就吸引了很多对自动交易,策略交易感兴趣的各路高人来使用。
2.CTP难点在于,一个库提供了行情和交易两套接口,各自均有一套业务流程,而且两者在业务上还存在部分业务关联,也就是说还要处理两套之间的业务同步问题,没有一些C++基础的人很难开发好用的CTP库。
3.本Demo目标是,在Windows环境下做两个程序:
一个封装CTP行情和交易接口成一个库,尽可能在高内聚低耦合的情况下,保持代码清晰,通俗尽可能让;
一个执行程序很容易的去调用这个库,这里没有使用MFC或QT,直接采用控制台程序,很清晰的展示使用库。
二、准备环境
1.开发工具:visual studio 2015或以上版本(下载)
本Demo采用Visual studio 2015 专业版 update 3
Windows7 64位
2.下载上期CTP库(下载)
综合交易平台API下载,下载列表中的windows下64位库(最新2015-05-15)),解压如下:
3.申请模拟账号申请)
主页右上角,注册账号,例子中方便开箱即用,会使用我自己申请好的,请自行换成自己的帐号。
三、程序介绍
1.先看下Demo的运行效果。
2.程序目录结构
①Show all files模式下,VS工程目录结构如下图:
共两个项目,CTPSample和CTPServer,CTPSample为封装交易所CTP的动态库,CTPServer为使用库的UI程序。
②代码目录结构
bin64
—–CTP CTP产生的共享文件
—–Log 日志文件
config.cfg 配置文件
build
CTPServer.sln 存放工程文件
Src
——CTPSample DLL代码
——CTPServer UI代码
——Framwork 框架代码,避免复杂,不做公开(这里主要提供日志,数据定义,可自己替换)
说明:confg.cfg主要保存了CTP的地址其他均为非本Demo演示的主要功能):
[info]
CTPFront.trade1 = tcp://180.168.146.187:10030
CTPFront.quote1 = tcp://180.168.146.187:10031
CTPFront.trade2 = tcp://180.168.146.187:10001
CTPFront.quote2 = tcp://180.168.146.187:10011
CTPFront.trade3 = tcp://218.202.237.33:10002
CTPFront.quote3 = tcp://ctp1-md11.citicsf.com:41213
3.模块介绍
CTPSample模块
CTPBase.h 动态库的导出定义
MyCTPQuote.h/MyCTPQuote.CPP 交易的封装
MyCTPQuote.h/MyCTPQuote.cpp 行情的封装
CTPServer模块
TradeManager.h/TradeManager.cpp UI主逻辑
CTPServer.cpp main启动
四、程序解析
1. CTPSample模块之MyCTPQuote.h
//定义一个管理器,管理行情接受 class CTPSAMPLE_EXPORT MyCTPQuote { //嵌入行情回报类 class MyRecv : public CThostFtdcMdSpi { public: MyRecv):m_Parentnullptr) {}; ~MyRecv) {}; void BindMyCTPQuote *Parent) { m_Parent = Parent; } public: ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 virtual void OnFrontConnected) { m_Parent->OnFrontConnected); } ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 ///@param nReason 错误原因 /// 0x1001 网络读失败 /// 0x1002 网络写失败 /// 0x2001 接收心跳超时 /// 0x2002 发送心跳失败 /// 0x2003 收到错误报文 virtual void OnFrontDisconnectedint nReason) { m_Parent->OnFrontDisconnectednReason); } ///心跳超时警告。当长时间未收到报文时,该方法被调用。 ///@param nTimeLapse 距离上次接收报文的时间 virtual void OnHeartBeatWarningint nTimeLapse) { m_Parent->OnHeartBeatWarningnTimeLapse); } ///登录请求响应 virtual void OnRspUserLoginCThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspUserLoginpRspUserLogin, pRspInfo, nRequestID, bIsLast); } ///登出请求响应 virtual void OnRspUserLogoutCThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspUserLogoutpUserLogout, pRspInfo, nRequestID, bIsLast); } ///错误应答 virtual void OnRspErrorCThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspErrorpRspInfo, nRequestID, bIsLast); } ///订阅行情应答 virtual void OnRspSubMarketDataCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspSubMarketDatapSpecificInstrument, pRspInfo, nRequestID, bIsLast); } ///取消订阅行情应答 virtual void OnRspUnSubMarketDataCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspUnSubMarketDatapSpecificInstrument, pRspInfo, nRequestID, bIsLast); } ///订阅询价应答 virtual void OnRspSubForQuoteRspCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspSubForQuoteRsppSpecificInstrument, pRspInfo, nRequestID, bIsLast); } ///取消订阅询价应答 virtual void OnRspUnSubForQuoteRspCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspUnSubForQuoteRsppSpecificInstrument, pRspInfo, nRequestID, bIsLast); } ///深度行情通知 virtual void OnRtnDepthMarketDataCThostFtdcDepthMarketDataField *pDepthMarketData) { m_Parent->OnRtnDepthMarketDatapDepthMarketData); } ///询价通知 virtual void OnRtnForQuoteRspCThostFtdcForQuoteRspField *pForQuoteRsp) { m_Parent->OnRtnForQuoteRsppForQuoteRsp); } public: MyCTPQuote *m_Parent; }; //thread public: MyCTPQuote ); ~MyCTPQuote); void setMainWidgetvoid *widget); // 订阅广播报文 void SubscribeCPacketReceiver *pPacketReceiver); // 取消广播报文订阅 void UnsubscribeCPacketReceiver *pPacketReceiver); static MyCTPQuote *Instance); void Initconst char *User, const char *pswd, const char *broker, const char *pszAddress); void FinishQryInstrument); void setLogconst string& str); bool m_bLoginSuccessed; public: ///////////////////////////////////////请求类函数,提供主要逻辑,供外部使用//////////////////////////////////////////////////////////////////////////// ///用户登录请求 int ReqUserLoginCThostFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) { return m_reqApi->ReqUserLoginpReqUserLoginField, nRequestID ); } ///登出请求 int ReqUserLogoutCThostFtdcUserLogoutField *pUserLogout, int nRequestID) { return m_reqApi->ReqUserLogoutpUserLogout, nRequestID); } ///获取当前交易日 ///@retrun 获取到的交易日 ///@remark 只有登录成功后,才能得到正确的交易日 const char *GetTradingDay) { return m_reqApi->GetTradingDay); } ///订阅行情。 ///@param ppInstrumentID 合约ID ///@param nCount 要订阅/退订行情的合约个数 ///@remark int SubscribeMarketDatachar *ppInstrumentID[], int nCount) { return m_reqApi->SubscribeMarketDatappInstrumentID, nCount); } ///退订行情。 ///@param ppInstrumentID 合约ID ///@param nCount 要订阅/退订行情的合约个数 ///@remark int UnSubscribeMarketDatachar *ppInstrumentID[], int nCount) { return m_reqApi->UnSubscribeMarketDatappInstrumentID, nCount); } public: ///////////////////////////////////////回报类函数,收到数据,更新本地行情信息//////////////////////////////////////////////////////////////////////////// ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 void OnFrontConnected); ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 ///@param nReason 错误原因 /// 0x1001 网络读失败 /// 0x1002 网络写失败 /// 0x2001 接收心跳超时 /// 0x2002 发送心跳失败 /// 0x2003 收到错误报文 void OnFrontDisconnectedint nReason); ///心跳超时警告。当长时间未收到报文时,该方法被调用。 ///@param nTimeLapse 距离上次接收报文的时间 void OnHeartBeatWarningint nTimeLapse); ///登录请求响应 void OnRspUserLoginCThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///登出请求响应 void OnRspUserLogoutCThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///错误应答 void OnRspErrorCThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///订阅行情应答 void OnRspSubMarketDataCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///取消订阅行情应答 void OnRspUnSubMarketDataCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///订阅询价应答 void OnRspSubForQuoteRspCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///取消订阅询价应答 void OnRspUnSubForQuoteRspCThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///深度行情通知 void OnRtnDepthMarketDataCThostFtdcDepthMarketDataField *pDepthMarketData); ///询价通知 void OnRtnForQuoteRspCThostFtdcForQuoteRspField *pForQuoteRsp); private: CThostFtdcMdApi* m_reqApi; MyRecv *m_RecvSpi; map<string /*InstrumentID*/, CThostFtdcInstrumentField> m_mapInstrument;//合约ID,合约信息 map<string /*InstrumentID*/,CThostFtdcDepthMarketDataField /*Quotation*/> m_mapInstrumentQuote;//保存 合约ID-最新行情 对,合约ID唯一。 vector<string /*InstrumentID*/> m_vecInstrumentId;//合约ID int requestID; string m_TradingDay; int m_session ; int m_frontId ; string OrderRef ; mutex m_mutex; ///用户登录信息 CThostFtdcReqUserLoginField *m_userLoginInfo; bool m_bQryInstrumentOK; //用于给上层订阅 typedef vector<CPacketReceiver*> VPKTRECEIVER; VPKTRECEIVER m_vPketReceiver; };
主要功能点:
①模块管理:
CTP的行情模块分两块,一个是同步查询API(CThostFtdcMdApi),一个是异步回报API(CThostFtdcMdSpi),这里定义了一个包装类,来管理这两类API,即
MyRecv来封装CThostFtdcMdSpi,CThostFtdcMdApi直接使用。
②给UI回报接口
本模块提供给上层的接口,定义了一个虚基类:
class CPacketReceiver { public: virtual void ReceiveCBroadcastPacket &pkt) = 0; }; 这里运用到actor模式,接受UI订阅: typedef vector<CPacketReceiver*> VPKTRECEIVER; VPKTRECEIVER m_vPketReceiver;
③数据保存
数据收集,定义几个map
map<string /*InstrumentID*/, CThostFtdcInstrumentField> m_mapInstrument;//合约ID,合约信息 map<string /*InstrumentID*/,CThostFtdcDepthMarketDataField /*Quotation*/> m_mapInstrumentQuote;//保存 合约ID-最新行情 对,合约ID唯一。 vector<string /*InstrumentID*/> m_vecInstrumentId;//合约ID
2. CTPSample模块之MyCTPTrade.h
//定义一个管理器,管理行情接受 class CTPSAMPLE_EXPORT MyCTPTrade { //嵌入行情回报类 class MyRecv : public CThostFtdcTraderSpi { public: MyRecv):m_Parentnullptr), m_nRequestId0){}; ~MyRecv) {}; void BindMyCTPTrade *Parent) { m_Parent = Parent; } public: ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 virtual void OnFrontConnected) { m_Parent->OnFrontConnected); } ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 ///@param nReason 错误原因 /// 0x1001 网络读失败 /// 0x1002 网络写失败 /// 0x2001 接收心跳超时 /// 0x2002 发送心跳失败 /// 0x2003 收到错误报文 virtual void OnFrontDisconnectedint nReason) { m_Parent->OnFrontDisconnectednReason); } ///客户端认证响应 virtual void OnRspAuthenticateCThostFtdcRspAuthenticateField *pRspAuthenticateField, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspAuthenticatepRspAuthenticateField,pRspInfo, nRequestID, bIsLast); } ///心跳超时警告。当长时间未收到报文时,该方法被调用。 ///@param nTimeLapse 距离上次接收报文的时间 virtual void OnHeartBeatWarningint nTimeLapse) { m_Parent->OnHeartBeatWarningnTimeLapse); } ///登录请求响应 virtual void OnRspUserLoginCThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspUserLoginpRspUserLogin, pRspInfo, nRequestID, bIsLast); } ///登出请求响应 virtual void OnRspUserLogoutCThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspUserLogoutpUserLogout, pRspInfo, nRequestID, bIsLast); } ///错误应答 virtual void OnRspErrorCThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {m_Parent->OnRspErrorpRspInfo, nRequestID, bIsLast);} /* ///用户口令更新请求响应 virtual void OnRspUserPasswordUpdateCThostFtdcUserPasswordUpdateField *pUserPasswordUpdate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///资金账户口令更新请求响应 virtual void OnRspTradingAccountPasswordUpdateCThostFtdcTradingAccountPasswordUpdateField *pTradingAccountPasswordUpdate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///报单录入请求响应 virtual void OnRspOrderInsertCThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///预埋单录入请求响应 virtual void OnRspParkedOrderInsertCThostFtdcParkedOrderField *pParkedOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///预埋撤单录入请求响应 virtual void OnRspParkedOrderActionCThostFtdcParkedOrderActionField *pParkedOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///报单操作请求响应 virtual void OnRspOrderActionCThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///查询最大报单数量响应 virtual void OnRspQueryMaxOrderVolumeCThostFtdcQueryMaxOrderVolumeField *pQueryMaxOrderVolume, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///投资者结算结果确认响应 virtual void OnRspSettlementInfoConfirmCThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///删除预埋单响应 virtual void OnRspRemoveParkedOrderCThostFtdcRemoveParkedOrderField *pRemoveParkedOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///删除预埋撤单响应 virtual void OnRspRemoveParkedOrderActionCThostFtdcRemoveParkedOrderActionField *pRemoveParkedOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///执行宣告录入请求响应 virtual void OnRspExecOrderInsertCThostFtdcInputExecOrderField *pInputExecOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///执行宣告操作请求响应 virtual void OnRspExecOrderActionCThostFtdcInputExecOrderActionField *pInputExecOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///询价录入请求响应 virtual void OnRspForQuoteInsertCThostFtdcInputForQuoteField *pInputForQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///报价录入请求响应 virtual void OnRspQuoteInsertCThostFtdcInputQuoteField *pInputQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///报价操作请求响应 virtual void OnRspQuoteActionCThostFtdcInputQuoteActionField *pInputQuoteAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///批量报单操作请求响应 virtual void OnRspBatchOrderActionCThostFtdcInputBatchOrderActionField *pInputBatchOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///期权自对冲录入请求响应 virtual void OnRspOptionSelfCloseInsertCThostFtdcInputOptionSelfCloseField *pInputOptionSelfClose, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///期权自对冲操作请求响应 virtual void OnRspOptionSelfCloseActionCThostFtdcInputOptionSelfCloseActionField *pInputOptionSelfCloseAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///申请组合录入请求响应 virtual void OnRspCombActionInsertCThostFtdcInputCombActionField *pInputCombAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询报单响应 virtual void OnRspQryOrderCThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询成交响应 virtual void OnRspQryTradeCThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资者持仓响应 virtual void OnRspQryInvestorPositionCThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询资金账户响应 virtual void OnRspQryTradingAccountCThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资者响应 virtual void OnRspQryInvestorCThostFtdcInvestorField *pInvestor, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询交易编码响应 virtual void OnRspQryTradingCodeCThostFtdcTradingCodeField *pTradingCode, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询合约保证金率响应 virtual void OnRspQryInstrumentMarginRateCThostFtdcInstrumentMarginRateField *pInstrumentMarginRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询合约手续费率响应 virtual void OnRspQryInstrumentCommissionRateCThostFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询交易所响应 virtual void OnRspQryExchangeCThostFtdcExchangeField *pExchange, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询产品响应 virtual void OnRspQryProductCThostFtdcProductField *pProduct, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; */ ///请求查询合约响应 virtual void OnRspQryInstrumentCThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { m_Parent->OnRspQryInstrumentpInstrument, pRspInfo, nRequestID, bIsLast); }; /* ///请求查询行情响应 virtual void OnRspQryDepthMarketDataCThostFtdcDepthMarketDataField *pDepthMarketData, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资者结算结果响应 virtual void OnRspQrySettlementInfoCThostFtdcSettlementInfoField *pSettlementInfo, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询转帐银行响应 virtual void OnRspQryTransferBankCThostFtdcTransferBankField *pTransferBank, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资者持仓明细响应 virtual void OnRspQryInvestorPositionDetailCThostFtdcInvestorPositionDetailField *pInvestorPositionDetail, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询客户通知响应 virtual void OnRspQryNoticeCThostFtdcNoticeField *pNotice, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询结算信息确认响应 virtual void OnRspQrySettlementInfoConfirmCThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资者持仓明细响应 virtual void OnRspQryInvestorPositionCombineDetailCThostFtdcInvestorPositionCombineDetailField *pInvestorPositionCombineDetail, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///查询保证金监管系统经纪公司资金账户密钥响应 virtual void OnRspQryCFMMCTradingAccountKeyCThostFtdcCFMMCTradingAccountKeyField *pCFMMCTradingAccountKey, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询仓单折抵信息响应 virtual void OnRspQryEWarrantOffsetCThostFtdcEWarrantOffsetField *pEWarrantOffset, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资者品种/跨品种保证金响应 virtual void OnRspQryInvestorProductGroupMarginCThostFtdcInvestorProductGroupMarginField *pInvestorProductGroupMargin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询交易所保证金率响应 virtual void OnRspQryExchangeMarginRateCThostFtdcExchangeMarginRateField *pExchangeMarginRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询交易所调整保证金率响应 virtual void OnRspQryExchangeMarginRateAdjustCThostFtdcExchangeMarginRateAdjustField *pExchangeMarginRateAdjust, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询汇率响应 virtual void OnRspQryExchangeRateCThostFtdcExchangeRateField *pExchangeRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询二级代理操作员银期权限响应 virtual void OnRspQrySecAgentACIDMapCThostFtdcSecAgentACIDMapField *pSecAgentACIDMap, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询产品报价汇率 virtual void OnRspQryProductExchRateCThostFtdcProductExchRateField *pProductExchRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询产品组 virtual void OnRspQryProductGroupCThostFtdcProductGroupField *pProductGroup, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询做市商合约手续费率响应 virtual void OnRspQryMMInstrumentCommissionRateCThostFtdcMMInstrumentCommissionRateField *pMMInstrumentCommissionRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询做市商期权合约手续费响应 virtual void OnRspQryMMOptionInstrCommRateCThostFtdcMMOptionInstrCommRateField *pMMOptionInstrCommRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询报单手续费响应 virtual void OnRspQryInstrumentOrderCommRateCThostFtdcInstrumentOrderCommRateField *pInstrumentOrderCommRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询资金账户响应 virtual void OnRspQrySecAgentTradingAccountCThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询二级代理商资金校验模式响应 virtual void OnRspQrySecAgentCheckModeCThostFtdcSecAgentCheckModeField *pSecAgentCheckMode, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询期权交易成本响应 virtual void OnRspQryOptionInstrTradeCostCThostFtdcOptionInstrTradeCostField *pOptionInstrTradeCost, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询期权合约手续费响应 virtual void OnRspQryOptionInstrCommRateCThostFtdcOptionInstrCommRateField *pOptionInstrCommRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询执行宣告响应 virtual void OnRspQryExecOrderCThostFtdcExecOrderField *pExecOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询询价响应 virtual void OnRspQryForQuoteCThostFtdcForQuoteField *pForQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询报价响应 virtual void OnRspQryQuoteCThostFtdcQuoteField *pQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询期权自对冲响应 virtual void OnRspQryOptionSelfCloseCThostFtdcOptionSelfCloseField *pOptionSelfClose, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询投资单元响应 virtual void OnRspQryInvestUnitCThostFtdcInvestUnitField *pInvestUnit, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询组合合约安全系数响应 virtual void OnRspQryCombInstrumentGuardCThostFtdcCombInstrumentGuardField *pCombInstrumentGuard, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询申请组合响应 virtual void OnRspQryCombActionCThostFtdcCombActionField *pCombAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询转帐流水响应 virtual void OnRspQryTransferSerialCThostFtdcTransferSerialField *pTransferSerial, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询银期签约关系响应 virtual void OnRspQryAccountregisterCThostFtdcAccountregisterField *pAccountregister, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///报单通知 virtual void OnRtnOrderCThostFtdcOrderField *pOrder) {}; ///成交通知 virtual void OnRtnTradeCThostFtdcTradeField *pTrade) {}; ///报单录入错误回报 virtual void OnErrRtnOrderInsertCThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo) {}; ///报单操作错误回报 virtual void OnErrRtnOrderActionCThostFtdcOrderActionField *pOrderAction, CThostFtdcRspInfoField *pRspInfo) {}; ///合约交易状态通知 virtual void OnRtnInstrumentStatusCThostFtdcInstrumentStatusField *pInstrumentStatus) {}; ///交易所公告通知 virtual void OnRtnBulletinCThostFtdcBulletinField *pBulletin) {}; ///交易通知 virtual void OnRtnTradingNoticeCThostFtdcTradingNoticeInfoField *pTradingNoticeInfo) {}; ///提示条件单校验错误 virtual void OnRtnErrorConditionalOrderCThostFtdcErrorConditionalOrderField *pErrorConditionalOrder) {}; ///执行宣告通知 virtual void OnRtnExecOrderCThostFtdcExecOrderField *pExecOrder) {}; ///执行宣告录入错误回报 virtual void OnErrRtnExecOrderInsertCThostFtdcInputExecOrderField *pInputExecOrder, CThostFtdcRspInfoField *pRspInfo) {}; ///执行宣告操作错误回报 virtual void OnErrRtnExecOrderActionCThostFtdcExecOrderActionField *pExecOrderAction, CThostFtdcRspInfoField *pRspInfo) {}; ///询价录入错误回报 virtual void OnErrRtnForQuoteInsertCThostFtdcInputForQuoteField *pInputForQuote, CThostFtdcRspInfoField *pRspInfo) {}; ///报价通知 virtual void OnRtnQuoteCThostFtdcQuoteField *pQuote) {}; ///报价录入错误回报 virtual void OnErrRtnQuoteInsertCThostFtdcInputQuoteField *pInputQuote, CThostFtdcRspInfoField *pRspInfo) {}; ///报价操作错误回报 virtual void OnErrRtnQuoteActionCThostFtdcQuoteActionField *pQuoteAction, CThostFtdcRspInfoField *pRspInfo) {}; ///询价通知 virtual void OnRtnForQuoteRspCThostFtdcForQuoteRspField *pForQuoteRsp) {}; ///保证金监控中心用户令牌 virtual void OnRtnCFMMCTradingAccountTokenCThostFtdcCFMMCTradingAccountTokenField *pCFMMCTradingAccountToken) {}; ///批量报单操作错误回报 virtual void OnErrRtnBatchOrderActionCThostFtdcBatchOrderActionField *pBatchOrderAction, CThostFtdcRspInfoField *pRspInfo) {}; ///期权自对冲通知 virtual void OnRtnOptionSelfCloseCThostFtdcOptionSelfCloseField *pOptionSelfClose) {}; ///期权自对冲录入错误回报 virtual void OnErrRtnOptionSelfCloseInsertCThostFtdcInputOptionSelfCloseField *pInputOptionSelfClose, CThostFtdcRspInfoField *pRspInfo) {}; ///期权自对冲操作错误回报 virtual void OnErrRtnOptionSelfCloseActionCThostFtdcOptionSelfCloseActionField *pOptionSelfCloseAction, CThostFtdcRspInfoField *pRspInfo) {}; ///申请组合通知 virtual void OnRtnCombActionCThostFtdcCombActionField *pCombAction) {}; ///申请组合录入错误回报 virtual void OnErrRtnCombActionInsertCThostFtdcInputCombActionField *pInputCombAction, CThostFtdcRspInfoField *pRspInfo) {}; ///请求查询签约银行响应 virtual void OnRspQryContractBankCThostFtdcContractBankField *pContractBank, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询预埋单响应 virtual void OnRspQryParkedOrderCThostFtdcParkedOrderField *pParkedOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询预埋撤单响应 virtual void OnRspQryParkedOrderActionCThostFtdcParkedOrderActionField *pParkedOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询交易通知响应 virtual void OnRspQryTradingNoticeCThostFtdcTradingNoticeField *pTradingNotice, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询经纪公司交易参数响应 virtual void OnRspQryBrokerTradingParamsCThostFtdcBrokerTradingParamsField *pBrokerTradingParams, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询经纪公司交易算法响应 virtual void OnRspQryBrokerTradingAlgosCThostFtdcBrokerTradingAlgosField *pBrokerTradingAlgos, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///请求查询监控中心用户令牌 virtual void OnRspQueryCFMMCTradingAccountTokenCThostFtdcQueryCFMMCTradingAccountTokenField *pQueryCFMMCTradingAccountToken, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///银行发起银行资金转期货通知 virtual void OnRtnFromBankToFutureByBankCThostFtdcRspTransferField *pRspTransfer) {}; ///银行发起期货资金转银行通知 virtual void OnRtnFromFutureToBankByBankCThostFtdcRspTransferField *pRspTransfer) {}; ///银行发起冲正银行转期货通知 virtual void OnRtnRepealFromBankToFutureByBankCThostFtdcRspRepealField *pRspRepeal) {}; ///银行发起冲正期货转银行通知 virtual void OnRtnRepealFromFutureToBankByBankCThostFtdcRspRepealField *pRspRepeal) {}; ///期货发起银行资金转期货通知 virtual void OnRtnFromBankToFutureByFutureCThostFtdcRspTransferField *pRspTransfer) {}; ///期货发起期货资金转银行通知 virtual void OnRtnFromFutureToBankByFutureCThostFtdcRspTransferField *pRspTransfer) {}; ///系统运行时期货端手工发起冲正银行转期货请求,银行处理完毕后报盘发回的通知 virtual void OnRtnRepealFromBankToFutureByFutureManualCThostFtdcRspRepealField *pRspRepeal) {}; ///系统运行时期货端手工发起冲正期货转银行请求,银行处理完毕后报盘发回的通知 virtual void OnRtnRepealFromFutureToBankByFutureManualCThostFtdcRspRepealField *pRspRepeal) {}; ///期货发起查询银行余额通知 virtual void OnRtnQueryBankBalanceByFutureCThostFtdcNotifyQueryAccountField *pNotifyQueryAccount) {}; ///期货发起银行资金转期货错误回报 virtual void OnErrRtnBankToFutureByFutureCThostFtdcReqTransferField *pReqTransfer, CThostFtdcRspInfoField *pRspInfo) {}; ///期货发起期货资金转银行错误回报 virtual void OnErrRtnFutureToBankByFutureCThostFtdcReqTransferField *pReqTransfer, CThostFtdcRspInfoField *pRspInfo) {}; ///系统运行时期货端手工发起冲正银行转期货错误回报 virtual void OnErrRtnRepealBankToFutureByFutureManualCThostFtdcReqRepealField *pReqRepeal, CThostFtdcRspInfoField *pRspInfo) {}; ///系统运行时期货端手工发起冲正期货转银行错误回报 virtual void OnErrRtnRepealFutureToBankByFutureManualCThostFtdcReqRepealField *pReqRepeal, CThostFtdcRspInfoField *pRspInfo) {}; ///期货发起查询银行余额错误回报 virtual void OnErrRtnQueryBankBalanceByFutureCThostFtdcReqQueryAccountField *pReqQueryAccount, CThostFtdcRspInfoField *pRspInfo) {}; ///期货发起冲正银行转期货请求,银行处理完毕后报盘发回的通知 virtual void OnRtnRepealFromBankToFutureByFutureCThostFtdcRspRepealField *pRspRepeal) {}; ///期货发起冲正期货转银行请求,银行处理完毕后报盘发回的通知 virtual void OnRtnRepealFromFutureToBankByFutureCThostFtdcRspRepealField *pRspRepeal) {}; ///期货发起银行资金转期货应答 virtual void OnRspFromBankToFutureByFutureCThostFtdcReqTransferField *pReqTransfer, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///期货发起期货资金转银行应答 virtual void OnRspFromFutureToBankByFutureCThostFtdcReqTransferField *pReqTransfer, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///期货发起查询银行余额应答 virtual void OnRspQueryBankAccountMoneyByFutureCThostFtdcReqQueryAccountField *pReqQueryAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; ///银行发起银期开户通知 virtual void OnRtnOpenAccountByBankCThostFtdcOpenAccountField *pOpenAccount) {}; ///银行发起银期销户通知 virtual void OnRtnCancelAccountByBankCThostFtdcCancelAccountField *pCancelAccount) {}; ///银行发起变更银行账号通知 virtual void OnRtnChangeAccountByBankCThostFtdcChangeAccountField *pChangeAccount) {}; */ public: //保证唯一 int m_nRequestId; int GetRequestId) {return ++m_nRequestId; } MyCTPTrade *m_Parent; }; //thread public: MyCTPTrade); ~MyCTPTrade); static MyCTPTrade *Instance); void setMainWidgetvoid *widget); void Initconst char *User, const char *pswd, const char *broker, const char *pszAddress); map<string, CThostFtdcInstrumentField>& GetMapInstrument); void setLogconst string& str); bool m_bLoginSuccessed; public: ///////////////////////////////////////请求类函数,提供主要逻辑,供外部使用//////////////////////////////////////////////////////////////////////////// ///用户登录请求 int ReqUserLoginCThostFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) { return m_reqApi->ReqUserLoginpReqUserLoginField, nRequestID ); } ///登出请求 int ReqUserLogoutCThostFtdcUserLogoutField *pUserLogout, int nRequestID) { return m_reqApi->ReqUserLogoutpUserLogout, nRequestID); } public: ///////////////////////////////////////回报类函数,收到数据,更新本地行情信息//////////////////////////////////////////////////////////////////////////// ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 void OnFrontConnected); ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 ///@param nReason 错误原因 /// 0x1001 网络读失败 /// 0x1002 网络写失败 /// 0x2001 接收心跳超时 /// 0x2002 发送心跳失败 /// 0x2003 收到错误报文 void OnFrontDisconnectedint nReason); ///心跳超时警告。当长时间未收到报文时,该方法被调用。 ///@param nTimeLapse 距离上次接收报文的时间 void OnHeartBeatWarningint nTimeLapse); void OnRspAuthenticateCThostFtdcRspAuthenticateField *pRspAuthenticateField, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///登录请求响应 void OnRspUserLoginCThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///登出请求响应 void OnRspUserLogoutCThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); void OnRspQryInstrumentCThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); void OnRspErrorCThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); public: atomic <bool> m_bQryIns;// 是否正在查询合约,如果正在查询,行情服务就不自己主动去订阅行情,因为查询合约完成后,会有订阅行情的动作 atomic <bool> m_bQryInsOK;// 是否查询合约成功,成功订阅行情的动作 private: CThostFtdcTraderApi* m_reqApi; MyRecv *m_RecvSpi; //vector <string /*InstrumentID*/> m_vecInstrumentId;//合约ID //int requestID; string m_TradingDay; int m_session ; int m_frontId ; string m_serverOrderRef ; int m_nOrderRef; ///用户登录信息 CThostFtdcReqUserLoginField *m_userLoginInfo; mutex m_getInstru; void *mainHandle; // 保存合约 map<string, CThostFtdcInstrumentField> m_mapInstrument;//合约ID,合约信息 map<wstring, map<wstring, map<wstring, CThostFtdcInstrumentField>>> m_mapInstrument2;//交易所,板块,合约信息 CConfigImpl* m_pConfig; };
①模块管理:
与CTP提供的行情库类似,这里定义了API和封装的回报API,如下:
CThostFtdcTraderApi* m_reqApi; MyRecv *m_RecvSpi;
②与UI通信
由于交易API用的比较频繁,而回报主要在初始化阶段和数据更新,没有定义回报接口,定义的是全局单例模式,直接共上层使用。
③数据管理
// 保存合约 map<string, CThostFtdcInstrumentField> m_mapInstrument;//合约ID,合约信息 map<wstring, map<wstring, map<wstring, CThostFtdcInstrumentField>>> m_mapInstrument2;//交易所,板块,合约信息
3.程序注意点
①UI初始化:
调用TradeManager::InitCTP启动CTP模块,主模块会订阅注册:
MyCTPQuote::Instance)->Subscribethis);
②交易模块与行情模块通信
当交易模块登陆成功后(通能说原子操作,来判断多条件满足),来调用行情的完成函数,已便行情模块来进行行情合约订阅
int Qry = atomic_exchange&MyCTPTrade::Instance)->m_bQryIns, false); int QryOK = atomic_exchange&MyCTPTrade::Instance)->m_bQryInsOK, true); if!Qry && QryOK) FinishQryInstrument);
③行情回报
收到行情回报,会调用下函数:
void MyCTPQuote::OnRtnDepthMarketDataCThostFtdcDepthMarketDataField *pDepthMarketData)
并组织结构,向订阅派发:
CBroadcastPacket pack; ///深度行情通知 ///每秒两次行情 void MyCTPQuote::OnRtnDepthMarketDataCThostFtdcDepthMarketDataField *pDepthMarketData) { if pDepthMarketData->OpenPrice >= LDBL_MAX) pDepthMarketData->OpenPrice = 0; if pDepthMarketData->HighestPrice >= LDBL_MAX) pDepthMarketData->HighestPrice = 0; if pDepthMarketData->LowestPrice >= LDBL_MAX) pDepthMarketData->LowestPrice = 0; if pDepthMarketData->ClosePrice >= LDBL_MAX) pDepthMarketData->ClosePrice = 0; if pDepthMarketData->PreClosePrice >= LDBL_MAX) pDepthMarketData->PreClosePrice = 0; string str = "Quote SDK 接收行情信息:InstrumentID:"; str += pDepthMarketData->InstrumentID ; str += " TradingDay:"; str += pDepthMarketData->TradingDay; str += " LastPrice:"; str += to_stringpDepthMarketData->LastPrice); str += " Volume:"; str += to_stringpDepthMarketData->Volume); str += " OpenPrice:"; str += to_stringpDepthMarketData->OpenPrice); str += " HighestPrice:"; str += to_stringpDepthMarketData->HighestPrice); str += " LowestPrice:"; str += to_stringpDepthMarketData->LowestPrice); str += " ClosePrice:"; str += to_stringpDepthMarketData->ClosePrice); str += " PreClosePrice:"; str += to_stringpDepthMarketData->PreClosePrice); str += " UpdateTime:"; str += pDepthMarketData->UpdateTime; CRLogE_APPINFO, str.c_str)); //本地保存 //转发到界面 //CThostFtdcDepthMarketDataField DepthMarketData; //memcpy_s&DepthMarketData, sizeofDepthMarketData) ,pDepthMarketData , sizeofCThostFtdcDepthMarketDataField)); //m_mapInstrumentQuote[pDepthMarketData->InstrumentID] = DepthMarketData; m_mapInstrumentQuote[pDepthMarketData->InstrumentID] = *pDepthMarketData; pack.SetParameter"InstrumentId", pDepthMarketData->InstrumentID); pack.SetParameter"TradingDay", pDepthMarketData->TradingDay); pack.SetParameter"OpenPrice", pDepthMarketData->OpenPrice); pack.SetParameter"HighestPrice", pDepthMarketData->HighestPrice); pack.SetParameter"LowestPrice", pDepthMarketData->LowestPrice); pack.SetParameter"ClosePrice", pDepthMarketData->ClosePrice); pack.SetParameter"PreClosePrice", pDepthMarketData->PreClosePrice); pack.SetParameter"UpperLimitPrice", pDepthMarketData->UpperLimitPrice); pack.SetParameter"LowerLimitPrice", pDepthMarketData->LowerLimitPrice); pack.SetParameter"AskPrice1", pDepthMarketData->AskPrice1); pack.SetParameter"AskVolume1", pDepthMarketData->AskVolume1); pack.SetParameter"BidPrice1", pDepthMarketData->BidPrice1); pack.SetParameter"BidVolume1", pDepthMarketData->BidVolume1); pack.SetParameter"LastPrice", pDepthMarketData->LastPrice); pack.SetParameter"Volume", pDepthMarketData->Volume); //给上层转发 // 广播报文 for VPKTRECEIVER::iterator it = m_vPketReceiver.begin); it < m_vPketReceiver.end); it++) { *it)->Receivepack); } }
④界面处理回报数据
收到数据可以按照自己的逻辑处理,本Demo进行了写共享队列。
QUOTATION quo = { 0 }; void TradeManager::ReceiveCBroadcastPacket &pkt) { unsigned int nLen = 0; const char* pcBuf = pkt.EncodenLen); //分发给相应队列处理 quo.DecodepcBuf, nLen); int uiCount = 0; string sXQueName, sTmp; for vector< CXQueueIo<QUOTATION>* >::iterator it = m_vecQueueIo.begin); it != m_vecQueueIo.end); ++it) { uiCount++; if 0 != *it) { *it)->Enquequo); sXQueName = "XQUE" + strutils::ToString<unsigned int>uiCount); sXQueName += ".XQUE_NAME"; if 0 == m_pConfig->GetPropertysXQueName, sTmp)) sXQueName = sTmp; CRLogE_APPINFO, "共享队列XQueue[%s]写完成", sXQueName.c_str)); } }//end for }
4.注意
内嵌Framwork所生成的动态库为本Demo提供日志和共享内存队列以及行情数据定义,可以自行定义替换,不存在bug,不影响演示,代码由于版权问题,暂不能公开,若有需要,请联系作者。