bool MySQLKDataDriver::_init() { string func_name(" [MySQLKDataDriver::MySQLKDataDriver]"); string default_host("127.0.0.1"); string default_usr("root"); string default_pwd(""); try { m_host = m_params.get<string>("host"); } catch(...) { m_host = default_host; HKU_WARN("Can't get mysql host! " << func_name); } try { m_port = m_params.get<int>("port"); } catch(...) { m_port = 3306; } try { m_usr = m_params.get<string>("usr"); } catch(...) { m_usr = default_usr; } try { m_pwd = m_params.get<string>("pwd"); } catch(...) { m_pwd = default_pwd; } shared_ptr<MYSQL> mysql(new MYSQL, MySQLCloser()); if (!mysql_init(mysql.get())) { HKU_ERROR(" Initial MySQL handle error!" << func_name); return false; } if (!mysql_real_connect(mysql.get(), m_host.c_str(), m_usr.c_str(), m_pwd.c_str(), NULL, m_port, NULL, 0) ) { HKU_ERROR(" Failed to connect to database!" << func_name); return false; } if (mysql_set_character_set(mysql.get(), "utf8")) { HKU_ERROR(" mysql_set_character_set error!" << func_name); return false; } m_mysql = mysql; return true; }
KRecord MySQLKDataDriver:: getKRecord(const string& market, const string& code, size_t pos, KQuery::KType kType) { string func_name(" [MySQLKDataDriver::getKRecord]"); KRecord result; if (!m_mysql) { HKU_ERROR("Null m_mysql!" << func_name); return result; } /*if (kType >= KQuery::INVALID_KTYPE ) { HKU_WARN("ktype(" << kType << ") is invalid" << func_name); return result; }*/ MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select date, open, high, low, close, amount, count from " << table << " order by date limit " << pos << ", 1"; if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return result; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return result; } while ((row = mysql_fetch_row(mysql_result))) { try { hku_uint64 d = boost::lexical_cast<hku_uint64>(row[0]); result.datetime = Datetime(d); result.openPrice = boost::lexical_cast<price_t>(row[1]); result.highPrice = boost::lexical_cast<price_t>(row[2]); result.lowPrice = boost::lexical_cast<price_t>(row[3]); result.closePrice = boost::lexical_cast<price_t>(row[4]); result.transAmount = boost::lexical_cast<price_t>(row[5]); result.transCount = boost::lexical_cast<price_t>(row[6]); } catch (...) { HKU_INFO("Error get record " << pos << " " << table << func_name); result = Null<KRecord>(); } } mysql_free_result(mysql_result); return result; }
bool SaftyLoss::check() { int n1 = getParam<int>("n1"); int n2 = getParam<int>("n2"); if (n1 < 2) { HKU_ERROR("Invalid param[n1] must >= 2 ! [SaftyLoss::SaftyLoss]"); return false; } if (n2 < 1) { HKU_ERROR("Invalid param[n2] must >= 1 ! [SaftyLoss::SaftyLoss]"); return false; } return true; }
void Weave::_calculate(const Indicator& ind) { size_t total = ind.size(); if (m_result_num != 0 && total != size()) { HKU_ERROR("ind's size must be equal weave's size! [Weave::_calculate]"); return; } if (total == 0) { return; } size_t old_m_result_num = m_result_num; m_result_num = ind.getResultNumber() + m_result_num; if (m_result_num > MAX_RESULT_NUM) { HKU_WARN("Weave only can contains " << MAX_RESULT_NUM << "reult_num! [Weave::_calculate]"); m_result_num = MAX_RESULT_NUM; } if (m_discard < ind.discard()) { m_discard = ind.discard(); } price_t null_price = Null<price_t>(); for (size_t i = old_m_result_num; i < m_result_num; ++i) { m_pBuffer[i] = new PriceList(total, null_price); for (size_t j = m_discard; j < total; ++j) { (*m_pBuffer[i])[j] = ind.get(j, i-old_m_result_num); } } }
size_t FixedPercentMoneyManager ::_getBuyNumber(const Datetime& datetime, const Stock& stock, price_t price, price_t risk, SystemPart from) { double p = getParam<double>("p"); if (p <= 0.0 || p > 1.0) { HKU_ERROR("Error param (p = " << p << ") [PercentRiskMoneyManager::_getBuyNumber]"); return 0; } if (risk == 0.0) { HKU_ERROR("risk is zero! [PercentRiskMoneyManager::_getBuyNumber"); return 0; } return int(m_tm->currentCash() * p / risk); }
bool IRound::check() { if (getParam<int>("ndigits") < 0) { HKU_ERROR("Invalid param[ndigits] ! (n >= 0) " << m_params << " [IRound::check]"); return false; } return true; }
bool ILowLineBars::check() { if (getParam<int>("n") < 0) { HKU_ERROR("Invalid param! (n>=0) " << m_params << " [ILowLineBars::check]"); return false; } return true; }
size_t MySQLKDataDriver:: getCount(const string& market, const string& code, KQuery::KType kType) { string func_name(" [MySQLKDataDriver::getCount]"); size_t result = 0; if (!m_mysql) { HKU_ERROR("Null m_mysql!" << func_name); return result; } /*if (kType >= KQuery::INVALID_KTYPE ) { HKU_WARN("ktype(" << kType << ") is invalid" << func_name); return result; }*/ MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select count(1) from " << table; if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return result; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return result; } while ((row = mysql_fetch_row(mysql_result))) { try { result = boost::lexical_cast<size_t>(row[0]); } catch (...) { HKU_INFO("Error get record count of" << table << func_name); result = 0; } } mysql_free_result(mysql_result); return result; }
Indicator HKU_API WEAVE(const Indicator& ind1, const Indicator& ind2) { if (!ind1.getImp() || !ind2.getImp()) { HKU_ERROR("ind1 or ind2 is Null Indicator! [WEAVE]"); return Indicator(); } IndicatorImpPtr p = make_shared<IndicatorImp>(); p->add(IndicatorImp::WEAVE, ind1.getImp(), ind2.getImp()); return p->calculate(); }
bool RightShift::check() { int n = getParam<int>("n"); if (n < 0) { HKU_ERROR("Invalid param! (n>=0) " << m_params << " [RightShift::RightShift]"); return false; } return true; }
bool IVarp::check() { int n = getParam<int>("n"); if (n < 2) { HKU_ERROR("Invalid param[n] ! (n >= 2) " << m_params << " [IVarp::calculate]"); return false; } return true; }
bool LowLine::check() { int n = getParam<int>("n"); if (n < 1) { HKU_ERROR("Invalid param[n] ! (n >= 1) " << m_params << " [HighLine::calculate]"); return false; } return true; }
Indicator HKU_API IF(const Indicator& ind1, const Indicator& ind2, const Indicator& ind3) { if (!ind1.getImp() || !ind2.getImp() || !ind3.getImp()) { HKU_ERROR("Exists null indicator! [IF]"); return Indicator(); } IndicatorImpPtr p = make_shared<IndicatorImp>(); p->add_if(ind1.getImp(), ind2.getImp(), ind3.getImp()); return p->calculate(); }
bool StockManager::addStockTypeInfo(const StockTypeInfo& stkTypeInfo) { if (m_stockTypeInfo.find(stkTypeInfo.type()) != m_stockTypeInfo.end()) { HKU_ERROR("The stockTypeInfo had exist! " << stkTypeInfo.type() << " [StockManager::addStockTypeInfo]"); return false; } m_stockTypeInfo[stkTypeInfo.type()] = stkTypeInfo; return true; }
bool StockManager::addMarketInfo(const MarketInfo& marketInfo) { string market = marketInfo.market(); boost::to_upper(market); if (m_marketInfoDict.find(market) != m_marketInfoDict.end()) { HKU_ERROR("The marketInfo had exist! " << market << " [StockManager::addMarketInfo]"); return false; } m_marketInfoDict[market] = marketInfo; return true; }
bool StockManager::addStock(const Stock& stock) { string market_code(stock.market_code()); boost::to_upper(market_code); if(m_stockDict.find(market_code) != m_stockDict.end()) { HKU_ERROR("The stock had exist! " << market_code << " [StockManager::addStock]"); return false; } m_stockDict[market_code] = stock; return true; }
bool MySQLKDataDriver::_query(const string& sql_str) { string func_name(" [MySQLKDataDriver::query]"); int res = mysql_query(m_mysql.get(), sql_str.c_str()); if (!res) { return true; } //重新连接数据库 HKU_INFO("MySQL connect invalid, will retry connect!" << func_name); m_mysql = NULL; shared_ptr<MYSQL> mysql(new MYSQL, MySQLCloser()); if (!mysql_init(mysql.get())) { HKU_ERROR(" Initial MySQL handle error!" << func_name); return false; } if (!mysql_real_connect(mysql.get(), m_host.c_str(), m_usr.c_str(), m_pwd.c_str(), NULL, m_port, NULL, 0) ) { HKU_ERROR(" Failed to connect to database!" << func_name); return false; } if (mysql_set_character_set(mysql.get(), "utf8")) { HKU_ERROR(" mysql_set_character_set error!" << func_name); return false; } m_mysql = mysql; res = mysql_query(m_mysql.get(), sql_str.c_str()); if(!res) { return true; } HKU_ERROR("mysql_query error! error no: " << res << " " << sql_str << func_name); return false; }
bool BaseInfoDriver::checkType() { bool result = false; try { string type = getParam<string>("type"); boost::to_upper(type); if (type == m_name) { result = true; } else { result = false; HKU_WARN("Type of driver mismatch! (" << type << " != " << m_name << ") " << "[BaseInfoDriver::checkType]"); } } catch(...) { result = false; HKU_ERROR("Can't get type of driver! [BaseInfoDriver::checkType]"); } return result; }
void IPriceList::_calculate(const Indicator& data) { //如果在叶子节点,直接取自身的data参数 if (isLeaf()) { PriceList x = getParam<PriceList>("data"); int discard = getParam<int>("discard"); size_t total = x.size(); _readyBuffer(total, 1); //更新抛弃数量 m_discard = discard > total ? total : discard; for (size_t i = m_discard; i < total; ++i) { _set(x[i], i); } return; } //不在叶子节点上,则忽略本身的data参数,认为其输入实际为函数入参中的data int result_index = getParam<int>("result_index"); if (result_index < 0 || result_index >= data.getResultNumber()) { HKU_ERROR("result_index out of range! [IPriceList::IPriceList]"); return; } size_t total = data.size(); _readyBuffer(total, 1); for (size_t i = data.discard(); i < total; ++i) { _set(data.get(i, result_index), i); } //更新抛弃数量 m_discard = data.discard(); }
void StockManager::setKDataDriver(const KDataDriverPtr& driver) { if (!driver) { HKU_ERROR("kdata driver is null! [StockManager::setKDataDriver]"); return; } if (m_kdataDriverParam == driver->getParameter()) { } else { m_kdataDriverParam = driver->getParameter(); } bool preload_day = false; try { preload_day = m_preloadParam.get<bool>("day"); if (preload_day) HKU_INFO("Preloading all day kdata to buffer!"); } catch(...) { preload_day = false; } bool preload_week = false; try { preload_week = m_preloadParam.get<bool>("week"); if (preload_week) HKU_INFO("Preloading all week kdata to buffer!"); } catch(...) { preload_week = false; } bool preload_month = false; try { preload_month = m_preloadParam.get<bool>("month"); if (preload_week) HKU_INFO("Preloading all month kdata to buffer!"); } catch(...) { preload_month = false; } bool preload_quarter = false; try { preload_quarter = m_preloadParam.get<bool>("quarter"); if (preload_quarter) HKU_INFO("Preloading all quarter kdata to buffer!"); } catch(...) { preload_quarter = false; } bool preload_halfyear = false; try { preload_halfyear = m_preloadParam.get<bool>("halfyear"); if (preload_halfyear) HKU_INFO("Preloading all halfyear kdata to buffer!"); } catch(...) { preload_halfyear = false; } bool preload_year = false; try { preload_year = m_preloadParam.get<bool>("year"); if (preload_year) HKU_INFO("Preloading all year kdata to buffer!"); } catch(...) { preload_year = false; } bool preload_min = false; try { preload_min = m_preloadParam.get<bool>("min"); if (preload_min) HKU_INFO("Preloading all 1 min kdata to buffer!"); } catch(...) { preload_min = false; } bool preload_min5 = false; try { preload_min5 = m_preloadParam.get<bool>("min5"); if (preload_min5) HKU_INFO("Preloading all 5 min kdata to buffer!"); } catch(...) { preload_min5 = false; } bool preload_min15 = false; try { preload_min15 = m_preloadParam.get<bool>("min15"); if (preload_min15) HKU_INFO("Preloading all 15 min kdata to buffer!"); } catch(...) { preload_min15 = false; } bool preload_min30 = false; try { preload_min30 = m_preloadParam.get<bool>("min30"); if (preload_min30) HKU_INFO("Preloading all 30 min kdata to buffer!"); } catch(...) { preload_min30 = false; } bool preload_min60 = false; try { preload_min60 = m_preloadParam.get<bool>("min60"); if (preload_min60) HKU_INFO("Preloading all 60 min kdata to buffer!"); } catch(...) { preload_min60 = false; } for(auto iter = m_stockDict.begin(); iter != m_stockDict.end(); ++iter) { if (iter->second.market() == "TMP") continue; iter->second.setKDataDriver(driver); 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); 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); } }
bool MySQLKDataDriver:: getIndexRangeByDate(const string& market, const string& code, const KQuery& query, size_t& out_start, size_t& out_end) { string func_name(" [MySQLKDataDriver::getIndexRangeByDate]"); out_start = 0; out_end = 0; if (query.queryType() != KQuery::DATE) { HKU_ERROR("queryType must be KQuery::DATE" << func_name); return false; } if(query.startDatetime() >= query.endDatetime() || query.startDatetime() > (Datetime::max)()) { return false; } MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, query.kType())); std::stringstream buf (std::stringstream::out); buf << "select count(1) from " << table << " where date<" << query.startDatetime().number(); if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return false; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return false; } while ((row = mysql_fetch_row(mysql_result))) { try { out_start = boost::lexical_cast<size_t>(row[0]); } catch (...) { HKU_INFO("Error boost::lexical_cast<size_t>" << table << func_name); out_start = 0; mysql_free_result(mysql_result); return false; } } mysql_free_result(mysql_result); buf.str(""); buf << "select count(1) from " << table << " where date<=" << query.endDatetime().number(); if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return false; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return false; } while ((row = mysql_fetch_row(mysql_result))) { try { out_end = boost::lexical_cast<size_t>(row[0]) - 1; } catch (...) { HKU_INFO("Error boost::lexical_cast<size_t>" << table << func_name); out_end = 0; mysql_free_result(mysql_result); return false; } } mysql_free_result(mysql_result); return true; }
void MySQLKDataDriver:: loadKData(const string& market, const string& code, KQuery::KType kType, size_t start_ix, size_t end_ix, KRecordListPtr out_buffer) { string func_name(" [MySQLKDataDriver::loadKData]"); if (!m_mysql) { //HKU_ERROR("Null m_mysql!" << func_name); return; } //if (kType >= KQuery::INVALID_KTYPE || start_ix >= end_ix) { if (start_ix >= end_ix) { HKU_WARN("ktype(" << kType << ") is invalid or start_ix(" << start_ix << ") >= endix(" << end_ix << ")" << func_name); return; } MYSQL_RES *result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select date, open, high, low, close, amount, count from " << table << " order by date limit " << start_ix << ", " << (end_ix - start_ix); if (!_query(buf.str())) { //HKU_ERROR("mysql_query error!" << func_name); return; } result = mysql_store_result(m_mysql.get()); if (!result) { HKU_ERROR("mysql_store_result error!" << func_name); return; } int i = 0; while ((row = mysql_fetch_row(result))) { try { KRecord k; hku_uint64 d = boost::lexical_cast<hku_uint64>(row[0]); k.datetime = Datetime(d); k.openPrice = boost::lexical_cast<price_t>(row[1]); k.highPrice = boost::lexical_cast<price_t>(row[2]); k.lowPrice = boost::lexical_cast<price_t>(row[3]); k.closePrice = boost::lexical_cast<price_t>(row[4]); k.transAmount = boost::lexical_cast<price_t>(row[5]); k.transCount = boost::lexical_cast<price_t>(row[6]); out_buffer->push_back(k); i++; } catch (...) { HKU_INFO("Can't fecth No." << i << " record in " << table << func_name); i++; continue; } } mysql_free_result(result); return; }
PriceList HistoryFinanceReader ::getHistoryFinanceInfo(Datetime date, const string& market, const string& code) { string funcname(" [HistoryFinanceReader::getHistoryFinanceInfo]"); PriceList result; string filename(m_dir + "/gpcw" + boost::lexical_cast<string>(date.number() / 10000) + ".dat"); FILE *fp = fopen(filename.c_str(), "rb"); if (NULL == fp) { HKU_INFO("Can't found " << filename << funcname); return result; } unsigned int report_date = 0; unsigned short max_count = 0; unsigned long report_size = 0; char header_buf[20]; if (!fread(header_buf, 1, 20, fp)) { HKU_ERROR("read data failed! " << filename << funcname); fclose(fp); return result; } memcpy(&report_date, header_buf + 2, 4); memcpy(&max_count, header_buf + 6, 2); memcpy(&report_size, header_buf + 12, 4); char stock_code[7]; hku_uint32 address = 0; for (int i = 0; i < max_count; i++) { if (!fread(stock_code, 1, 7, fp)) { HKU_ERROR("read stock_code failed! " << filename << funcname); fclose(fp); return result; } if (!fread(&address, 4, 1, fp)) { HKU_ERROR("read stock_item address failed! " << filename << funcname); fclose(fp); return result; } stock_code[6] = '\0'; if (strcmp(stock_code, code.c_str()) == 0) { break; } } if (address != 0) { const int MAX_COL_NUM = 350; float result_buffer[MAX_COL_NUM]; int report_fields_count = int(report_size / 4); if (report_fields_count >= MAX_COL_NUM) { HKU_WARN("Over MAX_COL_NUM! " << filename << funcname); report_fields_count = MAX_COL_NUM; } fseek(fp, address, SEEK_SET); if (!fread(result_buffer, 4, report_fields_count, fp)) { HKU_ERROR("read col data failed! " << filename << funcname); fclose(fp); return result; } result.reserve(report_fields_count); price_t null_price = Null<price_t>(); for (int i = 0; i < report_fields_count; i++) { if (result_buffer[i] == 0xf8f8f8f8) { result.push_back(null_price); } else { result.push_back(result_buffer[i]); } } } else { HKU_ERROR("Invalid address(0)! " << filename << funcname); } fclose(fp); return result; }