Skip to content

Commit

Permalink
优化双指标输入指标实现
Browse files Browse the repository at this point in the history
  • Loading branch information
fasiondog committed Feb 2, 2025
1 parent 90ae0d2 commit 9b23820
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 155 deletions.
64 changes: 64 additions & 0 deletions hikyuu_cpp/hikyuu/indicator/Indicator2InImp.cpp
Original file line number Diff line number Diff line change
@@ -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<bool>("fill_null", true);
}

Indicator2InImp::Indicator2InImp(const string& name, size_t result_num)
: IndicatorImp(name, result_num) {
setParam<bool>("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<bool>("fill_null", fill_null);
}

Indicator2InImp::~Indicator2InImp() {}

IndicatorImpPtr Indicator2InImp::_clone() {
auto p = make_shared<Indicator2InImp>();
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<bool>("fill_null"));
}

return ref;
}

} // namespace hku
65 changes: 65 additions & 0 deletions hikyuu_cpp/hikyuu/indicator/Indicator2InImp.h
Original file line number Diff line number Diff line change
@@ -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 <class Archive>
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 <class Archive> \
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<classname>(); \
p->m_ref_ind = m_ref_ind.clone(); \
return p; \
}

} // namespace hku
31 changes: 3 additions & 28 deletions hikyuu_cpp/hikyuu/indicator/imp/ICorr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -16,15 +13,13 @@ BOOST_CLASS_EXPORT(hku::ICorr)

namespace hku {

ICorr::ICorr() : IndicatorImp("CORR") {
ICorr::ICorr() : Indicator2InImp("CORR") {
setParam<int>("n", 10);
setParam<bool>("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<int>("n", n);
setParam<bool>("fill_null", fill_null);
}

ICorr::~ICorr() {}
Expand All @@ -36,31 +31,11 @@ void ICorr::_checkParam(const string& name) const {
}
}

IndicatorImpPtr ICorr::_clone() {
auto p = make_shared<ICorr>();
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<bool>("fill_null"));
}
Indicator ref = prepare(ind);

int n = getParam<int>("n");
if (n == 0) {
Expand Down
27 changes: 6 additions & 21 deletions hikyuu_cpp/hikyuu/indicator/imp/ICorr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class Archive>
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
39 changes: 4 additions & 35 deletions hikyuu_cpp/hikyuu/indicator/imp/IDma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,45 +13,18 @@ BOOST_CLASS_EXPORT(hku::IDma)

namespace hku {

IDma::IDma() : IndicatorImp("DMA") {
setParam<bool>("fill_null", true);
}
IDma::IDma() : Indicator2InImp("DMA") {}

IDma::IDma(const Indicator& ref_ind, bool fill_null) : IndicatorImp("DMA"), m_ref_ind(ref_ind) {
setParam<bool>("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<IDma>();
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<bool>("fill_null"));
}
Indicator ref = prepare(ind);

m_discard = std::max(ind.discard(), ref.discard());
auto* y = this->data();
Expand Down
29 changes: 6 additions & 23 deletions hikyuu_cpp/hikyuu/indicator/imp/IDma.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#pragma once

#include "../Indicator.h"
#include "../Indicator2InImp.h"

namespace hku {

Expand All @@ -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 <class Archive>
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
Loading

0 comments on commit 9b23820

Please sign in to comment.