通过MT4平台来由ctp接口操作期货,首先需要处理好商品和行情
1.期货商品品种
由于期货商品代号会随着时间变化,且商品品种较多,手动维护商品的话太繁琐。比较简单的处理方式
是做一个服务端的插件,在插件的启动事件
int APIENTRY MtSrvStartup(CServerInterface *server)
去检查并新增商品代号
这里主要用到了MT4接口的这两个个方法,取商品信息和新增商品
int __stdcall SymbolsGet(LPCSTR symbol,ConSymbol *security);
int __stdcall SymbolsAdd(ConSymbol *sec);
期货的品种种类是相对固定的,变化的只是月份,所以可以考虑常量定义相关种类,也可以考虑直接从四大期货的网站去爬。
我是直接用常量定义种类,然后根据当前月份计算目前的期货品种。
SymbolDefine Defines[SYMBOL_DEF_COUNT] = {//中国金融期货交易所 CFFEX{ "沪深300", "IF", 1, 1, {0}, 0},//当月、下月及随后两个季月(如当前为3月,则为4","5","6","9}},{ "上证50", "IH", 1, 1, {0}, 0},//当月、下月及随后两个季月{ "中证500", "IC", 1, 1, {0}, 0},//当月、下月及随后两个季月{ "5年期国债", "TF", 3, 2, {0}, 0},//最近的三个季月(3月、6月、9月、12月中的最近三个月循环)(当前为3月 则为6","9","12}},{ "10年期国债", "T", 3, 2, {0}, 0},//最近的三个季月(3月、6月、9月、12月中的最近三个月循环)//上海期货交易所 SHFE{ "铜", "cu", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "铝", "al", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "锌", "zn", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "铅", "pb", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "镍", "ni", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "锡", "sn", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "黄金", "au", 2, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "白银", "ag", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "螺纹钢", "rb", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "线材", "wr", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "热轧卷板", "hc", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "燃料油", "fu", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "沥青", "bu", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},{ "天然橡胶", "ru", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 1},//大连商品交易所 DCE{ "玉米", "c", 0, 0, { 1, 3, 5, 7, 9, 11 }, 2},{ "玉米淀粉", "cs", 0, 0, { 1, 3, 5, 7, 9, 11 }, 2},{ "黄大豆1号", "a", 0, 0, { 1, 3, 5, 7, 9, 11 }, 2},{ "黄大豆2号", "b", 0, 0, { 1, 3, 5, 7, 9, 11 }, 2},{ "豆粕", "m", 0, 0, { 1, 3, 5, 7, 8, 9, 11, 12 }, 2},{ "豆油", "y", 0, 0, { 1, 3, 5, 7, 8, 9, 11, 12 }, 2},{ "棕榈油", "p", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "纤维板", "fb", 2, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "胶合板", "bb", 2, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "鸡蛋", "jd", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "聚乙烯(塑料}},", "l", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "聚氯乙烯(PVC}},", "v", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "聚丙烯", "pp", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "焦炭", "j", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "焦煤", "jm", 1, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},{ "铁矿石", "i", 1, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 2},//郑州商品交易所 CZCE{ "强麦", "WH", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "普麦", "PM", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "棉花", "CF", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "白糖", "SR", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "PTA", "TA", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 3},{ "菜籽油", "OI", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "早籼稻", "RI", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "甲醇", "MA", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 3},{ "玻璃", "FG", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 3},{ "菜籽", "RS", 0, 0, { 7, 8, 9, 11 }, 3},{ "菜粕", "RM", 0, 0, { 1, 3, 5, 7, 8, 9, 11 }, 3},{ "动力煤", "ZC", 1, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 3},{ "粳稻", "JR", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "晚籼稻", "LR", 0, 0, { 1, 3, 5, 7, 9, 11 }, 3},{ "硅铁", "SF", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 3},{ "锰硅", "SM", 0, 0, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12 }, 3}
};
然后通过插件方便的新增所有的期货品种到MT4中
2.行情数据
处理好品种问题,接下来就是行情数据。
行情数据主要是两个事情,一个是用CTP接口取到数据,另一个是把数据写入MT4
1)取CTP的行情数据
只需要用到CTP的行情接口CThostFtdcMdApi
// 初始化UserApipUserApi = CThostFtdcMdApi::CreateFtdcMdApi(); // 创建UserApiCThostFtdcMdSpi* pUserSpi = new CMdSpi();pUserApi->RegisterSpi(pUserSpi); // 注册事件类pUserApi->RegisterFront(FRONT_ADDR); // connectpUserApi->Init();pUserApi->Join();
// pUserApi->Release();
在连接成功后,调用登录并订阅行情即可。
pUserApi->ReqUserLogin(&req, ++iRequestID);
SubscribeMarketData();
SubscribeForQuoteRsp();
CTP都有比较详细的接口说明,相关文档都很健全,这里就不多说了。
2)数据写入MT4
数据写入MT4有两个方式 都可以做到。
一个方式是使用DataFeed接口,做一个行情插件,关于行情插件有在此文(http://blog.csdn.net/mt4develop/article/details/51251465)简单介绍,这里的话,就是在行情插件中去调用CTP接口取报价数据即可。
另一个方式是使用普通插件接口,用接口的扩展事件
int APIENTRY MtSrvTelnet(char *buf, const int maxlen)
此接口可用于 向MT4发送任意自定义的数据,插件在此事件中处理即可。
那么此处可以做一个外部程序调用CTP接口取得数据,然后把数据发给MT4的扩展接口,然后在此事件中调用MT4新增报价的方法即可。
void __stdcall HistoryAddTick(FeedData *tick);