From 6aa40a1c85bdec1e84514d2c7c73399a1292f98d Mon Sep 17 00:00:00 2001 From: fasiondog Date: Sat, 15 Jun 2024 23:31:00 +0800 Subject: [PATCH 1/4] fixed INSUM --- hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp index de0d8dd0..d1150fa4 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp @@ -61,7 +61,11 @@ static IndicatorList getAllIndicators(const Block& block, const KQuery& query, static void insum_cum(const IndicatorList& inds, Indicator::value_t* dst, size_t len) { for (const auto& value : inds) { - HKU_ASSERT(value.size() == len); + if (value.empty()) { + continue; + } + HKU_CHECK(value.size() == len, "value len: {}, dst len: {}, stk: {}", value.size(), len, + value.getContext().getStock().name()); const auto* data = value.data(); for (size_t i = 0; i < len; i++) { if (!std::isnan(data[i])) { @@ -78,7 +82,11 @@ static void insum_cum(const IndicatorList& inds, Indicator::value_t* dst, size_t static void insum_mean(const IndicatorList& inds, Indicator::value_t* dst, size_t len) { vector count(len, 0); for (const auto& value : inds) { - HKU_ASSERT(value.size() == len); + if (value.empty()) { + continue; + } + HKU_CHECK(value.size() == len, "value len: {}, dst len: {}, stk: {}", value.size(), len, + value.getContext().getStock().name()); const auto* data = value.data(); for (size_t i = 0; i < len; i++) { if (!std::isnan(data[i])) { @@ -101,6 +109,11 @@ static void insum_mean(const IndicatorList& inds, Indicator::value_t* dst, size_ static void insum_max(const IndicatorList& inds, Indicator::value_t* dst, size_t len) { for (const auto& value : inds) { + if (value.empty()) { + continue; + } + HKU_CHECK(value.size() == len, "value len: {}, dst len: {}, stk: {}", value.size(), len, + value.getContext().getStock().name()); HKU_ASSERT(value.size() == len); const auto* data = value.data(); for (size_t i = 0; i < len; i++) { From 671cc8cf7e502dbabd6a970f8ddf9b82ca868e24 Mon Sep 17 00:00:00 2001 From: fasiondog Date: Sat, 15 Jun 2024 23:44:24 +0800 Subject: [PATCH 2/4] =?UTF-8?q?update=20INSUM,=20HKU=5FCHECK=20=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=91=8A=E8=AD=A6=E6=89=93=E5=8D=B0=E5=BF=BD=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp index d1150fa4..9c76ddbf 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp @@ -64,8 +64,11 @@ static void insum_cum(const IndicatorList& inds, Indicator::value_t* dst, size_t if (value.empty()) { continue; } - HKU_CHECK(value.size() == len, "value len: {}, dst len: {}, stk: {}", value.size(), len, - value.getContext().getStock().name()); + if (value.size() != len) { + HKU_WARN("Ignore stock: {}, value len: {}, dst len: {}, stk: {}", + value.getContext().getStock().name(), value.size(), len); + continue; + } const auto* data = value.data(); for (size_t i = 0; i < len; i++) { if (!std::isnan(data[i])) { @@ -85,8 +88,11 @@ static void insum_mean(const IndicatorList& inds, Indicator::value_t* dst, size_ if (value.empty()) { continue; } - HKU_CHECK(value.size() == len, "value len: {}, dst len: {}, stk: {}", value.size(), len, - value.getContext().getStock().name()); + if (value.size() != len) { + HKU_WARN("Ignore stock: {}, value len: {}, dst len: {}, stk: {}", + value.getContext().getStock().name(), value.size(), len); + continue; + } const auto* data = value.data(); for (size_t i = 0; i < len; i++) { if (!std::isnan(data[i])) { @@ -112,9 +118,11 @@ static void insum_max(const IndicatorList& inds, Indicator::value_t* dst, size_t if (value.empty()) { continue; } - HKU_CHECK(value.size() == len, "value len: {}, dst len: {}, stk: {}", value.size(), len, - value.getContext().getStock().name()); - HKU_ASSERT(value.size() == len); + if (value.size() != len) { + HKU_WARN("Ignore stock: {}, value len: {}, dst len: {}, stk: {}", + value.getContext().getStock().name(), value.size(), len); + continue; + } const auto* data = value.data(); for (size_t i = 0; i < len; i++) { if (!std::isnan(data[i])) { From c00f897cebae43e03a1aab6f71868217fb79dcd1 Mon Sep 17 00:00:00 2001 From: fasiondog Date: Sun, 16 Jun 2024 01:31:31 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=80=80=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hikyuu_cpp/hikyuu/GlobalInitializer.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hikyuu_cpp/hikyuu/GlobalInitializer.cpp b/hikyuu_cpp/hikyuu/GlobalInitializer.cpp index 1ce19261..2aef8bf0 100644 --- a/hikyuu_cpp/hikyuu/GlobalInitializer.cpp +++ b/hikyuu_cpp/hikyuu/GlobalInitializer.cpp @@ -84,18 +84,19 @@ void GlobalInitializer::clean() { getLatestVersion(), getLatestVersion()); } -#if !HKU_ENABLE_LEAK_DETECT && !defined(MSVC_LEAKER_DETECT) - // 未启用内存泄漏检测时,直接退出,让系统自行释放全部资源 - fmt::print("Quit Hikyuu system!\n\n"); - return; -#endif - releaseGlobalTaskGroup(); releaseScheduler(); releaseGlobalSpotAgent(); IndicatorImp::releaseDynEngine(); + +#if HKU_ENABLE_LEAK_DETECT || defined(MSVC_LEAKER_DETECT) + // 非内存泄漏检测时,内存让系统自动释放,避免某些场景下 windows 下退出速度过慢 StockManager::quit(); +#else + fmt::print("Quit Hikyuu system!\n\n"); +#endif + DataDriverFactory::release(); #if HKU_ENABLE_HDF5_KDATA From bba5f4c5a7ed6b088cec64372c9fbd1072a97ce2 Mon Sep 17 00:00:00 2001 From: fasiondog Date: Sun, 16 Jun 2024 02:53:00 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=20INSUM,=20BLOCKSETNUM?= =?UTF-8?q?=20=E5=8F=AF=E7=9B=B4=E6=8E=A5=E8=BE=93=E5=85=A5=20stock=20list?= =?UTF-8?q?,=20=E5=8F=AF=E4=BB=A5=E5=BF=BD=E7=95=A5=20query=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hikyuu_cpp/hikyuu/indicator/crt/BLOCKSETNUM.h | 10 +--- hikyuu_cpp/hikyuu/indicator/crt/INSUM.h | 7 +-- .../hikyuu/indicator/imp/IBlockSetNum.cpp | 16 +++---- hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp | 25 ++++++---- hikyuu_pywrap/indicator/_build_in.cpp | 46 +++++++++++++++---- 5 files changed, 61 insertions(+), 43 deletions(-) diff --git a/hikyuu_cpp/hikyuu/indicator/crt/BLOCKSETNUM.h b/hikyuu_cpp/hikyuu/indicator/crt/BLOCKSETNUM.h index 2bb851a1..f97d8603 100644 --- a/hikyuu_cpp/hikyuu/indicator/crt/BLOCKSETNUM.h +++ b/hikyuu_cpp/hikyuu/indicator/crt/BLOCKSETNUM.h @@ -18,14 +18,6 @@ namespace hku { * @return Indicator */ Indicator HKU_API BLOCKSETNUM(const Block& blk, const KQuery& query); - -/** - * 横向统计(返回板块股个数) - * @param category 板块分类 - * @param name 板块名称 - * @param query 统计范围 - * @return Indicator - */ -Indicator HKU_API BLOCKSETNUM(const string& category, const string& name, const KQuery& query); +Indicator HKU_API BLOCKSETNUM(const Block& blk); } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/crt/INSUM.h b/hikyuu_cpp/hikyuu/indicator/crt/INSUM.h index 6b7e4512..ea985684 100644 --- a/hikyuu_cpp/hikyuu/indicator/crt/INSUM.h +++ b/hikyuu_cpp/hikyuu/indicator/crt/INSUM.h @@ -23,14 +23,11 @@ Indicator HKU_API INSUM(const Block& block, const KQuery& query, const Indicator /** * 返回板块各成分该指标相应输出按计算类型得到的计算值.计算类型:0-累加,1-平均数,2-最大值,3-最小值. - * @param category 板块类别 - * @param category 板块名称 - * @param query 指定范围 + * @param block 指定板块 * @param ind 指定指标 * @param mode 计算类型:0-累加,1-平均数,2-最大值,3-最小值. * @return Indicator */ -Indicator HKU_API INSUM(const string& category, const string& name, const KQuery& query, - const Indicator& ind, int mode); +Indicator HKU_API INSUM(const Block& block, const Indicator& ind, int mode); } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IBlockSetNum.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IBlockSetNum.cpp index fab90646..21168e35 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IBlockSetNum.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IBlockSetNum.cpp @@ -43,7 +43,9 @@ void IBlockSetNum::_calculate(const Indicator& ind) { dates = k.getDatetimeList(); } else { KQuery q = getParam("query"); - dates = StockManager::instance().getTradingCalendar(q, getParam("market")); + if (q != KQuery(0, 0)) { + dates = StockManager::instance().getTradingCalendar(q, getParam("market")); + } } size_t total = dates.size(); @@ -72,17 +74,13 @@ Indicator HKU_API BLOCKSETNUM(const Block& block, const KQuery& query) { IndicatorImpPtr p = make_shared(); p->setParam("query", query); p->setParam("block", block); - if (query == Null()) { - p->setParam("ignore_context", true); - } else { - p->calculate(); - } + p->setParam("ignore_context", false); + p->calculate(); return Indicator(p); } -Indicator HKU_API BLOCKSETNUM(const string& category, const string& name, const KQuery& query) { - Block block = StockManager::instance().getBlock(category, name); - return BLOCKSETNUM(block, query); +Indicator HKU_API BLOCKSETNUM(const Block& block) { + return BLOCKSETNUM(block, KQuery(0, 0)); } } /* namespace hku */ diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp index 9c76ddbf..4fca6bce 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IInSum.cpp @@ -20,7 +20,7 @@ BOOST_CLASS_EXPORT(hku::IInSum) namespace hku { IInSum::IInSum() : IndicatorImp("INSUM", 1) { - setParam("query", KQueryByIndex(-100)); + setParam("query", KQuery(0, 0)); setParam("block", Block()); setParam("mode", 0); setParam("market", "SH"); @@ -138,7 +138,14 @@ static void insum_max(const IndicatorList& inds, Indicator::value_t* dst, size_t static void insum_min(const IndicatorList& inds, Indicator::value_t* dst, size_t len) { for (const auto& value : inds) { - HKU_ASSERT(value.size() == len); + if (value.empty()) { + continue; + } + if (value.size() != len) { + HKU_WARN("Ignore stock: {}, value len: {}, dst len: {}, stk: {}", + value.getContext().getStock().name(), value.size(), len); + continue; + } const auto* data = value.data(); for (size_t i = 0; i < len; i++) { if (!std::isnan(data[i])) { @@ -163,7 +170,9 @@ void IInSum::_calculate(const Indicator& ind) { dates = k.getDatetimeList(); } else { q = getParam("query"); - dates = StockManager::instance().getTradingCalendar(q, getParam("market")); + if (q != KQuery(0, 0)) { + dates = StockManager::instance().getTradingCalendar(q, getParam("market")); + } } size_t total = dates.size(); @@ -193,16 +202,12 @@ Indicator HKU_API INSUM(const Block& block, const KQuery& query, const Indicator p->setParam("query", query); p->setParam("block", block); p->setParam("mode", mode); - if (query == Null()) { - p->setParam("ignore_context", true); - } + p->setParam("ignore_context", false); return Indicator(p)(ind); } -Indicator HKU_API INSUM(const string& category, const string& name, const KQuery& query, - const Indicator& ind, int mode) { - Block block = StockManager::instance().getBlock(category, name); - return INSUM(block, query, ind, mode); +Indicator HKU_API INSUM(const Block& block, const Indicator& ind, int mode) { + return INSUM(block, KQuery(0, 0), ind, mode); } } /* namespace hku */ diff --git a/hikyuu_pywrap/indicator/_build_in.cpp b/hikyuu_pywrap/indicator/_build_in.cpp index 0d9ac686..f51eaa51 100644 --- a/hikyuu_pywrap/indicator/_build_in.cpp +++ b/hikyuu_pywrap/indicator/_build_in.cpp @@ -1849,6 +1849,7 @@ void export_Indicator_build_in(py::module& m) { :param int ix: 历史财务信息字段索引 :param int name: 历史财务信息字段名称)"); + m.def("BLOCKSETNUM", py::overload_cast(BLOCKSETNUM), py::arg("block")); m.def("BLOCKSETNUM", py::overload_cast(BLOCKSETNUM), py::arg("block"), py::arg("query"), R"(BLOCKSETNUM(block, query) @@ -1858,15 +1859,29 @@ void export_Indicator_build_in(py::module& m) { :param Query query: 统计范围)"); m.def( - "BLOCKSETNUM", py::overload_cast(BLOCKSETNUM), - py::arg("category"), py::arg("name"), py::arg("query"), R"(BLOCKSETNUM(category, name, query) + "BLOCKSETNUM", + [](const py::sequence& stks) { + Block blk; + blk.add(python_list_to_vector(stks)); + return BLOCKSETNUM(blk); + }, + py::arg("stks")); + m.def( + "BLOCKSETNUM", + [](const py::sequence& stks, const KQuery& query) { + Block blk; + blk.add(python_list_to_vector(stks)); + return BLOCKSETNUM(blk, query); + }, + py::arg("stks"), py::arg("query"), R"(BLOCKSETNUM(block, query) 横向统计(返回板块股个数) - :param str category: 板块类别 - :param str name: 板块名称 - :param query 统计范围)"); + :param Sequence stks: stock list + :param Query query: 统计范围)"); + m.def("INSUM", py::overload_cast(INSUM), py::arg("block"), + py::arg("ind"), py::arg("mode")); m.def("INSUM", py::overload_cast(INSUM), py::arg("block"), py::arg("query"), py::arg("ind"), py::arg("mode"), R"(INSUM(block, query, ind, mode) @@ -1881,14 +1896,25 @@ void export_Indicator_build_in(py::module& m) { m.def( "INSUM", - py::overload_cast(INSUM), - py::arg("category"), py::arg("name"), py::arg("query"), py::arg("ind"), py::arg("mode"), - R"(INSUM(category, name, ind, mode) + [](const py::sequence stks, const Indicator& ind, int mode) { + Block blk; + blk.add(python_list_to_vector(stks)); + return INSUM(blk, ind, mode); + }, + py::arg("stks"), py::arg("ind"), py::arg("mode")); + m.def( + "INSUM", + [](const py::sequence stks, const KQuery& query, const Indicator& ind, int mode) { + Block blk; + blk.add(python_list_to_vector(stks)); + return INSUM(blk, query, ind, mode); + }, + py::arg("stks"), py::arg("query"), py::arg("ind"), py::arg("mode"), + R"(INSUM(stks, query, ind, mode) 返回板块各成分该指标相应输出按计算类型得到的计算值.计算类型:0-累加,1-平均数,2-最大值,3-最小值. - :param str category: 板块类别 - :param str name: 板块名称 + :param Sequence stks: stock list :param Query query: 指定范围 :param Indicator ind: 指定指标 :param int mode: 计算类型:0-累加,1-平均数,2-最大值,3-最小值.