行情客户端系统.docx
《行情客户端系统.docx》由会员分享,可在线阅读,更多相关《行情客户端系统.docx(20页珍藏版)》请在冰豆网上搜索。
行情客户端系统
行情客户端系统
行情客户端应用程序接口
2006年10月19日
文件版本号
修正日期
备注
V1.01
2007-03-28
首次发布
V1.02
2009-08-07
修改示例程序,添加Join等待
第1章介绍
行情客户端系统API是一个基于C++的类库,通过使用和扩展类库提供的接口来实现行情数据的接收。
该类库包含以下5个文件:
文件名
版本
文件大小
文件描述
CFfexFtdcMduserApi.h
V1.02
11,441字节
行情接口头文件
CFfexFtdcUserApiStruct.h
V1.02
40,238字节
定义了UserAPI所需的一系列数据类型的头文件
CffexFtdcUserApiDataType.h
V1.02
142,601字节
定义了一系列业务相关的数据结构的头文件
CFfexmduserapi.dll
V1.02
983,121字节
动态链接库二进制文件
Cffexmduserapi.lib
V1.02
3,530字节
导入库文件
支持MSVC6.0,MSVC.NET2003编译器。
需要打开多线程编译选项/MT。
第2章体系结构
行情API使用建立在TCP协议之上FTD协议与交易所的行情发布服务器进行通讯。
行情发布服务器负责行情信息的产生与发布,但不参与交易过程。
参与交易需要使用另外的“交易员API”。
2.1通讯模式
FTD协议中的所有通讯都基于某个通讯模式。
通讯模式实际上就是通讯双方协同工作的方式。
行情发布涉及的通讯模式共有二种:
●对话通讯模式
●广播通讯模式
对话通讯模式是指由会员端主动发起的通讯请求。
该请求被交易所端接收和处理,并给予响应。
例如登入与登出。
这种通讯模式与普通的客户/服务器模式相同。
广播通讯模式是指交易所端主动,向市场中的相关会员发出相同的信息。
例如行情等。
通讯模式和网络的连接不一定存在简单的一对一的关系。
也就是说,一个网络连接中可能传送多种不同通讯模式的报文,一种通讯模式的报文也可以在多个不同的连接中传送。
无论哪种通讯模式,其通讯过程都如图1所示:
图1)各通讯模式的工作过程
2.2数据流
行情发布支持对话通讯模式、广播通讯模式:
对话通讯模式下支持对话数据流:
对话数据流是一个双向数据流,会员系统发送请求,行情发布系统反馈应答。
交易系统不维护对话流的状态。
系统故障时,对话数据流会重置,通讯途中的数据可能会丢失。
广播通讯模式下支持行情数据流:
行情数据流是一个单向数据流,由行情发布系统发向会员系统,用于发送行情信息;行情流是一个可靠的数据流,行情系统维护整个系统的行情流,在一个交易日内,会员系统断线恢复连接时,可以请求行情系统发送指定序号之后的行情流数据。
行情服务所提供的行情内容是按照主题组织的。
每个主题包括一组合约的行情,还包括了行情发布内容和发布方式,包括行情深度、采样频率、延迟时间等。
交易所会公布各行情主题的具体内容,并设定每个行情用户所能订阅的行情主题。
每个行情主题对应着一个行情流。
要获得行情通知,客户端必需在连接行情服务器时,订阅一个或多个行情发布主题。
第3章运行模式
3.1工作线程
交易员客户端应用程序至少由两个线程组成,一个是应用程序主线程,一个是交易员API工作线程。
应用程序与交易系统的通讯是由API工作线程驱动的。
CFfexFtdcMduserApi提供的接口是线程安全的,可以有多个应用程序线程同时发出请求。
CFfexFtdcMduserSpi提供的接口回调是由API工作线程驱动,如果重载的某个回调函数阻塞,则等于阻塞了API工作线程,API与交易系统的通讯会停止。
因此,在CFfexFtdcTraderSpi派生类的回调函数中,通常应迅速返回,可以利用将数据放入缓冲区或通过Windows的消息机制来实现。
3.2本地文件
交易员API在运行过程中,会将一些数据写入本地文件中。
调用CreateFtdcMduserApi函数,可以传递一个参数,指明存贮本地文件的路径。
该路径必须在运行前已创建好。
本地文件的扩展名都是”.con”。
第4章开发接口
行情客户端系统API提供了二个接口,分别为CFfexFtdcMduserApi和CFfexFtdcMduserSpi。
4.1CFfexFtdcMduserSpi接口
CFfexFtdcMduserSpi实现了事件通知接口。
用户必需派生CFfexFtdcMduserSpi接口,编写事件处理方法来处理感兴趣的事件。
4.1.1OnFrontConnected方法
当客户端与行情发布服务器建立起通信连接时(还未登录前),该方法被调用。
函数原型:
voidOnFrontConnected();
本方法在完成初始化后调用,可以在其中完成用户登录任务。
4.1.2OnFrontDisconnected方法
当客户端与交易后台通信连接断开时,该方法被调用。
当发生这个情况后,API会自动重新连接,客户端可不做处理。
函数原型:
voidOnFrontDisconnected(intnReason);
参数:
nReason:
连接断开原因
0x1001网络读失败
0x1002网络写失败
0x2001接收心跳超时
0x2002发送心跳失败
0x2003收到错误报文
4.1.3OnHeartBeatWarning方法
心跳超时警告。
当长时间未收到报文时,该方法被调用。
函数原型:
voidOnHeartBeatWarning(intnTimeLapse);
参数:
nTimeLapse:
距离上次接收报文的时间
4.1.4OnRspUserLogin方法
当客户端发出登录请求之后,该方法会被调用,通知客户端登录是否成功。
函数原型:
voidOnRspUserLogin(
CFfexFtdcRspUserLoginField*pRspUserLogin,
CFfexFtdcRspInfoField*pRspInfo,
intnRequestID,
boolbIsLast);
参数:
pRspUserLogin:
返回用户登录信息的地址。
用户登录信息结构:
structCFfexFtdcRspUserLoginField
{
///交易日
TFfexFtdcDateTypeTradingDay;
///登录成功时间
TFfexFtdcTimeTypeLoginTime;
///最大本地报单号
TFfexFtdcOrderLocalIDTypeMaxOrderLocalID;
///交易用户代码
TFfexFtdcUserIDTypeUserID;
///会员代码
TFfexFtdcParticipantIDTypeParticipantID;
};
pRspInfo:
返回用户响应信息的地址。
特别注意在有连续的成功的响应数据时,中间有可能返回NULL,但第一次不会,以下同。
错误代码为0时,表示操作成功,以下同。
响应信息结构:
structCFfexFtdcRspInfoField
{
///错误代码
TFfexFtdcErrorIDTypeErrorID;
///错误信息
TFfexFtdcErrorMsgTypeErrorMsg;
};
nRequestID:
返回用户登录请求的ID,该ID由用户在登录时指定。
bIsLast:
指示该次返回是否为针对nRequestID的最后一次返回。
4.1.5OnRspUserLogout方法
当客户端发出登出请求之后,该方法会被调用,通知客户端登出是否成功。
函数原型:
voidOnRspUserLogout(
CFfexFtdcRspUserLogoutField*pRspUserLogout,
CFfexFtdcRspInfoField*pRspInfo,
intnRequestID,
boolbIsLast);
参数:
pRspUserLogout:
返回用户登出信息的地址。
用户登出信息结构:
structCFfexFtdcRspUserLogoutField
{
///交易用户代码
TFfexFtdcUserIDTypeUserID;
///会员代码
TFfexFtdcParticipantIDTypeParticipantID;
};
pRspInfo:
返回用户响应信息的地址。
响应信息结构:
structCFfexFtdcRspInfoField
{
///错误代码
TFfexFtdcErrorIDTypeErrorID;
///错误信息
TFfexFtdcErrorMsgTypeErrorMsg;
};
nRequestID:
返回用户登出请求的ID,该ID由用户在登出时指定。
bIsLast:
指示该次返回是否为针对nRequestID的最后一次返回。
4.1.6OnRtnDepthMarketData方法
行情通知,行情服务器会主动通知客户端。
函数原型:
voidOnRtnDepthMarketData(CFfexFtdcDepthMarketDataField*pDepthMarketData);
参数:
pDepthMarketData:
返回市场行情信息的地址。
深度市场行情信息结构:
structCFfexFtdcDepthMarketDataField
{
///交易日
TFfexFtdcDateTypeTradingDay;
///结算组代码
TFfexFtdcSettlementGroupIDTypeSettlementGroupID;
///结算编号
TFfexFtdcSettlementIDTypeSettlementID;
///最新价
TFfexFtdcPriceTypeLastPrice;
///昨结算
TFfexFtdcPriceTypePreSettlementPrice;
///昨收盘
TFfexFtdcPriceTypePreClosePrice;
///昨持仓量
TFfexFtdcLargeVolumeTypePreOpenInterest;
///今开盘
TFfexFtdcPriceTypeOpenPrice;
///最高价
TFfexFtdcPriceTypeHighestPrice;
///最低价
TFfexFtdcPriceTypeLowestPrice;
///数量
TFfexFtdcVolumeTypeVolume;
///成交金额
TFfexFtdcMoneyTypeTurnover;
///持仓量
TFfexFtdcLargeVolumeTypeOpenInterest;
///今收盘
TFfexFtdcPriceTypeClosePrice;
///今结算
TFfexFtdcPriceTypeSettlementPrice;
///涨停板价
TFfexFtdcPriceTypeUpperLimitPrice;
///跌停板价
TFfexFtdcPriceTypeLowerLimitPrice;
///昨虚实度
TFfexFtdcRatioTypePreDelta;
///今虚实度
TFfexFtdcRatioTypeCurrDelta;
///最后修改时间
TFfexFtdcTimeTypeUpdateTime;
///最后修改毫秒
TFfexFtdcMillisecTypeUpdateMillisec;
///合约代码
TFfexFtdcInstrumentIDTypeInstrumentID;
///申买价一
TFfexFtdcPriceTypeBidPrice1;
///申买量一
TFfexFtdcVolumeTypeBidVolume1;
///申卖价一
TFfexFtdcPriceTypeAskPrice1;
///申卖量一
TFfexFtdcVolumeTypeAskVolume1;
///申买价二
TFfexFtdcPriceTypeBidPrice2;
///申买量二
TFfexFtdcVolumeTypeBidVolume2;
///申卖价二
TFfexFtdcPriceTypeAskPrice2;
///申卖量二
TFfexFtdcVolumeTypeAskVolume2;
///申买价三
TFfexFtdcPriceTypeBidPrice3;
///申买量三
TFfexFtdcVolumeTypeBidVolume3;
///申卖价三
TFfexFtdcPriceTypeAskPrice3;
///申卖量三
TFfexFtdcVolumeTypeAskVolume3;
///申买价四
TFfexFtdcPriceTypeBidPrice4;
///申买量四
TFfexFtdcVolumeTypeBidVolume4;
///申卖价四
TFfexFtdcPriceTypeAskPrice4;
///申卖量四
TFfexFtdcVolumeTypeAskVolume4;
///申买价五
TFfexFtdcPriceTypeBidPrice5;
///申买量五
TFfexFtdcVolumeTypeBidVolume5;
///申卖价五
TFfexFtdcPriceTypeAskPrice5;
///申卖量五
TFfexFtdcVolumeTypeAskVolume5;
};
4.1.7OnRspError方法
针对用户请求的出错通知。
函数原型:
voidOnRspError(
CFfexFtdcRspInfoField*pRspInfo,
intnRequestID,
boolbIsLast)
参数:
pRspInfo:
返回用户响应信息的地址。
响应信息结构:
structCFfexFtdcRspInfoField
{
///错误代码
TFfexFtdcErrorIDTypeErrorID;
///错误信息
TFfexFtdcErrorMsgTypeErrorMsg;
};
nRequestID:
返回用户登出请求的ID,该ID由用户在登出时指定。
bIsLast:
指示该次返回是否为针对nRequestID的最后一次返回。
4.2CFfexFtdcMduserApi接口
CFfexFtdcMduserApi接口提供给客户登陆、登出行情查询服务器,进行行情查询等功能。
4.2.1CreateFtdcMduserApi方法
产生一个CFfexFtdcMduserApi的一个实例,不能通过new来产生。
函数原型:
staticCFfexFtdcMduserApi*CreateFtdcMduserApi(constchar*pszFlowPath="");
参数:
pszFlowPath:
常量字符指针,用于指定一个文件目录来存贮行情服务发布消息的状态。
默认值代表当前目录。
返回值:
返回一个指向CFfexFtdcMduserApi实例的指针。
4.2.2Release方法
释放一个CFfexFtdcMduserApi实例。
函数原型:
voidRelease();
4.2.3Init方法
使客户端开始与行情发布服务器建立连接,连接成功后可以进行登陆。
函数原型:
voidInit();
4.2.4Join方法
客户端等待一个接口实例线程的结束。
函数原型:
voidJoin();
4.2.5GetTradingDay方法
获得当前交易日。
只有当与服务器连接建立后才会取到正确的值。
函数原型:
constchar*GetTradingDay();
返回值:
返回一个指向日期信息字符串的常量指针。
4.2.6RegisterSpi方法
注册一个派生自CFfexFtdcMduserSpi接口类的实例,该实例将完成事件处理。
函数原型:
voidRegisterSpi(CFfexFtdcMduserSpi*pSpi);
参数:
pSpi:
实现了CFfexFtdcMduserSpi接口的实例指针。
4.2.7RegisterFront方法
设置行情发布服务器的地址。
函数原型:
voidRegisterFront(char*pszFrontAddress);
参数:
pszFrontAddress:
指向后台服务器地址的指针。
服务器地址的格式为:
“protocol:
//ipaddress:
port”,如:
”tcp:
//127.0.0.1:
17001”。
“tcp”代表传输协议,“127.0.0.1”代表服务器地址。
”17001”代表服务器端口号。
4.2.8SubscribeMarketDataTopic方法
客户端订阅自己需要的行情。
订阅后行情服务器会自动发出行情通知给客户端。
函数原型:
voidSubscribeMarketDataTopic(intnTopicID,TE_RESUME_TYPEnResumeType);
参数:
nTopicID:
代表深度行情的主题,由交易所公布。
nResumeType:
市场行情重传方式
TERT_RESTART:
从本交易日开始重传
TERT_RESUME:
从上次收到的续传
TERT_QUICK:
先传送当前行情快照,再传送登录后市场行情的内容
4.2.9ReqUserLogin方法
用户发出登陆请求。
函数原型:
intReqUserLogin(
CFfexFtdcReqUserLoginField*pReqUserLoginField,
intnRequestID);
参数:
pReqUserLoginField:
指向用户登录请求结构的地址。
用户登录请求结构:
structCFfexFtdcReqUserLoginField
{
///交易日
TFfexFtdcDateTypeTradingDay;
///交易用户代码
TFfexFtdcUserIDTypeUserID;
///会员代码
TFfexFtdcParticipantIDTypeParticipantID;
///密码
TFfexFtdcPasswordTypePassword;
};
nRequestID:
用户登录请求的ID,该ID由用户指定,管理。
返回值:
0,代表成功。
其它值代表失败。
4.2.10ReqUserLogout方法
用户发出登出请求。
函数原型:
intReqUserLogout(
CFfexFtdcReqUserLogoutField*pReqUserLogout,
intnRequestID);
参数:
pReqUserLogout:
指向用户登出请求结构的地址。
用户登出请求结构:
structCFfexFtdcReqUserLogoutField
{
///交易用户代码
TFfexFtdcUserIDTypeUserID;
///会员代码
TFfexFtdcParticipantIDTypeParticipantID;
};
nRequestID:
用户登出请求的ID,该ID由用户指定,管理。
返回值:
0,代表成功。
其它值代表失败。
第5章开发示例
//mdusertest.cpp:
//一个简单的例子,介绍CFfexFtdcMduserApi和CFfexFtdcMduserSpi接口的使用。
#include"stdio.h"
#include"FtdcMduserApi.h"
classCSimpleHandler:
publicCFfexFtdcMduserSpi
{
public:
//构造函数,需要一个有效的指向CFfexFtdcMduserApi实例的指针
CSimpleHandler(CFfexFtdcMduserApi*pUserApi):
m_pUserApi(pUserApi){}
~CSimpleHandler(){}
//当客户端与行情发布服务器建立起通信连接,客户端需要进行登录
voidOnFrontConnected(){
CFfexFtdcReqUserLoginFieldreqUserLogin;
strcpy(reqUserLogin.TradingDay,m_pUserApi->GetTradingDay());
strcpy(reqUserLogin.ParticipantID,"P001");
strcpy(reqUserLogin.UserID,"U001");
strcpy(reqUserLogin.Password,"P001");
m_pUserApi->ReqUserLogin(&reqUserLogin,0);
}
//当客户端与行情发布服务器通信连接断开时,该方法被调用
voidOnFrontDisconnected(){
//当发生这个情况后,API会自动重新连接,客户端可不做处理
printf("OnFrontDisconnected.\n");
}
//当客户端发出登录请求之后,该方法会被调用,通知客户端登录是否成功
voidOnRspUserLogin(CFfexFtdcRspUserLoginField*pRspUserLogin,CFfexFtdcRspInfoField*pRspInfo,intnRequestID,boolbIsLast){
printf("OnRspUserLogin:
\n");
printf("ErrorCode=[%d],ErrorMsg=[%s]\n",pRspInfo->ErrorID,pRspInfo->ErrorMsg);
printf("RequestID=[%d],Chain=[%d]\n",nRequestID,bIsLast);
if(pRspInfo->ErrorID!
=0){
//端登失败,客户端需进行错误处理
printf("Failedtologin,errorcode=%derrormsg=%srequestid=%dchain=%d",pRspInfo->ErrorID,pRspInfo->ErrorMsg,nRequestID,bIsLast);
}
}
//深度行情通知,行情服