diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Band.h b/hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Band.h index 69bf4cb9..1005ee58 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Band.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Band.h @@ -13,7 +13,24 @@ namespace hku { -SignalPtr HKU_API SG_Band(const Indicator& sig, price_t lower, price_t upper); +/** + * 指标区间指示器, 当指标超过上轨时,买入;当指标低于下轨时,卖出。 + * @note 适用于 RSI 类,有绝对值区间的指标 + * @param ind 指标 + * @param lower 下轨 + * @param upper 上轨 + * @return SignalPtr + */ +SignalPtr HKU_API SG_Band(const Indicator& ind, price_t lower, price_t upper); + +/** + * 指标区间指示器, 当指标超过上轨指标时,买入;当指标低于下轨指标时,卖出。 + * @param ind 指标 + * @param lower 下轨指标 + * @param upper 上轨指标 + * @return SignalPtr + */ +SignalPtr HKU_API SG_Band(const Indicator& ind, const Indicator& lower, const Indicator& upper); } /* namespace hku */ diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp index 8121f695..275a9c3d 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp @@ -16,7 +16,7 @@ namespace hku { BandSignal::BandSignal() : SignalBase("SG_Band") {} BandSignal::BandSignal(const Indicator& ind, price_t lower, price_t upper) -: SignalBase("SG_Band"), m_ind(ind), m_lower(lower), m_upper(upper) { +: SignalBase("SG_Band"), m_ind(ind.clone()), m_lower(lower), m_upper(upper) { HKU_CHECK(lower > upper, "BandSignal: lower track is greater than upper track"); } diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal2.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal2.cpp new file mode 100644 index 00000000..3fda54c4 --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal2.cpp @@ -0,0 +1,63 @@ +/* + * BandSignal2.cpp + * + * Created on: 2023年09月23日 + * Author: yangrq1018 + */ +#include "../../../indicator/crt/KDATA.h" +#include "BandSignal2.h" + +#if HKU_SUPPORT_SERIALIZATION +BOOST_CLASS_EXPORT(hku::BandSignal2) +#endif + +namespace hku { + +BandSignal2::BandSignal2() : SignalBase("SG_Band") {} + +BandSignal2::BandSignal2(const Indicator& ind, const Indicator& lower, const Indicator& upper) +: SignalBase("SG_Band"), m_ind(ind.clone()), m_lower(lower.clone()), m_upper(upper.clone()) {} + +BandSignal2::~BandSignal2() {} + +SignalPtr BandSignal2::_clone() { + BandSignal2* p = new BandSignal2(); + p->m_upper = m_upper.clone(); + p->m_lower = m_lower.clone(); + p->m_ind = m_ind.clone(); + return SignalPtr(p); +} + +void BandSignal2::_calculate(const KData& kdata) { + Indicator ind = m_ind(kdata); + Indicator upper = m_upper(kdata); + Indicator lower = m_lower(kdata); + HKU_ASSERT(ind.size() == upper.size() && ind.size() == lower.size()); + + size_t discard = ind.discard(); + if (discard < upper.discard()) { + discard = upper.discard(); + } + if (discard < lower.discard()) { + discard = lower.discard(); + } + size_t total = ind.size(); + + auto const* inddata = ind.data(); + auto const* upperdata = upper.data(); + auto const* lowerdata = lower.data(); + auto const* ks = kdata.data(); + for (size_t i = discard; i < total; ++i) { + if (inddata[i] > upperdata[i]) { + _addBuySignal(ks[i].datetime); + } else if (inddata[i] < lowerdata[i]) { + _addSellSignal(ks[i].datetime); + } + } +} + +SignalPtr HKU_API SG_Band(const Indicator& sig, const Indicator& lower, const Indicator& upper) { + return SignalPtr(new BandSignal2(sig, lower, upper)); +} + +} // namespace hku \ No newline at end of file diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal2.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal2.h new file mode 100644 index 00000000..944543c8 --- /dev/null +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal2.h @@ -0,0 +1,47 @@ +/* + * BandSignal2.h + * + * Created on: 2023年09月23日 + * Author: yangrq1018 + */ + +#pragma once +#ifndef TRADE_SYS_SIGNAL_IMP_BANDSIGNAL_H_ +#define TRADE_SYS_SIGNAL_IMP_BANDSIGNAL_H_ + +#include "../../../indicator/Indicator.h" +#include "../SignalBase.h" + +namespace hku { + +class BandSignal2 : public SignalBase { +public: + BandSignal2(); + BandSignal2(const Indicator& sig, const Indicator& lower, const Indicator& upper); + virtual ~BandSignal2(); + + virtual SignalPtr _clone() override; + virtual void _calculate(const KData& kdata) override; + +private: + Indicator m_ind; + Indicator m_lower; + Indicator m_upper; + +//============================================ +// 序列化支持 +//============================================ +#if HKU_SUPPORT_SERIALIZATION + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SignalBase); + ar& BOOST_SERIALIZATION_NVP(m_ind); + ar& BOOST_SERIALIZATION_NVP(m_lower); + ar& BOOST_SERIALIZATION_NVP(m_upper); + } +#endif +}; +} // namespace hku + +#endif \ No newline at end of file diff --git a/hikyuu_pywrap/trade_sys/_Signal.cpp b/hikyuu_pywrap/trade_sys/_Signal.cpp index 934af06b..e028f778 100644 --- a/hikyuu_pywrap/trade_sys/_Signal.cpp +++ b/hikyuu_pywrap/trade_sys/_Signal.cpp @@ -204,14 +204,18 @@ void export_Signal(py::module& m) { :param int slow_n: 慢线EMA周期 :return: 信号指示器)"); - m.def("SG_Band", SG_Band, py::arg("ind"), py::arg("lower"), py::arg("upper"), + m.def("SG_Band", + py::overload_cast(SG_Band), + py::arg("ind"), py::arg("lower"), py::arg("upper")); + m.def("SG_Band", py::overload_cast(SG_Band), py::arg("ind"), + py::arg("lower"), py::arg("upper"), R"(SG_Band(ind, lower, upper) 指标区间指示器, 当指标超过上轨时,买入; 当指标低于下轨时,卖出。:: SG_Band(MA(C, n=10), 100, 200) - )"); + SG_Band(CLOSE, MA(LOW), MA(HIGH)))"); m.def("SG_AllwaysBuy", SG_AllwaysBuy, R"(SG_AllwaysBuy()