30 Star 78 Fork 79

liuyinghua/FastTrader

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
SimMarket.cpp 11.16 KB
一键复制 编辑 原始数据 按行查看 历史
liuyinghua 提交于 2024-10-25 21:43 +08:00 . 1增加各种类型的智能指针定义
#include "SimMarket.h"
#include "../SimpleLogLib/logging.h"
#include "file_helper.h"
#include "Tick.h"
#include <iostream>
#include <algorithm>
#include <tuple>
#include <string.h>
#include <iterator>
#include <boost/make_shared.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "../DataStoreLib/IDataStore.h"
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#if _MSC_VER >=1700
#include <chrono>
using namespace std;
#else
#include <boost/chrono/chrono.hpp>
using namespace boost;
#endif
#else
#include <chrono>
using namespace std;
#endif
#include "../common/Statistic.h"
#include "SimHub.h"
SimMarket::SimMarket()
:Market()
{
LOGINIT("sim_market");
m_bFrontDisconnected=false;
m_bIsLogined=false;
m_nRequestID = 0;
m_TakeTickTime = 0; //默认直接取一次数据;
m_Ktype = ktypeMin;//默认基于周期取数据;
//读取配置文件,这是用于配置回测的起止日期,回测周期;
try
{
boost::property_tree::ptree ptSim;
boost::property_tree::ini_parser::read_ini("SIM.ini", ptSim);
// auto ptInstrument = ptSim.get_child("Instruments");
// for (auto instIter = ptInstrument.begin(); instIter != ptInstrument.end(); ++instIter)
// {
// std::string InstrumentID = instIter->first;
// std::string ProductClass = instIter->second.get<std::string>("ProductClass");
// }
m_TakeTickTime = ptSim.get<int>("Mode.TakeTickTime", m_TakeTickTime);
m_Ktype = ptSim.get<>("Mode.Ktype", m_Ktype);
auto current_time = boost::posix_time::second_clock::local_time();
m_StartTradingDay = ptSim.get<std::string>("Mode.TradingDay", boost::gregorian::to_iso_string(current_time.date()));
m_EndTradingDay = ptSim.get<std::string>("Mode.EndTradingDay", boost::gregorian::to_iso_string(current_time.date()));
LOGDEBUG("行情回测参数文件:{}", "SIM.ini");
LOGDEBUG("每个数据的时间差:{},默认500毫秒", m_TakeTickTime);
LOGDEBUG("回测数据类型:{},默认为Tick类型", m_Ktype);
LOGDEBUG("回测开始时间:{},回测结束时间:{}", m_StartTradingDay, m_EndTradingDay);
}
catch (boost::property_tree::ini_parser_error& e1)
{
LOGDEBUG("SIM.ini parser error:{}", e1.what());
}
catch (std::exception& e1)
{
LOGDEBUG("SIM.ini read error:{}", e1.what());
}
}
bool SimMarket::Init( const BrokerInfo& s )
{
//SpiImplBase::connect(s);
m_ServerInfo=s;
m_DataStorePtr = IDataStore::CreateStore(
m_ServerInfo.market_server_front[0].address.c_str(),
IDataStore::dbtypeSqlite3
);
if (!m_ioService)
{
m_ioService = boost::make_shared<boost::asio::io_service>();
}
if (!m_ioWork)
{
m_ioWork = boost::make_shared<boost::asio::io_service::work>(boost::ref(*m_ioService));
}
return true;
}
bool SimMarket::Login( const UserLoginParam& u )
{
//DEBUG_METHOD();
// if (!m_MdApi)
// {
// return false;
// }
m_UserInfo=u;
// STAT_BEGIN("连接行情前置");
// m_MdApi->Init();
if (!m_ioThread)
{
m_ioThread = boost::make_shared<boost::thread>(boost::bind(&boost::asio::io_service::run, m_ioService));
}
m_ioService->post(boost::bind(&SimMarket::OnFrontConnected, shared_from_this()));
//等待登录完成;
boost::unique_lock<boost::mutex> lck(m_LoginMutex);
int login_timeout = m_ServerInfo.market_login_timeout;
if (login_timeout <= 0)
{
login_timeout = 30;
}
if (m_LoginCondVar.wait_for(lck, boost::chrono::seconds(login_timeout)) == boost::cv_status::timeout)
{
LOGDEBUG("行情登录超时...");
return false;
}
LOGDEBUG("行情登录完成...");
SimHub::get_instance().Register(shared_from_this());
return m_bIsLogined;
}
bool SimMarket::ReqUserLogin()
{
if (m_ioService)
{
m_ioService->post(boost::bind(&SimMarket::OnRspUserLogin, shared_from_this(), ++RequestID(), true));
}
return true;
}
bool SimMarket::SubscribeMarketData(const std::vector<std::string>& instruments,const std::string& exchg/*=""*/)
{
if (!m_DataStorePtr)
{
return false;
}
//获取没有订阅的;
std::vector<std::string> unSubInstruments;
if (!SubFilter(instruments,exchg,unSubInstruments))
{
return true;
}
for (std::size_t i = 0; i < unSubInstruments.size(); i++)
{
if (!unSubInstruments[i].empty())
{
m_ioService->post(
boost::bind(&SimMarket::OnRspSubMarketData,shared_from_this(),unSubInstruments[i],
0,true));
}
}
return true;
}
void SimMarket::OnRspSubMarketData(const std::string& subInst, int nRequestID, bool bIsLast)
{
unique_lock<mutex> lck(m_MutInst);
auto iiter=std::find_if(m_SubInstruments.begin(),m_SubInstruments.end(),
[&subInst](const std::map<std::string,std::vector<std::string> >::value_type& v)
{
return std::find(v.second.begin(),v.second.end(),subInst)!=v.second.end();
});
if (iiter==m_SubInstruments.end())
{
auto& vecInsts = m_SubInstruments[""];
vecInsts.push_back(subInst);
}
auto instIter = m_InstrumentDataMap.find(subInst);
if (instIter == m_InstrumentDataMap.end())
{
//读取数据;
boost::shared_ptr<InstrumentData> pInstrument =
boost::make_shared<InstrumentData>(subInst.c_str());
if (m_Ktype == ktypeNone)
{
//使用Tick进行回测;
m_DataStorePtr->PrepareData(pInstrument, InstrumentData::dataReport,m_Ktype);
}
else
{
auto current_time = boost::posix_time::second_clock::local_time();
if (!m_StartTradingDay.empty())
{
pInstrument->m_ptBegin = boost::posix_time::ptime(boost::gregorian::date_from_iso_string(m_StartTradingDay));
}
else
{
pInstrument->m_ptBegin = boost::posix_time::ptime(current_time.date() - boost::gregorian::days(1));
}
if (!m_EndTradingDay.empty())
{
pInstrument->m_ptEnd = boost::posix_time::ptime(boost::gregorian::date_from_iso_string(m_EndTradingDay));
}
else
{
pInstrument->m_ptEnd = boost::posix_time::ptime(current_time.date());
}
m_DataStorePtr->PrepareData(pInstrument, InstrumentData::dataK, m_Ktype,0);
//将K线数据转换成Tick数据;
pInstrument->GetKData(m_Ktype).ToReport(pInstrument->GetReport());
}
if (pInstrument->GetReport().size() > 0)
{
m_InstrumentDataMap.insert(std::make_pair(subInst, pInstrument));
if (m_TheSameTimeTickIndexMap.empty())
{
m_TheSameTimeTickIndexMap.insert(std::make_pair(subInst, 0));
}
else
{
std::pair<std::string, size_t> curFirstTick = *m_TheSameTimeTickIndexMap.begin();
boost::shared_ptr<InstrumentData> pFirstInstrument = m_InstrumentDataMap[curFirstTick.first];
ReportContainer& first_tick_container = pFirstInstrument->GetReport();
boost::posix_time::ptime first_tick_time =
boost::posix_time::from_time_t(first_tick_container[curFirstTick.second].UpdateTime);
first_tick_time += boost::posix_time::milliseconds(first_tick_container[curFirstTick.second].UpdateMillisec);
ReportContainer& tick_container = pFirstInstrument->GetReport();
for (size_t i = 0; i < tick_container.size(); ++i)
{
boost::posix_time::ptime tick_time =
boost::posix_time::from_time_t(tick_container[i].UpdateTime);
tick_time += boost::posix_time::milliseconds(tick_container[i].UpdateMillisec);
if (tick_time >= first_tick_time)
{
m_TheSameTimeTickIndexMap[subInst] = i;
break;
}
}
}
}
else
{
LOGDEBUG("{} No data to load",subInst);
}
}
TakeTick();
}
void SimMarket::TakeTick()
{
if (m_TakeTickTime == 0)
{
m_ioService->post(boost::bind(&SimMarket::OnTakeTickTimer,
shared_from_this(), boost::system::error_code()));
}
else
{
if (!m_TickTimer)
{
m_TickTimer = boost::make_shared<boost::asio::steady_timer>(*m_ioService);
}
m_TickTimer->expires_from_now(std::chrono::milliseconds(500));
m_TickTimer->async_wait(boost::bind(&SimMarket::OnTakeTickTimer,
shared_from_this(), boost::asio::placeholders::error));
}
}
void SimMarket::OnTakeTickTimer(const boost::system::error_code& ec)
{
//选取时间最小的;
std::map<std::string, TickSPtr > CurrentTicksMap;
boost::posix_time::ptime tick_min_start_time = boost::posix_time::second_clock::local_time();
for (auto idIter = m_TheSameTimeTickIndexMap.begin(); idIter != m_TheSameTimeTickIndexMap.end();)
{
boost::shared_ptr<InstrumentData> pInstrument = m_InstrumentDataMap[idIter->first];
ReportContainer& tick_container = pInstrument->GetReport();
size_t& tickIndex = m_TheSameTimeTickIndexMap[idIter->first];
if (tick_container.size() <= tickIndex)
{
idIter = m_TheSameTimeTickIndexMap.erase(idIter);
continue;
}
boost::posix_time::ptime tick_time = boost::posix_time::from_time_t(tick_container[tickIndex].UpdateTime);
tick_time += boost::posix_time::milliseconds(tick_container[tickIndex].UpdateMillisec);
if (tick_time < tick_min_start_time)
{
CurrentTicksMap.clear();
Tick& t = tick_container[idIter->second];
TickSPtr tick = boost::make_shared<Tick>(t);
CurrentTicksMap.insert(std::make_pair(idIter->first, tick));
}
else if (tick_time == tick_min_start_time)
{
Tick& t = tick_container[idIter->second];
TickSPtr tick = boost::make_shared<Tick>(t);
CurrentTicksMap.insert(std::make_pair(idIter->first, tick));
}
else
{
}
++idIter;
}
//将取到的数据播放一遍;
for (auto idIter = CurrentTicksMap.begin(); idIter != CurrentTicksMap.end(); ++idIter)
{
m_ioService->post(boost::bind(&SimMarket::OnRtnDepthMarketData, shared_from_this(), idIter->second));
//索引向前移动;
++m_TheSameTimeTickIndexMap[idIter->first];
}
TakeTick();
}
void SimMarket::OnRspUnSubMarketData(const std::string& subInst, int nRequestID, bool bIsLast)
{
unique_lock<mutex> lck(m_MutInst);
auto iiter = std::find_if(m_SubInstruments.begin(), m_SubInstruments.end(),
[&subInst](const std::map<std::string, std::vector<std::string> >::value_type& v)
{
return std::find(v.second.begin(), v.second.end(), subInst) != v.second.end();
});
if (iiter != m_SubInstruments.end())
{
std::remove(iiter->second.begin(), iiter->second.end(), subInst);
}
//NotifyApiMgr(RspUnSubMarketData, LPARAM(&subInst));
}
void SimMarket::OnRtnDepthMarketData(TickSPtr tick)
{
//LOGDEBUG("行情接收中...");
//保存深度行情;
if (tick)
{
SimHub::get_instance().OnRtnDepthMarket(tick);
//保存;
sigOnTick(tick);
//NotifyApiMgr(RtnDepthMarketData,LPARAM(tick.get()));
//通知交易接口;
}
}
// bool SimMarket::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo)
// {
// // 如果ErrorID != 0, 说明收到了错误的响应
// bool bResult = ((pRspInfo) && (pRspInfo->ErrorID != 0));
// return bResult;
// }
SimMarket::SimMarket(const SimMarket & other)
{
}
bool SimMarket::UnSubscribeMarketData( const std::vector<std::string>& instruments ,const std::string& exchg/*=""*/)
{
if (!m_DataStorePtr)
{
return false;
}
std::vector<std::string> unSubInstruments;
if (!UnSubFilter(instruments,exchg,unSubInstruments))
{
return false;
}
for (std::size_t i=0;i<unSubInstruments.size();i++)
{
}
return true;
}
void SimMarket::OnFrontConnected()
{
ReqUserLogin();
}
void SimMarket::OnRspUserLogin(int nRequestID, bool bIsLast)
{
if (bIsLast)
{
//LOGDEBUG("market login success,the market trading day is:{}", m_MdApi->GetTradingDay());
if (!m_bIsLogined)
{
m_bIsLogined = true;
m_LoginCondVar.notify_one();
}
sigOnUserLogin();
}
else
{
LOGDEBUG("行情登录失败...");
}
if (!m_SubInstruments.empty())
{
auto instIter = m_SubInstruments.begin();
for (; instIter != m_SubInstruments.end(); ++instIter)
{
SubscribeMarketData(instIter->second, instIter->first);
}
}
}
void SimMarket::SetTradingDay(const std::string& tradingDay)
{
}
SimMarket::~SimMarket()
{
LOGUNINIT();
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/mongodb_client/FastTrader.git
[email protected]:mongodb_client/FastTrader.git
mongodb_client
FastTrader
FastTrader
master

搜索帮助