基于CTP的国内期货程序化交易之行情获取讲解
来源:互联网 发布:卖软件代理 编辑:程序博客网 时间:2024/04/29 10:33
前面两篇文章主要讲了国外期货相关程序开发,使用的是郑州易盛的行情及交易api,而国内期货相关程序开发易盛貌似也是有sdk的,不过项目中使用的是上期技术的sdk,即大家经常提到的CTP api——综合交易平台api。相比较而言,易盛给自己的sdk起的名字好听一点,叫易盛国际金融衍生品交易分析系统,听着高大上一些。
上期技术的api使用思路与易盛的api基本一致,大同小异,其实无论谁设计这个架构,基本也都是这个思路,一个发起请求调用,一个响应请求回调,调用逻辑由sdk提供方编写,回调逻辑由开发者编写,这样共同完成整个业务逻辑开发。不过毕竟是两家公司开发的sdk,所以在定义参数及一些交易术语上,还是有些不同的,这个需要开发者多查阅文档、多摸索才行。
基于CPT api开发行情获取程序,主要用到的头文件为:ThostFtdcMdApi.h、ThostFtdcUserApiDataType.h及ThostFtdcUserApiStruct.h,动态库为:libthostmduserapi.so。
下面是一些代码示例:
1. 创建CTP api实例:
CThostFtdcMdApi *pMarketDataApi = CThostFtdcMdApi::CreateFtdcMdApi(dirName);
即通过调用CreateFtdcMdApi()创建api实例——pMarketDataApi,随后调用该实例发起各种请求,比如连接服务器、用户登录、订阅合约、退订合约等。
2. 创建CTP api回调实例:
MarketDataSource *pDataSource = new MarketDataSource(pMarketDataApi, this);这个需要自己编写相应实现类,需要继承上期技术提供的CThostFtdcMdSpi类。重写该类里面的方法,以处理服务器发过来的各类数据。
3. 将上述两个实例关联起来,并发起连接服务器及用户登录:
pMarketDataApi->RegisterSpi(pDataSource);pDataSource->connect(serverAddr, brokerId, username, password);连接服务器以及实例初始化相关代码:
void MarketDataSource::connect(string serverAddr, string brokerId, string username, string password){ serverAddr_ = serverAddr; brokerId_ = brokerId; username_ = username; password_ = password; pMarketDataApi_->RegisterFront((char *)serverAddr_.c_str()); pMarketDataApi_->Init();}连接请求发出后,OnFrontConnected()及OnRspUserLogin()会响应请求,根据返回的信息,可以确定是否登录完成。登录成功后,就可以订阅合约了。
void MarketDataSource::OnFrontConnected(){ LOG_INFO << username_ << " 回调: 与服务器已建立连接, 开始登录";}void MarketDataSource::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){ if (pRspInfo == NULL) { LOG_INFO << username_ << " 登录回调异常, 指针为空"; return; } if (pRspInfo->ErrorID == Err_Succeed) { LOG_INFO << username_ << " 登录成功, 当前交易日: " << pMarketDataApi_->GetTradingDay(); }}4. 订阅期货合约:
void MarketDataSource::subscribeContracts(std::set<ContractInfo> &contracts){ const size_t count = contracts.size(); char *instruments[count]; int i = 0; for (std::set<ContractInfo>::iterator it = contracts.begin(); it != contracts.end(); ++it) { string strInstrument = it->CommodityNo + it->ContractNo; instruments[i] = new char[32]; memset(instruments[i], 0, 32); strcpy(instruments[i], strInstrument.c_str()); i++; } int result = Err_Succeed; result = pMarketDataApi_->SubscribeMarketData(instruments, (int)count); if (result == Err_Succeed) { LOG_INFO << username_ << " " << "请求: 合约订阅成功"; } else { LOG_INFO << username_ << " " << "请求: 合约订阅失败" << " " << "错误码: " << result << " " << ErrorCode::get(result); } for (i = 0; i < count; ++i) { delete[] instruments[i]; }}上述代码主要参考CTP文档编写,比较简单,按照文档说明,填写正确参数,然后调用SubscribeMarketData()函数即可。
5. 接收行情数据:
void MarketDataSource::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData){ if (pDepthMarketData != NULL) { CThostFtdcDepthMarketDataField marketData; memcpy(&marketData, pDepthMarketData, sizeof(CThostFtdcDepthMarketDataField)); LOG_INFO << "行情更新:" << marketData.TradingDay << " " << marketData.UpdateTime << " " << marketData.UpdateMillisec << " " << marketData.InstrumentID << " " << marketData.LastPrice << " " << username_; }}一旦合约订阅成功,在交易时间段内,就会有行情数据源源不断的推送过来。上期技术文档中提到行情是每秒2条数据,这个还是比较准的。注意,这里有一个坑,那就是在非交易时间段,经常会接收脏数据,姑且叫测试数据吧。但这个测试数据是个十几位长的超级大浮点数,需要做好过滤,否则程序就各种异常了,甚至程序Crash。
1 0
- 基于CTP的国内期货程序化交易之行情获取讲解
- 基于CTP的国内期货程序化交易之报单流程讲解
- 国外期货程序化交易之行情获取讲解
- 浅谈CTP期货行情交易API
- 国外期货程序化交易之报单流程讲解
- 基于IB(Interactive Brokers)盈透证券的股票及期货行情获取讲解
- 小白期货CTP程序化交易开发入门(一)--CTP开发基础
- 期货程序化交易之期货入门知识摘录整理
- 基于CTP的程序化交易系统开发
- 基于CTP的程序化交易系统开发
- 基于CTP的程序化交易系统开…
- 转载]金仕达、恒生、上期CTP,期货公司的哪一套后台系统适合于程序化下单
- 基于CTP的程序化交易系统开发(一)
- 基于CTP的程序化交易系统开发(一)
- 基于CTP的程序化交易系统开发(二)
- 基于CTP的程序化交易系统开发(三)
- 我眼中的程序化交易之路
- 我眼中的程序化交易之路
- mongo自动备份脚本和恢复
- LeetCode- 169. Majority Element - 思路详解 -C++
- Windows2008 R2服务器配置TLS1.2方法
- C++字符串和基本类型转换的各种方法总结
- 2017.1.13【初中部 】普及组模拟赛C组 money 最小花费 题解
- 基于CTP的国内期货程序化交易之行情获取讲解
- 通过java连接mysql数据库
- 2017.1.12【初中部 GDKOI】模拟赛B组
- Java项目中读取properties文件
- 1021. Deepest Root
- 80老翁谈人生(346):方正不“正“,打击报复火星人有“方“
- Copyright中的年份是什么意思
- 经典iframe后台系统框架
- 【bzoj2818】Gcd