CTP 交易该如何
如果只是一个CTP用户,这样可能实现的要简单一下
需要继承CThostFtdcTraderSpi来实现自己的CustomTradeSpi类,用于交易下单、报单等操作的回调
除了重写的基类函数,还自己封装一些主动调用的操作函数,比如登入登出、下单报单、查询报单等
其中登入功能需要
前置机地址
brokerid
用户名
密码
甚至有的期货公司需要进行客户端认证的功能
关键就是报单接口和回报接口
- void CustomTradeSpi::reqOrderInsert(
- TThostFtdcInstrumentIDType instrumentID,
- TThostFtdcPriceType price,
- TThostFtdcVolumeType volume,
- TThostFtdcDirectionType direction)
- {
- CThostFtdcInputOrderField orderInsertReq;
- memset(&orderInsertReq, 0, sizeof(orderInsertReq));
- ///经纪公司代码
- strcpy(orderInsertReq.BrokerID, gBrokerID);
- ///投资者代码
- strcpy(orderInsertReq.InvestorID, gInvesterID);
- ///合约代码
- strcpy(orderInsertReq.InstrumentID, instrumentID);
- ///报单引用
- strcpy(orderInsertReq.OrderRef, order_ref);
- ///报单价格条件: 限价
- orderInsertReq.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
- ///买卖方向:
- orderInsertReq.Direction = direction;
- ///组合开平标志: 开仓
- orderInsertReq.CombOffsetFlag[0] = THOST_FTDC_OF_Open;
- ///组合投机套保标志
- orderInsertReq.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
- ///价格
- orderInsertReq.LimitPrice = price;
- ///数量:1
- orderInsertReq.VolumeTotalOriginal = volume;
- ///有效期类型: 当日有效
- orderInsertReq.TimeCondition = THOST_FTDC_TC_GFD;
- ///成交量类型: 任何数量
- orderInsertReq.VolumeCondition = THOST_FTDC_VC_AV;
- ///最小成交量: 1
- orderInsertReq.MinVolume = 1;
- ///触发条件: 立即
- orderInsertReq.ContingentCondition = THOST_FTDC_CC_Immediately;
- ///强平原因: 非强平
- orderInsertReq.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
- ///自动挂起标志: 否
- orderInsertReq.IsAutoSuspend = 0;
- ///用户强评标志: 否
- orderInsertReq.UserForceClose = 0;
- static int requestID = 0; // 请求编号
- int rt = g_pTradeUserApi->ReqOrderInsert(&orderInsertReq, ++requestID);
- if (!rt)
- std::cout << ">>>>>>发送报单录入请求成功" << std::endl;
- else
- std::cerr << "--->>>发送报单录入请求失败" << std::endl;
- }
- void CustomTradeSpi::reqOrderAction(CThostFtdcOrderField *pOrder)
- {
- static bool orderActionSentFlag = false; // 是否发送了报单
- if (orderActionSentFlag)
- return;
- CThostFtdcInputOrderActionField orderActionReq;
- memset(&orderActionReq, 0, sizeof(orderActionReq));
- ///经纪公司代码
- strcpy(orderActionReq.BrokerID, pOrder->BrokerID);
- ///投资者代码
- strcpy(orderActionReq.InvestorID, pOrder->InvestorID);
- ///报单操作引用
- // TThostFtdcOrderActionRefType OrderActionRef;
- ///报单引用
- strcpy(orderActionReq.OrderRef, pOrder->OrderRef);
- ///请求编号
- // TThostFtdcRequestIDType RequestID;
- ///前置编号
- orderActionReq.FrontID = trade_front_id;
- ///会话编号
- orderActionReq.SessionID = session_id;
- ///交易所代码
- // TThostFtdcExchangeIDType ExchangeID;
- ///报单编号
- // TThostFtdcOrderSysIDType OrderSysID;
- ///操作标志
- orderActionReq.ActionFlag = THOST_FTDC_AF_Delete;
- ///价格
- // TThostFtdcPriceType LimitPrice;
- ///数量变化
- // TThostFtdcVolumeType VolumeChange;
- ///用户代码
- // TThostFtdcUserIDType UserID;
- ///合约代码
- strcpy(orderActionReq.InstrumentID, pOrder->InstrumentID);
- static int requestID = 0; // 请求编号
- int rt = g_pTradeUserApi->ReqOrderAction(&orderActionReq, ++requestID);
- if (!rt)
- std::cout << ">>>>>>发送报单操作请求成功" << std::endl;
- else
- std::cerr << "--->>>发送报单操作请求失败" << std::endl;
- orderActionSentFlag = true;
- }
- void CustomTradeSpi::OnRtnOrder(CThostFtdcOrderField *pOrder)
- {
- char str[10];
- sprintf(str, "%d", pOrder->OrderSubmitStatus);
- int orderState = atoi(str) - 48; //报单状态0=已经提交,3=已经接受
- std::cout << "=====收到报单应答=====" << std::endl;
- if (isMyOrder(pOrder))
- {
- if (isTradingOrder(pOrder))
- {
- std::cout << "--->>> 等待成交中!" << std::endl;
- //reqOrderAction(pOrder); // 这里可以撤单
- //reqUserLogout(); // 登出测试
- }
- else if (pOrder->OrderStatus == THOST_FTDC_OST_Canceled)
- std::cout << "--->>> 撤单成功!" << std::endl;
- }
- }
- void CustomTradeSpi::OnRtnTrade(CThostFtdcTradeField *pTrade)
- {
- std::cout << "=====报单成功成交=====" << std::endl;
- std::cout << "成交时间: " << pTrade->TradeTime << std::endl;
- std::cout << "合约代码: " << pTrade->InstrumentID << std::endl;
- std::cout << "成交价格: " << pTrade->Price << std::endl;
- std::cout << "成交量: " << pTrade->Volume << std::endl;
- std::cout << "开平仓方向: " << pTrade->Direction << std::endl;
- }
如果是多个session的情况
又该如何考虑?
值得我们深究一下