diff --git a/hikyuu/gui/HikyuuTDX.py b/hikyuu/gui/HikyuuTDX.py index 68f4658a..3635a4bf 100644 --- a/hikyuu/gui/HikyuuTDX.py +++ b/hikyuu/gui/HikyuuTDX.py @@ -267,8 +267,6 @@ class MyMainWindow(QMainWindow, Ui_MainWindow): current_dir = os.path.dirname(__file__) self.setWindowIcon(QIcon("{}/hikyuu.ico".format(current_dir))) - # self.setFixedSize(self.width(), self.height()) - self.import_status_label.setText('') self.import_detail_textEdit.clear() self.reset_progress_bar() self.day_start_dateEdit.setMinimumDate(datetime.date(1990, 12, 19)) diff --git a/hikyuu/gui/data/ImportHistoryFinanceTask.py b/hikyuu/gui/data/ImportHistoryFinanceTask.py index b5d342d2..186aca4e 100644 --- a/hikyuu/gui/data/ImportHistoryFinanceTask.py +++ b/hikyuu/gui/data/ImportHistoryFinanceTask.py @@ -115,6 +115,13 @@ class ImportHistoryFinanceTask: old_md5 = hashlib.md5(f.read()).hexdigest() if old_md5 != item['hash']: self.download_file(item) + else: + # 不管是否有变化,都导入一次,以便切换引擎时可以导入 + shutil.unpack_archive(dest_file, extract_dir=self.dest_dir) + filename = item['filename'] + filename = f'{self.dest_dir}/{filename[0:-4]}.dat' + self.import_to_db(filename) + hku_info(f"Import finance file: {filename}") count += 1 self.queue.put([self.task_name, None, None, int(100 * count / self.total_count), self.total_count]) except Exception as e: diff --git a/hikyuu/gui/data/MainWindow.py b/hikyuu/gui/data/MainWindow.py index bed6eabd..b556a3a1 100644 --- a/hikyuu/gui/data/MainWindow.py +++ b/hikyuu/gui/data/MainWindow.py @@ -653,7 +653,7 @@ class Ui_MainWindow(object): "

导入深证分时数据:

\n" "

导入权息数据数:

\n" "

导入完毕!

