hikyuu2/hikyuu_pywrap/trade_sys/_MultiFactor.cpp

266 lines
11 KiB
C++
Raw Normal View History

2024-03-13 16:03:55 +08:00
/*
* Copyright (c) 2024 hikyuu.org
*
* Created on: 2024-03-13
* Author: fasiondog
*/
2024-03-30 19:02:35 +08:00
#include <hikyuu/trade_sys/multifactor/build_in.h>
2024-03-13 16:03:55 +08:00
#include "../pybind_utils.h"
namespace py = pybind11;
using namespace hku;
class PyMultiFactor : public MultiFactorBase {
PY_CLONE(PyMultiFactor, MultiFactorBase)
public:
using MultiFactorBase::MultiFactorBase;
PyMultiFactor(const MultiFactorBase& base) : MultiFactorBase(base) {}
2024-03-13 16:03:55 +08:00
IndicatorList _calculate(const vector<IndicatorList>& all_stk_inds) {
2024-03-18 00:48:19 +08:00
// PYBIND11_OVERLOAD_PURE_NAME(IndicatorList, MultiFactorBase, "_calculate", _calculate,
// all_stk_inds);
auto self = py::cast(this);
auto func = self.attr("_calculate")();
auto py_all_stk_inds = vector_to_python_list<IndicatorList>(all_stk_inds);
auto py_ret = func(py_all_stk_inds);
return py_ret.cast<IndicatorList>();
2024-03-13 16:03:55 +08:00
}
};
void export_MultiFactor(py::module& m) {
2024-03-17 23:30:24 +08:00
py::class_<ScoreRecord>(m, "ScoreRecord", "")
.def(py::init<>())
.def(py::init<const Stock&, ScoreRecord::value_t>())
.def("__str__", to_py_str<ScoreRecord>)
.def("__repr__", to_py_str<ScoreRecord>)
2024-05-02 15:15:38 +08:00
.def_readwrite("stock", &ScoreRecord::stock, "证券")
2024-05-02 15:16:11 +08:00
.def_readwrite("value", &ScoreRecord::value, "分值");
2024-03-17 23:30:24 +08:00
2024-03-18 00:48:19 +08:00
py::class_<MultiFactorBase, MultiFactorPtr, PyMultiFactor>(m, "MultiFactorBase",
2024-05-13 05:23:37 +08:00
py::dynamic_attr(),
2024-03-13 16:03:55 +08:00
R"(市场环境判定策略基类
- _calculate :
- _clone :
- _reset : )")
.def(py::init<>())
.def(py::init<const MultiFactorBase&>())
2024-03-13 16:03:55 +08:00
2024-03-15 21:19:56 +08:00
.def("__str__", to_py_str<MultiFactorBase>)
.def("__repr__", to_py_str<MultiFactorBase>)
2024-03-13 16:03:55 +08:00
2024-03-15 03:16:55 +08:00
.def_property("name", py::overload_cast<>(&MultiFactorBase::name, py::const_),
py::overload_cast<const string&>(&MultiFactorBase::name),
py::return_value_policy::copy, "名称")
.def_property("query", &MultiFactorBase::getQuery, &MultiFactorBase::setQuery,
py::return_value_policy::copy, R"(查询条件)")
2024-03-13 16:03:55 +08:00
.def("get_param", &MultiFactorBase::getParam<boost::any>, R"(get_param(self, name)
:param str name:
:return:
:raises out_of_range: )")
.def("set_param", &MultiFactorBase::setParam<boost::any>, R"(set_param(self, name, value)
:param str name:
:param value:
:raises logic_error: Unsupported type! )")
2024-03-15 21:19:56 +08:00
.def("have_param", &MultiFactorBase::haveParam, "是否存在指定参数")
2024-03-18 00:48:19 +08:00
.def("get_ref_stock", &MultiFactorBase::getRefStock, py::return_value_policy::copy,
"获取参考证券")
.def("set_ref_stock", &MultiFactorBase::setRefStock, R"(set_ref_stock(self, stk)
:param Stock stk: )")
2024-03-18 00:48:19 +08:00
.def("get_datetime_list", &MultiFactorBase::getDatetimeList, py::return_value_policy::copy,
"获取参考日期列表(由参考证券通过查询条件获得)")
2024-03-18 00:48:19 +08:00
.def("get_stock_list", &MultiFactorBase::getStockList, py::return_value_policy::copy,
"获取创建时指定的证券列表")
.def("set_stock_list", &MultiFactorBase::setStockList, R"(set_stock_list(self, stks)
:param list stks: )")
2024-03-18 00:48:19 +08:00
.def("get_stock_list_num", &MultiFactorBase::getStockListNumber,
"获取创建时指定的证券列表中证券数量")
2024-03-18 00:48:19 +08:00
.def("get_ref_indicators", &MultiFactorBase::getRefIndicators, py::return_value_policy::copy,
"获取创建时输入的原始因子列表")
2024-03-16 16:57:09 +08:00
.def("set_ref_indicators", &MultiFactorBase::setRefIndicators,
R"(set_ref_indicators(self, inds)
:param list inds: )")
2024-03-18 00:48:19 +08:00
.def("get_factor", &MultiFactorBase::getFactor, py::return_value_policy::copy,
py::arg("stock"), R"(get_factor(self, stock)
2024-03-15 21:19:56 +08:00
2024-03-18 00:48:19 +08:00
:param Stock stock: )")
.def("get_all_factors", &MultiFactorBase::getAllFactors, py::return_value_policy::copy,
R"(get_all_factors(self)
:return: [factor1, factor2, ...] )")
.def("get_ic", &MultiFactorBase::getIC, py::arg("ndays") = 0, R"(get_ic(self[, ndays=0])
IC,
ndays 使 IC/ICIR ic_n
使 ic_n
ndays 0, 使 ic_n IC
:rtype: Indicator)")
.def("get_icir", &MultiFactorBase::getICIR, py::arg("ir_n"), py::arg("ic_n") = 0,
R"(get_icir(self, ir_n[, ic_n=0])
ICIR
:param int ir_n: IR n
:param int ic_n: IC n ( get_ic ndays))")
.def("clone", &MultiFactorBase::clone, "克隆操作")
2024-03-15 21:19:56 +08:00
2024-03-16 16:57:09 +08:00
.def(
2024-03-30 13:42:42 +08:00
"get_scores",
[](MultiFactorBase& self, const Datetime& date, size_t start, py::object end,
2024-03-30 03:17:42 +08:00
py::object filter) {
2024-03-30 13:42:42 +08:00
size_t cend = end.is_none() ? Null<size_t>() : end.cast<size_t>();
2024-03-30 03:17:42 +08:00
if (filter.is_none()) {
2024-03-30 13:42:42 +08:00
return self.getScores(date, start, cend, std::function<bool(const ScoreRecord&)>());
2024-03-30 03:17:42 +08:00
}
HKU_CHECK(py::hasattr(filter, "__call__"), "filter not callable!");
py::object filter_func = filter.attr("__call__");
ScoreRecord sc;
try {
filter_func(sc);
2024-03-30 13:42:42 +08:00
return self.getScores(date, start, cend, [&](const ScoreRecord& score_) {
2024-03-30 03:17:42 +08:00
return filter_func(score_).cast<bool>();
});
} catch (...) {
filter_func(date, sc);
2024-03-30 13:42:42 +08:00
return self.getScores(date, start, cend,
[&](const Datetime& date_, const ScoreRecord& score_) {
return filter_func(date_, score_).cast<bool>();
});
2024-03-30 03:17:42 +08:00
}
2024-03-16 16:57:09 +08:00
},
py::arg("date"), py::arg("start") = 0, py::arg("end") = py::none(),
2024-03-30 03:17:42 +08:00
py::arg("filter") = py::none(),
2024-03-18 00:48:19 +08:00
R"(get_score(self, date[, start=0, end=Null])
:param Datetime date:
:param int start:
:param int end: ()
2024-03-30 03:17:42 +08:00
:param function func: (ScoreRecord)->bool (Datetime, ScoreRecord)->bool
2024-03-18 00:48:19 +08:00
:rtype: ScoreRecordList)")
.def("get_all_scores", &MultiFactorBase::getAllScores, py::return_value_policy::copy,
R"(get_all_scores(self)
2024-03-15 21:19:56 +08:00
2024-03-30 03:17:42 +08:00
:return: ScoreRecordList)")
2024-03-15 21:19:56 +08:00
2024-03-24 03:21:48 +08:00
.def("get_all_src_factors", &MultiFactorBase::getAllSrcFactors)
2024-03-15 21:19:56 +08:00
DEF_PICKLE(MultiFactorPtr);
2024-03-15 03:16:55 +08:00
2024-05-10 02:14:48 +08:00
m.def("MF_EqualWeight", py::overload_cast<>(MF_EqualWeight));
2024-03-15 03:16:55 +08:00
m.def(
"MF_EqualWeight",
[](const py::sequence& inds, const py::sequence& stks, const KQuery& query,
2024-03-30 14:51:36 +08:00
const py::object& ref_stk, int ic_n) {
2024-03-15 03:16:55 +08:00
IndicatorList c_inds = python_list_to_vector<Indicator>(inds);
StockList c_stks = python_list_to_vector<Stock>(stks);
2024-03-30 14:51:36 +08:00
return MF_EqualWeight(c_inds, c_stks, query,
ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast<Stock>(),
ic_n);
2024-03-15 03:16:55 +08:00
},
2024-03-30 14:51:36 +08:00
py::arg("inds"), py::arg("stks"), py::arg("query"), py::arg("ref_stk") = py::none(),
py::arg("ic_n") = 5,
2024-03-16 04:24:31 +08:00
R"(MF_EqualWeight(inds, stks, query, ref_stk[, ic_n=5])
:param sequense(Indicator) inds:
:param sequense(stock) stks:
:param Query query:
2024-03-30 14:51:36 +08:00
:param Stock ref_stk: ( sh000300 300)
2024-03-16 04:24:31 +08:00
:param int ic_n: IC N
2024-03-18 00:48:19 +08:00
:rtype: MultiFactor)");
2024-03-16 04:24:31 +08:00
2024-05-10 02:14:48 +08:00
m.def("MF_ICWeight", py::overload_cast<>(MF_ICWeight));
2024-03-16 04:24:31 +08:00
m.def(
"MF_ICWeight",
[](const py::sequence& inds, const py::sequence& stks, const KQuery& query,
2024-03-30 14:51:36 +08:00
const py::object& ref_stk, int ic_n, int ic_rolling_n) {
2024-03-16 04:24:31 +08:00
IndicatorList c_inds = python_list_to_vector<Indicator>(inds);
StockList c_stks = python_list_to_vector<Stock>(stks);
2024-03-30 14:51:36 +08:00
return MF_ICWeight(c_inds, c_stks, query,
ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast<Stock>(), ic_n,
ic_rolling_n);
2024-03-16 04:24:31 +08:00
},
2024-03-30 14:51:36 +08:00
py::arg("inds"), py::arg("stks"), py::arg("query"), py::arg("ref_stk") = py::none(),
py::arg("ic_n") = 5, py::arg("ic_rolling_n") = 120,
2024-03-16 04:24:31 +08:00
R"(MF_EqualWeight(inds, stks, query, ref_stk[, ic_n=5, ic_rolling_n=120])
IC权重合成因子
:param sequense(Indicator) inds:
:param sequense(stock) stks:
:param Query query:
2024-03-30 14:51:36 +08:00
:param Stock ref_stk: ( sh000300 300)
2024-03-16 04:24:31 +08:00
:param int ic_n: IC N
:param int ic_rolling_n: IC
2024-03-18 00:48:19 +08:00
:rtype: MultiFactor)");
2024-03-16 04:24:31 +08:00
2024-05-10 02:14:48 +08:00
m.def("MF_ICIRWeight", py::overload_cast<>(MF_ICIRWeight));
2024-03-16 04:24:31 +08:00
m.def(
"MF_ICIRWeight",
[](const py::sequence& inds, const py::sequence& stks, const KQuery& query,
2024-03-30 14:51:36 +08:00
const py::object& ref_stk, int ic_n, int ic_rolling_n) {
2024-03-16 04:24:31 +08:00
IndicatorList c_inds = python_list_to_vector<Indicator>(inds);
StockList c_stks = python_list_to_vector<Stock>(stks);
2024-03-30 14:51:36 +08:00
return MF_ICIRWeight(c_inds, c_stks, query,
ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast<Stock>(),
ic_n, ic_rolling_n);
2024-03-16 04:24:31 +08:00
},
2024-03-30 14:51:36 +08:00
py::arg("inds"), py::arg("stks"), py::arg("query"), py::arg("ref_stk") = py::none(),
py::arg("ic_n") = 5, py::arg("ic_rolling_n") = 120,
2024-03-16 04:24:31 +08:00
R"(MF_EqualWeight(inds, stks, query, ref_stk[, ic_n=5, ic_rolling_n=120])
ICIR权重合成因子
:param sequense(Indicator) inds:
:param sequense(stock) stks:
:param Query query:
2024-03-30 14:51:36 +08:00
:param Stock ref_stk: ( sh000300 300)
2024-03-16 04:24:31 +08:00
:param int ic_n: IC N
:param int ic_rolling_n: IC
2024-03-18 00:48:19 +08:00
:rtype: MultiFactor)");
2024-03-13 16:03:55 +08:00
}