#include <stdio.h>
#include "QdpFtdcTraderApi.h"
// 经纪公司代码
TQdpFtdcBrokerIDType g_chBrokerID;
// 交易用户代码
TQdpFtdcUserIDType g_chUserID;
//用户本地最大报单号
int g_UserOrderLocalID = 1;
class CSimpleHandler : public CQdpFtdcTraderSpi
{
public:
// 构造函数,需要一个有效的指向CQdpFtdcMduserApi实例的指针
CSimpleHandler(CQdpFtdcTraderApi *pUserApi) :
m_pUserApi(pUserApi) {}
~CSimpleHandler() {}
// 发出报单录入请求
int SendOrder()
{
CQdpFtdcInputOrderField ord;
memset(&ord, 0, sizeof(ord));
//经纪公司代码
strcpy(ord.BrokerID, g_chBrokerID);
//交易所
strcpy(ord.ExchangeID, "GFEX");
//投资者代码
strcpy(ord.InvestorID, "guofugqs0001");
// 用户代码
strcpy(ord.UserID, g_chUserID);
// 合约代码
strcpy(ord.InstrumentID, "lc2307");
//本地报单号
ord.UserOrderLocalID = g_UserOrderLocalID;
//sprintf(ord.UserOrderLocalID,"%012d", 91000001);
//报单类型
ord.OrderPriceType = QDP_FTDC_OPT_LimitPrice;
// 买卖方向
//strcpy(&(ord.Direction) , "1");
ord.Direction = QDP_FTDC_D_Buy;
// 开平标志
strcpy(&(ord.OffsetFlag), "0");
// 投机套保标志
ord.HedgeFlag = QDP_FTDC_CHF_Speculation;
// 价格
ord.LimitPrice = 228550;
// 数量
ord.Volume = 1;
// 有效期类型
//strcpy(&(ord.TimeCondition),"3" );
ord.TimeCondition = QDP_FTDC_TC_GFD;
//成交量类型
ord.VolumeCondition = QDP_FTDC_VC_AV;
//触发条件
//ord = QDP_FTDC_CC_Immediately
//强平原因
ord.ForceCloseReason = QDP_FTDC_FCR_NotForceClose;
// 自动挂起标志
ord.IsAutoSuspend = 0;
int ret = m_pUserApi->ReqOrderInsert(&ord, 0);
return ret;
}
// 发出撤单请求
void SendOrderAction()
{
CQdpFtdcOrderActionField ord;
memset(&ord, 0, sizeof(CQdpFtdcOrderActionField));
//经纪公司代码
strcpy(ord.BrokerID, "guofu");
//交易所
strcpy(ord.ExchangeID, "GFEX");
//投资者代码
strcpy(ord.InvestorID, "guofugqs0001");
// 用户代码
strcpy(ord.UserID, "gqs001");
strncpy(ord.OrderSysID, "60000221", sizeof(ord.OrderSysID));
// 合约代码
//strcpy(ord.InstrumentID, "lc2307");
//本地报单号
//ord.UserOrderActionLocalID = ++g_UserOrderLocalID;
//ord.UserOrderLocalID = 200;
ord.ActionFlag = QDP_FTDC_AF_Delete;
m_pUserApi->ReqOrderAction(&ord, 0);
}
// 合约查询请求
void QryInstrument()
{
CQdpFtdcQryInstrumentField tReq;
memset(&tReq, 0, sizeof(CQdpFtdcQryInstrumentField));
strncpy(tReq.ExchangeID, "CZCE", sizeof(tReq.ExchangeID));
//strncpy(tReq.InstrumentID, "IPS CF001&SR001", sizeof(tReq.InstrumentID));
strncpy(tReq.InstrumentID, "SPD CF011&CF103", sizeof(tReq.InstrumentID));
m_pUserApi->ReqQryInstrument(&tReq, 0);
}
// 持仓查询请求
void QryPosition()
{
CQdpFtdcQryInvestorPositionField tReq;
memset(&tReq, 0, sizeof(CQdpFtdcQryInvestorPositionField));
strncpy(tReq.BrokerID, g_chBrokerID, sizeof(tReq.BrokerID));
strncpy(tReq.UserID, g_chUserID, sizeof(tReq.UserID));
m_pUserApi->ReqQryInvestorPosition(&tReq, 0);
}
// 登录请求
void Login()
{
strcpy(g_chBrokerID, "guofu");
strcpy(g_chUserID, "m001");
CQdpFtdcReqUserLoginField reqUserLogin;
strcpy(reqUserLogin.BrokerID, g_chBrokerID);
strcpy(reqUserLogin.UserID, g_chUserID);
strcpy(reqUserLogin.Password, "1");
// 发出登陆请求
m_pUserApi->ReqUserLogin(&reqUserLogin, 0);
}
// 登录认证请求
int ReqAuth()
{
strcpy(g_chBrokerID, "guofu");
strcpy(g_chUserID, "m001");
CQdpFtdcAuthenticateField tReq;
memset(&tReq, 0, sizeof(CQdpFtdcAuthenticateField));
strncpy(tReq.AppID, "client_test_1.0", sizeof(tReq.AppID));
strncpy(tReq.AuthCode, "123456", sizeof(tReq.AuthCode));
strncpy(tReq.BrokerID, g_chBrokerID, sizeof(tReq.BrokerID));
strncpy(tReq.UserID, g_chUserID, sizeof(tReq.UserID));
return m_pUserApi->ReqAuthenticate(&tReq, 0);
}
// 双边报价请求
int SendQuoteOrder()
{
CQdpFtdcInputQuoteField quoteord;
memset("eord, 0, sizeof(CQdpFtdcInputQuoteField));
//经纪公司代码
strcpy(quoteord.BrokerID, "guofu");
//交易所
strcpy(quoteord.ExchangeID, "DCE");
//投资者代码
strcpy(quoteord.InvestorID, "guofu0001");
// 用户代码
strcpy(quoteord.UserID, g_chUserID);
// 合约代码
strcpy(quoteord.InstrumentID, "a2205");
quoteord.AskPrice = 7588;
quoteord.AskVolume = 3;
quoteord.AskOffsetFlag = QDP_FTDC_OF_Close;
quoteord.AskHedgeFlag = QDP_FTDC_CHF_Speculation;
quoteord.BidPrice = 7590;
quoteord.BidVolume = 3;
quoteord.BidOffsetFlag = QDP_FTDC_OF_Open;
quoteord.BidHedgeFlag = QDP_FTDC_CHF_Speculation;
quoteord.UserOrderLocalID = g_UserOrderLocalID;
quoteord.BidOrderRef = ++g_UserOrderLocalID;
quoteord.AskOrderRef = ++g_UserOrderLocalID;
int iRet = m_pUserApi->ReqQuoteInsert("eord, 0);
return iRet;
}
// 当客户端与量投科技建立起通信连接,客户端需要进行登录
virtual void OnFrontConnected()
{
printf("OnFrontConnected\n");
/*int nRet = ReqAuth();
printf("ReqAuthenticate:%d\n", nRet);*/
Login(); //无需认证的情况下可以直接登录
}
// 当客户端与量投科技通信连接断开时,该方法被调用
virtual void OnFrontDisconnected(int nReason)
{
// 当发生这个情况后,API会自动重新连接,客户端可不做处理
printf("OnFrontDisconnected, Reason=[%d].\n", nReason);
}
// 当客户端发出登录请求之后,该方法会被调用,通知客户端登录是否成功
virtual void OnRspUserLogin(CQdpFtdcRspUserLoginField *pRspUserLogin,
CQdpFtdcRspInfoField *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);
printf("maxlocalid=[%d]\n", pRspUserLogin->MaxOrderLocalID);
if (pRspInfo->ErrorID != 0)
{
// 端登失败,客户端需进行错误处理
printf("Failed to login, errorcode=%d errormsg=%s requestid=%d chain=%d",
pRspInfo->ErrorID, pRspInfo->ErrorMsg, nRequestID, bIsLast);
}
//准备就绪 QDP_TERT_PRIVATE 私有流; QDP_TERT_PUBLIC 公有流;
CQdpFtdcFlowStatusField ftdField1;
ftdField1.SequenceSeries = QDP_TERT_PRIVATE;
ftdField1.bReady = true;
m_pUserApi->ReqReady(&ftdField1, 0);
ftdField1.SequenceSeries = QDP_TERT_PUBLIC;
ftdField1.bReady = true;
m_pUserApi->ReqReady(&ftdField1, 0);
//QryPosition();
//QryInstrument();
//SendQuoteOrder();
SendOrder();
//SendOrderAction();
}
///登录认证应答
virtual void OnRspAuthenticate(CQdpFtdcRtnAuthenticateField *pRtnAuthenticate, CQdpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
if (NULL == pRtnAuthenticate)
{
printf("NULL == pRtnAuthenticate\n");
return;
}
if (NULL == pRspInfo)
{
printf("NULL == pRspInfo\n");
return;
}
printf("OnRspAuthenticate: ErrorID=[%d], ErrorMsg=[%s]\n", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
if (0 != pRspInfo->ErrorID)
{
return;
}
Login();
}
void OnRspQryInstrument(CQdpFtdcRspInstrumentField *pRspInstrument, CQdpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
if (pRspInstrument)
{
printf("OnRspQryInstrument===>[%s],LowerLimitPrice=[%f],UpperLimitPrice=[%f]\n", pRspInstrument->InstrumentID, pRspInstrument->LowerLimitPrice, pRspInstrument->UpperLimitPrice);
}
}
void OnRspQuoteInsert(CQdpFtdcInputQuoteField *pInputQuote, CQdpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
if (NULL == pRspInfo)
{
printf("NULL == pRspInfo\n");
return;
}
printf("OnRspQuoteInsert: ErrorID=[%d], ErrorMsg=[%s]\n", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
}
// 报单录入应答
virtual void OnRspOrderInsert(CQdpFtdcInputOrderField *pInputOrder,
CQdpFtdcRspInfoField *pRspInfo,
int nRequestID,
bool bIsLast)
{
if (NULL == pRspInfo)
{
printf("NULL == pRspInfo\n");
return;
}
// 输出报单录入结果
printf("OnRspOrderInsert ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
if (pRspInfo->ErrorID != 0)
{
printf("\n");
return;
}
if (NULL == pInputOrder)
{
printf("\nNULL == pInputOrder\n");
return;
}
printf(", orderSysID=[%s]\n", pInputOrder->OrderSysID);
}
virtual void OnRspOrderAction(CQdpFtdcOrderActionField *pOrderAction, CQdpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
if (NULL == pRspInfo)
{
printf("NULL == pRspInfo\n");
return;
}
printf("OnRspOrderAction ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID, pRspInfo->ErrorMsg);
if (pRspInfo->ErrorID != 0)
{
printf("\n");
return;
}
if (NULL == pOrderAction)
{
printf("\nNULL == pOrderAction\n");
return;
}
printf(", orderSysID=[%s]\n", pOrderAction->OrderSysID);
}
///报单回报
void OnRtnOrder(CQdpFtdcOrderField *pOrder)
{
if (NULL == pOrder)
{
printf("NULL == pOrder\n");
}
printf("OnRtnOrder->OrderSysID=[%s], OrderStatus=[%c]\n", pOrder->OrderSysID, pOrder->OrderStatus);
}
void OnRtnTrade(CQdpFtdcTradeField *pTrade)
{
if (NULL == pTrade)
{
printf("NULL == pTrade\n");
}
printf("OnRtnTrade->OrderSysID=[%s], tradeID=[%s]\n", pTrade->OrderSysID, pTrade->TradeID);
}
virtual void OnRtnInstrumentStatus(CQdpFtdcInstrumentStatusField *pInstrumentStatus)
{
if (NULL == pInstrumentStatus)
{
printf("NULL == pInstrumentStatus\n");
return;
}
printf("OnRtnInstrumentStatus:ExchangeID=[%s],InstrumentID=[%s],InstrumentStatus=[%c]\n",
pInstrumentStatus->ExchangeID, pInstrumentStatus->InstrumentID, pInstrumentStatus->InstrumentStatus);
}
void OnRspQryInvestorPosition(CQdpFtdcRspInvestorPositionField *pRspInvestorPosition, CQdpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
if (pRspInvestorPosition)
{
printf("OnRspQryInvestorPosition:InvestorID=[%s],ExchangeID=[%s],InsturmentID=[%s],Position=[%d]\n",
pRspInvestorPosition->InvestorID, pRspInvestorPosition->ExchangeID, pRspInvestorPosition->InstrumentID, pRspInvestorPosition->Position);
}
}
// 针对用户请求的出错通知
virtual void OnRspError(CQdpFtdcRspInfoField *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:
// 指向CQdpFtdcMduserApi实例的指针
CQdpFtdcTraderApi *m_pUserApi;
};
int main()
{
// 产生一个CQdpFtdcTraderApi实例
CQdpFtdcTraderApi *pUserApi = CQdpFtdcTraderApi::CreateFtdcTraderApi();
// 产生一个事件处理的实例
CSimpleHandler sh(pUserApi);
// 注册一事件处理的实例
pUserApi->RegisterSpi(&sh);
// 订阅私有流
// Qdp_TERT_RESTART:从本交易日开始重传
// Qdp_TERT_RESUME:从上次收到的续传
// Qdp_TERT_QUICK:只传送登录后私有流的内容
pUserApi->SubscribePrivateTopic(QDP_TERT_RESUME);
// 订阅公共流
// Qdp_TERT_RESTART:从本交易日开始重传
// Qdp_TERT_RESUME:从上次收到的续传
// Qdp_TERT_QUICK:只传送登录后公共流的内容
pUserApi->SubscribePublicTopic(QDP_TERT_RESUME);
// 设置量投科技服 务的地址,可以注册多个地址备用
pUserApi->RegisterFront("tcp://112.94.162.109:30005");
// pUserApi->SetHeartbeatTimeout(240);
// 使客户端开始与后台服务建立连接
pUserApi->Init();
pUserApi->Join();
// 释放API实例
pUserApi->Release();
return 0;
}