hikyuu2/hikyuu_cpp/hikyuu/StockManager.cpp

405 lines
12 KiB
C++
Raw Normal View History

2015-01-07 01:26:14 +08:00
/*
* StockManager.cpp
*
* Created on: 2011-11-9
* Author: fasiondog
*/
#include <chrono>
2015-01-07 01:26:14 +08:00
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include "utilities/util.h"
#include "StockManager.h"
#include "data_driver/KDataTempCsvDriver.h"
2019-08-16 01:17:24 +08:00
#include "data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h"
2018-04-16 03:46:43 +08:00
#include "data_driver/base_info/mysql/MySQLBaseInfoDriver.h"
2017-10-13 01:50:11 +08:00
#include "data_driver/block_info/qianlong/QLBlockInfoDriver.h"
#include "data_driver/kdata/hdf5/H5KDataDriver.h"
2017-10-13 01:50:11 +08:00
#include "data_driver/kdata/tdx/TdxKDataDriver.h"
2018-04-16 03:46:43 +08:00
#include "data_driver/kdata/mysql/MySQLKDataDriver.h"
2015-01-07 01:26:14 +08:00
namespace hku {
shared_ptr<StockManager> StockManager::m_sm;
StockManager::~StockManager() {
2019-12-30 00:20:21 +08:00
std::cout << "Quit Hikyuu system!\n" << std::endl;
2019-11-10 19:45:57 +08:00
// Cannot use log output when exiting!
// HKU_TRACE("Quit Hikyuu system!\n");
2015-01-07 01:26:14 +08:00
}
StockManager& StockManager::instance() {
2019-11-10 19:45:57 +08:00
if (!m_sm) {
2015-01-07 01:26:14 +08:00
m_sm = shared_ptr<StockManager>(new StockManager());
}
return (*m_sm);
}
2017-10-13 01:50:11 +08:00
Parameter default_preload_param() {
Parameter param;
param.set<bool>("day", true);
param.set<bool>("week", false);
param.set<bool>("month", false);
param.set<bool>("quarter", false);
param.set<bool>("halfyear", false);
param.set<bool>("year", false);
param.set<bool>("min", false);
param.set<bool>("min5", false);
param.set<bool>("min15", false);
param.set<bool>("min30", false);
param.set<bool>("min60", false);
return param;
}
Parameter default_other_param() {
Parameter param;
param.set<string>("tmpdir", ".");
2019-11-10 19:45:57 +08:00
param.set<string>("logger", "");
return param;
}
2019-12-30 00:20:21 +08:00
void StockManager::init(const Parameter& baseInfoParam, const Parameter& blockParam, const Parameter& kdataParam,
const Parameter& preloadParam, const Parameter& hikyuuParam) {
m_baseInfoDriverParam = baseInfoParam;
m_blockDriverParam = blockParam;
m_kdataDriverParam = kdataParam;
m_preloadParam = preloadParam;
m_hikyuuParam = hikyuuParam;
//获取临时路径信息
2017-10-13 01:50:11 +08:00
try {
m_tmpdir = hikyuuParam.get<string>("tmpdir");
} catch (...) {
m_tmpdir = "";
}
try {
m_datadir = hikyuuParam.get<string>("datadir");
} catch (...) {
m_datadir = "";
}
m_stockDict.clear();
m_marketInfoDict.clear();
m_stockTypeInfo.clear();
string funcname(" [StockManager::init]");
//初始化注册默认支持的数据驱动
2019-08-16 01:17:24 +08:00
DataDriverFactory::regBaseInfoDriver(make_shared<SQLiteBaseInfoDriver>());
DataDriverFactory::regBaseInfoDriver(make_shared<MySQLBaseInfoDriver>());
DataDriverFactory::regBlockDriver(make_shared<QLBlockInfoDriver>());
DataDriverFactory::regKDataDriver(make_shared<TdxKDataDriver>());
DataDriverFactory::regKDataDriver(make_shared<H5KDataDriver>());
DataDriverFactory::regKDataDriver(make_shared<MySQLKDataDriver>());
2017-10-13 01:50:11 +08:00
//加载证券基本信息
2017-10-13 01:50:11 +08:00
BaseInfoDriverPtr base_info = DataDriverFactory::getBaseInfoDriver(baseInfoParam);
base_info->loadBaseInfo();
//获取板块驱动
m_blockDriver = DataDriverFactory::getBlockDriver(blockParam);
2017-10-13 01:50:11 +08:00
//获取K线数据驱动并预加载指定的数据
HKU_INFO("Loading KData...");
std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
2017-10-13 01:50:11 +08:00
KDataDriverPtr kdata_driver = DataDriverFactory::getKDataDriver(kdataParam);
setKDataDriver(kdata_driver);
2019-11-10 19:45:57 +08:00
// add special Market, for temp csv file
2019-12-30 00:20:21 +08:00
m_marketInfoDict["TMP"] = MarketInfo("TMP", "Temp Csv file", "temp load from csv file", "000001", Null<Datetime>());
2017-10-13 01:50:11 +08:00
std::chrono::duration<double> sec = std::chrono::system_clock::now() - start_time;
HKU_INFO("{:<.2f}s Loaded Data.", sec.count());
}
2015-01-07 01:26:14 +08:00
void StockManager::setKDataDriver(const KDataDriverPtr& driver) {
if (!driver) {
HKU_ERROR("kdata driver is null!");
return;
}
2015-01-07 01:26:14 +08:00
if (m_kdataDriverParam == driver->getParameter()) {
} else {
m_kdataDriverParam = driver->getParameter();
}
2015-01-07 01:26:14 +08:00
bool preload_day = false;
try {
preload_day = m_preloadParam.get<bool>("day");
if (preload_day)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all day kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_day = false;
}
2015-01-07 01:26:14 +08:00
bool preload_week = false;
try {
preload_week = m_preloadParam.get<bool>("week");
if (preload_week)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all week kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_week = false;
}
2015-01-07 01:26:14 +08:00
bool preload_month = false;
try {
preload_month = m_preloadParam.get<bool>("month");
if (preload_week)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all month kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_month = false;
}
2015-01-07 01:26:14 +08:00
bool preload_quarter = false;
try {
preload_quarter = m_preloadParam.get<bool>("quarter");
if (preload_quarter)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all quarter kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_quarter = false;
}
2015-01-07 01:26:14 +08:00
bool preload_halfyear = false;
try {
preload_halfyear = m_preloadParam.get<bool>("halfyear");
if (preload_halfyear)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all halfyear kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_halfyear = false;
}
2015-01-07 01:26:14 +08:00
bool preload_year = false;
try {
preload_year = m_preloadParam.get<bool>("year");
if (preload_year)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all year kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_year = false;
}
bool preload_min = false;
try {
preload_min = m_preloadParam.get<bool>("min");
if (preload_min)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all 1 min kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_min = false;
}
bool preload_min5 = false;
try {
preload_min5 = m_preloadParam.get<bool>("min5");
if (preload_min5)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all 5 min kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_min5 = false;
}
bool preload_min15 = false;
try {
preload_min15 = m_preloadParam.get<bool>("min15");
if (preload_min15)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all 15 min kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_min15 = false;
}
bool preload_min30 = false;
try {
preload_min30 = m_preloadParam.get<bool>("min30");
if (preload_min30)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all 30 min kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_min30 = false;
}
2015-01-07 01:26:14 +08:00
bool preload_min60 = false;
try {
preload_min60 = m_preloadParam.get<bool>("min60");
if (preload_min60)
2019-03-24 00:17:11 +08:00
HKU_INFO("Preloading all 60 min kdata to buffer!");
2019-11-10 19:45:57 +08:00
} catch (...) {
preload_min60 = false;
}
2015-01-07 01:26:14 +08:00
2019-11-10 19:45:57 +08:00
for (auto iter = m_stockDict.begin(); iter != m_stockDict.end(); ++iter) {
if (iter->second.market() == "TMP")
continue;
iter->second.setKDataDriver(driver);
2015-01-07 01:26:14 +08:00
if (preload_day)
iter->second.loadKDataToBuffer(KQuery::DAY);
if (preload_week)
iter->second.loadKDataToBuffer(KQuery::WEEK);
if (preload_month)
iter->second.loadKDataToBuffer(KQuery::MONTH);
if (preload_quarter)
iter->second.loadKDataToBuffer(KQuery::QUARTER);
if (preload_halfyear)
iter->second.loadKDataToBuffer(KQuery::HALFYEAR);
if (preload_year)
iter->second.loadKDataToBuffer(KQuery::YEAR);
2015-01-07 01:26:14 +08:00
if (preload_min)
iter->second.loadKDataToBuffer(KQuery::MIN);
if (preload_min5)
iter->second.loadKDataToBuffer(KQuery::MIN5);
if (preload_min15)
iter->second.loadKDataToBuffer(KQuery::MIN15);
if (preload_min30)
iter->second.loadKDataToBuffer(KQuery::MIN30);
if (preload_min60)
iter->second.loadKDataToBuffer(KQuery::MIN60);
}
2015-01-07 01:26:14 +08:00
}
string StockManager::tmpdir() const {
2017-10-13 01:50:11 +08:00
return m_tmpdir;
2015-01-07 01:26:14 +08:00
}
string StockManager::datadir() const {
return m_datadir;
}
2015-01-07 01:26:14 +08:00
Stock StockManager::getStock(const string& querystr) const {
Stock result;
string query_str = querystr;
to_upper(query_str);
2016-04-03 00:08:31 +08:00
auto iter = m_stockDict.find(query_str);
2019-11-10 19:45:57 +08:00
if (iter != m_stockDict.end()) {
2015-01-07 01:26:14 +08:00
return iter->second;
}
return result;
}
MarketInfo StockManager::getMarketInfo(const string& market) const {
string market_tmp = market;
to_upper(market_tmp);
2016-04-03 00:08:31 +08:00
auto iter = m_marketInfoDict.find(market_tmp);
2019-11-10 19:45:57 +08:00
if (iter != m_marketInfoDict.end()) {
2015-01-07 01:26:14 +08:00
return iter->second;
}
return Null<MarketInfo>();
}
StockTypeInfo StockManager::getStockTypeInfo(uint32 type) const {
2016-04-03 00:08:31 +08:00
auto iter = m_stockTypeInfo.find(type);
2019-11-10 19:45:57 +08:00
if (iter != m_stockTypeInfo.end()) {
2015-01-07 01:26:14 +08:00
return iter->second;
}
return Null<StockTypeInfo>();
}
MarketList StockManager::getAllMarket() const {
MarketList result;
2016-04-03 00:08:31 +08:00
auto iter = m_marketInfoDict.begin();
2019-11-10 19:45:57 +08:00
for (; iter != m_marketInfoDict.end(); ++iter) {
2015-01-07 01:26:14 +08:00
result.push_back(iter->first);
}
return result;
}
2016-04-03 00:08:31 +08:00
Block StockManager::getBlock(const string& category, const string& name) {
2019-11-10 19:45:57 +08:00
return m_blockDriver ? m_blockDriver->getBlock(category, name) : Block();
2016-04-03 00:08:31 +08:00
}
BlockList StockManager::getBlockList(const string& category) {
return m_blockDriver ? m_blockDriver->getBlockList(category) : BlockList();
2016-04-03 00:08:31 +08:00
}
BlockList StockManager::getBlockList() {
return m_blockDriver ? m_blockDriver->getBlockList() : BlockList();
2016-04-03 00:08:31 +08:00
}
2019-11-10 19:45:57 +08:00
DatetimeList StockManager::getTradingCalendar(const KQuery& query, const string& market) {
2016-04-03 00:08:31 +08:00
Stock stock = getStock("SH000001");
size_t start_ix = 0, end_ix = 0;
DatetimeList result;
if (stock.getIndexRange(query, start_ix, end_ix)) {
2016-04-11 23:48:47 +08:00
result = stock.getDatetimeList(start_ix, end_ix, query.kType());
2016-04-03 00:08:31 +08:00
}
return result;
}
2019-12-30 00:20:21 +08:00
Stock StockManager::addTempCsvStock(const string& code, const string& day_filename, const string& min_filename,
price_t tick, price_t tickValue, int precision, size_t minTradeNumber,
size_t maxTradeNumber) {
string new_code(code);
to_upper(new_code);
2019-12-30 00:20:21 +08:00
Stock result("TMP", new_code, day_filename, STOCKTYPE_TMP, true, Datetime(199901010000), Null<Datetime>(), tick,
tickValue, precision, minTradeNumber, maxTradeNumber);
2019-11-10 19:45:57 +08:00
KDataTempCsvDriver* p = new KDataTempCsvDriver(day_filename, min_filename);
result.setKDataDriver(KDataDriverPtr(p));
result.loadKDataToBuffer(KQuery::DAY);
result.loadKDataToBuffer(KQuery::MIN);
2019-11-10 19:45:57 +08:00
if (!loadStock(result)) {
//加入失败返回Null<Stock>
return Null<Stock>();
}
return result;
}
void StockManager::removeTempCsvStock(const string& code) {
string query_str = "TMP" + code;
to_upper(query_str);
auto iter = m_stockDict.find(query_str);
2019-11-10 19:45:57 +08:00
if (iter != m_stockDict.end()) {
m_stockDict.erase(iter);
}
}
2019-08-15 21:00:00 +08:00
bool StockManager::loadStock(const Stock& stock) {
string market_code(stock.market_code());
to_upper(market_code);
2019-11-10 19:45:57 +08:00
if (m_stockDict.find(market_code) != m_stockDict.end()) {
HKU_ERROR("The stock had exist! {}", market_code);
return false;
}
m_stockDict[market_code] = stock;
return true;
}
bool StockManager::loadMarketInfo(const MarketInfo& marketInfo) {
string market = marketInfo.market();
to_upper(market);
if (m_marketInfoDict.find(market) != m_marketInfoDict.end()) {
HKU_ERROR("The marketInfo had exist! {}", market);
return false;
}
m_marketInfoDict[market] = marketInfo;
return true;
}
bool StockManager::loadStockTypeInfo(const StockTypeInfo& stkTypeInfo) {
if (m_stockTypeInfo.find(stkTypeInfo.type()) != m_stockTypeInfo.end()) {
HKU_ERROR("The stockTypeInfo had exist! {}", stkTypeInfo.type());
return false;
}
m_stockTypeInfo[stkTypeInfo.type()] = stkTypeInfo;
return true;
}
2019-11-10 19:45:57 +08:00
} // namespace hku