Skip to content

Commit

Permalink
IC, ICIR及相关MultiFactor 增加 spearman 参数,控制是否使用 spearman 计算相关系数
Browse files Browse the repository at this point in the history
  • Loading branch information
fasiondog committed Sep 26, 2024
1 parent b7fa7f6 commit ed7be6c
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 71 deletions.
13 changes: 7 additions & 6 deletions hikyuu_cpp/hikyuu/indicator/crt/IC.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 7 additions & 4 deletions hikyuu_cpp/hikyuu/indicator/crt/ICIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>("n", n);
Expand All @@ -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<int>("n", n);
Expand Down
22 changes: 16 additions & 6 deletions hikyuu_cpp/hikyuu/indicator/imp/IIc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,12 +24,14 @@ IIc::IIc() : IndicatorImp("IC", 1) {
setParam<int>("n", 1); // 调仓周期
// 对齐时是否以 nan 值进行填充,否则以小于当前日期的最后值作为填充
setParam<bool>("fill_null", true);
setParam<bool>("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<int>("n", n);
setParam<bool>("fill_null", true);
setParam<bool>("use_spearman", spearman);
}

IIc::~IIc() {}
Expand Down Expand Up @@ -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<bool>("use_spearman")) {
spearman = hku::CORR;
}

PriceList tmp(stk_count, Null<price_t>());
PriceList tmp_return(stk_count, Null<price_t>());
auto* dst = this->data();
Expand All @@ -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];
}

Expand All @@ -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<IIc>(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<IIc>(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
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/indicator/imp/IIc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 10 additions & 2 deletions hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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<bool>("spearman", spearman);
setParam<int>("ic_n", ic_n);
checkParam("ic_n");
_checkData();
Expand All @@ -93,6 +95,7 @@ void MultiFactorBase::initParam() {
setParam<bool>("zscore_out_extreme", false);
setParam<bool>("zscore_recursive", false);
setParam<double>("zscore_nsigma", 3.0);
setParam<bool>("use_spearman", true); // 默认使用SPEARMAN计算相关系数, 否则使用pearson相关系数
}

void MultiFactorBase::baseCheckParam(const string& name) const {
Expand Down Expand Up @@ -358,6 +361,11 @@ Indicator MultiFactorBase::getIC(int ndays) {

result.setDiscard(discard);

Indicator (*spearman)(const Indicator&, const Indicator&, int) = hku::SPEARMAN;
if (!getParam<bool>("use_spearman")) {
spearman = hku::CORR;
}

PriceList tmp(ind_count, Null<price_t>());
PriceList tmp_return(ind_count, Null<price_t>());
auto* dst = result.data();
Expand All @@ -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];
}

Expand Down
2 changes: 1 addition & 1 deletion hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class HKU_API MultiFactorBase : public enable_shared_from_this<MultiFactorBase>
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;

Expand Down
4 changes: 3 additions & 1 deletion hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
5 changes: 3 additions & 2 deletions hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
} // namespace hku
6 changes: 4 additions & 2 deletions hikyuu_cpp/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

} // namespace hku
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,8 +18,9 @@ namespace hku {
EqualWeightMultiFactor::EqualWeightMultiFactor() : MultiFactorBase("MF_EqualWeight") {}

EqualWeightMultiFactor::EqualWeightMultiFactor(const vector<Indicator>& 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<Indicator> EqualWeightMultiFactor::_calculate(
const vector<vector<Indicator>>& all_stk_inds) {
Expand Down Expand Up @@ -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<EqualWeightMultiFactor>(inds, stks, query, ref_stk, ic_n);
const KQuery& query, const Stock& ref_stk, int ic_n,
bool spearman) {
return make_shared<EqualWeightMultiFactor>(inds, stks, query, ref_stk, ic_n, spearman);
}

} // namespace hku
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class EqualWeightMultiFactor : public MultiFactorBase {
public:
EqualWeightMultiFactor();
EqualWeightMultiFactor(const vector<Indicator>& 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;
};

Expand Down
19 changes: 10 additions & 9 deletions hikyuu_cpp/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,8 +23,8 @@ ICIRMultiFactor::ICIRMultiFactor() : MultiFactorBase("MF_ICIRWeight") {

ICIRMultiFactor::ICIRMultiFactor(const vector<Indicator>& 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<int>("ic_rolling_n", ic_rolling_n);
checkParam("ic_rolling_n");
}
Expand All @@ -43,20 +42,22 @@ IndicatorList ICIRMultiFactor::_calculate(const vector<IndicatorList>& all_stk_i

int ic_n = getParam<int>("ic_n");
int ir_n = getParam<int>("ic_rolling_n");
bool spearman = getParam<bool>("use_spearman");

#if !MF_USE_MULTI_THREAD
size_t discard = 0;
vector<Indicator> 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<Indicator> 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<Indicator> 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++) {
Expand Down Expand Up @@ -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<ICIRMultiFactor>(inds, stks, query, ref_stk, ic_n, ic_rolling_n);
int ic_rolling_n, bool spearman) {
return make_shared<ICIRMultiFactor>(inds, stks, query, ref_stk, ic_n, ic_rolling_n, spearman);
}

} // namespace hku
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit ed7be6c

Please sign in to comment.