diff --git a/hikyuu_cpp/hikyuu/indicator/Indicator2InImp.cpp b/hikyuu_cpp/hikyuu/indicator/Indicator2InImp.cpp new file mode 100644 index 000000000..406b8821d --- /dev/null +++ b/hikyuu_cpp/hikyuu/indicator/Indicator2InImp.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 hikyuu.org + * + * Created on: 2025-02-03 + * Author: fasiondog + */ + +#include "hikyuu/indicator/crt/ALIGN.h" +#include "hikyuu/indicator/crt/CVAL.h" +#include "hikyuu/indicator/crt/SLICE.h" +#include "hikyuu/indicator/crt/CONTEXT.h" +#include "Indicator2InImp.h" + +#if HKU_SUPPORT_SERIALIZATION +BOOST_CLASS_EXPORT(hku::Indicator2InImp) +#endif + +namespace hku { + +Indicator2InImp::Indicator2InImp() : IndicatorImp("Indicator2InImp") { + setParam("fill_null", true); +} + +Indicator2InImp::Indicator2InImp(const string& name, size_t result_num) +: IndicatorImp(name, result_num) { + setParam("fill_null", true); +} + +Indicator2InImp::Indicator2InImp(const string& name, const Indicator& ref_ind, bool fill_null, + size_t result_num) +: IndicatorImp(name, result_num), m_ref_ind(ref_ind) { + setParam("fill_null", fill_null); +} + +Indicator2InImp::~Indicator2InImp() {} + +IndicatorImpPtr Indicator2InImp::_clone() { + auto p = make_shared(); + p->m_ref_ind = m_ref_ind.clone(); + return p; +} + +Indicator Indicator2InImp::prepare(const Indicator& ind) { + auto k = getContext(); + m_ref_ind.setContext(k); + + Indicator ref = m_ref_ind; + auto dates = ref.getDatetimeList(); + if (dates.empty()) { + // 如果不是时间序列,则以 ind 为基准,按右端对齐,不足用 nan 填充, 超长则截断左端 + if (ref.size() > ind.size()) { + ref = SLICE(ref, ref.size() - ind.size(), ref.size()); + } else if (ref.size() < ind.size()) { + ref = CVAL(ind, 0.) + ref; + } + } else if (k != ind.getContext()) { + // 如果是时间序列,当两者的上下文不同,则按日期对齐 + ref = ALIGN(m_ref_ind, ind, getParam("fill_null")); + } + + return ref; +} + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/Indicator2InImp.h b/hikyuu_cpp/hikyuu/indicator/Indicator2InImp.h new file mode 100644 index 000000000..014765547 --- /dev/null +++ b/hikyuu_cpp/hikyuu/indicator/Indicator2InImp.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 hikyuu.org + * + * Created on: 2025-02-03 + * Author: fasiondog + */ + +#pragma once + +#include "Indicator.h" + +namespace hku { + +class Indicator2InImp : public IndicatorImp { +public: + Indicator2InImp(); + explicit Indicator2InImp(const string& name, size_t result_num = 1); + Indicator2InImp(const string& name, const Indicator& ref_a, bool fill_null = false, + size_t result_num = 1); + virtual ~Indicator2InImp(); + + virtual IndicatorImpPtr _clone() override; + +protected: + Indicator prepare(const Indicator& ind); + +protected: + Indicator m_ref_ind; + +//============================================ +// 序列化支持 +//============================================ +#if HKU_SUPPORT_SERIALIZATION +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(IndicatorImp); + ar& BOOST_SERIALIZATION_NVP(m_ref_ind); + } +#endif +}; + +#if HKU_SUPPORT_SERIALIZATION +#define INDICATOR2IN_IMP_NO_PRIVATE_MEMBER_SERIALIZATION \ +private: \ + friend class boost::serialization::access; \ + template \ + void serialize(Archive& ar, const unsigned int version) { \ + ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Indicator2InImp); \ + } +#else +#define INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION +#endif + +#define INDICATOR2IN_IMP(classname) \ +public: \ + virtual void _calculate(const Indicator& data) override; \ + virtual IndicatorImpPtr _clone() override { \ + auto p = make_shared(); \ + p->m_ref_ind = m_ref_ind.clone(); \ + return p; \ + } + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/imp/ICorr.cpp b/hikyuu_cpp/hikyuu/indicator/imp/ICorr.cpp index 1b15a6f3f..c27c204c3 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/ICorr.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/ICorr.cpp @@ -5,9 +5,6 @@ * Author: fasiondog */ -#include "hikyuu/indicator/crt/ALIGN.h" -#include "hikyuu/indicator/crt/CVAL.h" -#include "hikyuu/indicator/crt/SLICE.h" #include "ICorr.h" #if HKU_SUPPORT_SERIALIZATION @@ -16,15 +13,13 @@ BOOST_CLASS_EXPORT(hku::ICorr) namespace hku { -ICorr::ICorr() : IndicatorImp("CORR") { +ICorr::ICorr() : Indicator2InImp("CORR") { setParam("n", 10); - setParam("fill_null", true); } ICorr::ICorr(const Indicator& ref_ind, int n, bool fill_null) -: IndicatorImp("CORR"), m_ref_ind(ref_ind) { +: Indicator2InImp("CORR", ref_ind, fill_null, 2) { setParam("n", n); - setParam("fill_null", fill_null); } ICorr::~ICorr() {} @@ -36,31 +31,11 @@ void ICorr::_checkParam(const string& name) const { } } -IndicatorImpPtr ICorr::_clone() { - auto p = make_shared(); - p->m_ref_ind = m_ref_ind.clone(); - return p; -} - void ICorr::_calculate(const Indicator& ind) { size_t total = ind.size(); HKU_IF_RETURN(total == 0, void()); - _readyBuffer(total, 2); - - auto k = getContext(); - m_ref_ind.setContext(k); - Indicator ref = m_ref_ind; - auto dates = ref.getDatetimeList(); - if (dates.empty()) { - if (ref.size() > ind.size()) { - ref = SLICE(ref, ref.size() - ind.size(), ref.size()); - } else if (ref.size() < ind.size()) { - ref = CVAL(ind, 0.) + ref; - } - } else if (k != ind.getContext()) { - ref = ALIGN(m_ref_ind, ind, getParam("fill_null")); - } + Indicator ref = prepare(ind); int n = getParam("n"); if (n == 0) { diff --git a/hikyuu_cpp/hikyuu/indicator/imp/ICorr.h b/hikyuu_cpp/hikyuu/indicator/imp/ICorr.h index 52a4e68d4..508505471 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/ICorr.h +++ b/hikyuu_cpp/hikyuu/indicator/imp/ICorr.h @@ -7,35 +7,20 @@ #pragma once -#include "../Indicator.h" +#include "../Indicator2InImp.h" namespace hku { -class ICorr : public IndicatorImp { +class ICorr : public Indicator2InImp { + INDICATOR2IN_IMP(ICorr) + INDICATOR2IN_IMP_NO_PRIVATE_MEMBER_SERIALIZATION + public: ICorr(); ICorr(const Indicator& ref_ind, int n, bool fill_null); virtual ~ICorr(); virtual void _checkParam(const string& name) const override; - virtual void _calculate(const Indicator& data) override; - virtual IndicatorImpPtr _clone() override; - -private: - Indicator m_ref_ind; - -//============================================ -// 序列化支持 -//============================================ -#if HKU_SUPPORT_SERIALIZATION -private: - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) { - ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(IndicatorImp); - ar& BOOST_SERIALIZATION_NVP(m_ref_ind); - } -#endif }; -} \ No newline at end of file +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IDma.cpp b/hikyuu_cpp/hikyuu/indicator/imp/IDma.cpp index 3cd41d7d8..9d40a0a91 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IDma.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/IDma.cpp @@ -5,10 +5,6 @@ * Author: fasiondog */ -#include "hikyuu/indicator/crt/ALIGN.h" -#include "hikyuu/indicator/crt/CVAL.h" -#include "hikyuu/indicator/crt/SLICE.h" -#include "hikyuu/indicator/crt/CONTEXT.h" #include "IDma.h" #if HKU_SUPPORT_SERIALIZATION @@ -17,45 +13,18 @@ BOOST_CLASS_EXPORT(hku::IDma) namespace hku { -IDma::IDma() : IndicatorImp("DMA") { - setParam("fill_null", true); -} +IDma::IDma() : Indicator2InImp("DMA") {} -IDma::IDma(const Indicator& ref_ind, bool fill_null) : IndicatorImp("DMA"), m_ref_ind(ref_ind) { - setParam("fill_null", fill_null); -} +IDma::IDma(const Indicator& ref_ind, bool fill_null) +: Indicator2InImp("DMA", ref_ind, fill_null, 1) {} IDma::~IDma() {} -void IDma::_checkParam(const string& name) const {} - -IndicatorImpPtr IDma::_clone() { - auto p = make_shared(); - p->m_ref_ind = m_ref_ind.clone(); - return p; -} - void IDma::_calculate(const Indicator& ind) { size_t total = ind.size(); HKU_IF_RETURN(total == 0, void()); - _readyBuffer(total, 1); - - auto k = getContext(); - m_ref_ind.setContext(k); - Indicator ref = m_ref_ind; - auto dates = ref.getDatetimeList(); - if (dates.empty()) { - // 如果不是时间序列,则以 ind 为基准,按右端对齐,不足用 nan 填充, 超长则截断左端 - if (ref.size() > ind.size()) { - ref = SLICE(ref, ref.size() - ind.size(), ref.size()); - } else if (ref.size() < ind.size()) { - ref = CVAL(ind, 0.) + ref; - } - } else if (k != ind.getContext()) { - // 如果是时间序列,当两者的上下文不同,则按日期对齐 - ref = ALIGN(m_ref_ind, ind, getParam("fill_null")); - } + Indicator ref = prepare(ind); m_discard = std::max(ind.discard(), ref.discard()); auto* y = this->data(); diff --git a/hikyuu_cpp/hikyuu/indicator/imp/IDma.h b/hikyuu_cpp/hikyuu/indicator/imp/IDma.h index 0024d596e..5a7d919bd 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/IDma.h +++ b/hikyuu_cpp/hikyuu/indicator/imp/IDma.h @@ -7,7 +7,7 @@ #pragma once -#include "../Indicator.h" +#include "../Indicator2InImp.h" namespace hku { @@ -17,31 +17,14 @@ namespace hku { * 算法:若Y=DMA(X,A) 则 Y=A*X+(1-A)*Y',其中Y'表示上一周期Y值。 * 例如:DMA(CLOSE,VOL/CAPITAL)表示求以换手率作平滑因子的平均价 */ -class IDma : public IndicatorImp { +class IDma : public Indicator2InImp { + INDICATOR2IN_IMP(IDma) + INDICATOR2IN_IMP_NO_PRIVATE_MEMBER_SERIALIZATION + public: IDma(); explicit IDma(const Indicator& ref_a, bool fill_null); virtual ~IDma(); - - virtual void _checkParam(const string& name) const override; - virtual void _calculate(const Indicator& data) override; - virtual IndicatorImpPtr _clone() override; - -private: - Indicator m_ref_ind; - -//============================================ -// 序列化支持 -//============================================ -#if HKU_SUPPORT_SERIALIZATION -private: - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) { - ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(IndicatorImp); - ar& BOOST_SERIALIZATION_NVP(m_ref_ind); - } -#endif }; -} \ No newline at end of file +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.cpp b/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.cpp index 105fba14b..578fb8a11 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.cpp +++ b/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.cpp @@ -5,9 +5,6 @@ * Author: fasiondog */ -#include "hikyuu/indicator/crt/ALIGN.h" -#include "hikyuu/indicator/crt/CVAL.h" -#include "hikyuu/indicator/crt/SLICE.h" #include "ISpearman.h" #if HKU_SUPPORT_SERIALIZATION @@ -16,15 +13,13 @@ BOOST_CLASS_EXPORT(hku::ISpearman) namespace hku { -ISpearman::ISpearman() : IndicatorImp("SPEARMAN") { +ISpearman::ISpearman() : Indicator2InImp("SPEARMAN") { setParam("n", 0); - setParam("fill_null", true); } ISpearman::ISpearman(const Indicator &ref_ind, int n, bool fill_null) -: IndicatorImp("SPEARMAN"), m_ref_ind(ref_ind) { +: Indicator2InImp("SPEARMAN", ref_ind, fill_null, 1) { setParam("n", n); - setParam("fill_null", fill_null); } ISpearman::~ISpearman() {} @@ -36,12 +31,6 @@ void ISpearman::_checkParam(const string &name) const { } } -IndicatorImpPtr ISpearman::_clone() { - auto p = make_shared(); - p->m_ref_ind = m_ref_ind.clone(); - return p; -} - static void spearmanLevel(const IndicatorImp::value_t *data, IndicatorImp::value_t *level, size_t total) { std::vector> data_index(total); @@ -80,21 +69,7 @@ void ISpearman::_calculate(const Indicator &ind) { size_t total = ind.size(); HKU_IF_RETURN(total == 0, void()); - _readyBuffer(total, 2); - - auto k = getContext(); - m_ref_ind.setContext(k); - Indicator ref = m_ref_ind; - auto dates = ref.getDatetimeList(); - if (dates.empty()) { - if (ref.size() > ind.size()) { - ref = SLICE(ref, ref.size() - ind.size(), ref.size()); - } else if (ref.size() < ind.size()) { - ref = CVAL(ind, 0.) + ref; - } - } else if (k != ind.getContext()) { - ref = ALIGN(m_ref_ind, ind, getParam("fill_null")); - } + Indicator ref = prepare(ind); int n = getParam("n"); if (n == 0) { diff --git a/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.h b/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.h index 613e24486..b969a6c78 100644 --- a/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.h +++ b/hikyuu_cpp/hikyuu/indicator/imp/ISpearman.h @@ -7,35 +7,20 @@ #pragma once -#include "../Indicator.h" +#include "../Indicator2InImp.h" namespace hku { -class ISpearman : public IndicatorImp { +class ISpearman : public Indicator2InImp { + INDICATOR2IN_IMP(ISpearman) + INDICATOR2IN_IMP_NO_PRIVATE_MEMBER_SERIALIZATION + public: ISpearman(); ISpearman(const Indicator& ref_ind, int n, bool fill_null); virtual ~ISpearman(); virtual void _checkParam(const string& name) const override; - virtual void _calculate(const Indicator& data) override; - virtual IndicatorImpPtr _clone() override; - -private: - Indicator m_ref_ind; - -//============================================ -// 序列化支持 -//============================================ -#if HKU_SUPPORT_SERIALIZATION -private: - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) { - ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(IndicatorImp); - ar& BOOST_SERIALIZATION_NVP(m_ref_ind); - } -#endif }; } // namespace hku \ No newline at end of file