sqa-tai 0.1.0 → 0.1.2
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 +39 -0
- data/Gemfile.lock +1 -1
- data/README.md +30 -2
- data/Rakefile +69 -0
- data/lib/sqa/tai/cycle_indicators.rb +72 -0
- data/lib/sqa/tai/help/data.json +697 -0
- data/lib/sqa/tai/help/resource.rb +66 -0
- data/lib/sqa/tai/help.rb +41 -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 +73 -1792
- data/mkdocs.yml +8 -10
- metadata +12 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
|
|
5
|
+
module SQA
|
|
6
|
+
module TAI
|
|
7
|
+
module Help
|
|
8
|
+
# Represents help documentation for a specific indicator
|
|
9
|
+
class Resource
|
|
10
|
+
attr_reader :indicator, :name, :category, :url
|
|
11
|
+
|
|
12
|
+
def initialize(indicator, name, category, path)
|
|
13
|
+
@indicator = indicator
|
|
14
|
+
@name = name
|
|
15
|
+
@category = category
|
|
16
|
+
@url = "#{BASE_URL}/#{path}/"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns URI object for the documentation URL
|
|
20
|
+
# @return [URI::HTTPS]
|
|
21
|
+
def uri
|
|
22
|
+
@uri ||= URI.parse(@url)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Opens the documentation URL in the default browser
|
|
26
|
+
# @return [Resource] self for chaining
|
|
27
|
+
def open
|
|
28
|
+
if RbConfig::CONFIG["host_os"] =~ /darwin/
|
|
29
|
+
system("open", @url)
|
|
30
|
+
elsif RbConfig::CONFIG["host_os"] =~ /linux|bsd/
|
|
31
|
+
system("xdg-open", @url)
|
|
32
|
+
elsif RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
|
|
33
|
+
system("start", @url)
|
|
34
|
+
else
|
|
35
|
+
warn "Unable to open browser on this platform"
|
|
36
|
+
end
|
|
37
|
+
self
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Fetches the documentation content from the URL
|
|
41
|
+
# @return [String] HTML content of the documentation page
|
|
42
|
+
def fetch
|
|
43
|
+
require "net/http"
|
|
44
|
+
Net::HTTP.get(uri)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns formatted help information
|
|
48
|
+
# @return [String]
|
|
49
|
+
def to_s
|
|
50
|
+
category_label = @category.to_s.split('_').map(&:capitalize).join(' ')
|
|
51
|
+
<<~HELP
|
|
52
|
+
Indicator: #{@indicator.to_s.upcase} (#{@name})
|
|
53
|
+
Category: #{category_label}
|
|
54
|
+
Website: #{@url}
|
|
55
|
+
HELP
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns detailed information about the help resource
|
|
59
|
+
# @return [String]
|
|
60
|
+
def inspect
|
|
61
|
+
"#<SQA::TAI::Help::Resource #{indicator} (#{category}): #{url}>"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/sqa/tai/help.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module SQA
|
|
6
|
+
module TAI
|
|
7
|
+
# Help module containing documentation metadata and URLs
|
|
8
|
+
module Help
|
|
9
|
+
# Base URL for the documentation site
|
|
10
|
+
BASE_URL = "https://madbomber.github.io/sqa-tai"
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# Lazy-loaded indicator metadata
|
|
14
|
+
# @return [Hash] Indicator metadata with symbolized keys
|
|
15
|
+
def indicators
|
|
16
|
+
@indicators ||= load_indicators
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def load_indicators
|
|
22
|
+
json_path = File.join(__dir__, "help", "data.json")
|
|
23
|
+
json_data = File.read(json_path)
|
|
24
|
+
data = JSON.parse(json_data)
|
|
25
|
+
|
|
26
|
+
# Convert to symbol keys for Ruby idioms
|
|
27
|
+
data.transform_keys(&:to_sym).transform_values do |meta|
|
|
28
|
+
{
|
|
29
|
+
name: meta["name"],
|
|
30
|
+
category: meta["category"].to_sym,
|
|
31
|
+
path: meta["path"]
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Load help resource class
|
|
41
|
+
require_relative "help/resource"
|
|
@@ -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
|