")) - self.import_status_label.setText(_translate("MainWindow", "import_status_label")) + self.import_status_label.setText(_translate("MainWindow", "请勿盘中导入!")) self.sched_import_pushButton.setText(_translate("MainWindow", "启动定时导入")) self.label_40.setText(_translate("MainWindow", "导入执行时间:")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "执行导入")) diff --git a/hikyuu/gui/data/MainWindow.ui b/hikyuu/gui/data/MainWindow.ui index 15962a1a..0ed2bb21 100644 --- a/hikyuu/gui/data/MainWindow.ui +++ b/hikyuu/gui/data/MainWindow.ui @@ -741,7 +741,7 @@ p, li { white-space: pre-wrap; } - import_status_label + 请勿盘中导入! diff --git a/hikyuu_cpp/hikyuu/indicator/crt/IC.h b/hikyuu_cpp/hikyuu/indicator/crt/IC.h index 5113e50f..4512d78d 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 5bae471b..10b29ad0 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 92a4a7de..422714e8 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 6036a9ab..e91c4ad4 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_manage/TradeManager.cpp b/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp index 1736db73..bdb8765f 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp +++ b/hikyuu_cpp/hikyuu/trade_manage/TradeManager.cpp @@ -129,15 +129,10 @@ void TradeManager::_reset() { TradeManagerPtr TradeManager::_clone() { auto p = make_shared(m_init_datetime, m_init_cash, m_costfunc, m_name); - p->m_params = m_params; - p->m_name = m_name; p->m_init_datetime = m_init_datetime; p->m_init_cash = m_init_cash; p->m_last_update_datetime = m_last_update_datetime; - // costfunc是一个公共的函数对象,是共享实现,无须deepcopy - p->m_costfunc = m_costfunc; - p->m_cash = m_cash; p->m_checkin_cash = m_checkin_cash; p->m_checkout_cash = m_checkout_cash; @@ -149,11 +144,7 @@ TradeManagerPtr TradeManager::_clone() { p->m_trade_list = m_trade_list; p->m_position = m_position; p->m_position_history = m_position_history; - p->m_broker_list = m_broker_list; - p->m_broker_last_datetime = m_broker_last_datetime; - p->m_actions = m_actions; - return p; } diff --git a/hikyuu_cpp/hikyuu/trade_manage/TradeManagerBase.h b/hikyuu_cpp/hikyuu/trade_manage/TradeManagerBase.h index f201c5e8..5eac5da6 100644 --- a/hikyuu_cpp/hikyuu/trade_manage/TradeManagerBase.h +++ b/hikyuu_cpp/hikyuu/trade_manage/TradeManagerBase.h @@ -168,6 +168,7 @@ public: p->m_name = m_name; p->m_broker_last_datetime = m_broker_last_datetime; p->m_costfunc = m_costfunc; + p->m_broker_list = m_broker_list; return p; } diff --git a/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp b/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.cpp index 496a5705..3dc06b28 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 9b0dca7e..3f41e7e5 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h +++ b/hikyuu_cpp/hikyuu/trade_sys/multifactor/MultiFactorBase.h @@ -29,7 +29,7 @@ public: 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 a1e41cad..fc9d48af 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 66a3d696..b08d2b85 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 59c88fd9..48bd83bf 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 c5b45966..ac7b636d 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 d8b1a40f..4fad0ae5 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 5b7a8bc8..4a8106eb 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 896a3409..9246ce0e 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 5b3bde35..00d5bb29 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 40c1e6af..4260976d 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_cpp/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h b/hikyuu_cpp/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h index e75ee61d..3970af31 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h +++ b/hikyuu_cpp/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h @@ -28,12 +28,13 @@ SelectorPtr HKU_API SE_MultiFactor(const MFPtr& mf, int topn = 10); * @param ic_n ic 对应的 ic_n 日收益率 * @param ic_rolling_n 计算滚动 IC (即 IC 的 n 日移动平均)周期 * @param ref_stk 参照对比证券,未指定时,默认使用 sh000300 沪深300指数 + * @param spearman 默认使用 spearman 计算相关系数,否则为 pearson * @param mode "MF_ICIRWeight" | "MF_ICWeight" | "MF_EqualWeight" 因子合成算法名称 * @return SelectorPtr * @ingroup Selector */ SelectorPtr HKU_API SE_MultiFactor(const IndicatorList& src_inds, int topn = 10, int ic_n = 5, int ic_rolling_n = 120, const Stock& ref_stk = Stock(), - const string& mode = "MF_ICIRWeight"); + bool spearman = true, const string& mode = "MF_ICIRWeight"); } // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/selector/imp/MultiFactorSelector.cpp b/hikyuu_cpp/hikyuu/trade_sys/selector/imp/MultiFactorSelector.cpp index d46b6aa9..672147c8 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/selector/imp/MultiFactorSelector.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/selector/imp/MultiFactorSelector.cpp @@ -19,10 +19,11 @@ MultiFactorSelector::MultiFactorSelector() : SelectorBase("SE_MultiFactor") { setParam("only_should_buy", false); setParam("ignore_null", true); // 是否忽略 MF 中 score 值为 nan 的证券 setParam("topn", 10); + setParam("reverse", false); // 逆序,此时 topn 代表最末尾的几个,相当于按最低值排序 setParam("ic_n", 5); setParam("ic_rolling_n", 120); - setParam("query", KQuery()); setParam("ref_stk", Stock()); + setParam("use_spearman", true); setParam("mode", "MF_ICIRWeight"); } @@ -32,13 +33,16 @@ MultiFactorSelector::MultiFactorSelector(const MFPtr& mf, int topn) setParam("only_should_buy", false); setParam("ignore_null", true); setParam("topn", topn); + setParam("reverse", false); setParam("ic_n", mf->getParam("ic_n")); - setParam("query", mf->getQuery()); setParam("ref_stk", mf->getRefStock()); if (mf->haveParam("ic_rolling_n")) { setParam("ic_rolling_n", mf->getParam("ic_rolling_n")); + } else { + setParam("ic_rolling_n", 120); } + setParam("use_spearman", mf->getParam("use_spearman")); setParam("mode", mf->name()); } @@ -84,11 +88,34 @@ SystemWeightList MultiFactorSelector::getSelected(Datetime date) { } ScoreRecordList scores; - if (getParam("ignore_null")) { - scores = m_mf->getScores(date, 0, topn, - [](const ScoreRecord& sc) { return !std::isnan(sc.value); }); + if (!getParam("reverse")) { + if (getParam("ignore_null")) { + scores = m_mf->getScores(date, 0, topn, + [](const ScoreRecord& sc) { return !std::isnan(sc.value); }); + } else { + scores = m_mf->getScores(date, 0, topn); + } } else { - scores = m_mf->getScores(date, 0, topn); + ScoreRecordList raw_scores = m_mf->getScores(date); + auto iter = raw_scores.rbegin(); + for (size_t count = 0; count < topn && iter != raw_scores.rend(); ++iter) { + if (!std::isnan(iter->value)) { + scores.emplace_back(*iter); + count++; + } + } + if (scores.size() < topn && !getParam("ignore_null")) { + size_t lack = topn - scores.size(); + iter = raw_scores.rbegin(); + for (size_t count = 0; count < lack && iter != raw_scores.rend(); ++iter) { + if (std::isnan(iter->value)) { + scores.emplace_back(*iter); + count++; + } else { + break; + } + } + } } if (getParam("only_should_buy")) { @@ -118,18 +145,19 @@ void MultiFactorSelector::_calculate() { stks.emplace_back(sys->getStock()); } - auto query = getParam("query"); + const auto& query = m_query; auto ic_n = getParam("ic_n"); auto ic_rolling_n = getParam("ic_rolling_n"); + bool spearman = getParam("use_spearman"); auto mode = getParam("mode"); if (!m_mf) { if ("MF_ICIRWeight" == mode) { - m_mf = MF_ICIRWeight(m_inds, stks, query, ref_stk, ic_n, ic_rolling_n); + m_mf = MF_ICIRWeight(m_inds, stks, query, ref_stk, ic_n, ic_rolling_n, spearman); } else if ("MF_ICWeight" == mode) { - m_mf = MF_ICWeight(m_inds, stks, query, ref_stk, ic_n, ic_rolling_n); + m_mf = MF_ICWeight(m_inds, stks, query, ref_stk, ic_n, ic_rolling_n, spearman); } else if ("MF_EqualWeight" == mode) { - m_mf = MF_EqualWeight(m_inds, stks, query, ref_stk, ic_n); + m_mf = MF_EqualWeight(m_inds, stks, query, ref_stk, ic_n, spearman); } else { HKU_THROW("Invalid mode: {}", mode); } @@ -139,6 +167,7 @@ void MultiFactorSelector::_calculate() { m_mf->setRefStock(ref_stk); m_mf->setStockList(stks); m_mf->setParam("ic_n", ic_n); + m_mf->setParam("use_spearman", spearman); if (m_mf->haveParam("ic_rolling_n")) { m_mf->setParam("ic_rolling_n", ic_rolling_n); } @@ -153,15 +182,16 @@ SelectorPtr HKU_API SE_MultiFactor(const MFPtr& mf, int topn) { return make_shared(mf, topn); } -SelectorPtr HKU_API SE_MultiFactor(const IndicatorList& src_inds, int topn = 10, int ic_n = 5, - int ic_rolling_n = 120, const Stock& ref_stk = Stock(), - const string& mode = "MF_ICIRWeight") { +SelectorPtr HKU_API SE_MultiFactor(const IndicatorList& src_inds, int topn, int ic_n, + int ic_rolling_n, const Stock& ref_stk, bool spearman, + const string& mode) { auto p = make_shared(); p->setIndicators(src_inds); p->setParam("topn", topn); p->setParam("ic_n", ic_n); p->setParam("ic_rolling_n", ic_rolling_n); p->setParam("ref_stk", ref_stk); + p->setParam("use_spearman", spearman); p->setParam("mode", mode); return p; } diff --git a/hikyuu_cpp/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h b/hikyuu_cpp/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h index e22fda83..580f8fa2 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +++ b/hikyuu_cpp/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h @@ -23,7 +23,7 @@ struct RunRanges { : start(start_), run_start(run_start_), end(end_) {} }; -class OptimalSelectorBase : public SelectorBase { +class HKU_API OptimalSelectorBase : public SelectorBase { CLASS_LOGGER_IMP(SE_Optimal) SELECTOR_IMP(OptimalSelectorBase) SELECTOR_NO_PRIVATE_MEMBER_SERIALIZATION @@ -42,6 +42,7 @@ public: // 以便继承子类只需要实现 _clone 和 该接口即可 // 该接口实现系统绩效评估,getSelected 时将取评估结果最大的系统 + // 使用 std::function 的话,在 C++ 中无法序列化,所以使用继承 virtual double evaluate(const SYSPtr& sys, const Datetime& endDate) noexcept { return Null(); } diff --git a/hikyuu_pywrap/indicator/_build_in.cpp b/hikyuu_pywrap/indicator/_build_in.cpp index f51eaa51..12beb811 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_manage/_TradeManager.cpp b/hikyuu_pywrap/trade_manage/_TradeManager.cpp index ee214ccf..80d3b7e8 100644 --- a/hikyuu_pywrap/trade_manage/_TradeManager.cpp +++ b/hikyuu_pywrap/trade_manage/_TradeManager.cpp @@ -254,7 +254,6 @@ void export_TradeManager(py::module& m) { 公共参数: - - reinvest=False (bool) : 红利是否再投资 - precision=2 (int) : 价格计算精度 - support_borrow_cash=False (bool) : 是否自动融资 - support_borrow_stock=False (bool) : 是否自动融券 diff --git a/hikyuu_pywrap/trade_sys/_MultiFactor.cpp b/hikyuu_pywrap/trade_sys/_MultiFactor.cpp index 17df8d00..8d1f0a49 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 diff --git a/hikyuu_pywrap/trade_sys/_Selector.cpp b/hikyuu_pywrap/trade_sys/_Selector.cpp index 7d805644..420e7ab1 100644 --- a/hikyuu_pywrap/trade_sys/_Selector.cpp +++ b/hikyuu_pywrap/trade_sys/_Selector.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "../pybind_utils.h" namespace py = pybind11; @@ -52,6 +53,41 @@ public: } }; +class PyOptimalSelector : public OptimalSelectorBase { + OPTIMAL_SELECTOR_NO_PRIVATE_MEMBER_SERIALIZATION + +public: + PyOptimalSelector() : OptimalSelectorBase("SE_PyOptimal") {} + explicit PyOptimalSelector(const py::function& evalfunc) + : OptimalSelectorBase("SE_PyOptimal"), m_evaluate(evalfunc) {} + virtual ~PyOptimalSelector() = default; + +public: + virtual SelectorPtr _clone() override { + return std::make_shared(); + } + + virtual double evaluate(const SYSPtr& sys, const Datetime& lastDate) noexcept override { + double ret = Null(); + try { + ret = m_evaluate(sys, lastDate).cast(); + } catch (const std::exception& e) { + HKU_ERROR(e.what()); + } catch (...) { + HKU_ERROR("Unknown error!"); + } + return ret; + } + +private: + // 目前无法序列化 + py::function m_evaluate; +}; + +SEPtr crtSEOptimal(const py::function&& evalfunc) { + return std::make_shared(evalfunc); +} + void export_Selector(py::module& m) { py::class_(m, "SystemWeight", py::dynamic_attr(), "系统权重系数结构,在资产分配时,指定对应系统的资产占比系数") @@ -216,13 +252,14 @@ void export_Selector(py::module& m) { m.def( "SE_MultiFactor", [](const py::sequence& inds, int topn, int ic_n, int ic_rolling_n, const py::object& ref_stk, - const string& mode) { + bool spearman, const string& mode) { IndicatorList c_inds = python_list_to_vector(inds); Stock c_ref_stk = ref_stk.is_none() ? getStock("sh000300") : ref_stk.cast(); - return SE_MultiFactor(c_inds, topn, ic_n, ic_rolling_n, c_ref_stk, mode); + return SE_MultiFactor(c_inds, topn, ic_n, ic_rolling_n, c_ref_stk, spearman, mode); }, py::arg("inds"), py::arg("topn") = 10, py::arg("ic_n") = 5, py::arg("ic_rolling_n") = 120, - py::arg("ref_stk") = py::none(), py::arg("mode") = "MF_ICIRWeight", + py::arg("ref_stk") = py::none(), py::arg("spearman") = true, + py::arg("mode") = "MF_ICIRWeight", R"(SE_MultiFactor 创建基于多因子评分的选择器,两种创建方式 @@ -237,8 +274,15 @@ void export_Selector(py::module& m) { :param int ic_n: 默认 IC 对应的 N 日收益率 :param int ic_rolling_n: IC 滚动周期 :param Stock ref_stk: 参考证券 (未指定时,默认为 sh000300 沪深300) + :param bool spearman: 默认使用 spearman 计算相关系数,否则为 pearson :param str mode: "MF_ICIRWeight" | "MF_ICWeight" | "MF_EqualWeight" 因子合成算法名称)"); + m.def("crtSEOptimal", crtSEOptimal, R"(crtSEOptimal(func) + + 快速创建自定义绩效评估函数的寻优选择器 + + :param func: 一个可调用对象,接收参数为 (sys, lastdate),返回一个 float 数值)"); + m.def("SE_MaxFundsOptimal", SE_MaxFundsOptimal, "账户资产最大寻优选择器"); m.def("SE_PerformanceOptimal", SE_PerformanceOptimal, "使用 Performance 统计结果进行寻优的选择器");