Skip to content

Commit 9206789

Browse files
committed
SG增强,支持逻辑及四则运算(continue)
1 parent 188bba2 commit 9206789

File tree

6 files changed

+98
-8
lines changed

6 files changed

+98
-8
lines changed

hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ double SignalBase::getSellValue(const Datetime& datetime) const {
135135
}
136136

137137
void SignalBase::_addSignal(const Datetime& datetime, double value) {
138-
HKU_IF_RETURN(iszero(value), void());
138+
HKU_IF_RETURN(iszero(value) || std::isnan(value), void());
139139

140140
double new_value = value + getBuyValue(datetime) + getSellValue(datetime);
141141
HKU_IF_RETURN(iszero(new_value), void());

hikyuu_cpp/hikyuu/trade_sys/signal/SignalBase.h

+2
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,13 @@ inline double SignalBase::getValue(const Datetime& datetime) const {
261261
}
262262

263263
inline void SignalBase::_addBuySignal(const Datetime& datetime, double value) {
264+
HKU_IF_RETURN(std::isnan(value), void());
264265
HKU_CHECK(value > 0.0, "buy value muse be > 0", value);
265266
_addSignal(datetime, value);
266267
}
267268

268269
inline void SignalBase::_addSellSignal(const Datetime& datetime, double value) {
270+
HKU_IF_RETURN(std::isnan(value), void());
269271
HKU_CHECK(value < 0.0, "sell value muse be > 0", value);
270272
_addSignal(datetime, value);
271273
}

hikyuu_cpp/hikyuu/trade_sys/signal/crt/SG_Bool.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ namespace hku {
1818
* 布尔信号指示器
1919
* @param buy 买入指示(结果Indicator中相应位置>0则代表买入)
2020
* @param sell 卖出指示(结果Indicator中相应位置>0则代表卖出)
21+
* @param alternate 买入与卖出信号是否交替出现,默认为true
2122
* @return 信号指示器
2223
* @ingroup Signal
2324
*/
24-
SignalPtr HKU_API SG_Bool(const Indicator& buy, const Indicator& sell);
25+
SignalPtr HKU_API SG_Bool(const Indicator& buy, const Indicator& sell, bool alternate = true);
2526

2627
} /* namespace hku */
2728

hikyuu_cpp/hikyuu/trade_sys/signal/imp/BoolSignal.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
* Author: fasiondog
66
*/
77

8-
#include "../../../indicator/crt/KDATA.h"
8+
#include "hikyuu/indicator/crt/ALIGN.h"
9+
#include "hikyuu/indicator/crt/KDATA.h"
910
#include "BoolSignal.h"
1011

1112
#if HKU_SUPPORT_SERIALIZATION
@@ -29,8 +30,8 @@ SignalPtr BoolSignal::_clone() {
2930
}
3031

3132
void BoolSignal::_calculate(const KData& kdata) {
32-
Indicator buy = m_bool_buy(kdata);
33-
Indicator sell = m_bool_sell(kdata);
33+
Indicator buy = ALIGN(m_bool_buy(kdata), kdata);
34+
Indicator sell = ALIGN(m_bool_sell(kdata), kdata);
3435
HKU_ERROR_IF_RETURN(buy.size() != sell.size(), void(), "buy.size() != sell.size()");
3536

3637
size_t discard = buy.discard() > sell.discard() ? buy.discard() : sell.discard();
@@ -46,8 +47,10 @@ void BoolSignal::_calculate(const KData& kdata) {
4647
}
4748
}
4849

49-
SignalPtr HKU_API SG_Bool(const Indicator& buy, const Indicator& sell) {
50-
return make_shared<BoolSignal>(buy, sell);
50+
SignalPtr HKU_API SG_Bool(const Indicator& buy, const Indicator& sell, bool alternate) {
51+
auto p = make_shared<BoolSignal>(buy, sell);
52+
p->setParam<bool>("alternate", alternate);
53+
return p;
5154
}
5255

5356
} /* namespace hku */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2025 hikyuu.org
3+
*
4+
* Created on: 2025-02-08
5+
* Author: fasiondog
6+
*/
7+
8+
#include "../../test_config.h"
9+
#include "hikyuu/trade_sys/signal/crt/SG_Logic.h"
10+
#include "hikyuu/trade_sys/signal/crt/SG_Manual.h"
11+
12+
using namespace hku;
13+
14+
/**
15+
* @defgroup test_Signal test_Signal_logic
16+
* @ingroup test_hikyuu_trade_sys_suite
17+
* @{
18+
*/
19+
20+
static void reset_expect(std::map<Datetime, double>& expect) {
21+
for (auto& iter : expect) {
22+
iter.second = 0.0;
23+
}
24+
}
25+
26+
/** @par 检测点 */
27+
TEST_CASE("test_SG_Add") {
28+
auto k = getKData("sz000001", KQueryByDate(Datetime(20111108), Datetime(20111201)));
29+
std::map<Datetime, double> expect;
30+
for (size_t i = 0; i < k.size(); i++) {
31+
HKU_INFO("{}", k[i]);
32+
expect[k[i].datetime] = 0.0;
33+
}
34+
35+
/** @arg sg1, sg2 不存在重叠 */
36+
auto sg1 = SG_Manual();
37+
sg1->_addBuySignal(Datetime(20111110));
38+
sg1->_addSellSignal(Datetime(20111114));
39+
40+
auto sg2 = SG_Manual();
41+
sg2->_addBuySignal(Datetime(20111115));
42+
sg2->_addSellSignal(Datetime(20111116));
43+
44+
auto ret = sg1 + sg2;
45+
ret->setParam<bool>("alternate", true);
46+
ret->setTO(k);
47+
48+
expect[Datetime(20111110)] = 1.0;
49+
expect[Datetime(20111114)] = -1.0;
50+
expect[Datetime(20111115)] = 1.0;
51+
expect[Datetime(20111116)] = -1.0;
52+
for (auto iter = expect.begin(); iter != expect.end(); ++iter) {
53+
CHECK_EQ(ret->getValue(iter->first), iter->second);
54+
}
55+
56+
/** @arg sg1, sg2 存在重叠 */
57+
sg1->reset();
58+
sg2->reset();
59+
sg1->_addBuySignal(Datetime(20111110));
60+
sg1->_addSellSignal(Datetime(20111114));
61+
sg2->_addBuySignal(Datetime(20111115));
62+
sg2->_addSellSignal(Datetime(20111116));
63+
64+
reset_expect(expect);
65+
}
66+
67+
/** @} */

hikyuu_pywrap/trade_sys/_Signal.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,32 @@ void export_Signal(py::module& m) {
133133

134134
.def("_reset", &SignalBase::_reset, "【重载接口】子类复位接口,复位内部私有变量")
135135

136+
.def("__add__", [](const SignalPtr& self, const SignalPtr& other) { return self + other; })
137+
.def("__add__", [](const SignalPtr& self, double other) { return self + other; })
138+
.def("__radd__", [](const SignalPtr& self, double other) { return other + self; })
139+
.def("__sub__", [](const SignalPtr& self, const SignalPtr& other) { return self - other; })
140+
.def("__sub__", [](const SignalPtr& self, double other) { return self - other; })
141+
.def("__rsub__", [](const SignalPtr& self, double other) { return other - self; })
142+
.def("__mul__", [](const SignalPtr& self, const SignalPtr& other) { return self * other; })
143+
.def("__mul__", [](const SignalPtr& self, double other) { return self * other; })
144+
.def("__rmul__", [](const SignalPtr& self, double other) { return other * self; })
145+
.def("__truediv__",
146+
[](const SignalPtr& self, const SignalPtr& other) { return self / other; })
147+
.def("__truediv__", [](const SignalPtr& self, double other) { return self / other; })
148+
.def("__rtruediv__", [](const SignalPtr& self, double other) { return other / self; })
149+
.def("__and__", [](const SignalPtr& self, const SignalPtr& other) { return self & other; })
150+
.def("__or__", [](const SignalPtr& self, const SignalPtr& other) { return self | other; })
151+
136152
DEF_PICKLE(SGPtr);
137153

138-
m.def("SG_Bool", SG_Bool, py::arg("buy"), py::arg("sell"),
154+
m.def("SG_Bool", SG_Bool, py::arg("buy"), py::arg("sell"), py::arg("alternate") = true,
139155
R"(SG_Bool(buy, sell)
140156
141157
布尔信号指示器,使用运算结果为类似bool数组的Indicator分别作为买入、卖出指示。
142158
143159
:param Indicator buy: 买入指示(结果Indicator中相应位置>0则代表买入)
144160
:param Indicator sell: 卖出指示(结果Indicator中相应位置>0则代表卖出)
161+
:param bool alternate: 是否交替买入卖出,默认为True
145162
:return: 信号指示器)");
146163

147164
m.def("SG_Single", SG_Single, py::arg("ind"), py::arg("filter_n") = 10,

0 commit comments

Comments
 (0)