CTP综合交易平台教程基本介绍一、系统简介交易托管系统API是一个基于C++的类库,通过使用和扩展类库提供的接口来实现相关交易功能,包括报单与报价的录入、报单与报价的撤销、报单与报价的挂起、报单与报价的激活、报单与报价的修改、报单与报价的查询、成交单查询、投资者查询、投资者持仓查询、合约查询、交易日获取等。支持MSVC6.0,MSVC.NET2003编译器。需要打开多线程编译选项/MT。二、体系结构交易员API使用建立在TCP协议之上FTD协议与交易托管系统进行通讯,交易托管系统负责投资者的交易业务处理。2.1.通讯模式FTD协议中的所有通讯都基于某个通讯模式。通讯模式实际上就是通讯双方协同工作的方式。FTD涉及的通讯模式共有三种:l对话通讯模式l私有通讯模式l广播通讯模式对话通讯模式是指由会员端主动发起的通讯请求。该请求被交易所端接收和处理,并给予响应。例如报单、查询等。这种通讯模式与普通的客户/服务器模式相同。私有通讯模式是指交易所端主动,向某个特定的会员发出的信息。例如成交回报等。广播通讯模式是指交易所端主动,向市场中的所有会员都发出相同的信息。例如公告、市场公共信息等。通讯模式和网络的连接不一定存在简单的一对一的关系。也就是说,一个网络连接中可能传送多种不同通讯模式的报文,一种通讯模式的报文也可以在多个不同的连接中传送。无论哪种通讯模式,其通讯过程都如图1所示本接口暂时没有使用广播通信方式。2.2.数据流交易托管系统支持对话通讯模式、私有通讯模式、广播通讯模式:对话通讯模式下支持对话数据流和查询数据流:对话数据流是一个双向数据流,交易托管系统发送交易请求,交易系统反馈应答。交易系统不维护对话流的状态。系统故障时,对话数据流会重置,通讯途中的数据可能会丢失。查询数据流是一个双向数据流,交易托管系统发送查询请求,交易系统反馈应答。交易系统不维护查询流的状态。系统故障时,查询数据流会重置,通讯途中的数据可能会丢失。私有通讯模式下支持私有数据流:私有流是一个单向数据流,由交易系统发向交易托管系统,用于传送交易员私有的通知和回报信息。私有流是一个可靠的数据流,交易系统维护每个交易托管系统的私有流,在一个交易日内,交易托管系统断线后恢复连接时,可以请求交易系统发送指定序号之后的私有流数据。私有数据流向交易托管系统提供报单状态报告、成交回报更等信息。广播通讯模式下支持公共数据流:公共数据流是一个单向数据流,由交易系统发向交易托管系统,用于发送市场公共信息;公共数据流也是一个可靠的数据流,交易系统维护整个系统的公共数据流,在一个交易日内,交易托管系统断线恢复连接时,可以请求交易系统发送指定序号之后的公共数据流数据。接口模式交易员API提供了二个接口,分别为CThostFtdcTraderApi和CThostFtdcTraderSpi。这两个接口对FTD协议进行了封装,方便客户端应用程序的开发。客户端应用程序可以通过CThostFtdcTraderApi发出操作请求,通继承CThostFtdcTraderSpi并重载回调函数来处理后台服务的响应。1.对话流和查询流编程接口通过对话流进行通讯的编程接口通常如下:请求:intCThostFtdcTraderApi::ReqXXX(CThostFtdcXXXField*pReqXXX,intnRequestID)响应:voidCThostFtdcTraderSpi::OnRspXXX(CThostFtdcXXXField*pRspXXX,CThostFtdcRspInfoField*pRspInfo,intnRequestID,boolbIsLast)其中请求接口第一个参数为请求的内容,不能为空。第二个参数为请求号。请求号由客户端应用程序负责维护,正常情况下每个请求的请求号不要重复。在接收交易托管系统的响应时,可以得到当时发出请求时填写的请求号,从而可以将响应与请求对应起来。当收到后台服务应答时,CThostFtdcTraderSpi的回调函数会被调用。如果响应数据不止一个,则回调函数会被多次调用。回调函数的第一个参数为响应的具体数据,如果出错或没有结果有可能为NULL。第二个参数为处理结果,表明本次请求的处理结果是成功还是失败。在发生多次回调时,除了第一次回调,其它的回调该参数都可能为NULL。第三个参数为请求号,即原来发出请求时填写的请求号。第四个参数为响应结束标志,表明是否是本次响应的最后一次回调。2.私有流编程接口私有流中的数据中会员的私有信息,包括报单回报、成交回报等。通过私有流接收回报的编程接口通常如下:voidCThostFtdcTraderSpi::OnRtnXXX(CThostFtdcXXXField*pXXX)或voidCThostFtdcTraderSpi::OnErrRtnXXX(CThostFtdcXXXField*pXXX,CThostFtdcRspInfoField*pRspInfo)当收到交易托管系统通过私有流发布的回报数据时,CThostFtdcTraderSpi的回调函数会被调用。回调函数的参数为回报的具体内容。运行模式工作线程交易员客户端应用程序至少由两个线程组成,一个是应用程序主线程,一个是交易员API工作线程。应用程序与交易系统的通讯是由API工作线程驱动的。CThostFtdcTraderApi提供的接口是线程安全的,可以有多个应用程序线程同时发出请求。CThostFtdcTraderSpi提供的接口回调是由API工作线程驱动,通过实现SPI中的接口方法,可以从交易托管系统收取所需数据。如果重载的某个回调函数阻塞,则等于阻塞了API工作线程,API与交易系统的通讯会停止。因此,在CThostFtdcTraderSpi派生类的回调函数中,通常应迅速返回,可以利用将数据放入缓冲区或通过Windows的消息机制来实现。本地文件交易员API在运行过程中,会将一些数据写入本地文件中。调用CreateFtdcTraderApi函数,可以传递一个参数,指明存贮本地文件的路径。该路径必须在运行前已创建好。本地文件的扩展名都是.con。开发接口通用规则客户端和交易托管系统的通讯过程分为2个阶段:初始化阶段和功能调用阶段。在初始化阶段,程序必须完成如下步骤(具体代码请参考开发实例):1,产生一个CThostFtdcTraderApi实例2,产生一个事件处理的实例3,注册一个事件处理的实例4,订阅私有流5,订阅公共流6,设置交易托管服务的地址在功能调用阶段,程序可以任意调用交易接口中的请求方法,如ReqOrderInsert等。同时按照需要响应回调接口中的。其他注意事项:1,API请求的输入参数不能为NULL。2,API请求的返回参数,0表示正确,其他表示错误,详细错误编码请查表。CThostFtdcTraderSpi接口CThostFtdcTraderSpi实现了事件通知接口。用户必需派生CThostFtdcTraderSpi接口,编写事件处理方法来处理感兴趣的事件。由于回调函数众多,在此不一一举例,只说明几个经典函数的功能与用法,其它函数可举一反三。1.OnFrontConnected方法当客户端与交易托管系统建立起通信连接时(还未登录前),该方法被调用。函数原形:voidOnFrontConnected();本方法在完成初始化后调用,可以在其中完成用户登录任务。2.OnFrontDisconnected方法当客户端与交易托管系统通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。自动重连地址,可能是原来注册的地址,也可能是系统支持的其它可用的通信地址,它由程序自动选择。函数原形:voidOnFrontDisconnected(intnReason);参数:nReason:连接断开原因0x1001网络读失败0x1002网络写失败0x2001接收心跳超时0x2002发送心跳失败0x2003收到错误报文3.OnRspUserLogin方法当客户端发出登录请求之后,交易托管系统返回响应时,该方法会被调用,通知客户端登录是否成功。函数原形:voidOnRspUserLogin(CThostFtdcRspUserLoginField*pRspUserLogin,CThostFtdcRspInfoField*pRspInfo,intnRequestID,boolbIsLast);参数:pRspUserLogin:返回用户登录信息的地址。用户登录信息结构:structCThostFtdcRspUserLoginField{///交易日TThostFtdcDateTypeTradingDay;///登录成功时间TThostFtdcTimeTypeLoginTime;///经纪公司代码TThostFtdcBrokerIDTypeBrokerID;///用户代码TThostFtdcUserIDTypeUserID;///交易系统名称TThostFtdcSystemNameTypeSystemName;};pRspInfo:返回用户响应信息的地址。特别注意在有连续的成功的响应数据时,中间有可能返回NULL,但第一次不会,以下同。错误代码为0时,表示操作成功,以下同。响应信息结构:structCThostFtdcRspInfoField{///错误代码TThostFtdcErrorIDTypeErrorID;///错误信息TThostFtdcErrorMsgTypeErrorMsg;};nRequestID:返回用户登录请求的ID,该ID由用户在登录时指定。bIsLast:指示该次返回是否为针对nRequestID的最后一次返回。4.OnRspOrderInsert方法报单录入应答。当客户端发出过报单录入指令后,交易托管系统返回响应时,该方法会被调用。函数原形:voidOnRspOrderInsert(CThostFtdcInputOrderField*pInputOrder,CThostFtdcRspInfoField*pRspInfo,intnRequestID,boolbIsLast);参数:pInputOrder:指向报单录入结构的地址,包含了提交报单录入时的输入数据,和后台返回的报单编号。输入报单结构:structCThostFtdcInputOrderField{///经纪公司代码TThostFtdcBrokerIDTypeBrokerID;///投资者代码TThostFtdcInvestorIDTypeInvestorID;///合约代码TThostFtdcInstrumentIDTypeInstrumentID;///报单引用TThostFtdcOrderRefTypeOrderRef;///用户代码TThostFtdcUserIDTypeUserID;///报单价格条件TThostFtdcOrderPriceTypeTypeOrderPriceType;///买卖方向TThostFtdcDirectionTypeDirection;///组合开平标志TThostFtdcCombOffsetFlagTypeCombOffsetFlag;///组合投机套保标志TThostFtdcCombHedgeFlagTypeCombHedgeFlag;///价格TThostFtdcPriceTypeLimitPrice;///数量TThostFtdcVolumeTypeVolumeTotalOriginal;///有效期类型TThostFtdcTimeConditionTypeTimeCondition;///GTD日期TThostFtdcDateTypeGTDDate;///成交量类型TThostFtdcVolumeConditionTypeVolumeCondition;///最小成交量TThostFtdcVolumeTypeMinVolume;///触发条件TThostFtdcContingentConditionTypeCont