From 966c8e66575a17f999c19faacaa0db7fab798e53 Mon Sep 17 00:00:00 2001 From: fasiondog Date: Tue, 2 Apr 2024 13:33:24 +0800 Subject: [PATCH] update SG for support cycle --- docs/examples/quick_crtsg.py | 13 ++++---- hikyuu/examples/Turtle_SG.py | 13 ++++---- hikyuu/examples/quick_crtsg.py | 12 ++++---- hikyuu/test/Signal.py | 4 +-- .../hikyuu/trade_sys/signal/SignalBase.cpp | 30 +++++++++++++++---- .../hikyuu/trade_sys/signal/SignalBase.h | 4 +-- .../trade_sys/signal/imp/AllwaysBuySignal.cpp | 3 +- .../trade_sys/signal/imp/BandSignal.cpp | 6 ++-- .../hikyuu/trade_sys/signal/imp/BandSignal.h | 2 +- .../trade_sys/signal/imp/BoolSignal.cpp | 8 ++--- .../hikyuu/trade_sys/signal/imp/BoolSignal.h | 2 +- .../trade_sys/signal/imp/CrossGoldSignal.cpp | 8 ++--- .../trade_sys/signal/imp/CrossGoldSignal.h | 2 +- .../trade_sys/signal/imp/CrossSignal.cpp | 8 ++--- .../hikyuu/trade_sys/signal/imp/CrossSignal.h | 2 +- .../trade_sys/signal/imp/CycleSignal.cpp | 2 +- .../trade_sys/signal/imp/SingleSignal.cpp | 6 ++-- .../trade_sys/signal/imp/SingleSignal.h | 2 +- .../trade_sys/signal/imp/SingleSignal2.cpp | 6 ++-- .../trade_sys/signal/imp/SingleSignal2.h | 2 +- .../hikyuu/trade_sys/signal/test_Signal.cpp | 2 +- hikyuu_pywrap/trade_sys/_Signal.cpp | 4 +-- 22 files changed, 78 insertions(+), 63 deletions(-) diff --git a/docs/examples/quick_crtsg.py b/docs/examples/quick_crtsg.py index 7bc645bc..1879ff43 100644 --- a/docs/examples/quick_crtsg.py +++ b/docs/examples/quick_crtsg.py @@ -2,20 +2,19 @@ # -*- coding: utf8 -*- # cp936 -#=============================================================================== +# =============================================================================== # Aothor: fasiondog # History: 20160407, Added by fasiondog -#=============================================================================== +# =============================================================================== from hikyuu import * -def TurtleSG(self): +def TurtleSG(self, k): n = self.get_param("n") - k = self.to c = CLOSE(k) - h = REF(HHV(c, n), 1) #前n日高点 - L = REF(LLV(c, n), 1) #前n日低点 + h = REF(HHV(c, n), 1) # 前n日高点 + L = REF(LLV(c, n), 1) # 前n日低点 for i in range(h.discard, len(k)): if (c[i] >= h[i]): self._add_buy_signal(k[i].datetime) @@ -30,7 +29,7 @@ if __name__ == "__main__": s = get_stock("sh000001") k = s.get_kdata(Query(-500)) - #只有设置交易对象时,才会开始实际计算 + # 只有设置交易对象时,才会开始实际计算 sg.to = k dates = k.get_datetime_list() for d in dates: diff --git a/hikyuu/examples/Turtle_SG.py b/hikyuu/examples/Turtle_SG.py index ce0c9b08..cbf82384 100644 --- a/hikyuu/examples/Turtle_SG.py +++ b/hikyuu/examples/Turtle_SG.py @@ -2,10 +2,10 @@ # -*- coding: utf8 -*- # cp936 -#=============================================================================== +# =============================================================================== # Aothor: fasiondog # History: 20160407, Added by fasiondog -#=============================================================================== +# =============================================================================== from hikyuu import * @@ -18,12 +18,11 @@ class TurtleSignal(SignalBase): def _clone(self): return TurtleSignal() - def _calculate(self): + def _calculate(self, k): n = self.get_param("n") - k = self.to c = CLOSE(k) - h = REF(HHV(c, n), 1) #前n日高点 - L = REF(LLV(c, n), 1) #前n日低点 + h = REF(HHV(c, n), 1) # 前n日高点 + L = REF(LLV(c, n), 1) # 前n日低点 for i in range(h.discard, len(k)): if (c[i] >= h[i]): self._add_buy_signal(k[i].datetime) @@ -38,7 +37,7 @@ if __name__ == "__main__": s = get_stock("sh000001") k = s.get_kdata(Query(-500)) - #只有设置交易对象时,才会开始实际计算 + # 只有设置交易对象时,才会开始实际计算 sg.to = k dates = k.get_datetime_list() for d in dates: diff --git a/hikyuu/examples/quick_crtsg.py b/hikyuu/examples/quick_crtsg.py index 7bc645bc..0b819080 100644 --- a/hikyuu/examples/quick_crtsg.py +++ b/hikyuu/examples/quick_crtsg.py @@ -2,20 +2,20 @@ # -*- coding: utf8 -*- # cp936 -#=============================================================================== +# =============================================================================== # Aothor: fasiondog # History: 20160407, Added by fasiondog -#=============================================================================== +# =============================================================================== from hikyuu import * -def TurtleSG(self): +def TurtleSG(self, k): n = self.get_param("n") k = self.to c = CLOSE(k) - h = REF(HHV(c, n), 1) #前n日高点 - L = REF(LLV(c, n), 1) #前n日低点 + h = REF(HHV(c, n), 1) # 前n日高点 + L = REF(LLV(c, n), 1) # 前n日低点 for i in range(h.discard, len(k)): if (c[i] >= h[i]): self._add_buy_signal(k[i].datetime) @@ -30,7 +30,7 @@ if __name__ == "__main__": s = get_stock("sh000001") k = s.get_kdata(Query(-500)) - #只有设置交易对象时,才会开始实际计算 + # 只有设置交易对象时,才会开始实际计算 sg.to = k dates = k.get_datetime_list() for d in dates: diff --git a/hikyuu/test/Signal.py b/hikyuu/test/Signal.py index 1d1e8d4d..56f213ce 100644 --- a/hikyuu/test/Signal.py +++ b/hikyuu/test/Signal.py @@ -26,7 +26,7 @@ class SignalPython(SignalBase): p._x = self._x return p - def _calculate(self): + def _calculate(self, kdata): self._add_buy_signal(Datetime(201201210000)) self._add_sell_signal(Datetime(201201300000)) @@ -91,7 +91,7 @@ class SignalTest(unittest.TestCase): self.assertEqual(p_clone.get_param("test"), 30) -def testSignal(self): +def testSignal(self, kdata): self._add_buy_signal(Datetime(201201210000)) self._add_sell_signal(Datetime(201201300000)) diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.cpp index 1b7ca65e..b4d68fd9 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.cpp @@ -72,11 +72,28 @@ SignalPtr SignalBase::clone() { void SignalBase::setTO(const KData& kdata) { HKU_IF_RETURN(m_kdata == kdata, void()); m_kdata = kdata; + HKU_IF_RETURN(kdata.empty(), void()); + bool cycle = getParam("cycle"); - m_cycle_start = Datetime::min(); - m_cycle_end = cycle ? Datetime::min() : Datetime::max(); - if (!cycle && !kdata.empty()) { - _calculate(); + m_cycle_start = kdata[0].datetime; + + const KQuery& query = kdata.getQuery(); + if (query.queryType() == KQuery::DATE) { + m_cycle_end = query.endDatetime(); + } else { + size_t last_pos = kdata.lastPos(); + const Stock& stk = kdata.getStock(); + if (last_pos + 1 >= stk.getCount(query.kType())) { + m_cycle_end = Null(); + } else { + KRecord krecord = stk.getKRecord(last_pos + 1, query.kType()); + m_cycle_end = krecord.datetime; + } + } + + KData cycle_kdata = kdata.getKData(m_cycle_start, m_cycle_end); + if (!cycle) { + _calculate(cycle_kdata); } } @@ -95,8 +112,9 @@ void SignalBase::startCycle(const Datetime& start, const Datetime& close) { HKU_CHECK(start >= m_cycle_end, "curretn start: {}, pre cycle end: {}", start, m_cycle_end); m_cycle_start = start; m_cycle_end = close; - if (!m_kdata.empty()) { - _calculate(); + KData kdata = m_kdata.getKData(start, close); + if (!kdata.empty()) { + _calculate(kdata); } } diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.h b/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.h index bf0dbf1d..7b15a51f 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.h @@ -108,7 +108,7 @@ public: virtual SignalPtr _clone() = 0; /** 子类计算接口,在setTO中调用 */ - virtual void _calculate() = 0; + virtual void _calculate(const KData&) = 0; private: void initParam(); @@ -196,7 +196,7 @@ public: \ virtual SignalPtr _clone() override { \ return SignalPtr(new classname()); \ } \ - virtual void _calculate() override; + virtual void _calculate(const KData&) override; /** * 客户程序都应使用该指针类型,操作信号指示器 diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.cpp index e0e6cc29..8a4bb311 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/AllwaysBuySignal.cpp @@ -24,8 +24,7 @@ void AllwaysBuySignal::_checkParam(const string& name) const { } } -void AllwaysBuySignal::_calculate() { - const auto& kdata = getTO(); +void AllwaysBuySignal::_calculate(const KData& kdata) { for (auto iter = kdata.cbegin(); iter != kdata.cend(); ++iter) { _addBuySignal(iter->datetime); } diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp index 2131acc5..8121f695 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.cpp @@ -30,13 +30,13 @@ SignalPtr BandSignal::_clone() { return SignalPtr(p); } -void BandSignal::_calculate() { - Indicator ind = m_ind(m_kdata); +void BandSignal::_calculate(const KData& kdata) { + Indicator ind = m_ind(kdata); size_t discard = ind.discard(); size_t total = ind.size(); auto const* inddata = ind.data(); - auto const* ks = m_kdata.data(); + auto const* ks = kdata.data(); for (size_t i = discard; i < total; ++i) { if (inddata[i] > m_upper) { _addBuySignal(ks[i].datetime); diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.h index f0b86213..cb9fa0c6 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BandSignal.h @@ -21,7 +21,7 @@ public: virtual ~BandSignal(); virtual SignalPtr _clone() override; - virtual void _calculate() override; + virtual void _calculate(const KData& kdata) override; private: Indicator m_ind; diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.cpp index e923b65e..0aae59c1 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.cpp @@ -28,16 +28,16 @@ SignalPtr BoolSignal::_clone() { return SignalPtr(p); } -void BoolSignal::_calculate() { - Indicator buy = m_bool_buy(m_kdata); - Indicator sell = m_bool_sell(m_kdata); +void BoolSignal::_calculate(const KData& kdata) { + Indicator buy = m_bool_buy(kdata); + Indicator sell = m_bool_sell(kdata); HKU_ERROR_IF_RETURN(buy.size() != sell.size(), void(), "buy.size() != sell.size()"); size_t discard = buy.discard() > sell.discard() ? buy.discard() : sell.discard(); size_t total = buy.size(); auto const* buydata = buy.data(); auto const* selldata = sell.data(); - auto const* ks = m_kdata.data(); + auto const* ks = kdata.data(); for (size_t i = discard; i < total; ++i) { if (buydata[i] > 0.0) _addBuySignal(ks[i].datetime); diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.h index 183b6ea4..31681a9a 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.h @@ -21,7 +21,7 @@ public: virtual ~BoolSignal(); virtual SignalPtr _clone() override; - virtual void _calculate() override; + virtual void _calculate(const KData& kdata) override; private: Indicator m_bool_buy; diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.cpp index 8198f3b0..41a3f264 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.cpp @@ -28,16 +28,16 @@ SignalPtr CrossGoldSignal::_clone() { return SignalPtr(p); } -void CrossGoldSignal::_calculate() { - Indicator fast = m_fast(m_kdata); - Indicator slow = m_slow(m_kdata); +void CrossGoldSignal::_calculate(const KData& kdata) { + Indicator fast = m_fast(kdata); + Indicator slow = m_slow(kdata); HKU_ERROR_IF_RETURN(fast.size() != slow.size(), void(), "fast.size() != slow.size()"); size_t discard = fast.discard() > slow.discard() ? fast.discard() : slow.discard(); size_t total = fast.size(); auto const* fastdata = fast.data(); auto const* slowdata = slow.data(); - auto const* ks = m_kdata.data(); + auto const* ks = kdata.data(); for (size_t i = discard + 1; i < total; ++i) { if (fastdata[i - 1] < slowdata[i - 1] && fastdata[i] > slowdata[i] && fastdata[i - 1] < fastdata[i] && slowdata[i - 1] < slowdata[i]) { diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.h index 90ae6eec..609ddb9b 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossGoldSignal.h @@ -21,7 +21,7 @@ public: virtual ~CrossGoldSignal(); virtual SignalPtr _clone() override; - virtual void _calculate() override; + virtual void _calculate(const KData& kdata) override; private: Indicator m_fast; diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.cpp index 73cd0948..d1b2ee20 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.cpp @@ -28,16 +28,16 @@ SignalPtr CrossSignal::_clone() { return SignalPtr(p); } -void CrossSignal::_calculate() { - Indicator fast = m_fast(m_kdata); - Indicator slow = m_slow(m_kdata); +void CrossSignal::_calculate(const KData& kdata) { + Indicator fast = m_fast(kdata); + Indicator slow = m_slow(kdata); HKU_ERROR_IF_RETURN(fast.size() != slow.size(), void(), "fast.size() != slow.size()"); size_t discard = fast.discard() > slow.discard() ? fast.discard() : slow.discard(); size_t total = fast.size(); auto const* fastdata = fast.data(); auto const* slowdata = slow.data(); - auto const* ks = m_kdata.data(); + auto const* ks = kdata.data(); for (size_t i = discard + 1; i < total; ++i) { if (fastdata[i - 1] < slowdata[i - 1] && fastdata[i] > slowdata[i]) { _addBuySignal(ks[i].datetime); diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.h index 3408d71a..5becffbb 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CrossSignal.h @@ -21,7 +21,7 @@ public: virtual ~CrossSignal(); virtual SignalPtr _clone() override; - virtual void _calculate() override; + virtual void _calculate(const KData& kdata) override; private: Indicator m_fast; diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.cpp index ed7f8a43..3ac99aaa 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/CycleSignal.cpp @@ -24,7 +24,7 @@ void CycleSignal::_checkParam(const string& name) const { } } -void CycleSignal::_calculate() { +void CycleSignal::_calculate(const KData& kdata) { _addBuySignal(getCycleStart()); } diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.cpp index 5561318b..e03772ad 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.cpp @@ -43,11 +43,11 @@ SignalPtr SingleSignal::_clone() { return SignalPtr(p); } -void SingleSignal::_calculate() { +void SingleSignal::_calculate(const KData& kdata) { int filter_n = getParam("filter_n"); double filter_p = getParam("filter_p"); - Indicator ind = m_ind(m_kdata); + Indicator ind = m_ind(kdata); Indicator dev = STDEV(DIFF(ind), filter_n); size_t start = dev.discard(); @@ -55,7 +55,7 @@ void SingleSignal::_calculate() { auto const* inddata = ind.data(); auto const* devdata = dev.data(); - auto const* ks = m_kdata.data(); + auto const* ks = kdata.data(); size_t total = dev.size(); for (size_t i = start; i < total; ++i) { double dama = inddata[i] - inddata[i - 1]; diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.h index 3de41838..66edfe5f 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal.h @@ -22,7 +22,7 @@ public: virtual void _checkParam(const string& name) const override; virtual SignalPtr _clone() override; - virtual void _calculate() override; + virtual void _calculate(const KData& kdata) override; private: Indicator m_ind; diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.cpp b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.cpp index 053c9aba..8629833f 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.cpp +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.cpp @@ -46,11 +46,11 @@ SignalPtr SingleSignal2::_clone() { return SignalPtr(p); } -void SingleSignal2::_calculate() { +void SingleSignal2::_calculate(const KData& kdata) { int filter_n = getParam("filter_n"); double filter_p = getParam("filter_p"); - Indicator ind = m_ind(m_kdata); + Indicator ind = m_ind(kdata); Indicator dev = REF(STDEV(DIFF(ind), filter_n), 1); size_t start = dev.discard(); @@ -62,7 +62,7 @@ void SingleSignal2::_calculate() { auto const* buydata = buy.data(); auto const* selldata = sell.data(); auto const* devdata = dev.data(); - auto const* ks = m_kdata.data(); + auto const* ks = kdata.data(); for (size_t i = start; i < total; ++i) { double filter = filter_p * devdata[i]; if (buydata[i] > filter) { diff --git a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.h b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.h index 22bd590f..92747700 100644 --- a/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.h +++ b/hikyuu_cpp/hikyuu/trade_sys/signal/imp/SingleSignal2.h @@ -22,7 +22,7 @@ public: virtual void _checkParam(const string& name) const override; virtual SignalPtr _clone() override; - virtual void _calculate() override; + virtual void _calculate(const KData& kdata) override; private: Indicator m_ind; diff --git a/hikyuu_cpp/unit_test/hikyuu/trade_sys/signal/test_Signal.cpp b/hikyuu_cpp/unit_test/hikyuu/trade_sys/signal/test_Signal.cpp index b87b44b3..12360cde 100644 --- a/hikyuu_cpp/unit_test/hikyuu/trade_sys/signal/test_Signal.cpp +++ b/hikyuu_cpp/unit_test/hikyuu/trade_sys/signal/test_Signal.cpp @@ -33,7 +33,7 @@ public: return SignalPtr(p); } - virtual void _calculate() {} + virtual void _calculate(const KData &) override {} private: int m_x; diff --git a/hikyuu_pywrap/trade_sys/_Signal.cpp b/hikyuu_pywrap/trade_sys/_Signal.cpp index ba255c97..76cfda63 100644 --- a/hikyuu_pywrap/trade_sys/_Signal.cpp +++ b/hikyuu_pywrap/trade_sys/_Signal.cpp @@ -18,8 +18,8 @@ public: using SignalBase::SignalBase; PySignalBase(const SignalBase& base) : SignalBase(base) {} - void _calculate() override { - PYBIND11_OVERLOAD_PURE(void, SignalBase, _calculate, ); + void _calculate(const KData& kdata) override { + PYBIND11_OVERLOAD_PURE(void, SignalBase, _calculate, kdata); } void _reset() override {