-
Notifications
You must be signed in to change notification settings - Fork 11
/
abands.cc
108 lines (81 loc) · 3.25 KB
/
abands.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
* This file is part of tindicators, licensed under GNU LGPL v3.
* Author: Ilya Pikulin <ilya.pikulin@gmail.com>, 2019-2021
*/
#include "../indicators.h"
#include "../utils/buffer.h"
int ti_abands_start(TI_REAL const *options) {
const TI_REAL period = options[0];
return (int)period-1;
}
/* Name: Acceleration Bands
* Source: Price Headley. Big Trends In Trading, 2002, p. 92. Original description
* ISBN: 0-471-41269-4
*/
int ti_abands(int size, TI_REAL const *const *inputs, TI_REAL const *options, TI_REAL *const *outputs) {
const TI_REAL *high = inputs[0];
const TI_REAL *low = inputs[1];
const TI_REAL *close = inputs[2];
const int period = (int)options[0];
TI_REAL *lower_band = outputs[0];
TI_REAL *upper_band = outputs[1];
TI_REAL *middle_point = outputs[2];
if (period < 1) { return TI_INVALID_OPTION; }
if (size <= ti_abands_start(options)) return TI_OKAY;
#define MULT(i) (high[i] + low[i] > 0 ? 4. * (high[i] - low[i]) / (high[i] + low[i]) : 0)
TI_REAL per = 1. / period;
ti_buffer *buffer_high = ti_buffer_new(period);
ti_buffer *buffer_low = ti_buffer_new(period);
TI_REAL close_sum = 0;
for (int i = 0; i < period; ++i) {
TI_REAL mult = MULT(i);
TI_REAL high_val = (1. + mult) * high[i];
ti_buffer_push(buffer_high, high_val);
TI_REAL low_val = (1. - mult) * low[i];
ti_buffer_push(buffer_low, low_val);
close_sum += close[i];
}
*upper_band++ = buffer_high->sum * per;
*lower_band++ = buffer_low->sum * per;
*middle_point++ = close_sum * per;
for (int i = period; i < size; ++i) {
TI_REAL mult = MULT(i);
TI_REAL high_val = (1. + mult) * high[i];
ti_buffer_push(buffer_high, high_val);
TI_REAL low_val = (1. - mult) * low[i];
ti_buffer_push(buffer_low, low_val);
close_sum += close[i] - close[i-period];
*upper_band++ = buffer_high->sum * per;
*lower_band++ = buffer_low->sum * per;
*middle_point++ = close_sum * per;
}
ti_buffer_free(buffer_high);
ti_buffer_free(buffer_low);
assert(lower_band - outputs[0] == size - ti_abands_start(options));
return TI_OKAY;
}
int ti_abands_ref(int size, TI_REAL const *const *inputs, TI_REAL const *options, TI_REAL *const *outputs) {
const TI_REAL *high = inputs[0];
const TI_REAL *low = inputs[1];
const TI_REAL *close = inputs[2];
const TI_REAL period = (int)options[0];
TI_REAL *lower_band = outputs[0];
TI_REAL *upper_band = outputs[1];
TI_REAL *middle_point = outputs[2];
if (period < 1) { return TI_INVALID_OPTION; }
for (int i = period-1; i < size; ++i) {
TI_REAL upper = 0;
TI_REAL mid = 0;
TI_REAL lower = 0;
for (int j = i-period+1; j <= i; ++j) {
upper += (high[j] * (1. + 2. * ((((high[j] - low[j]) / ((high[j] + low[j]) / 2.)) * 1000.) * .001))) / period;
mid += close[j] / period;
lower += (low[j] * (1. - 2. * ((((high[j] - low[j]) / ((high[j] + low[j]) / 2.)) * 1000.) * .001))) / period;
}
*upper_band++ = upper;
*middle_point++ = mid;
*lower_band++ = lower;
}
assert(lower_band - outputs[0] == size - ti_abands_start(options));
return TI_OKAY;
}