首页 > 其他 > 详细

Hello CTP(二)——CTP行情

时间:2021-05-08 00:09:34      阅读:14      评论:0      收藏:0      [点我收藏+]
Hello CTP(二)——CTP行情

一、CTP行情

1、CTP行情API简介

CThostFtdcMdApi行情API接口包含CThostFtdcMdApi和CThostFtdcMdSpi,通过CThostFtdcMdApiApi向CTP发送命令,通过CThostFtdcMdSpi接收CTP响应。

2、CTP行情获取

CTPMarketDataSource.h文件:

#ifndef CTPMARKETDATASOURCE_H
#define CTPMARKETDATASOURCE_H

#include <vector>
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <stdio.h>
#include "ThostFtdcMdApi.h"

class CTPMarketDataSource : public CThostFtdcMdSpi
{
public:
explicit CTPMarketDataSource(const char* yml);
void startMarketDataSource();
~CTPMarketDataSource();
public:
///当客户端与交易后台建立起通信连接时(还未登录前)被调用。
void OnFrontConnected();

///当客户端与交易后台通信连接断开时被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
///@param nReason 错误原因
/// 0x1001 网络读失败
/// 0x1002 网络写失败
/// 0x2001 接收心跳超时
/// 0x2002 发送心跳失败
/// 0x2003 收到错误报文
void OnFrontDisconnected(int nReason);

///心跳超时警告。当长时间未收到报文时,该方法被调用。
///@param nTimeLapse 距离上次接收报文的时间
void OnHeartBeatWarning(int nTimeLapse);

///登录请求响应
void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

///登出请求响应
void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

///错误应答
void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

///订阅行情应答
void OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

///取消订阅行情应答
void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
///深度行情通知
void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData);
private:
CThostFtdcMdApi *m_pMdUserApi;
};

#endif // CTPMARKETDATASOURCE_H

CTPMarketDataSource.cpp文件:

#include "CTPMarketDataSource.h"

CTPMarketDataSource::CTPMarketDataSource(const char *yml)
{
// 创建行情API实例
m_pMdUserApi = CThostFtdcMdApi::CreateFtdcMdApi();
}

void CTPMarketDataSource::startMarketDataSource()
{
// 注册事件类
m_pMdUserApi->RegisterSpi(this);
// 设置行情前置地址
std::string FrontAddr;
m_pMdUserApi->RegisterFront(const_cast<char *>(FrontAddr.c_str()));
m_pMdUserApi->Init();
// 等到线程退出
m_pMdUserApi->Join();
}

CTPMarketDataSource::~CTPMarketDataSource()
{
}

void CTPMarketDataSource::OnFrontConnected()
{
CThostFtdcReqUserLoginField loginReq;
std::string BrokerID, InvestorID, Password;
memset(&loginReq, 0, sizeof(loginReq));
strcpy(loginReq.BrokerID, BrokerID.c_str());
strcpy(loginReq.UserID, InvestorID.c_str());
strcpy(loginReq.Password, Password.c_str());
static int requestID = 0;
int rt = m_pMdUserApi->ReqUserLogin(&loginReq, requestID++);
}

void CTPMarketDataSource::OnFrontDisconnected(int nReason)
{
}

void CTPMarketDataSource::OnHeartBeatWarning(int nTimeLapse)
{

}

void CTPMarketDataSource::OnRspUserLogin(
CThostFtdcRspUserLoginField *pRspUserLogin,
CThostFtdcRspInfoField *pRspInfo,
int nRequestID,
bool bIsLast)
{
bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
if (bIsLast && !bResult)
{
printf("账户登录成功\n");
printf("交易日: %s", pRspUserLogin->TradingDay);
printf("登录时间: %s", pRspUserLogin->LoginTime);
printf("经纪商: %s", pRspUserLogin->BrokerID);
printf("账户名: %s", pRspUserLogin->UserID);
printf("SystemName: %s", pRspUserLogin->SystemName);
printf("ApiVersion: %s", m_pMdUserApi->GetApiVersion());

// 读取合约配置
int instrumentNum = 6;
char *instruments[instrumentNum];
int i = 0;

// 开始订阅行情
int rt = m_pMdUserApi->SubscribeMarketData(instruments, instrumentNum);
}
}

void CTPMarketDataSource::OnRspUserLogout(
CThostFtdcUserLogoutField *pUserLogout,
CThostFtdcRspInfoField *pRspInfo,
int nRequestID,
bool bIsLast)
{
bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
}

