综合交易系统 第一次运行

来源:互联网 发布:淘宝二次认证不通过 编辑:程序博客网 时间:2024/04/30 00:41

http://blog.sina.com.cn/s/blog_62715e790100ghrz.html

VC2008 的环境配置好了之后,交易系统终于可以运行了。当按下程序,看着一个黑框蹦出来了的那一刻,心里不禁无穷的欢喜。

综合交易系统 <wbr>第一次运行

当然不知道这个输出的结果是个什么意思,要仔细研究也要花上不少的精力。内心里还是很想弄明白程序的整个操作过程,但此时天色已经很晚了,脑袋昏昏的,看那些文字材料不知道要看到什么时候。看到《综合交易平台交易API特别说明》后面有一段代码挺不错的,很想将代码的实现过程弄清楚。可能硬着头皮看,不知道什么时候能看完。于是我打算一边打代码,一边揣摩每段代码的含义。花了差不多一个小时的时间,我敲完了代码,并对代码要实现的东西进行了一些总结。
现将代码贴出如下:
// tradeapitest.cpp
// 一个简单的例子, 介绍CThostFtdcTraderApi和CThostFtdcTraderSpi接口的使用
//本例将演示一个报单录入操作的过程
//CThostFtdcTraderApi : Api对象
//CThostFtdcTraderSpi : 事件处理对象
#include <stdio.h>
#include <windows.h>
#include ".\ThostTraderApi\ThostFtdcTraderApi.h"
//保单录入操作是否完成的标志
//Create a manual reset event with no signal
HANDLE g_hEvent = CreateEvent(NULL,true,false,NULL);
//会员代码
TThostFtdcBrokerIDType g_chBrokerID;
//交易用户代码
TThostFtdcUserIDType g_chUserID;
class CSimpleHandler : public CThostFtdcTraderSpi
{
public:
//构造函数,需要一个有效的指向CThostFtdcMduserApi实例的指针
CSimpleHandler(CThostFtdcTraderApi *pUserApi) : m_pUserApi(pUserApi){}
~CSimpleHandler(){}
//当客户端与交易托管系统建立起通信连接,客户端需要进行登录
virtual void OnFrontConnected()
{
CThostFtdcReqUserLoginField reqUserLogin;
//get BrokerID
printf("BrokerID: ");
scanf("%s", &g_chBrokerID);
strcpy(reqUserLogin.BrokerID,g_chBrokerID);
//get userid
printf("userid: ");
scanf("%s",&g_chUserID);
strcpy(reqUserLogin.UserID,g_chUserID);
//get password
printf("password:");
scanf("%s", &reqUserLogin.Password);
//发出登录请求
m_pUserApi->ReqUserLogin(&reqUserLogin,0);
}
virtual void OnFrontDisconnected(int nReason)
{
//当发生这个情况后,API会自动重新连接,客户端可不做处理
printf("OnFrontDisconnected.\n");
}
//当客户端发出登录请求之后,该方法会被调用,通知客户端登录是否成功
virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo,int nRequestID, bool bIsLast)
{
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("Failed to login, errorcode = %d errormsg= %s requestid = %d chain = %d", pRspInfo->ErrorID, pRspInfo->ErrorMsg, nRequestID, bIsLast);
exit(-1);
}
//登录成功,发出保单录入请求
CThostFtdcInputOrderField ord;
memset(&ord, 0, sizeof(ord));
//经纪公司代码
strcpy(ord.BrokerID, g_chBrokerID);
//投资者代码
strcpy(ord.InvestorID, "12345");
//合约代码
strcpy(ord.InstrumentID,"cn0601");
//报单引用
strcpy(ord.OrderRef,"000000000001");
//用户代码
strcpy(ord.UserID, g_chUserID);
//报单价格条件
ord.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
//买卖方向
ord.Direction = THOST_FTDC_D_Buy;
//组合开平标志
strcpy(ord.CombOffsetFlag,"0");
//组合投机套保标志
strcpy(ord.CombHedgeFlag,"1");
//价格
ord.LimitPrice = 50000;
//数量
ord.VolumeTotalOriginal = 10;
//有效期类型
ord.TimeCondition = THOST_FTDC_TC_GFD;
//GTD日期
strcpy(ord.GTDDate,"");
//成交量类型
ord.VolumeCondition = THOST_FTDC_VC_AV;
//最小成交量
ord.MinVolume = 0;
//触发条件
ord.ContingentCondition = THOST_FTDC_CC_Immediately;
//止损价
ord.StopPrice = 0;
//强平原因
ord.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
//自动挂起标志
ord.IsAutoSuspend =0;
m_pUserApi->ReqOrderInsert(&ord,1);
}
//保单录入应答
virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
//输出保单录入结果
printf("ErrorCode=[%d],ErrorMsg=[%s]\n",pRspInfo->ErrorID, pRspInfo->ErrorMsg);

