分享

[转载]综合交易系统第一次运行

 昵称D0XW1 2015-06-24
[转载]综合交易系统 <wbr>第一次运行

当然不知道这个输出的结果是个什么意思,要仔细研究也要花上不少的精力。内心里还是很想弄明白程序的整个操作过程,但此时天色已经很晚了,脑袋昏昏的,看那些文字材料不知道要看到什么时候。看到《综合交易平台交易API特别说明》后面有一段代码挺不错的,很想将代码的实现过程弄清楚。可能硬着头皮看,不知道什么时候能看完。于是我打算一边打代码,一边揣摩每段代码的含义。花了差不多一个小时的时间,我敲完了代码,并对代码要实现的东西进行了一些总结。
现将代码贴出如下:
 
// tradeapitest.cpp
// 一个简单的例子, 介绍CThostFtdcTraderApi和CThostFtdcTraderSpi接口的使用
//本例将演示一个报单录入操作的过程
//CThostFtdcTraderApi : Api对象
//CThostFtdcTraderSpi : 事件处理对象
#include <stdio.h>
#include <windows.h>
#include ".ThostTraderApiThostFtdcTraderApi.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 : 成交通知

今天就写到这里了,已经晚上4:30了,回去睡觉觉了!






    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多