From 277ac2c6d69582730afa920a2e5dc32ff6c9acac Mon Sep 17 00:00:00 2001 From: fasiondog Date: Tue, 26 Dec 2023 14:26:32 +0800 Subject: [PATCH] add analysis_sys_with_block --- hikyuu_cpp/hikyuu/analysis/analysis_sys.cpp | 85 +++++++++++++++++++++ hikyuu_cpp/hikyuu/analysis/analysis_sys.h | 42 ++++++++++ hikyuu_pywrap/_analysis.cpp | 30 +++++++- 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 hikyuu_cpp/hikyuu/analysis/analysis_sys.cpp create mode 100644 hikyuu_cpp/hikyuu/analysis/analysis_sys.h diff --git a/hikyuu_cpp/hikyuu/analysis/analysis_sys.cpp b/hikyuu_cpp/hikyuu/analysis/analysis_sys.cpp new file mode 100644 index 00000000..50a0f246 --- /dev/null +++ b/hikyuu_cpp/hikyuu/analysis/analysis_sys.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 hikyuu.org + * + * Created on: 2023-12-25 + * Author: fasiondog + */ + +#include "hikyuu/Block.h" +#include "analysis_sys.h" + +namespace hku { + +vector analysisSystemListWithBlock(const Block& blk, + const KQuery& query, + const SystemPtr sys_proto) { + vector result; + HKU_IF_RETURN(blk.empty() || !sys_proto, result); + + // auto cpu_num = std::thread::hardware_concurrency(); + // #if HKU_OS_WINDOWS + // size_t work_num = 5; + // if (cpu_num < work_num) { + // work_num = cpu_num; + // } + // #else + // size_t work_num = cpu_num; + // #endif + // MQStealThreadPool tg(work_num); + MQStealThreadPool tg; + vector> tasks; + + auto iter = blk.begin(); + for (; iter != blk.end(); ++iter) { + if (iter->isNull()) { + continue; + } + // HKU_INFO("{}", *iter); + auto kdata = iter->getKData(query); + + // auto stk = kdata.getStock(); + // auto sys = sys_proto->clone(); + // AnalysisSystemWithBlockOut ret; + // try { + // auto stk = kdata.getStock(); + // HKU_CHECK(sys, "sys is null!"); + // sys->run(kdata); + // // Performance per; + // // per.statistics(sys->getTM()); + // ret.market_code = stk.market_code(); + // ret.name = stk.name(); + // // ret.values = per.values(); + // } catch (const std::exception& e) { + // // HKU_ERROR(e.what()); + // } catch (...) { + // // HKU_ERROR("Unknown error!"); + // } + // result.emplace_back(ret); + + tasks.emplace_back(tg.submit([sys = sys_proto->clone(), kdata = iter->getKData(query)]() { + AnalysisSystemWithBlockOut ret; + try { + auto stk = kdata.getStock(); + HKU_CHECK(sys, "sys is null!"); + sys->run(kdata); + Performance per; + per.statistics(sys->getTM()); + ret.market_code = stk.market_code(); + ret.name = stk.name(); + ret.values = per.values(); + } catch (const std::exception& e) { + HKU_ERROR(e.what()); + } catch (...) { + HKU_ERROR("Unknown error!"); + } + return ret; + })); + } + + for (auto& task : tasks) { + result.emplace_back(task.get()); + } + return result; +} + +} // namespace hku diff --git a/hikyuu_cpp/hikyuu/analysis/analysis_sys.h b/hikyuu_cpp/hikyuu/analysis/analysis_sys.h new file mode 100644 index 00000000..4efa2711 --- /dev/null +++ b/hikyuu_cpp/hikyuu/analysis/analysis_sys.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 hikyuu.org + * + * Created on: 2023-12-25 + * Author: fasiondog + */ + +#pragma once + +#include "hikyuu/trade_sys/system/System.h" +#include "hikyuu/trade_manage/Performance.h" +#include "hikyuu/utilities/thread/MQStealThreadPool.h" + +namespace hku { + +struct HKU_API AnalysisSystemWithBlockOut { + string market_code; ///< 证券代码 + string name; ///< 证券名称 + PriceList values; ///< 统计各项指标值 + + AnalysisSystemWithBlockOut() = default; + AnalysisSystemWithBlockOut(const AnalysisSystemWithBlockOut& other) = default; + AnalysisSystemWithBlockOut(AnalysisSystemWithBlockOut&& rv) + : market_code(std::move(rv.market_code)), + name(std::move(rv.name)), + values(std::move(rv.values)) {} + + AnalysisSystemWithBlockOut& operator=(const AnalysisSystemWithBlockOut&) = default; + AnalysisSystemWithBlockOut& operator=(AnalysisSystemWithBlockOut&& rv) { + HKU_IF_RETURN(this == &rv, *this); + market_code = std::move(rv.market_code); + name = std::move(rv.name); + values = std::move(rv.values); + return *this; + } +}; + +vector HKU_API analysisSystemListWithBlock(const Block& blk, + const KQuery& query, + const SystemPtr sys_proto); + +} // namespace hku diff --git a/hikyuu_pywrap/_analysis.cpp b/hikyuu_pywrap/_analysis.cpp index 998572b4..a52b4ab5 100644 --- a/hikyuu_pywrap/_analysis.cpp +++ b/hikyuu_pywrap/_analysis.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "pybind_utils.h" using namespace boost::python; @@ -86,7 +87,7 @@ static py::dict combinate_ind_analysis_with_block(const Block& blk, const KQuery names.emplace_back(key); } - for (int i = 0, len = names.size(); i < len; i++) { + for (size_t i = 0, len = names.size(); i < len; i++) { tmp.emplace_back(py::list()); } @@ -110,6 +111,31 @@ static py::dict combinate_ind_analysis_with_block(const Block& blk, const KQuery return result; } +static py::list analysis_sys_with_block(const Block& blk, const KQuery& query, + SystemPtr sys_proto) { + vector records; + + // clang-format off + // Py_BEGIN_ALLOW_THREADS + records = analysisSystemListWithBlock(blk, query, sys_proto); + // Py_END_ALLOW_THREADS + // clang-format on + + HKU_INFO("analysis_sys_with_block"); + py::list result; + for (size_t i = 0, total = records.size(); i < total; i++) { + const auto& record = records[i]; + py::list tmp; + tmp.append(record.market_code); + tmp.append(record.name); + for (const auto& value : record.values) { + tmp.append(value); + } + result.append(tmp); + } + return result; +} + void export_analysis() { def("combinate_index", combinate_index, R"(combinate_index(seq) @@ -131,4 +157,6 @@ void export_analysis() { def("_combinate_ind_analysis", combinate_ind_analysis); def("_combinate_ind_analysis_with_block", combinate_ind_analysis_with_block); + + def("analysis_sys_with_block", analysis_sys_with_block); } \ No newline at end of file