第六节 代码的编写(2)
- 登陆交易:在写完登入行情部分界面上的代码后,再看一下登入交易这部分的代码,这部分在界面上内容比较简单,跟行情部分差不多,多了两个内容,订阅公共流,订阅私有流,说明一下,公共流就是指大家都能看到的公告,信息等,私有流,就是只传给你一个看的内容,比如交易信息,结算单确认等,看代码:
CMyCtpDlg::MsgDis(888, _T("正在连接交易服务器,请稍等..."));
CThostFtdcTraderSpi* pTraderSpi = new CTraderSpi; //创建spi对象
pUserTrApi = CThostFtdcTraderApi::CreateFtdcTraderApi(".\\flow\\"); //创建API对象
//将任务队列指针传给spi,由spi处理回调事宜
//将spi注册给api
pUserTrApi->RegisterSpi(pTraderSpi);
pUserTrApi->RegisterFront(FRONT_TR_ADDR);
pUserTrApi->SubscribePublicTopic(THOST_TERT_QUICK); //订阅公共流
pUserTrApi->SubscribePrivateTopic(THOST_TERT_QUICK); //订阅私有流
pUserTrApi->Init();
if (WAIT_TIMEOUT == WaitForSingleObject(TrXc, 5000)) {MsgDis(888, _T("连接交易服务器失败,连接超时")); }
//
跟行情一样的,这里也有一个回调函数的注册:pUserTrApi->RegisterSpi(pTraderSpi);
登陆成功后,就是在回调函数里写上自己需要处理的内容代码
第六节 代码的编写(3)
这一小节,我看一下订阅\退订\查询这一区域的代码,这部分的代码执行是在登陆行情与交易成功后才能进行的操作,否则点击是没有效果的,先看一下订阅这个按钮的代码:
void CMyCtpDlg::OnBnClickedButton1()
{
if (!LOGIN_MD_FLAG) { return; } //判断是不是已经成功登入行情服务器了
CString STRTEMP = _T("");
GetDlgItem(IDC_EDIT_INSTid)->GetWindowTextW(STRTEMP);
STRTEMP.Trim();
if (STRTEMP != "")
{
CStringToCharP(STRTEMP, ppInstrumentID);
CStringToChar(STRTEMP, INSTRUMENT_ID);
pUserMdApi->SubscribeMarketData(ppInstrumentID, 1); ///只订阅一个
}
else
{
return;
}
}
/
这个代码比较简单,先从输入框中取得合约的代码,再把合约的代码进行一下字符转换,然后调后CTP提供的API接口函数SubscribeMarketData() 进行订阅。
这里需要说明一下,CTP数据结构及变量的数据类型,很多是 string 或 char 型的,我们在windows下编程,要注意编程环境所用的数据类型,根据需要进行转换。
再看一下退订这个按钮的代码:
void CMyCtpDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
if (!LOGIN_MD_FLAG) { return; }
CString STRTEMP = _T("");
GetDlgItem(IDC_EDIT_INSTid)->GetWindowTextW(STRTEMP);
STRTEMP.Trim();
if (STRTEMP != "")
{
CStringToCharP(STRTEMP, ppInstrumentID);
pUserMdApi->UnSubscribeMarketData(ppInstrumentID, 1); ///只订阅一个
CMyCtpDlg::MsgDis(888, _T("取消一个合约行情的订阅..."));
m_IDC_LIST_MD.DeleteAllItems(); ///删除
}
}
跟订阅差不多,只说明一个地方,最后这一句:m_IDC_LIST_MD.DeleteAllItems(); ///删除
这句的目的是为了在行情显示栏中把退订的合约之前的行情数据删除了,否则,行情显示栏上还会有退订的合约在上面,只是不更新数据而已。
第六节 代码的编写(4)
另外两个按钮的代码,分别实现 查持数据,查挂单数据 的功能,我们在下单成交后,如果是开仓,我们的持仓就会增加数据,点一下 查持仓数据,就会返回持仓数据,然后我们把返回的数据显示在相应的持仓明细栏中,查挂单数据 也是同样的功能,我们直接看代码:
void CMyCtpDlg::OnBnClickedButton9()
{
if (!LOGIN_TR_FLAG) { return; }
all_PosDatas.clear(); ///清容器
CThostFtdcQryInvestorPositionDetailField req;
memset(&req, 0, sizeof(req));
strcpy_s(req.BrokerID, BROKER_ID);
strcpy_s(req.InvestorID, INVESTOR_ID);
int iResult = pUserTrApi->ReqQryInvestorPositionDetail(&req, ++iRequestTRID);
MsgDis(999, _T("请求查询持仓数据..."));
}
void CMyCtpDlg::OnBnClickedButton10()
{
if (!LOGIN_TR_FLAG) { return; }
all_OrderDatas.clear(); //清容器
CThostFtdcQryOrderField req;
memset(&req, 0, sizeof(req));
strcpy_s(req.BrokerID, BROKER_ID);///经纪公司代码
strcpy_s(req.InvestorID, INVESTOR_ID);///投资者代码
int iResult = pUserTrApi->ReqQryOrder(&req, ++iRequestTRID);
MsgDis(999, _T("请求查询挂单数据..."));
}
///
为了读者复制代码方便,我用分隔符把代码部分隔一下。
这里简单介绍一下代码的意思,第一句,判断是不是已经登陆交易服务器,第二句,清容器,数据返回我们先把数据装进一个容器里,再从容器里把数据取出来显示到界面上,所以,在查询数据之前,先把容器清空一下,因为可能存有之前的旧数据。
后面就是把参数赋值给对应的请求函数,执行完这一段代码,我们就从回调函数中把数据取回来,显示到界面上就可以了。
需要查看原文件的读者,欢迎前往 :https://ipacel.cc/ctp
看代码是一件很枯燥的事情,欢迎读者朋友加作者的微信(最后会留微信联系方式),索取源码,直接看源码,源码里也有相应的说明,加入我们的CTP期货程序化交易开发VIP群里,我们接供源码一对一讲解服务。