void CTPMarketDataSource::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
}

void CTPMarketDataSource::OnRspSubMarketData(
CThostFtdcSpecificInstrumentField *pSpecificInstrument,
CThostFtdcRspInfoField *pRspInfo,
int nRequestID,
bool bIsLast)
{
bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
if (!bResult)
{
// 订阅成功
}
}

void CTPMarketDataSource::OnRspUnSubMarketData(
CThostFtdcSpecificInstrumentField *pSpecificInstrument,
CThostFtdcRspInfoField *pRspInfo,
int nRequestID,
bool bIsLast)
{
bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
}

void CTPMarketDataSource::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
{
// 接收行情数据
// 处理订阅合约行情数据

}

main.cpp文件:

#include "CTPMarketDataSource.h"

int main(int argc, char *argv[])
{
CTPMarketDataSource *pMdSource = new CTPMarketDataSource("config.yml");
pMdSource->startMarketDataSource();

return 0;
}

CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.17)

PROJECT(CTPMarketDataSource)

set(CMAKE_CXX_FLAGS "-fPIC -O3")

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 默认输出debug版
#SET(CMAKE_BUILD_TYPE "Release")
SET(CMAKE_BUILD_TYPE "debug")
set(CMAKE_CXX_STANDARD 11)

set(CTP_INCLUDE ${CMAKE_SOURCE_DIR}/CTPLib/include)
include_directories(${CTP_INCLUDE})

set(CTP_LIB ${CMAKE_SOURCE_DIR}/CTPLib/lib)
link_directories(${CTP_LIB})

set(SOURCES main.cpp CTPMarketDataSource.cpp)
add_executable(${PROJECT_NAME} main.cpp CTPMarketDataSource.cpp)
target_link_libraries(${PROJECT_NAME} thostmduserapi_se pthread)

二、Sina行情

1、Sina行情简介

Sina财经提供实时行情数据的API接口,通过访问http://hq.sinajs.cn/list=sz002307,sh600928 可以获取sz002307,sh600928的行情数据。

var hq_str_sz002307="北新路桥,8.700,8.820,9.080,9.310,8.630,9.080,9.100,108452484,968707402.800,42300,9.080,91100,9.070,17500,9.060,42200,9.050,19200,9.040,7048,9.100,16600,9.110,47300,9.120,20460,9.130,21400,9.140,2019-03-27,14:33:03,00";
var hq_str_sh600928="西安银行,11.470,11.550,11.560,11.890,11.280,11.560,11.570,101874307,1186320558.000,46300,11.560,82562,11.550,57300,11.540,64300,11.530,27000,11.520,1100,11.570,6100,11.580,12700,11.590,27727,11.600,40600,11.610,2019-03-27,14:33:02,00";

2、Sina行情获取

SinaMarketDataSource.h文件:

#include <unistd.h>
#include <string>

#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

#include <hpsocket/HPSocket4C.h>

