第六节 代码的编写(6)
撤单按钮:
这个内容是一个系列的内容,这一节相对内容少一点,
需要查看原文件的读者,欢迎前往 :https://ipacel.cc/ctp
void CMyCtpDlg::OnBnClickedButtoncance()
{
if (!LOGIN_TR_FLAG) { return; }
if (GuaDan_Volume > 0)
{
CThostFtdcInputOrderActionField req;
memset(&req, 0, sizeof(req));
///经纪公司代码
strcpy_s(req.BrokerID, BROKER_ID);
///投资者代码
strcpy_s(req.InvestorID, INVESTOR_ID);
//报单引用 1
TThostFtdcOrderRefType Cance_OrderRef;
strcpy_s(Cance_OrderRef, GuaDan_OrderRef.c_str());
strcpy_s(req.OrderRef, Cance_OrderRef); ///ORDER_REF);
///交易所代码 2
TThostFtdcExchangeIDType Cance_ExchangeID;
strcpy_s(Cance_ExchangeID, Gua_Dan_ExchangeID.c_str());
strcpy_s(req.ExchangeID, Cance_ExchangeID);
///报单编号 3
TThostFtdcOrderSysIDType Cance_OrderSysID;
strcpy_s(Cance_OrderSysID, Gua_Dan_OrderSysID.c_str());
strcpy_s(req.OrderSysID, Cance_OrderSysID);
TThostFtdcInstrumentIDType Cance_INSTRUMENT_ID; // 合约代码
strcpy_s(Cance_INSTRUMENT_ID, GuaDan_InstrumentID.c_str());
///合约代码
strcpy_s(req.InstrumentID, Cance_INSTRUMENT_ID);
///操作标志
req.ActionFlag = THOST_FTDC_AF_Delete;
///请求编号
// TThostFtdcRequestIDType RequestID;
///前置编号
req.FrontID = FRONT_ID;
///会话编号
req.SessionID = SESSION_ID;
///用户代码 UserID非必填,是操作员账号,不填写会收不到OnErrRtnOrderAction回报 一般客户和InvestorID填写一样就可以
// TThostFtdcUserIDType UserID;
strcpy_s(req.UserID, INVESTOR_ID);
int iResult = pUserTrApi->ReqOrderAction(&req, ++iRequestTRID);
GuaDan_Volume = 0; ///先置0,以免重复撤单
}
}
/
代码讲解,这部分代码我用一个 GuaDan_Volume 参数,用来判断挂单数量,如果大于 0,则表示有挂单,则执行撤单操作。这里需要说明的是,撤单的信息是在未成交回报数据返回的时候,我们在显示这些数据的时候,把需要撤单的信息记录下来了,这里就只需要直接撤就可以了,记录撤信息在后面的 接收报单数据 的按钮中进行讲解。
执行策略按钮:这个按扭里面是空的,什么都没有写,就是留给读者自己按自己的策略编写代码即可。
信息显示栏:
void CMyCtpDlg::MsgDis(int iIF, CString MsgStr) ///显示消息
{
CString ss1; 序号
int i = m_IDC_LIST_IF.GetCount();
if (i >= 999) { m_IDC_LIST_IF.ResetContent(); i = 0; } ///清空
ss1.Format(_T("%d: "), i + 1);
switch (iIF)
{
case 205: {m_IDC_LIST_IF.AddString(ss1 + _T("205 ") + MsgStr); break; }
case 299: {m_IDC_LIST_IF.AddString(ss1 + _T("299 ") + MsgStr); break; }
case 303: {m_IDC_LIST_IF.AddString(ss1 + _T("303 ") + MsgStr); break; }
case 307: {m_IDC_LIST_IF.AddString(ss1 + _T("307 ") + MsgStr); break; }
case 353: {m_IDC_LIST_IF.AddString(ss1 + _T("353 ") + MsgStr); break; }
case 355: {m_IDC_LIST_IF.AddString(ss1 + _T("355 ") + MsgStr); break; }
case 356: {m_IDC_LIST_IF.AddString(ss1 + _T("356 ") + MsgStr); break; }
case 357: {m_IDC_LIST_IF.AddString(ss1 + _T("357 ") + MsgStr); break; }
case 358: {m_IDC_LIST_IF.AddString(ss1 + _T("358 ") + MsgStr); break; }
case 359: {m_IDC_LIST_IF.AddString(ss1 + _T("359 ") + MsgStr); break; }
case 396: {m_IDC_LIST_IF.AddString(ss1 + _T("396 ") + MsgStr); break; }
case 397: {m_IDC_LIST_IF.AddString(ss1 + _T("397 ") + MsgStr); break; }
case 398: {m_IDC_LIST_IF.AddString(ss1 + _T("398 ") + MsgStr); break; }
case 399: {m_IDC_LIST_IF.AddString(ss1 + _T("399 ") + MsgStr); break; }
default: {m_IDC_LIST_IF.AddString(ss1 + MsgStr); break; };
}
m_IDC_LIST_IF.SetCurSel(i);
}
/
这段代码的作用就是把信息显示出来给操作人员看的,这个比较简单,不讲解了。这个代还可以写得很简单,只需要几句代码就可以了,这里就不改写了,读者可以自已修改一下,让代码更简洁美观。