sqa-tai 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/sqa/tai/cycle_indicators.rb +72 -0
- data/lib/sqa/tai/momentum_indicators.rb +517 -0
- data/lib/sqa/tai/overlap_studies.rb +144 -0
- data/lib/sqa/tai/pattern_recognition.rb +684 -0
- data/lib/sqa/tai/price_transform.rb +64 -0
- data/lib/sqa/tai/statistical_functions.rb +122 -0
- data/lib/sqa/tai/version.rb +1 -1
- data/lib/sqa/tai/volatility_indicators.rb +179 -0
- data/lib/sqa/tai/volume_indicators.rb +54 -0
- data/lib/sqa/tai.rb +20 -1804
- data/mkdocs.yml +7 -10
- metadata +9 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c708d46e3d535588af3a14a4d209e32e79a34fa11733c3a20cec8e8a25ddf8f
|
|
4
|
+
data.tar.gz: 665274f5b878d3165f50edfc78a6c6903c95f3696483357d07b12b929f2a00fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 72e84001d6624688c24800916e2d9651a13d4047e3dc10e6dd53725b1ea464748890df15e4c35b74e1def91429dc2819750d87529cdb86f2d4fa3a8295fca706
|
|
7
|
+
data.tar.gz: b0a2341c3d7777326cddd41f50254f9ff5a290c73b63a6782495fc5c94a29759daa7d0d752cc82e1ea2cd3f1f749bb866ed69f76ba89d12cb1afc13959851a66
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.1] 2025-11-13
|
|
11
|
+
### Added
|
|
12
|
+
- Intraday Momentum Index (IMI) indicator
|
|
13
|
+
- GitHub Actions workflow to automatically deploy documentation to GitHub Pages
|
|
14
|
+
- Indicator template markdown file for documentation
|
|
15
|
+
- Chronological ordering note to indicator documentation
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- Hash return format handling from newer ta_lib_ffi versions
|
|
19
|
+
- Image alignment and naming in README
|
|
20
|
+
- API reference documentation formatting and index links
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Refactored library code into modular structure with 8 focused modules organized by indicator category
|
|
24
|
+
- `lib/sqa/tai/overlap_studies.rb` - Moving averages and bands
|
|
25
|
+
- `lib/sqa/tai/momentum_indicators.rb` - Momentum and oscillator indicators
|
|
26
|
+
- `lib/sqa/tai/volatility_indicators.rb` - Volatility and range indicators
|
|
27
|
+
- `lib/sqa/tai/volume_indicators.rb` - Volume-based indicators
|
|
28
|
+
- `lib/sqa/tai/price_transform.rb` - Price transformation functions
|
|
29
|
+
- `lib/sqa/tai/cycle_indicators.rb` - Hilbert Transform cycle indicators
|
|
30
|
+
- `lib/sqa/tai/statistical_functions.rb` - Statistical analysis functions
|
|
31
|
+
- `lib/sqa/tai/pattern_recognition.rb` - Candlestick pattern recognition
|
|
32
|
+
- Refactored test suite to mirror lib directory organization with 8 modular test files
|
|
33
|
+
- Reduced main `lib/sqa/tai.rb` from 1,851 lines to 67 lines (96% reduction)
|
|
34
|
+
- Reduced main `test/sqa/tai_test.rb` to core tests only, extracted 72 tests into category-specific files
|
|
35
|
+
- Updated indicator count to 132
|
|
36
|
+
- Reorganized README sections
|
|
37
|
+
- Improved SQA name from "Stock Qualitative Analysis" to "Simple Qualitative Analysis"
|
|
38
|
+
- Updated gemspec description
|
|
39
|
+
|
|
10
40
|
## [0.1.0] - 2025-11-06
|
|
11
41
|
|
|
12
42
|
### Added
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
<table>
|
|
9
9
|
<tr>
|
|
10
|
-
<td width="30%" valign="
|
|
11
|
-
<img src="docs/assets/images/sqa
|
|
10
|
+
<td width="30%" valign="middle" align="center">
|
|
11
|
+
<img src="docs/assets/images/sqa.jpg" alt="Ruby Turns Information into Knowledge" width="80%">
|
|
12
12
|
<br/>
|
|
13
13
|
</td>
|
|
14
14
|
<td width="70%" valign="top">
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SQA
|
|
4
|
+
module TAI
|
|
5
|
+
# Cycle Indicators
|
|
6
|
+
module CycleIndicators
|
|
7
|
+
# Hilbert Transform - Dominant Cycle Period
|
|
8
|
+
# @param prices [Array<Float>] Array of prices
|
|
9
|
+
# @return [Array<Float>] Dominant cycle period values
|
|
10
|
+
def ht_dcperiod(prices)
|
|
11
|
+
check_available!
|
|
12
|
+
validate_prices!(prices)
|
|
13
|
+
|
|
14
|
+
TALibFFI.ht_dcperiod(prices)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Hilbert Transform - Trend vs Cycle Mode
|
|
18
|
+
# @param prices [Array<Float>] Array of prices
|
|
19
|
+
# @return [Array<Integer>] Trend mode (1) or cycle mode (0)
|
|
20
|
+
def ht_trendmode(prices)
|
|
21
|
+
check_available!
|
|
22
|
+
validate_prices!(prices)
|
|
23
|
+
|
|
24
|
+
TALibFFI.ht_trendmode(prices)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Hilbert Transform - Dominant Cycle Phase
|
|
28
|
+
# @param prices [Array<Float>] Array of prices
|
|
29
|
+
# @return [Array<Float>] Dominant cycle phase values
|
|
30
|
+
def ht_dcphase(prices)
|
|
31
|
+
check_available!
|
|
32
|
+
validate_prices!(prices)
|
|
33
|
+
|
|
34
|
+
TALibFFI.ht_dcphase(prices)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Hilbert Transform - Phasor Components
|
|
38
|
+
# @param prices [Array<Float>] Array of prices
|
|
39
|
+
# @return [Array<Array<Float>>] [inphase, quadrature]
|
|
40
|
+
def ht_phasor(prices)
|
|
41
|
+
check_available!
|
|
42
|
+
validate_prices!(prices)
|
|
43
|
+
|
|
44
|
+
result = TALibFFI.ht_phasor(prices)
|
|
45
|
+
|
|
46
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
47
|
+
if result.is_a?(Hash)
|
|
48
|
+
[result[:in_phase], result[:quadrature]]
|
|
49
|
+
else
|
|
50
|
+
result
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Hilbert Transform - SineWave
|
|
55
|
+
# @param prices [Array<Float>] Array of prices
|
|
56
|
+
# @return [Array<Array<Float>>] [sine, lead_sine]
|
|
57
|
+
def ht_sine(prices)
|
|
58
|
+
check_available!
|
|
59
|
+
validate_prices!(prices)
|
|
60
|
+
|
|
61
|
+
result = TALibFFI.ht_sine(prices)
|
|
62
|
+
|
|
63
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
64
|
+
if result.is_a?(Hash)
|
|
65
|
+
[result[:sine], result[:lead_sine]]
|
|
66
|
+
else
|
|
67
|
+
result
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SQA
|
|
4
|
+
module TAI
|
|
5
|
+
# Momentum Indicators
|
|
6
|
+
module MomentumIndicators
|
|
7
|
+
# Relative Strength Index
|
|
8
|
+
# @param prices [Array<Float>] Array of prices
|
|
9
|
+
# @param period [Integer] Time period (default: 14)
|
|
10
|
+
# @return [Array<Float>] RSI values
|
|
11
|
+
def rsi(prices, period: 14)
|
|
12
|
+
check_available!
|
|
13
|
+
validate_prices!(prices)
|
|
14
|
+
validate_period!(period, prices.size)
|
|
15
|
+
|
|
16
|
+
TALibFFI.rsi(prices, time_period: period)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Intraday Momentum Index
|
|
20
|
+
# @param open_prices [Array<Float>] Array of open prices
|
|
21
|
+
# @param close_prices [Array<Float>] Array of close prices
|
|
22
|
+
# @param period [Integer] Time period (default: 14)
|
|
23
|
+
# @return [Array<Float>] IMI values
|
|
24
|
+
def imi(open_prices, close_prices, period: 14)
|
|
25
|
+
check_available!
|
|
26
|
+
validate_prices!(open_prices)
|
|
27
|
+
validate_prices!(close_prices)
|
|
28
|
+
validate_period!(period, [open_prices.size, close_prices.size].min)
|
|
29
|
+
|
|
30
|
+
TALibFFI.imi(open_prices, close_prices, time_period: period)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Moving Average Convergence/Divergence
|
|
34
|
+
# @param prices [Array<Float>] Array of prices
|
|
35
|
+
# @param fast_period [Integer] Fast period (default: 12)
|
|
36
|
+
# @param slow_period [Integer] Slow period (default: 26)
|
|
37
|
+
# @param signal_period [Integer] Signal period (default: 9)
|
|
38
|
+
# @return [Array<Array<Float>>] [macd, signal, histogram]
|
|
39
|
+
def macd(prices, fast_period: 12, slow_period: 26, signal_period: 9)
|
|
40
|
+
check_available!
|
|
41
|
+
validate_prices!(prices)
|
|
42
|
+
|
|
43
|
+
result = TALibFFI.macd(
|
|
44
|
+
prices,
|
|
45
|
+
fast_period: fast_period,
|
|
46
|
+
slow_period: slow_period,
|
|
47
|
+
signal_period: signal_period
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
51
|
+
if result.is_a?(Hash)
|
|
52
|
+
[result[:macd], result[:macd_signal], result[:macd_hist]]
|
|
53
|
+
else
|
|
54
|
+
result
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Stochastic Oscillator
|
|
59
|
+
# @param high [Array<Float>] High prices
|
|
60
|
+
# @param low [Array<Float>] Low prices
|
|
61
|
+
# @param close [Array<Float>] Close prices
|
|
62
|
+
# @param fastk_period [Integer] Fast K period (default: 5)
|
|
63
|
+
# @param slowk_period [Integer] Slow K period (default: 3)
|
|
64
|
+
# @param slowd_period [Integer] Slow D period (default: 3)
|
|
65
|
+
# @return [Array<Array<Float>>] [slowk, slowd]
|
|
66
|
+
def stoch(high, low, close, fastk_period: 5, slowk_period: 3, slowd_period: 3)
|
|
67
|
+
check_available!
|
|
68
|
+
validate_prices!(high)
|
|
69
|
+
validate_prices!(low)
|
|
70
|
+
validate_prices!(close)
|
|
71
|
+
|
|
72
|
+
result = TALibFFI.stoch(
|
|
73
|
+
high,
|
|
74
|
+
low,
|
|
75
|
+
close,
|
|
76
|
+
fastk_period: fastk_period,
|
|
77
|
+
slowk_period: slowk_period,
|
|
78
|
+
slowd_period: slowd_period
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
82
|
+
if result.is_a?(Hash)
|
|
83
|
+
[result[:slow_k], result[:slow_d]]
|
|
84
|
+
else
|
|
85
|
+
result
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Momentum
|
|
90
|
+
# @param prices [Array<Float>] Array of prices
|
|
91
|
+
# @param period [Integer] Time period (default: 10)
|
|
92
|
+
# @return [Array<Float>] Momentum values
|
|
93
|
+
def mom(prices, period: 10)
|
|
94
|
+
check_available!
|
|
95
|
+
validate_prices!(prices)
|
|
96
|
+
validate_period!(period, prices.size)
|
|
97
|
+
|
|
98
|
+
TALibFFI.mom(prices, time_period: period)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Commodity Channel Index
|
|
102
|
+
# @param high [Array<Float>] High prices
|
|
103
|
+
# @param low [Array<Float>] Low prices
|
|
104
|
+
# @param close [Array<Float>] Close prices
|
|
105
|
+
# @param period [Integer] Time period (default: 14)
|
|
106
|
+
# @return [Array<Float>] CCI values
|
|
107
|
+
def cci(high, low, close, period: 14)
|
|
108
|
+
check_available!
|
|
109
|
+
validate_prices!(high)
|
|
110
|
+
validate_prices!(low)
|
|
111
|
+
validate_prices!(close)
|
|
112
|
+
|
|
113
|
+
TALibFFI.cci(high, low, close, time_period: period)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Williams' %R
|
|
117
|
+
# @param high [Array<Float>] High prices
|
|
118
|
+
# @param low [Array<Float>] Low prices
|
|
119
|
+
# @param close [Array<Float>] Close prices
|
|
120
|
+
# @param period [Integer] Time period (default: 14)
|
|
121
|
+
# @return [Array<Float>] WILLR values
|
|
122
|
+
def willr(high, low, close, period: 14)
|
|
123
|
+
check_available!
|
|
124
|
+
validate_prices!(high)
|
|
125
|
+
validate_prices!(low)
|
|
126
|
+
validate_prices!(close)
|
|
127
|
+
|
|
128
|
+
TALibFFI.willr(high, low, close, time_period: period)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Rate of Change
|
|
132
|
+
# @param prices [Array<Float>] Array of prices
|
|
133
|
+
# @param period [Integer] Time period (default: 10)
|
|
134
|
+
# @return [Array<Float>] ROC values
|
|
135
|
+
def roc(prices, period: 10)
|
|
136
|
+
check_available!
|
|
137
|
+
validate_prices!(prices)
|
|
138
|
+
validate_period!(period, prices.size)
|
|
139
|
+
|
|
140
|
+
TALibFFI.roc(prices, time_period: period)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Rate of Change Percentage
|
|
144
|
+
# @param prices [Array<Float>] Array of prices
|
|
145
|
+
# @param period [Integer] Time period (default: 10)
|
|
146
|
+
# @return [Array<Float>] ROCP values
|
|
147
|
+
def rocp(prices, period: 10)
|
|
148
|
+
check_available!
|
|
149
|
+
validate_prices!(prices)
|
|
150
|
+
validate_period!(period, prices.size)
|
|
151
|
+
|
|
152
|
+
TALibFFI.rocp(prices, time_period: period)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Rate of Change Ratio
|
|
156
|
+
# @param prices [Array<Float>] Array of prices
|
|
157
|
+
# @param period [Integer] Time period (default: 10)
|
|
158
|
+
# @return [Array<Float>] ROCR values
|
|
159
|
+
def rocr(prices, period: 10)
|
|
160
|
+
check_available!
|
|
161
|
+
validate_prices!(prices)
|
|
162
|
+
validate_period!(period, prices.size)
|
|
163
|
+
|
|
164
|
+
TALibFFI.rocr(prices, time_period: period)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Percentage Price Oscillator
|
|
168
|
+
# @param prices [Array<Float>] Array of prices
|
|
169
|
+
# @param fast_period [Integer] Fast period (default: 12)
|
|
170
|
+
# @param slow_period [Integer] Slow period (default: 26)
|
|
171
|
+
# @param ma_type [Integer] Moving average type (default: 0)
|
|
172
|
+
# @return [Array<Float>] PPO values
|
|
173
|
+
def ppo(prices, fast_period: 12, slow_period: 26, ma_type: 0)
|
|
174
|
+
check_available!
|
|
175
|
+
validate_prices!(prices)
|
|
176
|
+
|
|
177
|
+
TALibFFI.ppo(prices, fast_period: fast_period, slow_period: slow_period, ma_type: ma_type)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Average Directional Movement Index
|
|
181
|
+
# @param high [Array<Float>] High prices
|
|
182
|
+
# @param low [Array<Float>] Low prices
|
|
183
|
+
# @param close [Array<Float>] Close prices
|
|
184
|
+
# @param period [Integer] Time period (default: 14)
|
|
185
|
+
# @return [Array<Float>] ADX values
|
|
186
|
+
def adx(high, low, close, period: 14)
|
|
187
|
+
check_available!
|
|
188
|
+
validate_prices!(high)
|
|
189
|
+
validate_prices!(low)
|
|
190
|
+
validate_prices!(close)
|
|
191
|
+
|
|
192
|
+
TALibFFI.adx(high, low, close, time_period: period)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Average Directional Movement Index Rating
|
|
196
|
+
# @param high [Array<Float>] High prices
|
|
197
|
+
# @param low [Array<Float>] Low prices
|
|
198
|
+
# @param close [Array<Float>] Close prices
|
|
199
|
+
# @param period [Integer] Time period (default: 14)
|
|
200
|
+
# @return [Array<Float>] ADXR values
|
|
201
|
+
def adxr(high, low, close, period: 14)
|
|
202
|
+
check_available!
|
|
203
|
+
validate_prices!(high)
|
|
204
|
+
validate_prices!(low)
|
|
205
|
+
validate_prices!(close)
|
|
206
|
+
|
|
207
|
+
TALibFFI.adxr(high, low, close, time_period: period)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Absolute Price Oscillator
|
|
211
|
+
# @param prices [Array<Float>] Array of prices
|
|
212
|
+
# @param fast_period [Integer] Fast period (default: 12)
|
|
213
|
+
# @param slow_period [Integer] Slow period (default: 26)
|
|
214
|
+
# @param ma_type [Integer] Moving average type (default: 0)
|
|
215
|
+
# @return [Array<Float>] APO values
|
|
216
|
+
def apo(prices, fast_period: 12, slow_period: 26, ma_type: 0)
|
|
217
|
+
check_available!
|
|
218
|
+
validate_prices!(prices)
|
|
219
|
+
|
|
220
|
+
TALibFFI.apo(prices, fast_period: fast_period, slow_period: slow_period, ma_type: ma_type)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Aroon
|
|
224
|
+
# @param high [Array<Float>] High prices
|
|
225
|
+
# @param low [Array<Float>] Low prices
|
|
226
|
+
# @param period [Integer] Time period (default: 14)
|
|
227
|
+
# @return [Array<Array<Float>>] [aroon_down, aroon_up]
|
|
228
|
+
def aroon(high, low, period: 14)
|
|
229
|
+
check_available!
|
|
230
|
+
validate_prices!(high)
|
|
231
|
+
validate_prices!(low)
|
|
232
|
+
|
|
233
|
+
result = TALibFFI.aroon(high, low, time_period: period)
|
|
234
|
+
|
|
235
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
236
|
+
if result.is_a?(Hash)
|
|
237
|
+
[result[:aroon_down], result[:aroon_up]]
|
|
238
|
+
else
|
|
239
|
+
result
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Aroon Oscillator
|
|
244
|
+
# @param high [Array<Float>] High prices
|
|
245
|
+
# @param low [Array<Float>] Low prices
|
|
246
|
+
# @param period [Integer] Time period (default: 14)
|
|
247
|
+
# @return [Array<Float>] AROONOSC values
|
|
248
|
+
def aroonosc(high, low, period: 14)
|
|
249
|
+
check_available!
|
|
250
|
+
validate_prices!(high)
|
|
251
|
+
validate_prices!(low)
|
|
252
|
+
|
|
253
|
+
TALibFFI.aroonosc(high, low, time_period: period)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Balance of Power
|
|
257
|
+
# @param open [Array<Float>] Open prices
|
|
258
|
+
# @param high [Array<Float>] High prices
|
|
259
|
+
# @param low [Array<Float>] Low prices
|
|
260
|
+
# @param close [Array<Float>] Close prices
|
|
261
|
+
# @return [Array<Float>] BOP values
|
|
262
|
+
def bop(open, high, low, close)
|
|
263
|
+
check_available!
|
|
264
|
+
validate_prices!(open)
|
|
265
|
+
validate_prices!(high)
|
|
266
|
+
validate_prices!(low)
|
|
267
|
+
validate_prices!(close)
|
|
268
|
+
|
|
269
|
+
TALibFFI.bop(open, high, low, close)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Chande Momentum Oscillator
|
|
273
|
+
# @param prices [Array<Float>] Array of prices
|
|
274
|
+
# @param period [Integer] Time period (default: 14)
|
|
275
|
+
# @return [Array<Float>] CMO values
|
|
276
|
+
def cmo(prices, period: 14)
|
|
277
|
+
check_available!
|
|
278
|
+
validate_prices!(prices)
|
|
279
|
+
validate_period!(period, prices.size)
|
|
280
|
+
|
|
281
|
+
TALibFFI.cmo(prices, time_period: period)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# Directional Movement Index
|
|
285
|
+
# @param high [Array<Float>] High prices
|
|
286
|
+
# @param low [Array<Float>] Low prices
|
|
287
|
+
# @param close [Array<Float>] Close prices
|
|
288
|
+
# @param period [Integer] Time period (default: 14)
|
|
289
|
+
# @return [Array<Float>] DX values
|
|
290
|
+
def dx(high, low, close, period: 14)
|
|
291
|
+
check_available!
|
|
292
|
+
validate_prices!(high)
|
|
293
|
+
validate_prices!(low)
|
|
294
|
+
validate_prices!(close)
|
|
295
|
+
|
|
296
|
+
TALibFFI.dx(high, low, close, time_period: period)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# MACD with Controllable MA Type
|
|
300
|
+
# @param prices [Array<Float>] Array of prices
|
|
301
|
+
# @param fast_period [Integer] Fast period (default: 12)
|
|
302
|
+
# @param fast_ma_type [Integer] Fast MA type (default: 0)
|
|
303
|
+
# @param slow_period [Integer] Slow period (default: 26)
|
|
304
|
+
# @param slow_ma_type [Integer] Slow MA type (default: 0)
|
|
305
|
+
# @param signal_period [Integer] Signal period (default: 9)
|
|
306
|
+
# @param signal_ma_type [Integer] Signal MA type (default: 0)
|
|
307
|
+
# @return [Array<Array<Float>>] [macd, signal, histogram]
|
|
308
|
+
def macdext(prices, fast_period: 12, fast_ma_type: 0, slow_period: 26, slow_ma_type: 0, signal_period: 9, signal_ma_type: 0)
|
|
309
|
+
check_available!
|
|
310
|
+
validate_prices!(prices)
|
|
311
|
+
|
|
312
|
+
result = TALibFFI.macdext(
|
|
313
|
+
prices,
|
|
314
|
+
fast_period: fast_period,
|
|
315
|
+
fast_ma_type: fast_ma_type,
|
|
316
|
+
slow_period: slow_period,
|
|
317
|
+
slow_ma_type: slow_ma_type,
|
|
318
|
+
signal_period: signal_period,
|
|
319
|
+
signal_ma_type: signal_ma_type
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
323
|
+
if result.is_a?(Hash)
|
|
324
|
+
[result[:macd], result[:macd_signal], result[:macd_hist]]
|
|
325
|
+
else
|
|
326
|
+
result
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# MACD Fix 12/26
|
|
331
|
+
# @param prices [Array<Float>] Array of prices
|
|
332
|
+
# @param signal_period [Integer] Signal period (default: 9)
|
|
333
|
+
# @return [Array<Array<Float>>] [macd, signal, histogram]
|
|
334
|
+
def macdfix(prices, signal_period: 9)
|
|
335
|
+
check_available!
|
|
336
|
+
validate_prices!(prices)
|
|
337
|
+
|
|
338
|
+
result = TALibFFI.macdfix(prices, signal_period: signal_period)
|
|
339
|
+
|
|
340
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
341
|
+
if result.is_a?(Hash)
|
|
342
|
+
[result[:macd], result[:macd_signal], result[:macd_hist]]
|
|
343
|
+
else
|
|
344
|
+
result
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Money Flow Index
|
|
349
|
+
# @param high [Array<Float>] High prices
|
|
350
|
+
# @param low [Array<Float>] Low prices
|
|
351
|
+
# @param close [Array<Float>] Close prices
|
|
352
|
+
# @param volume [Array<Float>] Volume values
|
|
353
|
+
# @param period [Integer] Time period (default: 14)
|
|
354
|
+
# @return [Array<Float>] MFI values
|
|
355
|
+
def mfi(high, low, close, volume, period: 14)
|
|
356
|
+
check_available!
|
|
357
|
+
validate_prices!(high)
|
|
358
|
+
validate_prices!(low)
|
|
359
|
+
validate_prices!(close)
|
|
360
|
+
validate_prices!(volume)
|
|
361
|
+
|
|
362
|
+
TALibFFI.mfi(high, low, close, volume, time_period: period)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Minus Directional Indicator
|
|
366
|
+
# @param high [Array<Float>] High prices
|
|
367
|
+
# @param low [Array<Float>] Low prices
|
|
368
|
+
# @param close [Array<Float>] Close prices
|
|
369
|
+
# @param period [Integer] Time period (default: 14)
|
|
370
|
+
# @return [Array<Float>] MINUS_DI values
|
|
371
|
+
def minus_di(high, low, close, period: 14)
|
|
372
|
+
check_available!
|
|
373
|
+
validate_prices!(high)
|
|
374
|
+
validate_prices!(low)
|
|
375
|
+
validate_prices!(close)
|
|
376
|
+
|
|
377
|
+
TALibFFI.minus_di(high, low, close, time_period: period)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# Minus Directional Movement
|
|
381
|
+
# @param high [Array<Float>] High prices
|
|
382
|
+
# @param low [Array<Float>] Low prices
|
|
383
|
+
# @param period [Integer] Time period (default: 14)
|
|
384
|
+
# @return [Array<Float>] MINUS_DM values
|
|
385
|
+
def minus_dm(high, low, period: 14)
|
|
386
|
+
check_available!
|
|
387
|
+
validate_prices!(high)
|
|
388
|
+
validate_prices!(low)
|
|
389
|
+
|
|
390
|
+
TALibFFI.minus_dm(high, low, time_period: period)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
# Plus Directional Indicator
|
|
394
|
+
# @param high [Array<Float>] High prices
|
|
395
|
+
# @param low [Array<Float>] Low prices
|
|
396
|
+
# @param close [Array<Float>] Close prices
|
|
397
|
+
# @param period [Integer] Time period (default: 14)
|
|
398
|
+
# @return [Array<Float>] PLUS_DI values
|
|
399
|
+
def plus_di(high, low, close, period: 14)
|
|
400
|
+
check_available!
|
|
401
|
+
validate_prices!(high)
|
|
402
|
+
validate_prices!(low)
|
|
403
|
+
validate_prices!(close)
|
|
404
|
+
|
|
405
|
+
TALibFFI.plus_di(high, low, close, time_period: period)
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Plus Directional Movement
|
|
409
|
+
# @param high [Array<Float>] High prices
|
|
410
|
+
# @param low [Array<Float>] Low prices
|
|
411
|
+
# @param period [Integer] Time period (default: 14)
|
|
412
|
+
# @return [Array<Float>] PLUS_DM values
|
|
413
|
+
def plus_dm(high, low, period: 14)
|
|
414
|
+
check_available!
|
|
415
|
+
validate_prices!(high)
|
|
416
|
+
validate_prices!(low)
|
|
417
|
+
|
|
418
|
+
TALibFFI.plus_dm(high, low, time_period: period)
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
# Rate of Change Ratio 100 scale
|
|
422
|
+
# @param prices [Array<Float>] Array of prices
|
|
423
|
+
# @param period [Integer] Time period (default: 10)
|
|
424
|
+
# @return [Array<Float>] ROCR100 values
|
|
425
|
+
def rocr100(prices, period: 10)
|
|
426
|
+
check_available!
|
|
427
|
+
validate_prices!(prices)
|
|
428
|
+
validate_period!(period, prices.size)
|
|
429
|
+
|
|
430
|
+
TALibFFI.rocr100(prices, time_period: period)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# Stochastic Fast
|
|
434
|
+
# @param high [Array<Float>] High prices
|
|
435
|
+
# @param low [Array<Float>] Low prices
|
|
436
|
+
# @param close [Array<Float>] Close prices
|
|
437
|
+
# @param fastk_period [Integer] Fast K period (default: 5)
|
|
438
|
+
# @param fastd_period [Integer] Fast D period (default: 3)
|
|
439
|
+
# @return [Array<Array<Float>>] [fastk, fastd]
|
|
440
|
+
def stochf(high, low, close, fastk_period: 5, fastd_period: 3)
|
|
441
|
+
check_available!
|
|
442
|
+
validate_prices!(high)
|
|
443
|
+
validate_prices!(low)
|
|
444
|
+
validate_prices!(close)
|
|
445
|
+
|
|
446
|
+
result = TALibFFI.stochf(
|
|
447
|
+
high,
|
|
448
|
+
low,
|
|
449
|
+
close,
|
|
450
|
+
fastk_period: fastk_period,
|
|
451
|
+
fastd_period: fastd_period
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
455
|
+
if result.is_a?(Hash)
|
|
456
|
+
[result[:fast_k], result[:fast_d]]
|
|
457
|
+
else
|
|
458
|
+
result
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# Stochastic RSI
|
|
463
|
+
# @param prices [Array<Float>] Array of prices
|
|
464
|
+
# @param period [Integer] Time period (default: 14)
|
|
465
|
+
# @param fastk_period [Integer] Fast K period (default: 5)
|
|
466
|
+
# @param fastd_period [Integer] Fast D period (default: 3)
|
|
467
|
+
# @return [Array<Array<Float>>] [fastk, fastd]
|
|
468
|
+
def stochrsi(prices, period: 14, fastk_period: 5, fastd_period: 3)
|
|
469
|
+
check_available!
|
|
470
|
+
validate_prices!(prices)
|
|
471
|
+
|
|
472
|
+
result = TALibFFI.stochrsi(
|
|
473
|
+
prices,
|
|
474
|
+
time_period: period,
|
|
475
|
+
fastk_period: fastk_period,
|
|
476
|
+
fastd_period: fastd_period
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
480
|
+
if result.is_a?(Hash)
|
|
481
|
+
[result[:fast_k], result[:fast_d]]
|
|
482
|
+
else
|
|
483
|
+
result
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA
|
|
488
|
+
# @param prices [Array<Float>] Array of prices
|
|
489
|
+
# @param period [Integer] Time period (default: 30)
|
|
490
|
+
# @return [Array<Float>] TRIX values
|
|
491
|
+
def trix(prices, period: 30)
|
|
492
|
+
check_available!
|
|
493
|
+
validate_prices!(prices)
|
|
494
|
+
validate_period!(period, prices.size)
|
|
495
|
+
|
|
496
|
+
TALibFFI.trix(prices, time_period: period)
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# Ultimate Oscillator
|
|
500
|
+
# @param high [Array<Float>] High prices
|
|
501
|
+
# @param low [Array<Float>] Low prices
|
|
502
|
+
# @param close [Array<Float>] Close prices
|
|
503
|
+
# @param period1 [Integer] First period (default: 7)
|
|
504
|
+
# @param period2 [Integer] Second period (default: 14)
|
|
505
|
+
# @param period3 [Integer] Third period (default: 28)
|
|
506
|
+
# @return [Array<Float>] ULTOSC values
|
|
507
|
+
def ultosc(high, low, close, period1: 7, period2: 14, period3: 28)
|
|
508
|
+
check_available!
|
|
509
|
+
validate_prices!(high)
|
|
510
|
+
validate_prices!(low)
|
|
511
|
+
validate_prices!(close)
|
|
512
|
+
|
|
513
|
+
TALibFFI.ultosc(high, low, close, time_period1: period1, time_period2: period2, time_period3: period3)
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
end
|