class SinaMarketDataSource
{
public:
SinaMarketDataSource(){}
void StartMarketDataSource(const char* yml);
void Stop();
virtual ~SinaMarketDataSource();
private:
bool SendHTTPRequest(const char *data);

protected:
static EnHandleResult __HP_CALL OnConnect(HP_HttpClient pSender, CONNID dwConnID);
static EnHandleResult __HP_CALL OnHandShake(HP_HttpClient pSender, CONNID dwConnID);
static EnHandleResult __HP_CALL OnSend(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength);
static EnHandleResult __HP_CALL OnReceive(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength);
static EnHandleResult __HP_CALL OnClose(HP_HttpClient pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode);
static EnHttpParseResult __HP_CALL OnMessageBegin(HP_HttpClient pSender, CONNID dwConnID);
static EnHttpParseResult __HP_CALL OnStatusLine(HP_HttpClient pSender, CONNID dwConnID, USHORT usStatusCode, LPCSTR lpszDesc);
static EnHttpParseResult __HP_CALL OnHeader(HP_HttpClient pSender, CONNID dwConnID, LPCSTR lpszName, LPCSTR lpszValue);
static EnHttpParseResult __HP_CALL OnHeadersComplete(HP_HttpClient pSender, CONNID dwConnID);
static EnHttpParseResult __HP_CALL OnBody(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength);
static EnHttpParseResult __HP_CALL OnChunkHeader(HP_HttpClient pSender, CONNID dwConnID, int iLength);
static EnHttpParseResult __HP_CALL OnChunkComplete(HP_HttpClient pSender, CONNID dwConnID);
static EnHttpParseResult __HP_CALL OnMessageComplete(HP_HttpClient pSender, CONNID dwConnID);
static EnHttpParseResult __HP_CALL OnUpgrade(HP_HttpClient pSender, CONNID dwConnID, EnHttpUpgradeType enUpgradeType);
static EnHttpParseResult __HP_CALL OnParseError(HP_HttpClient pSender, CONNID dwConnID, int iErrorCode, LPCSTR lpszErrorDesc);
static EnHandleResult __HP_CALL OnWSMessageHeader(HP_HttpClient pSender, CONNID dwConnID, BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], ULONGLONG ullBodyLen);
static EnHandleResult __HP_CALL OnWSMessageBody(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength);
static EnHandleResult __HP_CALL OnWSMessageComplete(HP_HttpClient pSender, CONNID dwConnID);
private:
SinaMarketDataSource &operator=(const SinaMarketDataSource &);
SinaMarketDataSource(const SinaMarketDataSource &);
private:
HP_HttpClient m_pHTTPClient;
HP_HttpClientListener m_pHTTPClientListener;
static std::unordered_map<std::string, std::string> m_sTickerMarketData;
std::string m_URL;
};

SinaMarketDataSource.cpp文件:

#include "SinaMarketDataSource.h"

std::unordered_map<std::string, std::string> SinaMarketDataSource::m_sTickerMarketData;

SinaMarketDataSource::SinaMarketDataSource()
{
m_URL = "http://hq.sinajs.cn?list=sh601003,sh601001";
m_pHTTPClientListener = ::Create_HP_HttpClientListener();
m_pHTTPClient = ::Create_HP_HttpClient(m_pHTTPClientListener);

::HP_Set_FN_HttpClient_OnConnect(m_pHTTPClientListener, OnConnect);
::HP_Set_FN_HttpClient_OnHandShake(m_pHTTPClientListener, OnHandShake);
::HP_Set_FN_HttpClient_OnReceive(m_pHTTPClientListener, OnReceive);
::HP_Set_FN_HttpClient_OnSend(m_pHTTPClientListener, OnSend);
::HP_Set_FN_HttpClient_OnClose(m_pHTTPClientListener, OnClose);

::HP_Set_FN_HttpClient_OnMessageBegin(m_pHTTPClientListener, OnMessageBegin);
::HP_Set_FN_HttpClient_OnStatusLine(m_pHTTPClientListener, OnStatusLine);
::HP_Set_FN_HttpClient_OnHeader(m_pHTTPClientListener, OnHeader);
::HP_Set_FN_HttpClient_OnHeadersComplete(m_pHTTPClientListener, OnHeadersComplete);
::HP_Set_FN_HttpClient_OnBody(m_pHTTPClientListener, OnBody);
::HP_Set_FN_HttpClient_OnChunkHeader(m_pHTTPClientListener, OnChunkHeader);
::HP_Set_FN_HttpClient_OnChunkComplete(m_pHTTPClientListener, OnChunkComplete);
::HP_Set_FN_HttpClient_OnMessageComplete(m_pHTTPClientListener, OnMessageComplete);
::HP_Set_FN_HttpClient_OnUpgrade(m_pHTTPClientListener, OnUpgrade);
::HP_Set_FN_HttpClient_OnParseError(m_pHTTPClientListener, OnParseError);

::HP_Set_FN_HttpClient_OnWSMessageHeader(m_pHTTPClientListener, OnWSMessageHeader);
::HP_Set_FN_HttpClient_OnWSMessageBody(m_pHTTPClientListener, OnWSMessageBody);
::HP_Set_FN_HttpClient_OnWSMessageComplete(m_pHTTPClientListener, OnWSMessageComplete);

::HP_HttpClient_SetUseCookie(m_pHTTPClient, true);
::HP_TcpClient_SetKeepAliveTime(m_pHTTPClient, 60000);
}

SinaMarketDataSource::~SinaMarketDataSource()
{
::Destroy_HP_HttpClient(m_pHTTPClient);
::Destroy_HP_HttpClientListener(m_pHTTPClientListener);
::HP_HttpCookie_MGR_SaveToFile("./cookie", TRUE);
}

