hikyuu2/hikyuu_pywrap/_analysis.cpp

197 lines
6.6 KiB
C++
Raw Normal View History

2023-12-28 02:21:36 +08:00
/*
* Copyright (c) 2023 hikyuu.org
*
* Created on: 2023-10-10
* Author: fasiondog
*/
#include <hikyuu/analysis/combinate.h>
2023-12-26 14:26:32 +08:00
#include <hikyuu/analysis/analysis_sys.h>
2023-12-28 02:21:36 +08:00
#include "pybind_utils.h"
using namespace hku;
namespace py = pybind11;
static py::list combinate_index(py::object seq) {
size_t total = len(seq);
std::vector<size_t> index_list(total);
for (size_t i = 0; i < total; ++i) {
index_list[i] = i;
}
py::list result;
std::vector<std::vector<size_t>> comb = combinateIndex(index_list);
for (size_t i = 0, count = comb.size(); i < count; i++) {
py::list tmp = vector_to_python_list<size_t>(comb[i]);
result.append(tmp);
}
return result;
}
static py::list combinate_indicator(const py::sequence& seq, int n) {
size_t total = len(seq);
std::vector<Indicator> inds(total);
for (size_t i = 0; i < total; ++i) {
inds[i] = seq[i].cast<Indicator>();
}
auto comb = combinateIndicator(inds, n);
return vector_to_python_list(comb);
}
static py::dict combinate_ind_analysis(const Stock& stk, const KQuery& query, TradeManagerPtr tm,
SystemPtr sys, py::sequence buy_inds, py::sequence sell_inds,
int n) {
std::vector<Indicator> c_buy_inds;
for (size_t i = 0, total = len(buy_inds); i < total; i++) {
c_buy_inds.emplace_back(buy_inds[i].cast<Indicator>());
}
std::vector<Indicator> c_sell_inds;
for (size_t i = 0, total = len(sell_inds); i < total; i++) {
c_sell_inds.emplace_back(sell_inds[i].cast<Indicator>());
}
py::dict result;
auto pers = combinateIndicatorAnalysis(stk, query, tm, sys, c_buy_inds, c_sell_inds, n);
for (auto iter = pers.begin(); iter != pers.end(); ++iter) {
result[iter->first.c_str()] = std::move(iter->second);
}
return result;
}
static py::dict combinate_ind_analysis_with_block(const Block& blk, const KQuery& query,
TradeManagerPtr tm, SystemPtr sys,
const py::sequence& buy_inds,
const py::sequence& sell_inds, int n) {
std::vector<Indicator> c_buy_inds;
for (size_t i = 0, total = len(buy_inds); i < total; i++) {
c_buy_inds.emplace_back(buy_inds[i].cast<Indicator>());
}
std::vector<Indicator> c_sell_inds;
for (size_t i = 0, total = len(sell_inds); i < total; i++) {
c_sell_inds.emplace_back(sell_inds[i].cast<Indicator>());
}
auto records =
combinateIndicatorAnalysisWithBlock(blk, query, tm, sys, c_buy_inds, c_sell_inds, n);
std::vector<py::list> tmp;
StringList names{"组合名称", "证券代码", "证券名称"};
Performance per;
auto keys = per.names();
for (const auto& key : keys) {
names.emplace_back(key);
}
for (size_t i = 0, len = names.size(); i < len; i++) {
tmp.emplace_back(py::list());
}
for (size_t i = 0, total = records.size(); i < total; i++) {
CombinateAnalysisOutput& record = records[i];
tmp[0].append(record.combinateName);
tmp[1].append(record.market_code);
2023-12-28 02:21:36 +08:00
tmp[2].append(record.name);
HKU_WARN_IF(names.size() != record.values.size() + 3, "lenght invalid: {} {}", names.size(),
record.values.size());
for (size_t j = 3, len = names.size(); j < len; j++) {
tmp[j].append(record.values[j - 3]);
}
}
py::dict result;
for (size_t i = 0, total = names.size(); i < total; i++) {
result[names[i].c_str()] = tmp[i];
}
return result;
}
2024-02-02 09:57:11 +08:00
static py::dict analysis_sys_list(const py::object& pystk_list, const KQuery& query,
SystemPtr sys_proto) {
2024-02-24 03:52:02 +08:00
HKU_CHECK(sys_proto, "sys_proto is null!");
sys_proto->reset(true, true);
SystemList sys_list;
StockList stk_list;
if (py::isinstance<Block>(pystk_list)) {
const auto& blk = pystk_list.cast<Block&>();
for (const auto& stk : blk) {
sys_list.emplace_back(std::move(sys_proto->clone()));
stk_list.emplace_back(stk);
}
} else if (py::isinstance<StockManager>(pystk_list)) {
const auto& blk = pystk_list.cast<StockManager&>();
for (const auto& stk : blk) {
sys_list.emplace_back(std::move(sys_proto->clone()));
stk_list.emplace_back(stk);
}
} else if (py::isinstance<py::sequence>(pystk_list)) {
2023-12-31 19:18:14 +08:00
auto pyseq = pystk_list.cast<py::sequence>();
for (const auto& obj : pyseq) {
sys_list.emplace_back(std::move(sys_proto->clone()));
stk_list.emplace_back(obj.cast<Stock&>());
}
}
2023-12-26 14:26:32 +08:00
vector<AnalysisSystemWithBlockOut> records;
{
py::gil_scoped_release release;
records = analysisSystemList(sys_list, stk_list, query);
}
2023-12-26 14:26:32 +08:00
2024-02-02 09:57:11 +08:00
Performance per;
auto keys = per.names();
std::vector<py::list> tmp(keys.size() + 2);
2023-12-26 14:26:32 +08:00
for (size_t i = 0, total = records.size(); i < total; i++) {
const auto& record = records[i];
if (record.values.size() != keys.size()) {
continue;
}
2024-02-02 09:57:11 +08:00
tmp[0].append(record.market_code);
tmp[1].append(record.name);
for (size_t j = 0, len = keys.size(); j < len; j++) {
tmp[j + 2].append(record.values[j]);
2023-12-26 14:26:32 +08:00
}
2024-02-02 09:57:11 +08:00
}
py::dict result;
result["证券代码"] = tmp[0];
result["证券名称"] = tmp[1];
for (size_t i = 0, total = keys.size(); i < total; i++) {
if (!tmp[i + 2].empty()) {
result[keys[i].c_str()] = tmp[i + 2];
}
2023-12-26 14:26:32 +08:00
}
return result;
}
2023-12-28 02:21:36 +08:00
void export_analysis(py::module& m) {
m.def("combinate_index", combinate_index, R"(combinate_index(seq)
, 15
:param inds: list tuple 使
:return:
:rtype: list)");
m.def("combinate_ind", combinate_indicator, py::arg("inds"), py::arg("n") = 7,
R"(combinate_ind(inds[, n=7])
, [ind1, ind2], [EXIST(ind1,n), EXIST(ind2,n),
EXIST(ind1,n)&EXIST(ind2,n)]
:param list|tuple|seq inds:
:param int n: n
:return:
:rtype: list)");
2024-01-26 04:46:44 +08:00
m.def("inner_combinate_ind_analysis", combinate_ind_analysis);
m.def("inner_combinate_ind_analysis_with_block", combinate_ind_analysis_with_block);
2023-12-26 14:26:32 +08:00
2024-02-02 09:57:11 +08:00
m.def("inner_analysis_sys_list", analysis_sys_list);
2023-12-28 02:21:36 +08:00
}