#include"acsy/util/publictools.h"
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include "ThostTraderApi/win32/ThostFtdcMdApi.h"
#include "ThostTraderApi/win32/ThostFtdcTraderApi.h"
#include <fstream>
#include <vector>
#include <string>
#include <boost/filesystem.hpp>
#include<string>
#include<mutex>
#include "acsy/util/acsyapplication.h"
#define MAX_ACCEPTABLE_PRICE (1.0E+15)
#define DEAL_TOO_MAX( x ) if( ((x)>MAX_ACCEPTABLE_PRICE) || ((x)<(0-MAX_ACCEPTABLE_PRICE)) ) x = 0
HANDLE g_hEvent = CreateEvent(NULL, true, false, NULL);
namespace acsy
{
namespace trader
{
struct A
{
std::mutex mutex;
bool value;
void setValue(bool v){
this->mutex.lock();
this->value = v;
this->mutex.unlock();
}
bool getValue(){
return this->value;
}
void fun();
bool fun1();
};
class tools :public util::Application < tools > {
public:
TThostFtdcBrokerIDType m_chBrokerID;
TThostFtdcUserIDType m_chUserID;
TThostFtdcUserIDType m_chUserPassword;
TThostFtdcInstrumentIDType m_instrumentID;
TThostFtdcExchangeIDType m_exchangeID;
TThostFtdcExchangeInstIDType m_exchangeInstID;
TThostFtdcInstrumentIDType m_productID;
std::vector<std::string> m_vec;
A m_login;
A m_insok;
int cnt = 0;
int cnt1 = 0;
CThostFtdcMdApi *m_pUserApi1;
CThostFtdcTraderApi *m_pUserApi;
public:
tools();
int main();
std::string getappname(){ return "shujubaocun"; }
};
template < class T > class Deal{
public:
void setValue(const T &v);
T getValue() const;
public:
std::mutex m_mutex;
T m_value;
};
class datasvrlog :public util::Logger
{
public:
virtual int log(const char *str);
};
class CSimpleHandler : public CThostFtdcTraderSpi
{
public:
// 构造函数,需要 个有效的指向CThostFtdcMduserApi实例的指针
CSimpleHandler(CThostFtdcTraderApi *pUserApi, tools *tl);
~CSimpleHandler() {}
virtual void OnFrontConnected();
virtual void OnFrontDisconnected(int nReason);
virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
virtual void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
public:
tools *tl;
};
class CSimpleHandler1 : public CThostFtdcMdSpi
{
public:
CSimpleHandler1(CThostFtdcMdApi *pUserApi1,tools *tl);
~CSimpleHandler1() {};
virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData) override;
virtual void OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);
virtual void OnFrontDisconnected(int nReason);
virtual void OnFrontConnected();
public:
tools *tl;
};
//tools实现
int tools::main()
{
datasvrlog ds;
ref().logger().registerLogger(&ds);
// 产生一个CThostFtdcTraderApi实例
CThostFtdcTraderApi *pUserApi = CThostFtdcTraderApi::CreateFtdcTraderApi();
CThostFtdcMdApi *pUserApi1 = CThostFtdcMdApi::CreateFtdcMdApi();
// 产生一个事件处理的实例
CSimpleHandler sh(pUserApi, this);
CSimpleHandler1 sh1(pUserApi1, this);
// 注册 事件处理的实例
pUserApi->RegisterSpi(&sh);
pUserApi1->RegisterSpi(&sh1);
// 订阅私有流
// TERT_RESTART:从本交易日开始重传
// TERT_RESUME:从上次收到的续传
// TERT_QUICK:只传送登录后私有流的内容
pUserApi->SubscribePrivateTopic(THOST_TERT_RESUME);
// 订阅公共流
// TERT_RESTART:从本交易日开始重传
// TERT_RESUME:从上次收到的续传
// TERT_QUICK:只传送登录后公共流的内容
pUserApi->SubscribePublicTopic(THOST_TERT_RESUME);
// 设置交易托管系统服务的地址,可以注册多个地址备用
pUserApi->RegisterFront("tcp://180.168.146.187:10000");
pUserApi1->RegisterFront("tcp://180.168.146.187:10010");
// 使客户端开始与后台服务建立连接
pUserApi->Init();
pUserApi1->Init();
// 客户端等待报单操作完成
WaitForSingleObject(g_hEvent, INFINITE);
// 释放API实例
pUserApi->Release();
pUserApi1->Release();
system("pause");
return 0;
}
tools::tools()
{
m_insok.value = false;
m_login.value = false;
strcpy(m_chBrokerID, "9999");
strcpy(m_chUserID, "******");
strcpy(m_chUserPassword, "******");
strcpy(m_instrumentID, "");
strcpy(m_exchangeID, "");
strcpy(m_productID, "");
}
//datasvrlog实现
int datasvrlog::log(const char *str)
{
std::string filename = "h:\\log.txt";
std::ifstream ifs(filename);
if (ifs) //存在
{
std::ofstream fout(filename, std::ios::app);
fout << str;
fout.close();
}
else //不存在
{
std::ofstream fout(filename);
fout << str;
}
return 0;
}
//CSimpleHandler实现
CSimpleHandler::CSimpleHandler(CThostFtdcTraderApi *pUserApi,tools *tl)
{
this->tl = tl;
tl->m_pUserApi = pUserApi;
}
void CSimpleHandler::OnFrontConnected()
{
CThostFtdcReqUserLoginField reqUserLogin;
strcpy(reqUserLogin.BrokerID, tl->m_chBrokerID);
strcpy(reqUserLogin.UserID, tl->m_chUserID);
strcpy(reqUserLogin.Password, tl->m_chUserPassword);
tl->m_pUserApi->ReqUserLogin(&reqUserLogin, 0);
}
void CSimpleHandler::OnFrontDisconnected(int nReason)
{
// 当发生这个情况后,API会自动重新连接,客户端可不做处理
tools::instance().logger().log("OnFrontDisconnected.");
}
void CSimpleHandler::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin,CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
tools::instance().logger().log("OnRspUserLogin:");
tools::instance().logger().log("ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID,
pRspInfo->ErrorMsg);
tools::instance().logger().log("RequestID= [%d], Chain=[%d]", nRequestID, bIsLast);
if (pRspInfo->ErrorID != 0) {
// 端登失败,客户端需进行错误处理
tools::instance().logger().log("Trader failed to login, errorcode=%d errormsg=%s requestid=%d chain = %d", pRspInfo->ErrorID, pRspInfo->ErrorMsg, nRequestID, bIsLast);
/*exit(-1);*/
Sleep(5000);
tl->cnt++;
CThostFtdcReqUserLoginField reqUserLogin;
strcpy(reqUserLogin.BrokerID, tl->m_chBrokerID);
strcpy(reqUserLogin.UserID, tl->m_chUserID);
strcpy(reqUserLogin.Password, tl->m_chUserPassword);
tl->m_pUserApi->ReqUserLogin(&reqUserLogin, 0);
tools::instance().logger().log("Trader登录失败后,第[%d]次登录!",tl->cnt);
}
//查询合约请求
else if (pRspInfo->ErrorID == 0)
{
CThostFtdcQryInstrumentField req;
strcpy(req.InstrumentID, tl->m_instrumentID);
strcpy(req.ExchangeInstID, tl->m_exchangeInstID);
strcpy(req.ExchangeID, tl->m_exchangeID);
strcpy(req.ProductID, tl->m_productID);
tl->m_pUserApi->ReqQryInstrument(&req, 0);
}
}
void CSimpleHandler::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder,CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
// 输出报单录入结果
tools::instance().logger().log("ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID,
pRspInfo->ErrorMsg);
// 通知报单录入完成
SetEvent(g_hEvent);
};
void CSimpleHandler::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
tools::instance().logger().log("OnRspError:");
tools::instance().logger().log("ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID,
pRspInfo->ErrorMsg);
tools::instance().logger().log("RequestID= [%d], Chain=[%d]", nRequestID, bIsLast);
// 客户端需进行错误处理
//{客户端的错误处理}
}
void CSimpleHandler::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
tools::instance().logger().log("合约请求响应!,InstrumentID:[%s]", pInstrument->InstrumentID);
std::cout << "InstrumentID=" << pInstrument->InstrumentID << std::endl;
tl->m_vec.push_back(pInstrument->InstrumentID);
if (bIsLast)
{
tl->m_insok.fun(); //m_insok加锁
if (tl->m_login.fun1()==true) //m_login加锁
{
int len = tl->m_vec.size();
char** Instrument = new char*[len];
for (int i = 0; i < len; i++)
{
Instrument[i] = const_cast<char*>(tl->m_vec[i].c_str());
}
tl->m_pUserApi1->SubscribeMarketData(Instrument, len);
}
}
std::string ss = "\n";
std::string isd = pInstrument->InstrumentID + ss;
}
//CSimpleHandler1实现
CSimpleHandler1::CSimpleHandler1(CThostFtdcMdApi *pUserApi1,tools *tl)
{
this->tl = tl;
tl->m_pUserApi1 = pUserApi1;
}
void CSimpleHandler1::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
tools::instance().logger().log("OnRspError:");
tools::instance().logger().log("ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID,
pRspInfo->ErrorMsg);
tools::instance().logger().log("RequestID=[%d], Chain=[%d]", nRequestID, bIsLast);
// 客户端需进行错误处理
//{客户端的错误处理}
}
void CSimpleHandler1::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
{
// 输出报单录入结果
char stime[64];
acsy::util::BinDateTime bts_now = acsy::util::BinDateTime::now();
acsy::util::BinDateTime bts_now_local = bts_now + 8 * acsy::util::BinDateTime::MILLIS_PER_HOUR;
bts_now_local.toLongString(stime);
/*"InstrumentID=[%s],UpdateTime=[%s],UpdateMillisec=[%d],LastPrice=[%lf],BidPrice1=[%lf],AskPrice1=[%],LowestPrice=[%],HighestPrice=[%],Volume=[%],BidVolume1=[%],AskVolume1=[%],OpenInterest=[%],Turnover=[%]\n"*/
DEAL_TOO_MAX(pDepthMarketData->PreOpenInterest);
DEAL_TOO_MAX(pDepthMarketData->PreClosePrice);
DEAL_TOO_MAX(pDepthMarketData->PreSettlementPrice);
DEAL_TOO_MAX(pDepthMarketData->ClosePrice);
DEAL_TOO_MAX(pDepthMarketData->SettlementPrice);
DEAL_TOO_MAX(pDepthMarketData->OpenInterest);
DEAL_TOO_MAX(pDepthMarketData->LastPrice);
DEAL_TOO_MAX(pDepthMarketData->UpperLimitPrice);
DEAL_TOO_MAX(pDepthMarketData->LowerLimitPrice);
DEAL_TOO_MAX(pDepthMarketData->HighestPrice);
DEAL_TOO_MAX(pDepthMarketData->LowestPrice);
DEAL_TOO_MAX(pDepthMarketData->OpenPrice);
DEAL_TOO_MAX(pDepthMarketData->LowestPrice);
DEAL_TOO_MAX(pDepthMarketData->Turnover);
if (pDepthMarketData->AskPrice1 > 10 * pDepthMarketData->LastPrice)
{
pDepthMarketData->AskPrice1 = pDepthMarketData->LastPrice;
}
if (pDepthMarketData->BidPrice1 > 10 * pDepthMarketData->LastPrice)
{
pDepthMarketData->BidPrice1 = pDepthMarketData->LastPrice;
}
printf("%s,%s.%03d,%.4f,%.4f,%.4f,%.4f,%.4f,%d,%d,%d,%s,%.2lf,%.2lf\n",
pDepthMarketData->InstrumentID, pDepthMarketData->UpdateTime, pDepthMarketData->UpdateMillisec, pDepthMarketData->LastPrice,
pDepthMarketData->BidPrice1, pDepthMarketData->AskPrice1, pDepthMarketData->LowestPrice, pDepthMarketData->HighestPrice,
pDepthMarketData->Volume, pDepthMarketData->BidVolume1, pDepthMarketData->AskVolume1, stime,
pDepthMarketData->OpenInterest, pDepthMarketData->Turnover);
std::string subs = acsy::util::strprintf("%s,%s.%03d,%.4f,%.4f,%.4f,%.4f,%.4f,%d,%d,%d,%s,%.2lf,%.2lf\n",
pDepthMarketData->InstrumentID, pDepthMarketData->UpdateTime, pDepthMarketData->UpdateMillisec, pDepthMarketData->LastPrice,
pDepthMarketData->BidPrice1, pDepthMarketData->AskPrice1, pDepthMarketData->LowestPrice, pDepthMarketData->HighestPrice,
pDepthMarketData->Volume, pDepthMarketData->BidVolume1, pDepthMarketData->AskVolume1, stime,
pDepthMarketData->OpenInterest, pDepthMarketData->Turnover);
namespace fs = boost::filesystem;
/* char stime[30] = "2015-10-23 14:07:03.579";*/
std::string date;
date = stime;
std::string s1 = date.substr(0, 4);
std::string s2 = date.substr(5, 2);
std::string s3 = date.substr(8, 2);
std::string floder = "h:\\" + s1 + s2 + s3;
fs::path full_path(fs::initial_path());
full_path = fs::system_complete(fs::path(floder, fs::native));
if (!fs::exists(floder))
{
fs::create_directories(floder);
}
std::string filename = pDepthMarketData->InstrumentID;
std::string filename1 = floder + "\\" + filename + ".csv";
std::ifstream ifs(filename1);
if (ifs) //存在
{
std::ofstream fout(filename1, std::ios::app);
fout << subs;
fout.close();
}
else //不存在
{
std::ofstream fout(filename1);
fout << subs;
}
}
void CSimpleHandler1::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
tools::instance().logger().log("行情请求响应!,InstrumentID:[%s]", pSpecificInstrument->InstrumentID);
}
void CSimpleHandler1::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
if (bIsLast)
{
tl->m_login.fun(); //m_login加锁
if (tl->m_insok.fun1()==true) //m_insok加锁
{
int len = tl->m_vec.size();
char** Instrument = new char*[len];
for (int i = 0; i < len; i++)
{
Instrument[i] = const_cast<char*>(tl->m_vec[i].c_str());
}
tl->m_pUserApi1->SubscribeMarketData(Instrument, len);
}
}
tools::instance().logger().log("OnRspUserLogin:");
tools::instance().logger().log("ErrorCode=[%d], ErrorMsg=[%s]", pRspInfo->ErrorID,
pRspInfo->ErrorMsg);
tools::instance().logger().log("RequestID=[%d], Chain=[%d]", nRequestID, bIsLast);
if (pRspInfo->ErrorID != 0) {
// 端登失败,客户端需进行错误处理
tools::instance().logger().log("MD failed to login, errorcode=%d errormsg=%s requestid=%d chain = %d", pRspInfo->ErrorID, pRspInfo->ErrorMsg, nRequestID, bIsLast);
/*exit(-1);*/
Sleep(5000);
tl->cnt1++;
CThostFtdcReqUserLoginField reqUserLogin;
strcpy(reqUserLogin.BrokerID, tl->m_chBrokerID);
strcpy(reqUserLogin.UserID, tl->m_chUserID);
strcpy(reqUserLogin.Password, tl->m_chUserPassword);
tl->m_pUserApi1->ReqUserLogin(&reqUserLogin, 0);
tools::instance().logger().log("MD登录失败后,第[%d]次登录!", tl->cnt1);
}
}
void CSimpleHandler1::OnFrontDisconnected(int nReason)
{
// 当发生这个情况后,API会自动重新连接,客户端可不做处理
tools::instance().logger().log("OnFrontDisconnected.");
}
void CSimpleHandler1::OnFrontConnected()
{
CThostFtdcReqUserLoginField reqUserLogin;
strcpy(reqUserLogin.BrokerID, tl->m_chBrokerID);
strcpy(reqUserLogin.UserID, tl->m_chUserID);
strcpy(reqUserLogin.Password, tl->m_chUserPassword);
tl->m_pUserApi1->ReqUserLogin(&reqUserLogin, 0);
}
void A::fun()
{
this->mutex.lock();
this->value = true;
this->mutex.unlock();
}
bool A::fun1()
{
bool b;
this->mutex.lock();
b = this->value;
this->mutex.unlock();
return b;
}
}
}
ACSY_DEF_MAINCLASS(acsy::trader::tools);
期货行情接口开发之一
最新推荐文章于 2024-05-10 16:00:07 发布