Skip to content

Commit e43d127

Browse files
committed
add WMA
1 parent 4c47f69 commit e43d127

File tree

5 files changed

+89
-66
lines changed

5 files changed

+89
-66
lines changed

hikyuu_cpp/hikyuu/indicator/crt/WMA.h

+15-14
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,26 @@ namespace hku {
2020
* @ingroup Indicator
2121
*/
2222
Indicator HKU_API WMA(int n = 22);
23-
// Indicator HKU_API MA(const IndParam& n);
24-
25-
// /**
26-
// * 简单移动平均
27-
// * @param ind 待计算的数据
28-
// * @param n 计算均值的周期窗口,n为0时从第一个有效数据开始计算
29-
// * @ingroup Indicator
30-
// */
23+
Indicator HKU_API WMA(const IndParam& n);
24+
25+
/**
26+
* 加权移动平均
27+
* 算法:Yn=(1*X1+2*X2+...+n*Xn)/(1+2+...+n)
28+
* @param ind 待计算的数据
29+
* @param n 计算均值的周期窗口
30+
* @ingroup Indicator
31+
*/
3132
inline Indicator HKU_API WMA(const Indicator& ind, int n = 22) {
3233
return WMA(n)(ind);
3334
}
3435

35-
// inline Indicator HKU_API MA(const Indicator& ind, const IndParam& n) {
36-
// return MA(n)(ind);
37-
// }
36+
inline Indicator HKU_API WMA(const Indicator& ind, const IndParam& n) {
37+
return WMA(n)(ind);
38+
}
3839

39-
// inline Indicator MA(const Indicator& ind, const Indicator& n) {
40-
// return MA(IndParam(n))(ind);
41-
// }
40+
inline Indicator WMA(const Indicator& ind, const Indicator& n) {
41+
return WMA(IndParam(n))(ind);
42+
}
4243

4344
} // namespace hku
4445

hikyuu_cpp/hikyuu/indicator/imp/IWma.cpp

+39-32
Original file line numberDiff line numberDiff line change
@@ -42,42 +42,49 @@ void IWma::_calculate(const Indicator& ind) {
4242
return;
4343
}
4444

