一、下单
下单用限价单方法,目前支持市价单的只有郑商所和大商所。但是如果想要在其他交易所下市价单,也可通过下限价为跌停价或者涨停价的限价单达到同样的效果。
二、查询持仓
CTP查询持仓直接调用交易API中的持仓查询方法ReqQryInvestorPosition(InstrumentID, ExchangeID)即可,但系统限定查询间隔为1秒以上,否则会返回查仓查询错误,错误代码为-2。
CTP系统在下单之后仓位不会立刻变化,因此,在下单之后sleep一下再查询持仓,才可以得到正确的仓位数据。
ReqOrderInsert_Ordinary(orderData.ExchangeID, orderData.InstrumentID,
orderData.Direction, orderData.dPrice, orderData.cOffsetFlag,
orderData.g_chVolume);
WaitForSingleObject(g_hEvent, INFINITE); ///返回撤单或者返回成交回报
Sleep(1000);
ReqQryInvestorPosition(orderData.InstrumentID, orderData.ExchangeID);
WaitForSingleObject(g_hEvent, INFINITE); ///仓位查询通知
但是如果模型运行的周期较小或者网络等原因,仓位来不及变化会对模型的判断造成影响。因此,建议在程序开始运行的时候查询初始仓位,随后自己结合报单通知和成交回报记录仓位。
通过设置信号句柄约束程序执行的逻辑。
///成交回报
virtual void OnRtnTrade(CThostFtdcTradeField* pTrade)
{
printf("<成交回报>\n");
ofstream ofile;
if (pTrade && strcmp(pTrade->InvestorID, g_chInvestorID) != 0)
{
return;
}
else
{
CTraderSpi::OnRtnTrade(pTrade);
strcpy_s(g_chOrderSysID, pTrade->OrderSysID);
strcpy_s(g_chOrderRef, pTrade->OrderRef);
strcpy_s(g_chExchangeID, pTrade->ExchangeID);
for (int iMDObjNum = 0; iMDObjNum < md_InstrumentID.size(); iMDObjNum++)
{
if (0 == strcmp(md_InstrumentID[iMDObjNum].c_str(), pTrade->InstrumentID))
{
if (pTrade->Direction == '0' && pTrade->OffsetFlag == '0') //开多
{
strcpy(longPositionData[iMDObjNum].InstrumentID, pTrade->InstrumentID);
longPositionData[iMDObjNum].PosiDirection = pTrade->Direction;
longPositionData[iMDObjNum].Volume = pTrade->Volume;
longPositionData[iMDObjNum].avgPrice = pTrade->Price;
}
if (pTrade->Direction == '1' && pTrade->OffsetFlag == '3') //平多
{
strcpy(longPositionData[iMDObjNum].InstrumentID, pTrade->InstrumentID);
longPositionData[iMDObjNum].PosiDirection = pTrade->Direction;
longPositionData[iMDObjNum].Volume = longPositionData[iMDObjNum].Volume - pTrade->Volume;
longPositionData[iMDObjNum].avgPrice = pTrade->Price;
}
if (pTrade->Direction == '1' && pTrade->OffsetFlag == '0') //开空
{
strcpy(shortPositionData[iMDObjNum].InstrumentID, pTrade->InstrumentID);
shortPositionData[iMDObjNum].PosiDirection = pTrade->Direction;
shortPositionData[iMDObjNum].Volume = pTrade->Volume;
shortPositionData[iMDObjNum].avgPrice = pTrade->Price;
}
if (pTrade->Direction == '0' && pTrade->OffsetFlag == '3') //平空
{
strcpy(shortPositionData[iMDObjNum].InstrumentID, pTrade->InstrumentID);
shortPositionData[iMDObjNum].PosiDirection = pTrade->Direction;
shortPositionData[iMDObjNum].Volume = shortPositionData[iMDObjNum].Volume - pTrade->Volume;
shortPositionData[iMDObjNum].avgPrice = pTrade->Price;
}
}
}
ofile.open("tradeHistory.csv", ios::app);
ofile << pTrade->TradeTime << "," << pTrade->ExchangeID << "," << pTrade->InstrumentID << ","
<< pTrade->Direction << "," << pTrade->Price << "," << pTrade->Volume << "," << pTrade->OffsetFlag << endl;
ofile.close();
}
SetEvent(g_hEvent);
printf("</成交回报>\n");
}