-
Notifications
You must be signed in to change notification settings - Fork 611
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #329 from fasiondog/feature/one_side_sg
add SG_OneSide
- Loading branch information
Showing
10 changed files
with
273 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) 2025 hikyuu.org | ||
* | ||
* Created on: 2025-02-13 | ||
* Author: fasiondog | ||
*/ | ||
|
||
#pragma once | ||
#ifndef TRADE_SYS_SIGNAL_CRT_SG_ONESIDE_H_ | ||
#define TRADE_SYS_SIGNAL_CRT_SG_ONESIDE_H_ | ||
|
||
#include "../../../indicator/Indicator.h" | ||
#include "../SignalBase.h" | ||
|
||
namespace hku { | ||
|
||
/** | ||
* 根据输入指标构建单边信号(单纯的只包含买入或卖出信号),如果指标值大于0,则加入信号 | ||
* @param ind 指示指标 | ||
* @param is_buy 加入的是买入信号还是卖出信号 | ||
* @return 信号指示器 | ||
* @ingroup Signal | ||
*/ | ||
SignalPtr HKU_API SG_OneSide(const Indicator& ind, bool is_buy); | ||
|
||
} /* namespace hku */ | ||
|
||
#endif /* TRADE_SYS_SIGNAL_CRT_SG_ONESIDE_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (c) 2025 hikyuu.org | ||
* | ||
* Created on: 2025-02-13 | ||
* Author: fasiondog | ||
*/ | ||
|
||
#include "hikyuu/indicator/crt/ALIGN.h" | ||
#include "hikyuu/indicator/crt/KDATA.h" | ||
#include "OneSideSignal.h" | ||
|
||
#if HKU_SUPPORT_SERIALIZATION | ||
BOOST_CLASS_EXPORT(hku::OneSideSignal) | ||
#endif | ||
|
||
namespace hku { | ||
|
||
OneSideSignal::OneSideSignal() : SignalBase("SG_OneSide") { | ||
setParam<bool>("alternate", false); | ||
setParam<bool>("is_buy", true); // 买入信号,否则为添加卖出信号 | ||
} | ||
|
||
OneSideSignal::OneSideSignal(const Indicator& ind, bool is_buy) | ||
: SignalBase("SG_OneSide"), m_ind(ind.clone()) { | ||
setParam<bool>("alternate", false); | ||
setParam<bool>("is_buy", is_buy); | ||
} | ||
|
||
OneSideSignal::~OneSideSignal() {} | ||
|
||
void OneSideSignal::_checkParam(const string& name) const { | ||
if (name == "alternate") { | ||
HKU_CHECK(!getParam<bool>(name), "alternate only be false!"); | ||
} | ||
} | ||
|
||
SignalPtr OneSideSignal::_clone() { | ||
auto p = make_shared<OneSideSignal>(); | ||
p->m_ind = m_ind.clone(); | ||
return p; | ||
} | ||
|
||
void OneSideSignal::_calculate(const KData& kdata) { | ||
Indicator ind = m_ind(kdata); | ||
HKU_IF_RETURN(ind.empty() || ind.size() != kdata.size(), void()); | ||
|
||
bool is_buy = getParam<bool>("is_buy"); | ||
const auto* src = ind.data(); | ||
auto const* ks = kdata.data(); | ||
size_t discard = ind.discard(); | ||
size_t total = ind.size(); | ||
|
||
for (size_t i = discard; i < total; ++i) { | ||
if (src[i] > 0.0) { | ||
if (is_buy) { | ||
_addBuySignal(ks[i].datetime); | ||
} else { | ||
_addSellSignal(ks[i].datetime); | ||
} | ||
} | ||
} | ||
} | ||
|
||
SignalPtr HKU_API SG_OneSide(const Indicator& ind, bool is_buy) { | ||
return make_shared<OneSideSignal>(ind, is_buy); | ||
} | ||
|
||
} /* namespace hku */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright (c) 2025 hikyuu.org | ||
* | ||
* Created on: 2025-02-13 | ||
* Author: fasiondog | ||
*/ | ||
|
||
#pragma once | ||
#ifndef TRADE_SYS_SIGNAL_IMP_ONESIDESIGNAL_H_ | ||
#define TRADE_SYS_SIGNAL_IMP_ONESIDESIGNAL_H_ | ||
|
||
#include "../../../indicator/Indicator.h" | ||
#include "../SignalBase.h" | ||
|
||
namespace hku { | ||
|
||
// 根据输入指标构建单边信号(单纯的只包含买入或卖出信号),如果指标值大于0,则加入信号 | ||
class OneSideSignal : public SignalBase { | ||
public: | ||
OneSideSignal(); | ||
OneSideSignal(const Indicator& ind, bool is_buy); | ||
virtual ~OneSideSignal(); | ||
|
||
virtual SignalPtr _clone() override; | ||
virtual void _calculate(const KData& kdata) override; | ||
virtual void _checkParam(const string& name) const override; | ||
|
||
private: | ||
Indicator m_ind; | ||
|
||
//============================================ | ||
// 序列化支持 | ||
//============================================ | ||
#if HKU_SUPPORT_SERIALIZATION | ||
friend class boost::serialization::access; | ||
template <class Archive> | ||
void serialize(Archive& ar, const unsigned int version) { | ||
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SignalBase); | ||
ar& BOOST_SERIALIZATION_NVP(m_ind); | ||
} | ||
#endif | ||
}; | ||
|
||
} /* namespace hku */ | ||
|
||
#endif /* TRADE_SYS_SIGNAL_IMP_ONESIDESIGNAL_H_ */ |
95 changes: 95 additions & 0 deletions
95
hikyuu_cpp/unit_test/hikyuu/trade_sys/signal/test_SG_OneSide.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Copyright (c) 2025 hikyuu.org | ||
* | ||
* Created on: 2025-02-13 | ||
* Author: fasiondog | ||
*/ | ||
|
||
#include "doctest/doctest.h" | ||
#include "hikyuu/StockManager.h" | ||
#include "hikyuu/indicator/crt/KDATA.h" | ||
#include "hikyuu/indicator/crt/REF.h" | ||
#include "hikyuu/trade_sys/signal/crt/SG_Logic.h" | ||
#include "hikyuu/trade_sys/signal/crt/SG_Bool.h" | ||
#include "hikyuu/trade_sys/signal/crt/SG_OneSide.h" | ||
|
||
using namespace hku; | ||
|
||
/** | ||
* @defgroup test_Signal test_Signal | ||
* @ingroup test_hikyuu_trade_sys_suite | ||
* @{ | ||
*/ | ||
|
||
/** @par 检测点 */ | ||
TEST_CASE("test_SG_OneSide") { | ||
auto k = getKData("sh000001", KQuery(-30)); | ||
Indicator ind; | ||
SignalPtr sg; | ||
|
||
/** @arg 输入ind为空 */ | ||
sg = SG_OneSide(ind, true); | ||
sg->setTO(k); | ||
CHECK_UNARY(sg->getBuySignal().empty()); | ||
CHECK_UNARY(sg->getSellSignal().empty()); | ||
|
||
sg = SG_OneSide(ind, false); | ||
sg->setTO(k); | ||
CHECK_UNARY(sg->getBuySignal().empty()); | ||
CHECK_UNARY(sg->getSellSignal().empty()); | ||
|
||
/** @arg 单边买入信号 */ | ||
ind = CLOSE() > REF(CLOSE(), 1); | ||
auto sg_buy = SG_OneSide(ind, true); | ||
sg_buy->setTO(k); | ||
auto expect = ind(k); | ||
for (size_t i = expect.discard(); i < expect.size(); i++) { | ||
if (expect[i] > 0.0) { | ||
CHECK_UNARY(sg_buy->shouldBuy(k[i].datetime)); | ||
CHECK_UNARY(!sg_buy->shouldSell(k[i].datetime)); | ||
} else { | ||
CHECK_UNARY(!sg_buy->shouldBuy(k[i].datetime)); | ||
CHECK_UNARY(!sg_buy->shouldSell(k[i].datetime)); | ||
} | ||
} | ||
|
||
/** @arg 单边卖出信号 */ | ||
ind = CLOSE() < REF(CLOSE(), 1); | ||
auto sg_sell = SG_OneSide(ind, false); | ||
sg_sell->setTO(k); | ||
expect = ind(k); | ||
for (size_t i = expect.discard(); i < expect.size(); i++) { | ||
if (expect[i] > 0.0) { | ||
CHECK_UNARY(sg_sell->shouldSell(k[i].datetime)); | ||
CHECK_UNARY(!sg_sell->shouldBuy(k[i].datetime)); | ||
} else { | ||
CHECK_UNARY(!sg_sell->shouldSell(k[i].datetime)); | ||
CHECK_UNARY(!sg_sell->shouldBuy(k[i].datetime)); | ||
} | ||
} | ||
|
||
/** @arg 尝试改变 alternate 参数 */ | ||
sg_sell->setParam<bool>("alternate", false); | ||
CHECK_THROWS(sg_sell->setParam<bool>("alternate", true)); | ||
|
||
/** @arg 单边买入 + 单边卖出 */ | ||
sg = sg_buy + sg_sell; | ||
sg->setTO(k); | ||
auto sg_expect = SG_Bool(CLOSE() > REF(CLOSE(), 1), CLOSE() < REF(CLOSE(), 1)); | ||
sg_expect->setTO(k); | ||
for (size_t i = 0; i < k.size(); i++) { | ||
CHECK_EQ(sg->shouldBuy(k[i].datetime), sg_expect->shouldBuy(k[i].datetime)); | ||
CHECK_EQ(sg->shouldSell(k[i].datetime), sg_expect->shouldSell(k[i].datetime)); | ||
} | ||
|
||
sg->setParam<bool>("alternate", false); | ||
sg_expect = SG_Bool(CLOSE() > REF(CLOSE(), 1), CLOSE() < REF(CLOSE(), 1), false); | ||
sg->setTO(k); | ||
sg_expect->setTO(k); | ||
for (size_t i = 0; i < k.size(); i++) { | ||
CHECK_EQ(sg->shouldBuy(k[i].datetime), sg_expect->shouldBuy(k[i].datetime)); | ||
CHECK_EQ(sg->shouldSell(k[i].datetime), sg_expect->shouldSell(k[i].datetime)); | ||
} | ||
} | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters