diff --git a/hikyuu_cpp/hikyuu/Stock.cpp b/hikyuu_cpp/hikyuu/Stock.cpp index 961215775..9e7e84f33 100644 --- a/hikyuu_cpp/hikyuu/Stock.cpp +++ b/hikyuu_cpp/hikyuu/Stock.cpp @@ -7,6 +7,7 @@ #include "StockManager.h" #include "data_driver/KDataDriver.h" +#include "data_driver/HistoryFinanceReader.h" #include "utilities/util.h" #include "KData.h" @@ -655,6 +656,17 @@ TransList Stock::getTransList(const KQuery& query) const { } +PriceList Stock::getHistoryFinanceInfo(const Datetime& date) const { + if (type() == STOCKTYPE_A) { + StockManager& sm = StockManager::instance(); + HistoryFinanceReader rd(sm.datadir() + "/downloads/finance"); + return rd.getHistoryFinanceInfo(date, market(), code()); + } + + return PriceList(); +} + + KRecord Stock:: getKRecordByDate(const Datetime& datetime, KQuery::KType ktype) const { size_t startix = 0, endix = 0; diff --git a/hikyuu_cpp/hikyuu/Stock.h b/hikyuu_cpp/hikyuu/Stock.h index 7a1422925..3b458ad4d 100644 --- a/hikyuu_cpp/hikyuu/Stock.h +++ b/hikyuu_cpp/hikyuu/Stock.h @@ -162,6 +162,12 @@ class HKU_API Stock { /** 获取历史分笔数据 */ TransList getTransList(const KQuery& query) const; + /** + * 获取历史财务信息 + * @param date 指定日期必须是0331、0630、0930、1231,如 Datetime(201109300000) + */ + PriceList getHistoryFinanceInfo(const Datetime& date) const; + /** 设置权息信息 */ void setWeightList(const StockWeightList&); diff --git a/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp b/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp index b65ebd9f1..cf56a43db 100644 --- a/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp +++ b/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.cpp @@ -7,9 +7,8 @@ * Author: fasiondog */ -#include +#include #include -#include "../StockTypeInfo.h" #include "HistoryFinanceReader.h" namespace hku { @@ -24,42 +23,49 @@ HistoryFinanceReader::~HistoryFinanceReader() { } PriceList HistoryFinanceReader -::getHistoryFinanceInfo(Datetime date, const Stock& stock) { +::getHistoryFinanceInfo(Datetime date, + const string& market, const string& code) { + string funcname(" [HistoryFinanceReader::getHistoryFinanceInfo]"); PriceList result; - if (stock.type() != STOCKTYPE_A) { - return result; - } string filename(m_dir + "/gpcw" + boost::lexical_cast(date.number() / 10000) + ".dat"); - std::cout << filename << std::endl; - std::ifstream file(filename.c_str(), std::ifstream::binary); - if( !file ) { - HKU_INFO("Can't found " << filename - << " [HistoryFinanceReader::getHistoryFinanceInfo]"); + 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]; - file.read(header_buf, 20); + if (!fread(header_buf, 1, 20, fp)) { + HKU_ERROR("read data failed! " << filename << funcname); + 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_item_buf[11]; char stock_code[7]; unsigned long address = 0; for (int i = 0; i < max_count; i++) { - file.read(stock_item_buf, 11); - memcpy(stock_code, stock_item_buf, 6); + if (!fread(stock_code, 1, 7, fp)) { + HKU_ERROR("read stock_code failed! " << filename << funcname); + return result; + } + + if (!fread(&address, sizeof(unsigned long), 1, fp)) { + HKU_ERROR("read stock_item address failed! " << filename << funcname); + return result; + } + stock_code[6] = '\0'; - if (string(stock_code) == stock.code()) { - memcpy(&address, stock_item_buf + 7, 4); + if (strcmp(stock_code, code.c_str()) == 0) { break; } } @@ -67,15 +73,18 @@ ::getHistoryFinanceInfo(Datetime date, const Stock& stock) { const int MAX_COL_NUM = 350; float result_buffer[MAX_COL_NUM]; if (address != 0) { - std::cout << address << std::endl; int report_fields_count = int(report_size / 4); if (report_fields_count >= MAX_COL_NUM) { HKU_WARN("Over MAX_COL_NUM! [HistoryFinanceReader::getHistoryFinanceInfo]"); report_fields_count = MAX_COL_NUM; - report_size = report_fields_count * 4; } - file.seekg(address); - file.read((char *)result_buffer, report_size); + + fseek(fp, address, SEEK_SET); + + if (!fread((char *)result_buffer, sizeof(float), report_fields_count, fp)) { + HKU_ERROR("read col data failed!" << filename << funcname); + return result; + } result.reserve(report_fields_count); price_t null_price = Null(); @@ -88,7 +97,7 @@ ::getHistoryFinanceInfo(Datetime date, const Stock& stock) { } } - file.close(); + fclose(fp); return result; } diff --git a/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.h b/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.h index 339ecc838..c58dabc62 100644 --- a/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.h +++ b/hikyuu_cpp/hikyuu/data_driver/HistoryFinanceReader.h @@ -24,7 +24,8 @@ class HKU_API HistoryFinanceReader { HistoryFinanceReader(const string& dir); virtual ~HistoryFinanceReader(); - PriceList getHistoryFinanceInfo(Datetime date, const Stock& stock); + PriceList getHistoryFinanceInfo(Datetime date, + const string& market, const string& code); private: string m_dir; //历史财务信息文件存放目录 diff --git a/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_temp.cpp b/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_temp.cpp index 4ba8519f0..281a45f22 100644 --- a/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_temp.cpp +++ b/hikyuu_cpp/unit_test/libs/hikyuu/hikyuu/test_temp.cpp @@ -12,17 +12,18 @@ using namespace hku; BOOST_AUTO_TEST_CASE( test_temp ) { StockManager& sm = StockManager::instance(); - string dirname(sm.datadir() + "/downloads/finance"); - - std::cout << "**************************" << std::endl; - - HistoryFinanceReader rd = HistoryFinanceReader(dirname); - PriceList result = rd.getHistoryFinanceInfo(Datetime(201109300000), getStock("sh600000")); + Stock stk = getStock("sh600000"); + PriceList result = stk.getHistoryFinanceInfo(Datetime(201109300000)); BOOST_CHECK(result.size() == 286); - - float x = 0xf8f8f8f8; - std::cout << result.size() << std::endl; - std::cout << x << std::endl; - - std::cout << "**************************" << std::endl; + BOOST_CHECK_CLOSE(result[0], 1.067, 0.00001); + BOOST_CHECK_CLOSE(result[1], 1.061, 0.00001); + BOOST_CHECK_CLOSE(result[2], 1.360, 0.00001); + BOOST_CHECK_CLOSE(result[3], 7.482, 0.00001); + BOOST_CHECK_CLOSE(result[9], 0.0, 0.00001); + BOOST_CHECK_CLOSE(result[14], 7.87818e+09, 0.00001); + BOOST_CHECK_CLOSE(result[282], 6.327156e+06, 0.00001); + BOOST_CHECK_CLOSE(result[285], 0.0, 0.00001); + //for (int i = 0; i < 286; i++) { + // std::cout << result[i] << std::endl; + //} } diff --git a/hikyuu_pywrap/_Stock.cpp b/hikyuu_pywrap/_Stock.cpp index 48e49a83d..2b2ba65d0 100644 --- a/hikyuu_pywrap/_Stock.cpp +++ b/hikyuu_pywrap/_Stock.cpp @@ -60,6 +60,7 @@ void export_Stock() { .def("getKRecordList", &Stock::getKRecordList) .def("getDatetimeList", getDatetimeList1) .def("getDatetimeList", getDatetimeList2) + .def("getHistoryFinanceInfo", &Stock::getHistoryFinanceInfo) .def("realtimeUpdate", &Stock::realtimeUpdate) .def("getWeight", getWeight1) .def("getWeight", getWeight2)