Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

优化双指标输入指标实现 #323

Merged
merged 5 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
8 changes: 7 additions & 1 deletion hikyuu_cpp/hikyuu/indicator/crt/WINNER.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
namespace hku {

/**
* 求绝对值
* 获利盘比例
* @details
* <pre>
* 用法: WINNER(CLOSE) 表示以当前收市价卖出的获利盘比例。
* 例如: 返回0.1表示10%获利盘;WINNER(10.5)表示10.5元价格的获利盘比例
* 该函数仅对日线分析周期有效。
* </pre>
* @ingroup Indicator
*/
Indicator HKU_API WINNER();
Expand Down
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 (m_ref_ind.size() != ind.size()) {
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
36 changes: 4 additions & 32 deletions hikyuu_cpp/hikyuu/indicator/imp/IDma.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 "IDma.h"

#if HKU_SUPPORT_SERIALIZATION
Expand All @@ -16,43 +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()) {
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 (m_ref_ind.size() != ind.size()) {
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