From ed7be6c4a6aa0f4ca456e075b7689b7c55c7404c Mon Sep 17 00:00:00 2001 From: fasiondog Date: Thu, 26 Sep 2024 11:51:21 +0800 Subject: [PATCH] =?UTF-8?q?IC,=20ICIR=E5=8F=8A=E7=9B=B8=E5=85=B3MultiFacto?= =?UTF-8?q?r=20=E5=A2=9E=E5=8A=A0=20spearman=20=E5=8F=82=E6=95=B0=EF=BC=8C?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=98=AF=E5=90=A6=E4=BD=BF=E7=94=A8=20spearm?= =?UTF-8?q?an=20=E8=AE=A1=E7=AE=97=E7=9B=B8=E5=85=B3=E7=B3=BB=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hikyuu_cpp/hikyuu/indicator/crt/IC.h | 13 ++++++----- hikyuu_cpp/hikyuu/indicator/crt/ICIR.h | 11 ++++++---- hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp | 22 ++++++++++++++----- hikyuu_cpp/hikyuu/indicator/imp/IIc.h | 2 +- .../trade_sys/multifactor/MultiFactorBase.cpp | 12 ++++++++-- .../trade_sys/multifactor/MultiFactorBase.h | 2 +- .../multifactor/crt/MF_EqualWeight.h | 4 +++- .../trade_sys/multifactor/crt/MF_ICIRWeight.h | 5 +++-- .../trade_sys/multifactor/crt/MF_ICWeight.h | 6 +++-- .../imp/EqualWeightMultiFactor.cpp | 13 +++++------ .../multifactor/imp/EqualWeightMultiFactor.h | 2 +- .../multifactor/imp/ICIRMultiFactor.cpp | 19 ++++++++-------- .../multifactor/imp/ICIRMultiFactor.h | 2 +- .../multifactor/imp/ICMultiFactor.cpp | 20 +++++++++-------- .../trade_sys/multifactor/imp/ICMultiFactor.h | 2 +- hikyuu_pywrap/indicator/_build_in.cpp | 21 ++++++++++-------- hikyuu_pywrap/trade_sys/_MultiFactor.cpp | 21 ++++++++++-------- 17 files changed, 106 insertions(+), 71 deletions(-) diff --git a/hikyuu_cpp/hikyuu/indicator/crt/IC.h b/hikyuu_cpp/hikyuu/indicator/crt/IC.h index 5113e50f9..4512d78d7 100644 --- a/hikyuu_cpp/hikyuu/indicator/crt/IC.h +++ b/hikyuu_cpp/hikyuu/indicator/crt/IC.h @@ -18,23 +18,24 @@ namespace hku { * @param query 查询条件 * @param ref_stk 参照证券,默认 sh000300 沪深300 * @param n 时间窗口 (对应 n 日收益率) + * @param spearman 使用 spearman 相关系数,否则为 pearson * @return Indicator * @ingroup Indicator */ Indicator HKU_API IC(const StockList& stks, const KQuery& query, - const Stock& ref_stk = getStock("sh000300"), int n = 1); + const Stock& ref_stk = getStock("sh000300"), int n = 1, bool spearman = true); Indicator HKU_API IC(const Block& blk, const KQuery& query, - const Stock& ref_stk = getStock("sh000300"), int n = 1); + const Stock& ref_stk = getStock("sh000300"), int n = 1, bool spearman = true); inline Indicator IC(const Indicator& ind, const StockList& stks, const KQuery& query, - const Stock& ref_stk = getStock("sh000300"), int n = 1) { - return IC(stks, query, ref_stk, n)(ind); + const Stock& ref_stk = getStock("sh000300"), int n = 1, bool spearman = true) { + return IC(stks, query, ref_stk, n, spearman)(ind); } inline Indicator IC(const Indicator& ind, const Block& blk, const KQuery& query, - const Stock& ref_stk = getStock("sh000300"), int n = 1) { - return IC(blk, query, ref_stk, n)(ind); + const Stock& ref_stk = getStock("sh000300"), int n = 1, bool spearman = true) { + return IC(blk, query, ref_stk, n, spearman)(ind); } } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/crt/ICIR.h b/hikyuu_cpp/hikyuu/indicator/crt/ICIR.h index 5bae471ba..10b29ad02 100644 --- a/hikyuu_cpp/hikyuu/indicator/crt/ICIR.h +++ b/hikyuu_cpp/hikyuu/indicator/crt/ICIR.h @@ -22,12 +22,14 @@ namespace hku { * @param ref_stk 参照证券,默认 sh000300 沪深300 * @param n IC对应的N日收益率 * @param rolling_n 滚动时间窗口 + * @param spearman 使用 spearman 相关系数,否则为 pearson * @return Indicator * @ingroup Indicator */ inline Indicator ICIR(const Indicator& ind, const StockList& stks, const KQuery& query, - const Stock& ref_stk = getStock("sh000300"), int n = 1, int rolling_n = 120) { - Indicator ic = IC(ind, stks, query, ref_stk, n); + const Stock& ref_stk = getStock("sh000300"), int n = 1, int rolling_n = 120, + bool spearman = true) { + Indicator ic = IC(ind, stks, query, ref_stk, n, spearman); Indicator x = MA(ic, rolling_n) / STDEV(ic, rolling_n); x.name("ICIR"); x.setParam("n", n); @@ -36,8 +38,9 @@ inline Indicator ICIR(const Indicator& ind, const StockList& stks, const KQuery& } inline Indicator ICIR(const Indicator& ind, const Block& blk, const KQuery& query, - const Stock& ref_stk = getStock("sh000300"), int n = 1, int rolling_n = 120) { - Indicator ic = IC(ind, blk, query, ref_stk, n); + const Stock& ref_stk = getStock("sh000300"), int n = 1, int rolling_n = 120, + bool spearman = true) { + Indicator ic = IC(ind, blk, query, ref_stk, n, spearman); Indicator x = MA(ic, rolling_n) / STDEV(ic, rolling_n); x.name("ICIR"); x.setParam("n", n); diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp index 92a4a7de5..422714e85 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp @@ -11,6 +11,7 @@ #include "hikyuu/indicator/crt/ROCP.h" #include "hikyuu/indicator/crt/PRICELIST.h" #include "hikyuu/indicator/crt/SPEARMAN.h" +#include "hikyuu/indicator/crt/CORR.h" #include "IIc.h" #if HKU_SUPPORT_SERIALIZATION @@ -23,12 +24,14 @@ IIc::IIc() : IndicatorImp("IC", 1) { setParam("n", 1); // 调仓周期 // 对齐时是否以 nan 值进行填充,否则以小于当前日期的最后值作为填充 setParam("fill_null", true); + setParam("use_spearman", true); // 默认使用SPEARMAN计算相关系数, 否则使用pearson相关系数 } -IIc::IIc(const StockList& stks, const KQuery& query, int n, const Stock& ref_stk) +IIc::IIc(const StockList& stks, const KQuery& query, int n, const Stock& ref_stk, bool spearman) : IndicatorImp("IC", 1), m_query(query), m_ref_stk(ref_stk), m_stks(stks) { setParam("n", n); setParam("fill_null", true); + setParam("use_spearman", spearman); } IIc::~IIc() {} @@ -89,6 +92,11 @@ void IIc::_calculate(const Indicator& inputInd) { m_discard = discard; HKU_IF_RETURN(m_discard >= days_total, void()); + Indicator (*spearman)(const Indicator&, const Indicator&, int) = hku::SPEARMAN; + if (!getParam("use_spearman")) { + spearman = hku::CORR; + } + PriceList tmp(stk_count, Null()); PriceList tmp_return(stk_count, Null()); auto* dst = this->data(); @@ -100,7 +108,7 @@ void IIc::_calculate(const Indicator& inputInd) { } auto a = PRICELIST(tmp); auto b = PRICELIST(tmp_return); - auto ic = hku::SPEARMAN(a, b, stk_count); + auto ic = spearman(a, b, stk_count); dst[i] = ic[ic.size() - 1]; } @@ -112,13 +120,15 @@ void IIc::_calculate(const Indicator& inputInd) { } } -Indicator HKU_API IC(const StockList& stks, const KQuery& query, const Stock& ref_stk, int n) { - return Indicator(make_shared(stks, query, n, ref_stk)); +Indicator HKU_API IC(const StockList& stks, const KQuery& query, const Stock& ref_stk, int n, + bool spearman) { + return Indicator(make_shared(stks, query, n, ref_stk, spearman)); } -Indicator HKU_API IC(const Block& blk, const KQuery& query, const Stock& ref_stk, int n) { +Indicator HKU_API IC(const Block& blk, const KQuery& query, const Stock& ref_stk, int n, + bool spearman) { StockList stks = blk.getStockList(); - return IC(stks, query, ref_stk, n); + return IC(stks, query, ref_stk, n, spearman); } } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IIc.h b/hikyuu_cpp/hikyuu/indicator/imp/IIc.h index 6036a9ab3..e91c4ad49 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IIc.h +++ b/hikyuu_cpp/hikyuu/indicator/imp/IIc.h @@ -14,7 +14,7 @@ namespace hku { class IIc : public IndicatorImp { public: IIc(); - IIc(const StockList& stks, const KQuery& query, int n, const Stock& ref_stk); + IIc(const StockList& stks, const KQuery& query, int n, const Stock& ref_stk, bool spearman); virtual ~IIc(); virtual void _checkParam(const string& name) const override; diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp b/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp index 496a57051..3dc06b283 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp @@ -14,6 +14,7 @@ #include "hikyuu/indicator/crt/IC.h" #include "hikyuu/indicator/crt/ICIR.h" #include "hikyuu/indicator/crt/SPEARMAN.h" +#include "hikyuu/indicator/crt/CORR.h" #include "hikyuu/indicator/crt/ZSCORE.h" #include "MultiFactorBase.h" @@ -77,9 +78,10 @@ MultiFactorBase::MultiFactorBase(const MultiFactorBase& base) MultiFactorBase::MultiFactorBase(const IndicatorList& inds, const StockList& stks, const KQuery& query, const Stock& ref_stk, const string& name, - int ic_n) + int ic_n, bool spearman) : m_name(name), m_inds(inds), m_stks(stks), m_ref_stk(ref_stk), m_query(query) { initParam(); + setParam("spearman", spearman); setParam("ic_n", ic_n); checkParam("ic_n"); _checkData(); @@ -93,6 +95,7 @@ void MultiFactorBase::initParam() { setParam("zscore_out_extreme", false); setParam("zscore_recursive", false); setParam("zscore_nsigma", 3.0); + setParam("use_spearman", true); // 默认使用SPEARMAN计算相关系数, 否则使用pearson相关系数 } void MultiFactorBase::baseCheckParam(const string& name) const { @@ -358,6 +361,11 @@ Indicator MultiFactorBase::getIC(int ndays) { result.setDiscard(discard); + Indicator (*spearman)(const Indicator&, const Indicator&, int) = hku::SPEARMAN; + if (!getParam("use_spearman")) { + spearman = hku::CORR; + } + PriceList tmp(ind_count, Null()); PriceList tmp_return(ind_count, Null()); auto* dst = result.data(); @@ -368,7 +376,7 @@ Indicator MultiFactorBase::getIC(int ndays) { } auto a = PRICELIST(tmp); auto b = PRICELIST(tmp_return); - auto ic = hku::SPEARMAN(a, b, ind_count); + auto ic = spearman(a, b, ind_count); dst[i] = ic[ic.size() - 1]; } diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h index 9b0dca7eb..3f41e7e54 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h @@ -29,7 +29,7 @@ class HKU_API MultiFactorBase : public enable_shared_from_this MultiFactorBase(); explicit MultiFactorBase(const string& name); MultiFactorBase(const IndicatorList& inds, const StockList& stks, const KQuery& query, - const Stock& ref_stk, const string& name, int ic_n); + const Stock& ref_stk, const string& name, int ic_n, bool spearman); MultiFactorBase(const MultiFactorBase&); virtual ~MultiFactorBase() = default; diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h index a1e41cadc..fc9d48af5 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h @@ -17,10 +17,12 @@ namespace hku { * @param query 日期范围 * @param ref_stk 参考证券 * @param ic_n 默认 IC 对应的 N 日收益率 + * @param spearman 默认使用 spearman 计算相关系数,否则为 pearson * @return MultiFactorPtr */ MultiFactorPtr HKU_API MF_EqualWeight(const IndicatorList& inds, const StockList& stks, - const KQuery& query, const Stock& ref_stk, int ic_n = 5); + const KQuery& query, const Stock& ref_stk, int ic_n = 5, + bool spearman = true); MultiFactorPtr HKU_API MF_EqualWeight(); diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h index 66a3d696a..b08d2b85c 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h @@ -19,11 +19,12 @@ namespace hku { * @param ref_stk 参考证券 * @param ic_n 默认 IC 对应的 N 日收益率 * @param ic_rolling_n IC 滚动窗口 + * @param spearman 默认使用 spearman 计算相关系数,否则为 pearson * @return MultiFactorPtr */ MultiFactorPtr HKU_API MF_ICIRWeight(const IndicatorList& inds, const StockList& stks, const KQuery& query, const Stock& ref_stk, int ic_n = 5, - int ic_rolling_n = 120); + int ic_rolling_n = 120, bool spearman = true); MultiFactorPtr HKU_API MF_ICIRWeight(); -} \ No newline at end of file +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h index 59c88fd99..48bd83bf9 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h @@ -19,10 +19,12 @@ namespace hku { * @param ref_stk 参考证券 * @param ic_n 默认 IC 对应的 N 日收益率 * @param ic_rolling_n IC 滚动窗口 + * @param spearman 默认使用 spearman 计算相关系数,否则为 pearson * @return MultiFactorPtr */ MultiFactorPtr HKU_API MF_ICWeight(const IndicatorList& inds, const StockList& stks, const KQuery& query, const Stock& ref_stk, int ic_n = 5, - int ic_rolling_n = 120); + int ic_rolling_n = 120, bool spearman = true); MultiFactorPtr HKU_API MF_ICWeight(); -} \ No newline at end of file + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.cpp b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.cpp index c5b459665..ac7b636d7 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.cpp @@ -7,9 +7,6 @@ #include "hikyuu/utilities/thread/algorithm.h" #include "hikyuu/indicator/crt/PRICELIST.h" -#include "hikyuu/indicator/crt/IC.h" -#include "hikyuu/indicator/crt/ICIR.h" -#include "hikyuu/indicator/crt/SPEARMAN.h" #include "EqualWeightMultiFactor.h" #if HKU_SUPPORT_SERIALIZATION @@ -21,8 +18,9 @@ namespace hku { EqualWeightMultiFactor::EqualWeightMultiFactor() : MultiFactorBase("MF_EqualWeight") {} EqualWeightMultiFactor::EqualWeightMultiFactor(const vector& inds, const StockList& stks, - const KQuery& query, const Stock& ref_stk, int ic_n) -: MultiFactorBase(inds, stks, query, ref_stk, "MF_EqualWeight", ic_n) {} + const KQuery& query, const Stock& ref_stk, int ic_n, + bool spearman) +: MultiFactorBase(inds, stks, query, ref_stk, "MF_EqualWeight", ic_n, spearman) {} vector EqualWeightMultiFactor::_calculate( const vector>& all_stk_inds) { @@ -116,8 +114,9 @@ MultiFactorPtr HKU_API MF_EqualWeight() { } MultiFactorPtr HKU_API MF_EqualWeight(const IndicatorList& inds, const StockList& stks, - const KQuery& query, const Stock& ref_stk, int ic_n) { - return make_shared(inds, stks, query, ref_stk, ic_n); + const KQuery& query, const Stock& ref_stk, int ic_n, + bool spearman) { + return make_shared(inds, stks, query, ref_stk, ic_n, spearman); } } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h index d8b1a40f3..4fad0ae5e 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h @@ -18,7 +18,7 @@ class EqualWeightMultiFactor : public MultiFactorBase { public: EqualWeightMultiFactor(); EqualWeightMultiFactor(const vector& inds, const StockList& stks, - const KQuery& query, const Stock& ref_stk, int ic_n); + const KQuery& query, const Stock& ref_stk, int ic_n, bool spearman); virtual ~EqualWeightMultiFactor() = default; }; diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.cpp b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.cpp index 5b7a8bc80..4a8106eb7 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.cpp @@ -9,7 +9,6 @@ #include "hikyuu/indicator/crt/PRICELIST.h" #include "hikyuu/indicator/crt/IC.h" #include "hikyuu/indicator/crt/ICIR.h" -#include "hikyuu/indicator/crt/SPEARMAN.h" #include "ICIRMultiFactor.h" #if HKU_SUPPORT_SERIALIZATION @@ -24,8 +23,8 @@ ICIRMultiFactor::ICIRMultiFactor() : MultiFactorBase("MF_ICIRWeight") { ICIRMultiFactor::ICIRMultiFactor(const vector& inds, const StockList& stks, const KQuery& query, const Stock& ref_stk, int ic_n, - int ic_rolling_n) -: MultiFactorBase(inds, stks, query, ref_stk, "MF_ICIRWeight", ic_n) { + int ic_rolling_n, bool spearman) +: MultiFactorBase(inds, stks, query, ref_stk, "MF_ICIRWeight", ic_n, spearman) { setParam("ic_rolling_n", ic_rolling_n); checkParam("ic_rolling_n"); } @@ -43,20 +42,22 @@ IndicatorList ICIRMultiFactor::_calculate(const vector& all_stk_i int ic_n = getParam("ic_n"); int ir_n = getParam("ic_rolling_n"); + bool spearman = getParam("use_spearman"); #if !MF_USE_MULTI_THREAD size_t discard = 0; vector icir(ind_count); for (size_t ii = 0; ii < ind_count; ii++) { - icir[ii] = ICIR(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n, ir_n); + icir[ii] = ICIR(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n, ir_n, spearman); if (icir[ii].discard() > discard) { discard = icir[ii].discard(); } } #else - vector icir = parallel_for_index(0, ind_count, [this, ic_n, ir_n](size_t ii) { - return ICIR(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n, ir_n); - }); + vector icir = + parallel_for_index(0, ind_count, [this, ic_n, ir_n, spearman](size_t ii) { + return ICIR(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n, ir_n, spearman); + }); size_t discard = 0; for (size_t ii = 0; ii < ind_count; ii++) { @@ -147,8 +148,8 @@ MultiFactorPtr HKU_API MF_ICIRWeight() { MultiFactorPtr HKU_API MF_ICIRWeight(const IndicatorList& inds, const StockList& stks, const KQuery& query, const Stock& ref_stk, int ic_n, - int ic_rolling_n) { - return make_shared(inds, stks, query, ref_stk, ic_n, ic_rolling_n); + int ic_rolling_n, bool spearman) { + return make_shared(inds, stks, query, ref_stk, ic_n, ic_rolling_n, spearman); } } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h index 896a34094..9246ce0ee 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h @@ -18,7 +18,7 @@ class ICIRMultiFactor : public MultiFactorBase { public: ICIRMultiFactor(); ICIRMultiFactor(const IndicatorList& inds, const StockList& stks, const KQuery& query, - const Stock& ref_stk, int ic_n, int ic_rolling_n); + const Stock& ref_stk, int ic_n, int ic_rolling_n, bool spearman); virtual ~ICIRMultiFactor() = default; virtual void _checkParam(const string& name) const override; diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.cpp b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.cpp index 5b3bde354..00d5bb297 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.cpp @@ -9,7 +9,6 @@ #include "hikyuu/indicator/crt/PRICELIST.h" #include "hikyuu/indicator/crt/IC.h" #include "hikyuu/indicator/crt/MA.h" -#include "hikyuu/indicator/crt/SPEARMAN.h" #include "ICMultiFactor.h" #if HKU_SUPPORT_SERIALIZATION @@ -23,8 +22,8 @@ ICMultiFactor::ICMultiFactor() : MultiFactorBase("MF_ICWeight") { } ICMultiFactor::ICMultiFactor(const IndicatorList& inds, const StockList& stks, const KQuery& query, - const Stock& ref_stk, int ic_n, int ic_rolling_n) -: MultiFactorBase(inds, stks, query, ref_stk, "MF_ICWeight", ic_n) { + const Stock& ref_stk, int ic_n, int ic_rolling_n, bool spearman) +: MultiFactorBase(inds, stks, query, ref_stk, "MF_ICWeight", ic_n, spearman) { setParam("ic_rolling_n", ic_rolling_n); checkParam("ic_rolling_n"); } @@ -42,21 +41,23 @@ IndicatorList ICMultiFactor::_calculate(const vector& all_stk_ind int ic_n = getParam("ic_n"); int ic_rolling_n = getParam("ic_rolling_n"); + bool spearman = getParam("use_spearman"); // 计算每个原始因子的滚动IC值 #if !MF_USE_MULTI_THREAD size_t discard = 0; IndicatorList ic(ind_count); for (size_t ii = 0; ii < ind_count; ii++) { - ic[ii] = MA(IC(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n), ic_rolling_n); + ic[ii] = MA(IC(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n, spearman), ic_rolling_n); if (ic[ii].discard() > discard) { discard = ic[ii].discard(); } } #else - IndicatorList ic = parallel_for_index(0, ind_count, [this, ic_n, ic_rolling_n](size_t ii) { - return MA(IC(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n), ic_rolling_n); - }); + IndicatorList ic = + parallel_for_index(0, ind_count, [this, ic_n, ic_rolling_n, spearman](size_t ii) { + return MA(IC(m_inds[ii], m_stks, m_query, m_ref_stk, ic_n, spearman), ic_rolling_n); + }); size_t discard = 0; for (size_t ii = 0; ii < ind_count; ii++) { if (ic[ii].discard() > discard) { @@ -148,8 +149,9 @@ MultiFactorPtr HKU_API MF_ICWeight() { MultiFactorPtr HKU_API MF_ICWeight(const IndicatorList& inds, const StockList& stks, const KQuery& query, const Stock& ref_stk, int ic_n, - int ic_rolling_n) { - return std::make_shared(inds, stks, query, ref_stk, ic_n, ic_rolling_n); + int ic_rolling_n, bool spearman) { + return std::make_shared(inds, stks, query, ref_stk, ic_n, ic_rolling_n, + spearman); } } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h index 40c1e6af0..4260976db 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h @@ -18,7 +18,7 @@ class ICMultiFactor : public MultiFactorBase { public: ICMultiFactor(); ICMultiFactor(const IndicatorList& inds, const StockList& stks, const KQuery& query, - const Stock& ref_stk, int ic_n, int ic_rolling_n); + const Stock& ref_stk, int ic_n, int ic_rolling_n, bool spearman); virtual ~ICMultiFactor() = default; virtual void _checkParam(const string& name) const override; diff --git a/hikyuu_pywrap/indicator/_build_in.cpp b/hikyuu_pywrap/indicator/_build_in.cpp index f51eaa512..12beb811f 100644 --- a/hikyuu_pywrap/indicator/_build_in.cpp +++ b/hikyuu_pywrap/indicator/_build_in.cpp @@ -1748,20 +1748,21 @@ void export_Indicator_build_in(py::module& m) { m.def( "IC", [](const Indicator& ind, const py::object& stks, const KQuery& query, const Stock& ref_stk, - int n) { + int n, bool spearman) { if (py::isinstance(stks)) { const auto& blk = stks.cast(); - return IC(ind, blk, query, ref_stk, n); + return IC(ind, blk, query, ref_stk, n, spearman); } if (py::isinstance(stks)) { StockList c_stks = python_list_to_vector(stks); - return IC(ind, c_stks, query, ref_stk, n); + return IC(ind, c_stks, query, ref_stk, n, spearman); } HKU_THROW("Input stks must be Block or sequenc(Stock)!"); }, py::arg("ind"), py::arg("stks"), py::arg("query"), py::arg("ref_stk"), py::arg("n") = 1, + py::arg("spearman") = true, R"(IC(ind, stks, query, ref_stk[, n=1]) 计算指定的因子相对于参考证券的 IC (实际为 RankIC) @@ -1770,26 +1771,27 @@ void export_Indicator_build_in(py::module& m) { :param sequence(stock)|Block stks 证券组合 :param Query query: 查询条件 :param Stock ref_stk: 参照证券,通常使用 sh000300 沪深300 - :param int n: 时间窗口)"); + :param int n: 时间窗口 + :param bool spearman: 使用 spearman 相关系数,否则为 pearson)"); m.def( "ICIR", [](const Indicator& ind, const py::object& stks, const KQuery& query, const Stock& ref_stk, - int n, int rolling_n) { + int n, int rolling_n, bool spearman) { if (py::isinstance(stks)) { const auto& blk = stks.cast(); - return ICIR(ind, blk, query, ref_stk, n, rolling_n); + return ICIR(ind, blk, query, ref_stk, n, rolling_n, spearman); } if (py::isinstance(stks)) { StockList c_stks = python_list_to_vector(stks); - return ICIR(ind, c_stks, query, ref_stk, n, rolling_n); + return ICIR(ind, c_stks, query, ref_stk, n, rolling_n, spearman); } HKU_THROW("Input stks must be Block or sequenc(Stock)!"); }, py::arg("ind"), py::arg("stks"), py::arg("query"), py::arg("ref_stk"), py::arg("n") = 1, - py::arg("rolling_n") = 120, + py::arg("rolling_n") = 120, py::arg("spearman") = true, R"(ICIR(ind, stks, query, ref_stk[, n=1, rolling_n=120]) 计算 IC 因子 IR = IC的多周期均值/IC的标准方差 @@ -1799,7 +1801,8 @@ void export_Indicator_build_in(py::module& m) { :param Query query: 查询条件 :param Stock ref_stk: 参照证券,通常使用 sh000300 沪深300 :param int n: 计算IC时对应的 n 日收益率 - :param int rolling_n: 滚动周期)"); + :param int rolling_n: 滚动周期 + :param bool spearman: 使用 spearman 相关系数,否则为 pearson)"); m.def("ZSCORE", ZSCORE_1, py::arg("out_extreme") = false, py::arg("nsigma") = 3.0, py::arg("recursive") = false); diff --git a/hikyuu_pywrap/trade_sys/_MultiFactor.cpp b/hikyuu_pywrap/trade_sys/_MultiFactor.cpp index 17df8d00c..8d1f0a492 100644 --- a/hikyuu_pywrap/trade_sys/_MultiFactor.cpp +++ b/hikyuu_pywrap/trade_sys/_MultiFactor.cpp @@ -194,15 +194,15 @@ void export_MultiFactor(py::module& m) { m.def( "MF_EqualWeight", [](const py::sequence& inds, const py::sequence& stks, const KQuery& query, - const py::object& ref_stk, int ic_n) { + const py::object& ref_stk, int ic_n, bool spearman) { IndicatorList c_inds = python_list_to_vector(inds); StockList c_stks = python_list_to_vector(stks); return MF_EqualWeight(c_inds, c_stks, query, ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast(), - ic_n); + ic_n, spearman); }, py::arg("inds"), py::arg("stks"), py::arg("query"), py::arg("ref_stk") = py::none(), - py::arg("ic_n") = 5, + py::arg("ic_n") = 5, py::arg("spearman") = true, R"(MF_EqualWeight(inds, stks, query, ref_stk[, ic_n=5]) 等权重合成因子 @@ -212,21 +212,22 @@ void export_MultiFactor(py::module& m) { :param Query query: 日期范围 :param Stock ref_stk: 参考证券 (未指定时,默认为 sh000300 沪深300) :param int ic_n: 默认 IC 对应的 N 日收益率 + :param bool spearman: 默认使用 spearman 计算相关系数,否则为 pearson :rtype: MultiFactor)"); m.def("MF_ICWeight", py::overload_cast<>(MF_ICWeight)); m.def( "MF_ICWeight", [](const py::sequence& inds, const py::sequence& stks, const KQuery& query, - const py::object& ref_stk, int ic_n, int ic_rolling_n) { + const py::object& ref_stk, int ic_n, int ic_rolling_n, bool spearman) { IndicatorList c_inds = python_list_to_vector(inds); StockList c_stks = python_list_to_vector(stks); return MF_ICWeight(c_inds, c_stks, query, ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast(), ic_n, - ic_rolling_n); + ic_rolling_n, spearman); }, 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, + py::arg("ic_n") = 5, py::arg("ic_rolling_n") = 120, py::arg("spearman") = true, R"(MF_EqualWeight(inds, stks, query, ref_stk[, ic_n=5, ic_rolling_n=120]) 滚动IC权重合成因子 @@ -237,21 +238,22 @@ void export_MultiFactor(py::module& m) { :param Stock ref_stk: (未指定时,默认为 sh000300 沪深300) :param int ic_n: 默认 IC 对应的 N 日收益率 :param int ic_rolling_n: IC 滚动周期 + :param bool spearman: 默认使用 spearman 计算相关系数,否则为 pearson :rtype: MultiFactor)"); m.def("MF_ICIRWeight", py::overload_cast<>(MF_ICIRWeight)); m.def( "MF_ICIRWeight", [](const py::sequence& inds, const py::sequence& stks, const KQuery& query, - const py::object& ref_stk, int ic_n, int ic_rolling_n) { + const py::object& ref_stk, int ic_n, int ic_rolling_n, bool spearman) { IndicatorList c_inds = python_list_to_vector(inds); StockList c_stks = python_list_to_vector(stks); return MF_ICIRWeight(c_inds, c_stks, query, ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast(), - ic_n, ic_rolling_n); + ic_n, ic_rolling_n, spearman); }, 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, + py::arg("ic_n") = 5, py::arg("ic_rolling_n") = 120, py::arg("spearman") = true, R"(MF_EqualWeight(inds, stks, query, ref_stk[, ic_n=5, ic_rolling_n=120]) 滚动ICIR权重合成因子 @@ -262,5 +264,6 @@ void export_MultiFactor(py::module& m) { :param Stock ref_stk: 参考证券 (未指定时,默认为 sh000300 沪深300) :param int ic_n: 默认 IC 对应的 N 日收益率 :param int ic_rolling_n: IC 滚动周期 + :param bool spearman: 默认使用 spearman 计算相关系数,否则为 pearson :rtype: MultiFactor)"); } \ No newline at end of file