45-
size_t startIdx = m_discard;
46-
size_t outIdx = m_discard;
47-
size_t trailingIdx = startIdx - 1;
48-
49-
value_t tempReal = 0.0, periodSum = 0.0, periodSub = 0.0;
50-
size_t inIdx = ind.discard();
51-
size_t i = 1;
52-
while (inIdx < startIdx) {
53-
tempReal = src[inIdx++];
54-
periodSub += tempReal;
55-
periodSum += tempReal * i;
56-
i++;
45+
value_t subsum = 0.0, sum = 0.0;
46+
for (size_t i = ind.discard(), end = m_discard + 1, count = 1; i < end; i++, count++) {
47+
subsum += src[i];
48+
sum += src[i] * count;
5749
}
5850

59-
size_t endIdx = total - 1;
60-
value_t trailingValue = 0.;
6151
value_t divider = n * (n + 1) / 2.0;
62-
while (inIdx <= endIdx) {
63-
tempReal = src[inIdx++];
64-
periodSub += tempReal;
65-
periodSub -= trailingValue;
66-
periodSum += tempReal * n;
67-
// HKU_INFO("{}: {}, {} ", inIdx - 1, periodSum, divider);
68-
trailingValue = src[trailingIdx++];
69-
dst[outIdx++] = periodSum / divider;
70-
periodSum -= periodSub;
52+
dst[m_discard] = sum / divider;
53+
54+
size_t trailingIdx = ind.discard();
55+
for (size_t i = m_discard + 1; i < total; i++) {
56+
value_t tmp = src[i];
57+
sum -= subsum;
58+
subsum += tmp;
59+
subsum -= src[trailingIdx++];
60+
sum += tmp * n;
61+
dst[i] = sum / divider;
7162
}
7263
}
7364

7465
void IWma::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {
66+
if (step < 1) {
67+
_set(Null<value_t>(), curPos);
68+
return;
69+
}
70+
71+
if (step == 1) {
72+
_set(ind[curPos], curPos);
73+
return;
74+
}
75+
7576
size_t start = _get_step_start(curPos, step, ind.discard());
76-
price_t sum = 0.0;
77-
for (size_t i = start; i <= curPos; i++) {
78-
sum += ind[i];
77+
if (curPos + 1 - start < step) {
78+
_set(Null<value_t>(), curPos);
79+
return;
80+
}
81+
82+
value_t sum = 0.0;
83+
size_t n = 1;
84+
for (size_t i = start; i <= curPos; i++, n++) {
85+
sum += (ind[i] * n);
7986
}
80-
_set(sum / (curPos - start + 1), curPos);
87+
_set(sum / (step * (step + 1) / 2.), curPos);
8188
}
8289

8390
Indicator HKU_API WMA(int n) {
@@ -86,10 +93,10 @@ Indicator HKU_API WMA(int n) {
8693
return Indicator(p);
8794
}
8895

89-
// Indicator HKU_API MA(const IndParam& n) {
90-
// IndicatorImpPtr p = make_shared<IWma>();
91-
// p->setIndParam("n", n);
92-
// return Indicator(p);
93-
// }
96+
Indicator HKU_API WMA(const IndParam& n) {
97+
IndicatorImpPtr p = make_shared<IWma>();
98+
p->setIndParam("n", n);
99+
return Indicator(p);
100+
}
94101

95102
} /* namespace hku */

hikyuu_cpp/unit_test/hikyuu/indicator/test_Indicator.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@
1717
* @{
1818
*/
1919

20+
/** @par 检测点 */
21+
TEST_CASE("test_indicator_other") {
22+
double dx = Null<double>();
23+
size_t ix = size_t(dx);
24+
// 随机值
25+
HKU_INFO("double nan to size_t: {}", ix);
26+
27+
float fx = Null<float>();
28+
ix = size_t(fx);
29+
// 随机值
30+
HKU_INFO("float nan to size_t: {}", ix);
31+
}
32+
2033
/** @par 检测点 */
2134
TEST_CASE("test_indicator_alike") {
2235
/** @arg 空 indicator 比较 */

hikyuu_cpp/unit_test/hikyuu/indicator/test_WMA.cpp

+4-17
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,14 @@ TEST_CASE("test_WMA") {
7878
CHECK_EQ(result[9], doctest::Approx(6.).epsilon(0.0001));
7979
}
8080

81-
#if 0
8281
/** @par 检测点 */
83-
TEST_CASE("test_SUM_dyn") {
82+
TEST_CASE("test_WMA_dyn") {
8483
Stock stock = StockManager::instance().getStock("sh000001");
8584
KData kdata = stock.getKData(KQuery(-30));
8685
// KData kdata = stock.getKData(KQuery(0, Null<size_t>(), KQuery::MIN));
8786
Indicator c = CLOSE(kdata);
88-
Indicator expect = SUM(c, 10);
89-
Indicator result = SUM(c, CVAL(c, 10));
87+
Indicator expect = WMA(c, 10);
88+
Indicator result = WMA(c, CVAL(c, 10));
9089
CHECK_EQ(expect.size(), result.size());
9190
CHECK_EQ(expect.discard(), result.discard());
9291
for (size_t i = 0; i < result.discard(); i++) {
@@ -96,18 +95,7 @@ TEST_CASE("test_SUM_dyn") {
9695
CHECK_EQ(expect[i], doctest::Approx(result[i]));
9796
}
9897

99-
result = SUM(c, IndParam(CVAL(c, 10)));
100-
CHECK_EQ(expect.size(), result.size());
101-
CHECK_EQ(expect.discard(), result.discard());
102-
for (size_t i = 0; i < result.discard(); i++) {
103-
CHECK_UNARY(std::isnan(result[i]));
104-
}
105-
for (size_t i = expect.discard(); i < expect.size(); i++) {
106-
CHECK_EQ(expect[i], doctest::Approx(result[i]));
107-
}
108-
109-
expect = SUM(c, 0);
110-
result = SUM(c, CVAL(c, 0));
98+
result = WMA(c, IndParam(CVAL(c, 10)));
11199
CHECK_EQ(expect.size(), result.size());
112100
CHECK_EQ(expect.discard(), result.discard());
113101
for (size_t i = 0; i < result.discard(); i++) {
@@ -117,7 +105,6 @@ TEST_CASE("test_SUM_dyn") {
117105
CHECK_EQ(expect[i], doctest::Approx(result[i]));
118106
}
119107
}
120-
#endif
121108

122109
//-----------------------------------------------------------------------------
123110
// test export

hikyuu_pywrap/indicator/_build_in.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ Indicator (*MA_3)(const Indicator&, const IndParam&) = MA;
9797
Indicator (*MA_4)(const Indicator&, const Indicator&) = MA;
9898
Indicator (*MA_5)(const Indicator&, int) = MA;
9999

100+
Indicator (*WMA_1)(int) = WMA;
101+
Indicator (*WMA_2)(const IndParam&) = WMA;
102+
Indicator (*WMA_3)(const Indicator&, const IndParam&) = WMA;
103+
Indicator (*WMA_4)(const Indicator&, const Indicator&) = WMA;
104+
Indicator (*WMA_5)(const Indicator&, int) = WMA;
105+
100106
Indicator (*SMA_1)(int, double) = SMA;
101107
Indicator (*SMA_2)(int, const IndParam&) = SMA;
102108
Indicator (*SMA_3)(const IndParam&, double) = SMA;
@@ -729,6 +735,18 @@ void export_Indicator_build_in(py::module& m) {
729735
:param int|Indicator|IndParam n: 时间窗口
730736
:rtype: Indicator)");
731737

738+
m.def("WMA", WMA_1, py::arg("n") = 22);
739+
m.def("WMA", WMA_2, py::arg("n"));
740+
m.def("WMA", WMA_3, py::arg("data"), py::arg("n"));
741+
m.def("WMA", WMA_4, py::arg("data"), py::arg("n"));
742+
m.def("WMA", WMA_5, py::arg("data"), py::arg("n") = 22, R"(WMA([data, n=22])
743+
744+
加权移动平均,算法:Yn=(1*X1+2*X2+...+n*Xn)/(1+2+...+n)
745+
746+
:param Indicator data: 输入数据
747+
:param int|Indicator|IndParam n: 时间窗口
748+
:rtype: Indicator)");
749+
732750
m.def("AMA", AMA_1, py::arg("n") = 10, py::arg("fast_n") = 2, py::arg("slow_n") = 30);
733751
m.def("AMA", AMA_2, py::arg("n"), py::arg("fast_n"), py::arg("slow_n"));
734752
m.def("AMA", AMA_4, py::arg("data"), py::arg("n"), py::arg("fast_n"), py::arg("slow_n"));
@@ -1935,7 +1953,4 @@ void export_Indicator_build_in(py::module& m) {
19351953
:param Indicator ind: 指定指标
19361954
:param int mode: 计算类型:0-累加,1-平均数,2-最大值,3-最小值.
19371955
:rtype: Indicator)");
1938-
1939-
m.def("WMA", py::overload_cast<int>(WMA), py::arg("n"));
1940-
m.def("WMA", py::overload_cast<const Indicator&, int>(WMA), py::arg("ind"), py::arg("n"));
19411956
}

0 commit comments

Comments
 (0)