// 01qt_ctp.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = 01qt_ctp
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
# 三种情况都可以, 但是最后一种情况不跨平台.
LIBS += -L(TARGET) -lthostmduserapi_se
#LIBS += -L./debug -lthostmduserapi_se
#LIBS += ./debug/thostmduserapi_se.dll
SOURCES += \
main.cpp \
UICTPWidget.cpp \
MdSpi.cpp
HEADERS += \
UICTPWidget.h \
MdSpi.h \
ThostFtdcMdApi.h
FORMS += \
UICTPWidget.ui
// MdSpi.h
#ifndef MDSPI_H
#define MDSPI_H
#include <QObject>
#include "ThostFtdcMdApi.h"
class MdSpi : public QObject, public CThostFtdcMdApi
{
Q_OBJECT
public:
explicit MdSpi(QObject *parent = nullptr);
private:
typedef struct
{
char FRONT_ADDR[100];
TThostFtdcBrokerIDType BROKER_ID;
TThostFtdcInvestorIDType INVESTOR_ID;
TThostFtdcPasswordType PASSWORD;
} MDStruct;
MDStruct hq;
///错误应答
virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
///@param nReason 错误原因
/// 0x1001 网络读失败
/// 0x1002 网络写失败
/// 0x2001 接收心跳超时
/// 0x2002 发送心跳失败
/// 0x2003 收到错误报文
virtual void OnFrontDisconnected(int nReason);
///心跳超时警告。当长时间未收到报文时,该方法被调用。
///@param nTimeLapse 距离上次接收报文的时间
virtual void OnHeartBeatWarning(int nTimeLapse);
///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
virtual void OnFrontConnected();
///登录请求响应
virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
///订阅行情应答
virtual void OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
///取消订阅行情应答
virtual void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
///深度行情通知
virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData);
void ReqUserLogin();
void SubscribeMarketData();
bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);
CThostFtdcMdApi *pUserApi;
signals:
public slots:
};
#endif // MDSPI_H
// MdSpi.cpp
#include "MdSpi.h"
#include<iostream>
using namespace std;
#pragma warning(disable:4996)
char *contractID[] = {"rb2209,RM209"};
int contractSize = 2;
//请求编号
extern int iRequestID = 0;
MdSpi::MdSpi(QObject *parent): QObject(parent) {
}
void MdSpi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
cerr << "--->>>"<<__FUNCTION__<< endl;
IsErrorRspInfo(pRspInfo);
}
void MdSpi::OnFrontDisconnected(int nReason) {
cerr << "--->>>"<<__FUNCTION__<< endl;
cerr << "___>>>Reason = " << nReason << endl;
}
void MdSpi::OnHeartBeatWarning(int nTimeLapse)
{
cerr << "--->>>"<<__FUNCTION__<< endl;
cerr << "--->>>nTimeLapse = "<<nTimeLapse << endl;
}
void MdSpi::OnFrontConnected()
{
cerr << "--->>>"<<__FUNCTION__<< endl;
//用户登录请求
ReqUserLogin();
}
void MdSpi::ReqUserLogin()
{
CThostFtdcReqUserLoginField req;
memset(&req, 0, sizeof(req));
strcpy(req.BrokerID, hq.BROKER_ID);
strcpy(req.UserID, "");
strcpy(req.Password, "");
int iResult = pUserApi->ReqUserLogin(&req, ++iRequestID);
cerr << "--->>>发送用户登录请求: "<<((iResult == 0) ? "成功" : "失败") << endl;
}
void MdSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>>"<<__FUNCTION__<< endl;
if(bIsLast && !IsErrorRspInfo(pRspInfo)) {
//获取当前交易日
cerr << "--->>>获取当前交易日 = "<<pUserApi->GetTradingDay()<<endl;
SubscribeMarketData();
}
}
void MdSpi::SubscribeMarketData()
{
int iResult = pUserApi->SubscribeMarketData(contractID, contractSize);
cerr << "--->>> 发送行情订阅请求: "<< ((iResult == 0) ? "成功" : "失败") << endl;
}
void MdSpi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>>"<<__FUNCTION__<< endl;
}
void MdSpi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>>"<<__FUNCTION__<< endl;
}
void MdSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
{
cerr << "--->>>"<<__FUNCTION__<< endl;
}
bool MdSpi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo)
{
//如果ErrorID !=0, 说明收到错误的响应
bool bResult = ((pRspInfo) && (pRspInfo->ErrorID !=0));
if(bResult) {
cerr << "--->> ErrorID = "<<pRspInfo->ErrorID << ", ErrorMsg = "<<pRspInfo->ErrorMsg << endl;
}
return bResult;
}