void SinaMarketDataSource::StartMarketDataSource(const char *yml)
{
bool ret = ::HP_Client_StartWithBindAddress(m_pHTTPClient, "183.232.24.241", 80, false, NULL);
if (!ret)
{
printf("%s\n", ::HP_Client_GetLastErrorDesc(m_pHTTPClient));
}

while (true)
{
// 发送行情查询请求
bool ok = SendHTTPRequest(m_URL.c_str());
if (!ok)
{
printf("%s\n", ::HP_Client_GetLastErrorDesc(m_pHTTPClient));
}
// 行情数据每3秒推送一次
sleep(3);
}
}

void SinaMarketDataSource::Stop()
{
::HP_Client_Stop(m_pHTTPClient);
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnConnect(HP_HttpClient pSender, CONNID dwConnID)
{
TCHAR szAddress[50];
int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
USHORT usPort;
::HP_Client_GetRemoteHost(pSender, szAddress, &iAddressLen, &usPort);
printf("connected to %s:%d successed\n", szAddress, usPort);
return HR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnHandShake(HP_HttpClient pSender, CONNID dwConnID)
{
return HR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnSend(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength)
{
return HR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnReceive(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength)
{
return HR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnClose(HP_HttpClient pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
{
TCHAR szAddress[50];
int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
USHORT usPort;
::HP_Client_GetRemoteHost(pSender, szAddress, &iAddressLen, &usPort);
printf("{}:{} closed\n", szAddress, usPort);

return HR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnMessageBegin(HP_HttpClient pSender, CONNID dwConnID)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnStatusLine(HP_HttpClient pSender, CONNID dwConnID, USHORT usStatusCode, LPCSTR lpszDesc)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnHeader(HP_HttpClient pSender, CONNID dwConnID, LPCSTR lpszName, LPCSTR lpszValue)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnHeadersComplete(HP_HttpClient pSender, CONNID dwConnID)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnBody(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength)
{
std::string response = (const char *)pData;
// 接收并且处理行情数据
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnChunkHeader(HP_HttpClient pSender, CONNID dwConnID, int iLength)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnChunkComplete(HP_HttpClient pSender, CONNID dwConnID)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnMessageComplete(HP_HttpClient pSender, CONNID dwConnID)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnUpgrade(HP_HttpClient pSender, CONNID dwConnID, EnHttpUpgradeType enUpgradeType)
{
return HPR_OK;
}

EnHttpParseResult __HP_CALL SinaMarketDataSource::OnParseError(HP_HttpClient pSender, CONNID dwConnID, int iErrorCode, LPCSTR lpszErrorDesc)
{
return HPR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnWSMessageHeader(HP_HttpClient pSender, CONNID dwConnID, BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], ULONGLONG ullBodyLen)
{
return HR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnWSMessageBody(HP_HttpClient pSender, CONNID dwConnID, const BYTE *pData, int iLength)
{
return HR_OK;
}

EnHandleResult __HP_CALL SinaMarketDataSource::OnWSMessageComplete(HP_HttpClient pSender, CONNID dwConnID)
{
BYTE iOperationCode;
::HP_HttpClient_GetWSMessageState(pSender, nullptr, nullptr, &iOperationCode, nullptr, nullptr, nullptr);

if (iOperationCode == 0x8)
return HR_ERROR;

return HR_OK;
}

bool SinaMarketDataSource::SendHTTPRequest(const char *url)
{
return HP_HttpClient_SendGet(m_pHTTPClient, url, NULL, 0);
}

main.cpp文件:

#include "SinaMarketDataSource.h"

int main(int argc, char *argv[])
{

SinaMarketDataSource* source = new SinaMarketDataSource;
source->StartMarketDataSource("config.yml");
return 0;
}

CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.17)

PROJECT(SinaMarketDataSource)

set(CMAKE_CXX_FLAGS "-fPIC")

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 默认输出debug版
#SET(CMAKE_BUILD_TYPE "Release")
SET(CMAKE_BUILD_TYPE "debug")
set(CMAKE_CXX_STANDARD 11)

set(SOURCES main.cpp SinaMarketDataSource.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})

target_link_libraries(${PROJECT_NAME} hpsocket4c pthread) 

Hello CTP(二)——CTP行情

原文:https://blog.51cto.com/u_9291927/2759857

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!