//通知保单录入完成
SetEvent(g_hEvent);
}
//保单回报
virtual void OnRtnOrder(CThostFtdcOrderField *pOrder)
{
printf("OnRtnOrder:\n");
printf("OrderSysID=[%s]\n", pOrder->OrderSysID);
}

//针对用户请求的出错通知
virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
printf("OnRspError:\n");
printf("ErrorCode=[%d],ErrorMsg=[%s]\n",pRspInfo->ErrorID,pRspInfo->ErrorMsg);
printf("RequestID=[%d],Chain=[%d]\n",nRequestID,bIsLast);
//客户端需要进行错误处理
{
//客户端的错误处理
}
}
private:
//指向CThostFtdcMduserApi实例的指针
CThostFtdcTraderApi *m_pUserApi;
};
int main()
{
//产生一个CThostFtdcTraderApi实例
CThostFtdcTraderApi *pUserApi = CThostFtdcTraderApi::CreateFtdcTraderApi();
//产生一个事件处理的实例
CSimpleHandler sh(pUserApi); //相当于将sh依附于pUserApi
//注册一个事件处理的实例
pUserApi->RegisterSpi(&sh); //pUserApi发生的一切事件都会调用sh中的处理函数
//订阅私有流
// TERT_RESTART: 从本交易日开始重传
// TERT_RESUME: 从上次收到的续传
// TERT_QUICK: 只传送登录后私有流的内容
pUserApi->SubscribePrivateTopic(THOST_TERT_RESUME);
//订阅公共流
// TERT_RESTART:从本交易日开始重传
// TERT_RESUME: 从上次收到的续传
// TERT_QUICK: 只传送登录后公共流的内容
pUserApi->SubscribePublicTopic(THOST_TERT_RESUME);
//设置交易托管系统服务的地址,可以注册多个地址备用
pUserApi->RegisterFront("tcp://172.16.0.31:57205");
//使客户端开始与后台服务器建立连接
pUserApi->Init();
//客户端等待报单操作完成
WaitForSingleObject(g_hEvent,INFINITE);
//释放API实例
pUserApi->Release();
return 0;
}
整个函数的重点在于新建立的CSimpleHandler是如何实现CThostFtdcTraderSpi的各个虚函数的,正是这种个性话的操作才让程序化控制交易流程得以实现. 这些虚函数和回调函数很像,有点像是模拟窗口程序的特点。
另外main函数实现了这样一个流程:创建Api对象(pUserApi)-> 注册事件处理对象 (sh)-> 订阅共有流(SubscribePublicTopic-> 订阅私有流(SubscribePrivateTopic-> 注册前置机(RegisterFront-> 初始化Api(Init)。至于初始化过程后面的内容,以后再慢慢研究了^_^

通过对CSimpleHandler的观察,不难得出交易系统处理报单大致是这样一个流程:
综合交易系统 <wbr>第一次运行

另外从网上流传的一个交易开发流程的实例里面可以看出CThostFtdcTraderSpi应该不止这样六个虚函数,从网上收集了一下,至少有这些虚函数需要去实现:

1. OnFrontConnected : 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
2. OnRspUserLogin : 登录请求响应, 当连接成功之后会调用这个函数
3. OnRspSettlementInfoConfirm: 投资者结算结果确认响应
4. OnRspQryInstrument: 请求查询合约响应
5. OnRspQryTradingAccount: 请求查询资金账户响应
6. OnRspQryInvestorPosition: 请求查询投资者持仓响应
7. OnRspOrderInsert : 报单录入请求响应, 可以在OnRspUserLogin后面就下单,当然什么时候下单都可以,看程序怎么调了。程序员可以自行安排下单的时间和顺序。
8. OnRspOrderAction : 报单操作请求响应
9. OnRspError : 错误应答
10. OnFrontDisconnected : 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
11. OnHeartBeatWarning : 心跳超时警告。当长时间未收到报文时,该方法被调用。
12. OnRtnOrder : 报单通知,也叫报单回报。 应该是交易所回传过来的报单信息
13. OnRtnTrade : 成交通知

 

原创粉丝点击