mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-11-30 10:59:43 +08:00
add SE_Multi_factor, SG_Allways_buy
This commit is contained in:
parent
32af840049
commit
ddebb76217
@ -19,6 +19,6 @@
|
||||
#include "system/build_in.h"
|
||||
#include "allocatefunds/build_in.h"
|
||||
#include "selector/build_in.h"
|
||||
#include "factor/build_in.h"
|
||||
#include "multifactor/build_in.h"
|
||||
|
||||
#endif /* ALL_TRADE_SYS_H_ */
|
||||
|
@ -123,6 +123,14 @@ void MultiFactorBase::paramChanged() {
|
||||
m_calculated = false;
|
||||
}
|
||||
|
||||
void MultiFactorBase::reset() {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
_reset();
|
||||
|
||||
// 仅重置 m_calculated,其他缓存不重置,否则线程不安全
|
||||
m_calculated = false;
|
||||
}
|
||||
|
||||
MultiFactorPtr MultiFactorBase::clone() {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
MultiFactorPtr p;
|
||||
@ -142,23 +150,23 @@ MultiFactorPtr MultiFactorBase::clone() {
|
||||
p->m_stks = m_stks;
|
||||
p->m_ref_stk = m_ref_stk;
|
||||
p->m_query = m_query;
|
||||
p->m_stk_map = m_stk_map;
|
||||
p->m_all_factors = m_all_factors;
|
||||
p->m_date_index = m_date_index;
|
||||
p->m_stk_factor_by_date = m_stk_factor_by_date;
|
||||
p->m_ref_dates = m_ref_dates;
|
||||
p->m_ic = m_ic.clone();
|
||||
p->m_calculated = m_calculated;
|
||||
|
||||
p->m_inds.reserve(m_inds.size());
|
||||
for (const auto& ind : m_inds) {
|
||||
p->m_inds.emplace_back(ind.clone());
|
||||
}
|
||||
|
||||
p->m_all_factors.reserve(m_all_factors.size());
|
||||
for (const auto& ind : m_all_factors) {
|
||||
p->m_all_factors.emplace_back(ind.clone());
|
||||
}
|
||||
p->m_calculated = false;
|
||||
// 强制重算,不克隆以下缓存,避免非线程安全
|
||||
// p->m_stk_map = m_stk_map;
|
||||
// p->m_date_index = m_date_index;
|
||||
// p->m_stk_factor_by_date = m_stk_factor_by_date;
|
||||
// p->m_ic = m_ic.clone();
|
||||
// p->m_all_factors.reserve(m_all_factors.size());
|
||||
// for (const auto& ind : m_all_factors) {
|
||||
// p->m_all_factors.emplace_back(ind.clone());
|
||||
// }
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -181,6 +189,22 @@ const ScoreRecordList& MultiFactorBase::getScore(const Datetime& d) {
|
||||
return m_stk_factor_by_date[iter->second];
|
||||
}
|
||||
|
||||
ScoreRecordList MultiFactorBase::getScores(const Datetime& date, size_t start, size_t end) {
|
||||
ScoreRecordList ret;
|
||||
HKU_IF_RETURN(start >= end, ret);
|
||||
|
||||
const auto& cross = getScore(date);
|
||||
if (end == Null<size_t>() || end > cross.size()) {
|
||||
end = cross.size();
|
||||
}
|
||||
|
||||
for (size_t i = start; i < end; i++) {
|
||||
ret.emplace_back(cross[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ScoreRecordList MultiFactorBase::getScores(const Datetime& date, size_t start, size_t end,
|
||||
std::function<bool(const ScoreRecord&)>&& filter) {
|
||||
ScoreRecordList ret;
|
@ -82,6 +82,8 @@ public:
|
||||
/** 获取指定日期截面的所有因子值,已经降序排列 */
|
||||
const ScoreRecordList& getScore(const Datetime&);
|
||||
|
||||
ScoreRecordList getScores(const Datetime& date, size_t start, size_t end = Null<size_t>());
|
||||
|
||||
/**
|
||||
* 获取指定日期截面 [start, end] 范围内的因子值(评分), 并通过filer进行过滤
|
||||
* @param date 指定日期
|
||||
@ -89,13 +91,11 @@ public:
|
||||
* @param end 排序起始点(不含该点)
|
||||
* @param filter 过滤函数
|
||||
*/
|
||||
ScoreRecordList getScores(
|
||||
const Datetime& date, size_t start, size_t end = Null<size_t>(),
|
||||
std::function<bool(const ScoreRecord&)>&& filter = std::function<bool(const ScoreRecord&)>());
|
||||
ScoreRecordList getScores(const Datetime& date, size_t start, size_t end,
|
||||
std::function<bool(const ScoreRecord&)>&& filter);
|
||||
|
||||
ScoreRecordList getScores(const Datetime& date, size_t start, size_t end = Null<size_t>(),
|
||||
std::function<bool(const Datetime&, const ScoreRecord&)>&& filter =
|
||||
std::function<bool(const Datetime&, const ScoreRecord&)>());
|
||||
ScoreRecordList getScores(const Datetime& date, size_t start, size_t end,
|
||||
std::function<bool(const Datetime&, const ScoreRecord&)>&& filter);
|
||||
|
||||
/** 获取所有截面数据,已按降序排列 */
|
||||
const vector<ScoreRecordList>& getAllScores();
|
||||
@ -123,9 +123,12 @@ public:
|
||||
*/
|
||||
vector<IndicatorList> getAllSrcFactors();
|
||||
|
||||
void reset();
|
||||
|
||||
typedef std::shared_ptr<MultiFactorBase> MultiFactorPtr;
|
||||
MultiFactorPtr clone();
|
||||
|
||||
virtual void _reset() {}
|
||||
virtual MultiFactorPtr _clone() = 0;
|
||||
virtual IndicatorList _calculate(const vector<IndicatorList>&) = 0;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define TRADE_SYS_SELECTOR_BUILD_IN_H_
|
||||
|
||||
#include "crt/SE_Fixed.h"
|
||||
#include "crt/SE_Multi_factor.h"
|
||||
#include "crt/SE_Signal.h"
|
||||
|
||||
#endif /* TRADE_SYS_SELECTOR_BUILD_IN_H_ */
|
||||
|
22
hikyuu_cpp/hikyuu/trade_sys/selector/crt/SE_Multi_factor.h
Normal file
22
hikyuu_cpp/hikyuu/trade_sys/selector/crt/SE_Multi_factor.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hikyuu/trade_sys/multifactor/MultiFactorBase.h"
|
||||
#include "../SelectorBase.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
SelectorPtr HKU_API SE_Multi_factor(const MFPtr& mf, int topn = 10);
|
||||
|
||||
SelectorPtr HKU_API SE_Multi_factor(const IndicatorList& src_inds, const StockList& stks,
|
||||
const KQuery& query, int topn = 10, int ic_n = 5,
|
||||
int ic_rolling_n = 120, const Stock& ref_stk = Stock(),
|
||||
const string& mode = "MF_ICIRWeight");
|
||||
|
||||
} // namespace hku
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#include "hikyuu/trade_sys/multifactor/build_in.h"
|
||||
#include "MultiFactorSelector.h"
|
||||
|
||||
#if HKU_SUPPORT_SERIALIZATION
|
||||
BOOST_CLASS_EXPORT(hku::MultiFactorSelector)
|
||||
#endif
|
||||
|
||||
namespace hku {
|
||||
|
||||
MultiFactorSelector::MultiFactorSelector() : SelectorBase("SE_Multi_factor") {
|
||||
setParam<int>("topn", 10);
|
||||
}
|
||||
|
||||
MultiFactorSelector::MultiFactorSelector(const MFPtr& mf, int topn)
|
||||
: SelectorBase("SE_Multi_factor"), m_mf(mf) {
|
||||
HKU_CHECK(mf, "mf is null!");
|
||||
setParam<int>("topn", topn);
|
||||
checkParam("topn");
|
||||
}
|
||||
|
||||
MultiFactorSelector::~MultiFactorSelector() {}
|
||||
|
||||
void MultiFactorSelector::_checkParam(const string& name) const {
|
||||
if ("topn" == name) {
|
||||
int topn = getParam<int>("topn");
|
||||
HKU_ASSERT(topn > 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiFactorSelector::_reset() {
|
||||
if (m_mf) {
|
||||
m_mf->reset();
|
||||
}
|
||||
m_stk_sys_dict.clear();
|
||||
}
|
||||
|
||||
SelectorPtr MultiFactorSelector::_clone() {
|
||||
MultiFactorSelector* p = new MultiFactorSelector();
|
||||
p->m_mf = m_mf->clone();
|
||||
p->m_stk_sys_dict = m_stk_sys_dict;
|
||||
return SelectorPtr(p);
|
||||
}
|
||||
|
||||
bool MultiFactorSelector::isMatchAF(const AFPtr& af) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SystemWeightList MultiFactorSelector::getSelected(Datetime date) {
|
||||
SystemWeightList ret;
|
||||
auto scores = m_mf->getScores(date, 0, getParam<int>("topn"),
|
||||
[](const ScoreRecord& sc) { return !std::isnan(sc.value); });
|
||||
for (const auto& sc : scores) {
|
||||
ret.emplace_back(m_stk_sys_dict[sc.stock], sc.value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MultiFactorSelector::_calculate() {
|
||||
for (const auto& sys : m_real_sys_list) {
|
||||
m_stk_sys_dict[sys->getStock()] = sys;
|
||||
}
|
||||
}
|
||||
|
||||
SelectorPtr HKU_API SE_Multi_factor(const MFPtr& mf, int topn) {
|
||||
return make_shared<MultiFactorSelector>(mf, topn);
|
||||
}
|
||||
|
||||
SelectorPtr HKU_API SE_Multi_factor(const IndicatorList& src_inds, const StockList& stks,
|
||||
const KQuery& query, int topn, int ic_n, int ic_rolling_n,
|
||||
const Stock& ref_stk, const string& mode) {
|
||||
Stock n_ref_stk = ref_stk.isNull() ? getStock("sh000300") : ref_stk;
|
||||
MFPtr mf;
|
||||
if ("MF_ICIRWeight" == mode) {
|
||||
mf = MF_ICIRWeight(src_inds, stks, query, n_ref_stk, ic_n, ic_rolling_n);
|
||||
} else if ("MF_ICWeight" == mode) {
|
||||
mf = MF_ICWeight(src_inds, stks, query, n_ref_stk, ic_n, ic_rolling_n);
|
||||
} else if ("MF_EqualWeight" == mode) {
|
||||
mf = MF_EqualWeight(src_inds, stks, query, n_ref_stk, ic_n);
|
||||
} else {
|
||||
HKU_THROW("Invalid mode: {}", mode);
|
||||
}
|
||||
|
||||
return make_shared<MultiFactorSelector>(mf, topn);
|
||||
}
|
||||
|
||||
} // namespace hku
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hikyuu/trade_sys/multifactor/MultiFactorBase.h"
|
||||
#include "../SelectorBase.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
class MultiFactorSelector : public SelectorBase {
|
||||
public:
|
||||
MultiFactorSelector();
|
||||
MultiFactorSelector(const MFPtr& mf, int topn);
|
||||
virtual ~MultiFactorSelector();
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
virtual void _reset() override;
|
||||
virtual SelectorPtr _clone() override;
|
||||
virtual SystemWeightList getSelected(Datetime date) override;
|
||||
virtual bool isMatchAF(const AFPtr& af) override;
|
||||
virtual void _calculate() override;
|
||||
|
||||
private:
|
||||
MFPtr m_mf;
|
||||
unordered_map<Stock, SYSPtr> m_stk_sys_dict;
|
||||
|
||||
//============================================
|
||||
// 序列化支持
|
||||
//============================================
|
||||
#if HKU_SUPPORT_SERIALIZATION
|
||||
friend class boost::serialization::access;
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int version) {
|
||||
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SelectorBase);
|
||||
ar& BOOST_SERIALIZATION_NVP(m_mf);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace hku
|
@ -82,7 +82,7 @@ public:
|
||||
* 获取交易对象
|
||||
* @return 交易对象(KData)
|
||||
*/
|
||||
KData getTO() const;
|
||||
const KData& getTO() const;
|
||||
|
||||
/** 复位操作 */
|
||||
void reset();
|
||||
@ -198,7 +198,7 @@ typedef shared_ptr<SignalBase> SGPtr;
|
||||
HKU_API std::ostream& operator<<(std::ostream&, const SignalBase&);
|
||||
HKU_API std::ostream& operator<<(std::ostream&, const SignalPtr&);
|
||||
|
||||
inline KData SignalBase::getTO() const {
|
||||
inline const KData& SignalBase::getTO() const {
|
||||
return m_kdata;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef SIGNAL_BUILD_IN_H_
|
||||
#define SIGNAL_BUILD_IN_H_
|
||||
|
||||
#include "crt/SG_Allways_buy.h"
|
||||
#include "crt/SG_Cross.h"
|
||||
#include "crt/SG_CrossGold.h"
|
||||
#include "crt/SG_Flex.h"
|
||||
|
15
hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Allways_buy.h
Normal file
15
hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Allways_buy.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../SignalBase.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
SignalPtr HKU_API SG_Allways_buy();
|
||||
|
||||
}
|
38
hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.cpp
Normal file
38
hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#include "AllwaysBuySignal.h"
|
||||
|
||||
#if HKU_SUPPORT_SERIALIZATION
|
||||
BOOST_CLASS_EXPORT(hku::AllwaysBuySignal)
|
||||
#endif
|
||||
|
||||
namespace hku {
|
||||
|
||||
AllwaysBuySignal::AllwaysBuySignal() : SignalBase("SG_Allways_buy") {
|
||||
setParam<bool>("alternate", false);
|
||||
}
|
||||
|
||||
void AllwaysBuySignal::_checkParam(const string& name) const {
|
||||
if ("alternate" == name) {
|
||||
bool alternate = getParam<bool>(name);
|
||||
HKU_CHECK(!alternate, "param alternate must be false!");
|
||||
}
|
||||
}
|
||||
|
||||
void AllwaysBuySignal::_calculate() {
|
||||
const auto& kdata = getTO();
|
||||
for (auto iter = kdata.cbegin(); iter != kdata.cend(); ++iter) {
|
||||
_addBuySignal(iter->datetime);
|
||||
}
|
||||
}
|
||||
|
||||
SignalPtr HKU_API SG_Allways_buy() {
|
||||
return SignalPtr(new AllwaysBuySignal);
|
||||
}
|
||||
|
||||
} // namespace hku
|
25
hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.h
Normal file
25
hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 hikyuu.org
|
||||
*
|
||||
* Created on: 2024-03-30
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../SignalBase.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
class AllwaysBuySignal : public SignalBase {
|
||||
SIGNAL_IMP(AllwaysBuySignal)
|
||||
SIGNAL_NO_PRIVATE_MEMBER_SERIALIZATION
|
||||
|
||||
public:
|
||||
AllwaysBuySignal();
|
||||
virtual ~AllwaysBuySignal() = default;
|
||||
|
||||
virtual void _checkParam(const string& name) const override;
|
||||
};
|
||||
|
||||
} // namespace hku
|
@ -14,7 +14,7 @@
|
||||
#include <hikyuu/indicator/crt/IC.h>
|
||||
#include <hikyuu/indicator/crt/ROCR.h>
|
||||
#include <hikyuu/indicator/crt/KDATA.h>
|
||||
#include <hikyuu/trade_sys/factor/crt/MF_EqualWeight.h>
|
||||
#include <hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h>
|
||||
|
||||
using namespace hku;
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <hikyuu/indicator/crt/ROCR.h>
|
||||
#include <hikyuu/indicator/crt/KDATA.h>
|
||||
#include <hikyuu/indicator/crt/STDEV.h>
|
||||
#include <hikyuu/trade_sys/factor/crt/MF_ICIRWeight.h>
|
||||
#include <hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h>
|
||||
|
||||
using namespace hku;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <hikyuu/indicator/crt/ROCR.h>
|
||||
#include <hikyuu/indicator/crt/KDATA.h>
|
||||
#include <hikyuu/indicator/crt/PRICELIST.h>
|
||||
#include <hikyuu/trade_sys/factor/crt/MF_ICWeight.h>
|
||||
#include <hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h>
|
||||
|
||||
using namespace hku;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#include <hikyuu/trade_sys/factor/build_in.h>
|
||||
#include <hikyuu/trade_sys/multifactor/build_in.h>
|
||||
#include "../pybind_utils.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
@ -51,7 +51,8 @@ void export_Signal(py::module& m) {
|
||||
.def_property("name", py::overload_cast<>(&SignalBase::name, py::const_),
|
||||
py::overload_cast<const string&>(&SignalBase::name),
|
||||
py::return_value_policy::copy, "名称")
|
||||
.def_property("to", &SignalBase::getTO, &SignalBase::setTO, "设置或获取交易对象")
|
||||
.def_property("to", &SignalBase::getTO, &SignalBase::setTO, py::return_value_policy::copy,
|
||||
"设置或获取交易对象")
|
||||
|
||||
.def("get_param", &SignalBase::getParam<boost::any>, R"(get_param(self, name)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user