mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-02 11:58:21 +08:00
优化STDED/STDP,使用移位算法
This commit is contained in:
parent
328a4c9408
commit
5bc8d0dc8f
@ -26,40 +26,54 @@ bool IStdev::check() {
|
||||
|
||||
void IStdev::_calculate(const Indicator& data) {
|
||||
size_t total = data.size();
|
||||
int n = getParam<int>("n");
|
||||
|
||||
m_discard = data.discard() + n - 1;
|
||||
m_discard = data.discard();
|
||||
if (m_discard >= total) {
|
||||
m_discard = total;
|
||||
return;
|
||||
}
|
||||
|
||||
Indicator ma = MA(data, n);
|
||||
size_t N = n - 1;
|
||||
for (size_t i = discard(); i < total; ++i) {
|
||||
price_t mean = ma[i];
|
||||
price_t sum = 0.0;
|
||||
for (size_t j = i + 1 - n; j <= i; ++j) {
|
||||
sum += std::pow(data[j] - mean, 2);
|
||||
}
|
||||
_set(std::sqrt(sum / N), i);
|
||||
int n = getParam<int>("n");
|
||||
|
||||
vector<price_t> pow_buf(data.size());
|
||||
price_t ex = 0.0, ex2 = 0.0;
|
||||
size_t num = 0;
|
||||
size_t start_pos = m_discard;
|
||||
size_t first_end = start_pos + n >= total ? total : start_pos + n;
|
||||
price_t k = data[start_pos];
|
||||
for (size_t i = start_pos; i < first_end; i++) {
|
||||
num++;
|
||||
price_t d = data[i] - k;
|
||||
ex += d;
|
||||
price_t d_pow = std::pow(d, 2);
|
||||
pow_buf[i] = d_pow;
|
||||
ex2 += d_pow;
|
||||
_set(num == 1 ? 0. : std::sqrt((ex2 - std::pow(ex, 2) / num) / (num - 1)), i);
|
||||
}
|
||||
|
||||
for (size_t i = first_end; i < total; i++) {
|
||||
ex -= data[i - n] - k;
|
||||
ex2 -= pow_buf[i - n];
|
||||
price_t d = data[i] - k;
|
||||
ex += d;
|
||||
price_t d_pow = std::pow(d, 2);
|
||||
pow_buf[i] = d_pow;
|
||||
ex2 += d_pow;
|
||||
_set(std::sqrt((ex2 - std::pow(ex, 2) / n) / (n - 1)), i);
|
||||
}
|
||||
}
|
||||
|
||||
void IStdev::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {
|
||||
HKU_IF_RETURN(step > 0 && curPos < ind.discard() + step - 1, void());
|
||||
size_t start = _get_step_start(curPos, step, ind.discard());
|
||||
price_t sum = 0.0;
|
||||
size_t num = 0;
|
||||
price_t ex = 0.0, ex2 = 0.0;
|
||||
price_t k = ind[start];
|
||||
for (size_t i = start; i <= curPos; i++) {
|
||||
sum += ind[i];
|
||||
num++;
|
||||
price_t d = ind[i] - k;
|
||||
ex += d;
|
||||
ex2 += std::pow(d, 2);
|
||||
}
|
||||
price_t mean = sum / step;
|
||||
sum = 0.0;
|
||||
size_t N = step - 1;
|
||||
for (size_t i = start; i <= curPos; i++) {
|
||||
sum += std::pow(ind[i] - mean, 2);
|
||||
}
|
||||
_set(std::sqrt(sum / N), curPos);
|
||||
_set(num <= 1 ? 0.0 : std::sqrt((ex2 - std::pow(ex, 2) / num) / (num - 1)), curPos);
|
||||
}
|
||||
|
||||
Indicator HKU_API STDEV(int n) {
|
||||
|
@ -28,38 +28,54 @@ bool IStdp::check() {
|
||||
|
||||
void IStdp::_calculate(const Indicator& data) {
|
||||
size_t total = data.size();
|
||||
int n = getParam<int>("n");
|
||||
|
||||
m_discard = data.discard() + n - 1;
|
||||
m_discard = data.discard();
|
||||
if (m_discard >= total) {
|
||||
m_discard = total;
|
||||
return;
|
||||
}
|
||||
|
||||
Indicator ma = MA(data, n);
|
||||
for (size_t i = discard(); i < total; ++i) {
|
||||
price_t mean = ma[i];
|
||||
price_t sum = 0.0;
|
||||
for (size_t j = i + 1 - n; j <= i; ++j) {
|
||||
sum += std::pow(data[j] - mean, 2);
|
||||
}
|
||||
_set(std::sqrt(sum / n), i);
|
||||
int n = getParam<int>("n");
|
||||
|
||||
vector<price_t> pow_buf(data.size());
|
||||
price_t ex = 0.0, ex2 = 0.0;
|
||||
size_t num = 0;
|
||||
size_t start_pos = m_discard;
|
||||
size_t first_end = start_pos + n >= total ? total : start_pos + n;
|
||||
price_t k = data[start_pos];
|
||||
for (size_t i = start_pos; i < first_end; i++) {
|
||||
num++;
|
||||
price_t d = data[i] - k;
|
||||
ex += d;
|
||||
price_t d_pow = std::pow(d, 2);
|
||||
pow_buf[i] = d_pow;
|
||||
ex2 += d_pow;
|
||||
_set(std::sqrt((ex2 - std::pow(ex, 2) / num) / num), i);
|
||||
}
|
||||
|
||||
for (size_t i = first_end; i < total; i++) {
|
||||
ex -= data[i - n] - k;
|
||||
ex2 -= pow_buf[i - n];
|
||||
price_t d = data[i] - k;
|
||||
ex += d;
|
||||
price_t d_pow = std::pow(d, 2);
|
||||
pow_buf[i] = d_pow;
|
||||
ex2 += d_pow;
|
||||
_set(std::sqrt((ex2 - std::pow(ex, 2) / n) / n), i);
|
||||
}
|
||||
}
|
||||
|
||||
void IStdp::_dyn_run_one_step(const Indicator& ind, size_t curPos, size_t step) {
|
||||
HKU_IF_RETURN(step > 0 && curPos < ind.discard() + step - 1, void());
|
||||
size_t start = _get_step_start(curPos, step, ind.discard());
|
||||
price_t sum = 0.0;
|
||||
size_t num = 0;
|
||||
price_t ex = 0.0, ex2 = 0.0;
|
||||
price_t k = ind[start];
|
||||
for (size_t i = start; i <= curPos; i++) {
|
||||
sum += ind[i];
|
||||
num++;
|
||||
price_t d = ind[i] - k;
|
||||
ex += d;
|
||||
ex2 += std::pow(d, 2);
|
||||
}
|
||||
price_t mean = sum / step;
|
||||
sum = 0.0;
|
||||
for (size_t i = start; i <= curPos; i++) {
|
||||
sum += std::pow(ind[i] - mean, 2);
|
||||
}
|
||||
_set(std::sqrt(sum / step), curPos);
|
||||
_set(num == 0 ? 0.0 : std::sqrt((ex2 - std::pow(ex, 2) / num) / num), curPos);
|
||||
}
|
||||
|
||||
Indicator HKU_API STDP(int n) {
|
||||
|
@ -35,13 +35,13 @@ TEST_CASE("test_STDEV") {
|
||||
Indicator ind = PRICELIST(d);
|
||||
Indicator dev = STDEV(ind, 10);
|
||||
CHECK_EQ(dev.size(), 15);
|
||||
CHECK_UNARY(std::isnan(dev[8]));
|
||||
CHECK_LT(std::fabs(dev[9] - 2.923088), 0.000001);
|
||||
CHECK_LT(std::fabs(dev[10] - 3.142893), 0.000001);
|
||||
CHECK_LT(std::fabs(dev[11] - 2.830390), 0.000001);
|
||||
CHECK_LT(std::fabs(dev[12] - 3.267686), 0.000001);
|
||||
CHECK_LT(std::fabs(dev[13] - 3.653004), 0.000001);
|
||||
CHECK_LT(std::fabs(dev[14] - 4.001388), 0.000001);
|
||||
|
||||
vector<price_t> expected{0, 0.707107, 1, 1.29099, 1.58114,
|
||||
1.47196, 1.97605, 1.83225, 2.44949, 2.92309,
|
||||
3.14289, 2.83039, 3.26769, 3.653, 4.00139};
|
||||
for (size_t i = 0; i < dev.size(); i++) {
|
||||
CHECK_EQ(dev[i], doctest::Approx(expected[i]).epsilon(0.0001));
|
||||
}
|
||||
|
||||
/** @arg n = 1时 */
|
||||
dev = STDEV(ind, 1);
|
||||
|
@ -36,7 +36,13 @@ TEST_CASE("test_STDP") {
|
||||
Indicator dev = STDP(ind, 10);
|
||||
CHECK_EQ(dev.name(), "STDP");
|
||||
CHECK_EQ(dev.size(), 15);
|
||||
CHECK_UNARY(std::isnan(dev[8]));
|
||||
|
||||
vector<price_t> expected{0, 0.5, 0.816497, 1.11803, 1.41421, 1.34371, 1.82946, 1.71391,
|
||||
2.3094, 2.77308, 2.98161, 2.68514, 3.1, 3.46554, 3.79605};
|
||||
for (size_t i = 0; i < dev.size(); i++) {
|
||||
CHECK_EQ(dev[i], doctest::Approx(expected[i]).epsilon(0.0001));
|
||||
}
|
||||
|
||||
CHECK_LT(std::fabs(dev[9] - 2.77308), 0.00001);
|
||||
CHECK_LT(std::fabs(dev[10] - 2.98161), 0.00001);
|
||||
CHECK_LT(std::fabs(dev[11] - 2.68514), 0.00001);
|
||||
|
@ -39,9 +39,9 @@ TEST_CASE("test_VAR") {
|
||||
CHECK_EQ(dev.name(), "VAR");
|
||||
CHECK_EQ(dev.size(), 15);
|
||||
|
||||
vector<price_t> expected{0., 0.55, 1., 1.666667, 2.5, 2.16667, 3.90476, 3.35714,
|
||||
vector<price_t> expected{0., 0.5, 1., 1.666667, 2.5, 2.16667, 3.90476, 3.35714,
|
||||
6., 8.54444, 9.87778, 8.01111, 10.6778, 13.3444, 16.0111};
|
||||
for (size_t i = 9; i < dev.size(); i++) {
|
||||
for (size_t i = 0; i < dev.size(); i++) {
|
||||
CHECK_EQ(dev[i], doctest::Approx(expected[i]).epsilon(0.001));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user