indicator_hub 0.1.0

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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +551 -0
  6. data/Rakefile +12 -0
  7. data/exe/indicator_hub +4 -0
  8. data/lib/indicator_hub/calculation_helpers.rb +196 -0
  9. data/lib/indicator_hub/indicators/adi.rb +37 -0
  10. data/lib/indicator_hub/indicators/adtv.rb +27 -0
  11. data/lib/indicator_hub/indicators/adx.rb +102 -0
  12. data/lib/indicator_hub/indicators/ao.rb +39 -0
  13. data/lib/indicator_hub/indicators/atr.rb +45 -0
  14. data/lib/indicator_hub/indicators/base_indicator.rb +68 -0
  15. data/lib/indicator_hub/indicators/bb.rb +44 -0
  16. data/lib/indicator_hub/indicators/cci.rb +41 -0
  17. data/lib/indicator_hub/indicators/cmf.rb +54 -0
  18. data/lib/indicator_hub/indicators/cmo.rb +49 -0
  19. data/lib/indicator_hub/indicators/cr.rb +26 -0
  20. data/lib/indicator_hub/indicators/dc.rb +40 -0
  21. data/lib/indicator_hub/indicators/dlr.rb +27 -0
  22. data/lib/indicator_hub/indicators/dpo.rb +32 -0
  23. data/lib/indicator_hub/indicators/dr.rb +27 -0
  24. data/lib/indicator_hub/indicators/ema.rb +40 -0
  25. data/lib/indicator_hub/indicators/envelopes_ema.rb +36 -0
  26. data/lib/indicator_hub/indicators/eom.rb +48 -0
  27. data/lib/indicator_hub/indicators/fi.rb +45 -0
  28. data/lib/indicator_hub/indicators/ichimoku.rb +76 -0
  29. data/lib/indicator_hub/indicators/imi.rb +48 -0
  30. data/lib/indicator_hub/indicators/kc.rb +46 -0
  31. data/lib/indicator_hub/indicators/kst.rb +82 -0
  32. data/lib/indicator_hub/indicators/macd.rb +46 -0
  33. data/lib/indicator_hub/indicators/mfi.rb +62 -0
  34. data/lib/indicator_hub/indicators/mi.rb +81 -0
  35. data/lib/indicator_hub/indicators/nvi.rb +42 -0
  36. data/lib/indicator_hub/indicators/obv.rb +41 -0
  37. data/lib/indicator_hub/indicators/obv_mean.rb +42 -0
  38. data/lib/indicator_hub/indicators/pivot_points.rb +44 -0
  39. data/lib/indicator_hub/indicators/price_channel.rb +38 -0
  40. data/lib/indicator_hub/indicators/qstick.rb +36 -0
  41. data/lib/indicator_hub/indicators/rmi.rb +48 -0
  42. data/lib/indicator_hub/indicators/roc.rb +37 -0
  43. data/lib/indicator_hub/indicators/rsi.rb +67 -0
  44. data/lib/indicator_hub/indicators/sma.rb +32 -0
  45. data/lib/indicator_hub/indicators/so.rb +76 -0
  46. data/lib/indicator_hub/indicators/trix.rb +53 -0
  47. data/lib/indicator_hub/indicators/tsi.rb +67 -0
  48. data/lib/indicator_hub/indicators/uo.rb +67 -0
  49. data/lib/indicator_hub/indicators/vi.rb +54 -0
  50. data/lib/indicator_hub/indicators/volume_oscillator.rb +55 -0
  51. data/lib/indicator_hub/indicators/vpt.rb +35 -0
  52. data/lib/indicator_hub/indicators/vwap.rb +33 -0
  53. data/lib/indicator_hub/indicators/wilders_smoothing.rb +36 -0
  54. data/lib/indicator_hub/indicators/wma.rb +36 -0
  55. data/lib/indicator_hub/indicators/wr.rb +36 -0
  56. data/lib/indicator_hub/series.rb +79 -0
  57. data/lib/indicator_hub/talib_adapter.rb +23 -0
  58. data/lib/indicator_hub/validation.rb +49 -0
  59. data/lib/indicator_hub/version.rb +6 -0
  60. data/lib/indicator_hub.rb +485 -0
  61. data/sig/indicator_hub.rbs +4 -0
  62. metadata +112 -0
@@ -0,0 +1,485 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "indicator_hub/version"
4
+ require_relative "indicator_hub/calculation_helpers"
5
+ require_relative "indicator_hub/series"
6
+ require_relative "indicator_hub/indicators/adi"
7
+ require_relative "indicator_hub/indicators/adtv"
8
+ require_relative "indicator_hub/indicators/adx"
9
+ require_relative "indicator_hub/indicators/ao"
10
+ require_relative "indicator_hub/indicators/atr"
11
+ require_relative "indicator_hub/indicators/bb"
12
+ require_relative "indicator_hub/indicators/cci"
13
+ require_relative "indicator_hub/indicators/cmf"
14
+ require_relative "indicator_hub/indicators/cmo"
15
+ require_relative "indicator_hub/indicators/cr"
16
+ require_relative "indicator_hub/indicators/dc"
17
+ require_relative "indicator_hub/indicators/dlr"
18
+ require_relative "indicator_hub/indicators/dpo"
19
+ require_relative "indicator_hub/indicators/dr"
20
+ require_relative "indicator_hub/indicators/ema"
21
+ require_relative "indicator_hub/indicators/envelopes_ema"
22
+ require_relative "indicator_hub/indicators/eom"
23
+ require_relative "indicator_hub/indicators/fi"
24
+ require_relative "indicator_hub/indicators/ichimoku"
25
+ require_relative "indicator_hub/indicators/imi"
26
+ require_relative "indicator_hub/indicators/kc"
27
+ require_relative "indicator_hub/indicators/kst"
28
+ require_relative "indicator_hub/indicators/macd"
29
+ require_relative "indicator_hub/indicators/mfi"
30
+ require_relative "indicator_hub/indicators/mi"
31
+ require_relative "indicator_hub/indicators/nvi"
32
+ require_relative "indicator_hub/indicators/obv_mean"
33
+ require_relative "indicator_hub/indicators/obv"
34
+ require_relative "indicator_hub/indicators/pivot_points"
35
+ require_relative "indicator_hub/indicators/price_channel"
36
+ require_relative "indicator_hub/indicators/qstick"
37
+ require_relative "indicator_hub/indicators/rmi"
38
+ require_relative "indicator_hub/indicators/roc"
39
+ require_relative "indicator_hub/indicators/rsi"
40
+ require_relative "indicator_hub/indicators/sma"
41
+ require_relative "indicator_hub/indicators/so"
42
+ require_relative "indicator_hub/indicators/trix"
43
+ require_relative "indicator_hub/indicators/tsi"
44
+ require_relative "indicator_hub/indicators/uo"
45
+ require_relative "indicator_hub/indicators/vi"
46
+ require_relative "indicator_hub/indicators/volume_oscillator"
47
+ require_relative "indicator_hub/indicators/vpt"
48
+ require_relative "indicator_hub/indicators/vwap"
49
+ require_relative "indicator_hub/indicators/wilders_smoothing"
50
+ require_relative "indicator_hub/indicators/wma"
51
+ require_relative "indicator_hub/indicators/wr"
52
+
53
+ # Base module for IndicatorHub technical analysis library.
54
+ module IndicatorHub
55
+ # Generic error class for all IndicatorHub errors.
56
+ class Error < StandardError; end
57
+
58
+ # Main API for technical analysis indicators
59
+
60
+ # Group 1: Single Series Indicators (Usually :close)
61
+
62
+ # Calculates the Simple Moving Average (SMA).
63
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
64
+ # @param period [Integer] The SMA period.
65
+ # @param field [Symbol] The field to use if data is an array of hashes.
66
+ # @return [Array<Float, nil>] The calculated SMA values.
67
+ def self.sma(data, period: 20, field: :close)
68
+ Indicators::SMA.new(data, period: period, field: field).calculate
69
+ end
70
+
71
+ # Calculates the Exponential Moving Average (EMA).
72
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
73
+ # @param period [Integer] The EMA period.
74
+ # @param field [Symbol] The field to use if data is an array of hashes.
75
+ # @return [Array<Float, nil>] The calculated EMA values.
76
+ def self.ema(data, period: 20, field: :close)
77
+ Indicators::EMA.calculate(normalize_series(data, field), period: period)
78
+ end
79
+
80
+ # Calculates the Weighted Moving Average (WMA).
81
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
82
+ # @param period [Integer] The WMA period.
83
+ # @param field [Symbol] The field to use if data is an array of hashes.
84
+ # @return [Array<Float, nil>] The calculated WMA values.
85
+ def self.wma(data, period: 20, field: :close)
86
+ Indicators::WMA.calculate(normalize_series(data, field), period: period)
87
+ end
88
+
89
+ # Calculates the Relative Strength Index (RSI).
90
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
91
+ # @param period [Integer] The RSI period.
92
+ # @param field [Symbol] The field to use if data is an array of hashes.
93
+ # @return [Array<Float, nil>] The calculated RSI values.
94
+ def self.rsi(data, period: 14, field: :close)
95
+ Indicators::RSI.calculate(normalize_series(data, field), period: period)
96
+ end
97
+
98
+ # Calculates the Chande Momentum Oscillator (CMO).
99
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
100
+ # @param period [Integer] The CMO period.
101
+ # @param field [Symbol] The field to use if data is an array of hashes.
102
+ # @return [Array<Float, nil>] The calculated CMO values.
103
+ def self.cmo(data, period: 14, field: :close)
104
+ Indicators::CMO.calculate(normalize_series(data, field), period: period)
105
+ end
106
+
107
+ # Calculates the Daily Log Return (DLR).
108
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
109
+ # @param field [Symbol] The field to use if data is an array of hashes.
110
+ # @return [Array<Float, nil>] The calculated DLR values.
111
+ def self.dlr(data, field: :close)
112
+ Indicators::DLR.calculate(normalize_series(data, field))
113
+ end
114
+
115
+ # Calculates the Detrended Price Oscillator (DPO).
116
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
117
+ # @param period [Integer] The DPO period.
118
+ # @param field [Symbol] The field to use if data is an array of hashes.
119
+ # @return [Array<Float, nil>] The calculated DPO values.
120
+ def self.dpo(data, period: 20, field: :close)
121
+ Indicators::DPO.calculate(normalize_series(data, field), period: period)
122
+ end
123
+
124
+ # Calculates the Daily Return (DR).
125
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
126
+ # @param field [Symbol] The field to use if data is an array of hashes.
127
+ # @return [Array<Float, nil>] The calculated DR values.
128
+ def self.dr(data, field: :close)
129
+ Indicators::DR.calculate(normalize_series(data, field))
130
+ end
131
+
132
+ # Calculates the Rate of Change (ROC).
133
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
134
+ # @param period [Integer] The ROC period.
135
+ # @param field [Symbol] The field to use if data is an array of hashes.
136
+ # @return [Array<Float, nil>] The calculated ROC values.
137
+ def self.roc(data, period: 12, field: :close)
138
+ Indicators::ROC.calculate(normalize_series(data, field), period: period)
139
+ end
140
+
141
+ # Calculates the TRIX (Triple Exponential Average).
142
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
143
+ # @param period [Integer] The TRIX period.
144
+ # @param field [Symbol] The field to use if data is an array of hashes.
145
+ # @return [Array<Float, nil>] The calculated TRIX values.
146
+ def self.trix(data, period: 15, field: :close)
147
+ Indicators::TRIX.calculate(normalize_series(data, field), period: period)
148
+ end
149
+
150
+ # Calculates the True Strength Index (TSI).
151
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
152
+ # @param fast_period [Integer] The fast TSI period.
153
+ # @param slow_period [Integer] The slow TSI period.
154
+ # @param field [Symbol] The field to use if data is an array of hashes.
155
+ # @return [Array<Float, nil>] The calculated TSI values.
156
+ def self.tsi(data, fast_period: 13, slow_period: 25, field: :close)
157
+ Indicators::TSI.calculate(normalize_series(data, field), fast_period: fast_period, slow_period: slow_period)
158
+ end
159
+
160
+ # Calculates Wilder's Smoothing.
161
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
162
+ # @param period [Integer] The smoothing period.
163
+ # @param field [Symbol] The field to use if data is an array of hashes.
164
+ # @return [Array<Float, nil>] The calculated values.
165
+ def self.wilders_smoothing(data, period: 14, field: :close)
166
+ Indicators::WildersSmoothing.calculate(normalize_series(data, field), period: period)
167
+ end
168
+
169
+ # Group 2: OHLCV Indicators
170
+
171
+ # Calculates the Accumulation/Distribution Index (ADI).
172
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
173
+ # @return [Array<Float, nil>] The calculated ADI values.
174
+ def self.adi(data)
175
+ Indicators::ADI.calculate(normalize_ohlcv(data))
176
+ end
177
+
178
+ # Calculates the Average Daily Trading Volume (ADTV).
179
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
180
+ # @param period [Integer] The ADTV period.
181
+ # @return [Array<Float, nil>] The calculated ADTV values.
182
+ def self.adtv(data, period: 20)
183
+ Indicators::ADTV.calculate(normalize_ohlcv(data), period: period)
184
+ end
185
+
186
+ # Calculates the Average Directional Index (ADX).
187
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
188
+ # @param period [Integer] The ADX period.
189
+ # @return [Array<Float, nil>] The calculated ADX values.
190
+ def self.adx(data, period: 14)
191
+ Indicators::ADX.calculate(normalize_ohlcv(data), period: period)
192
+ end
193
+
194
+ # Calculates the Awesome Oscillator (AO).
195
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
196
+ # @param short_period [Integer] The short AO period.
197
+ # @param long_period [Integer] The long AO period.
198
+ # @return [Array<Float, nil>] The calculated AO values.
199
+ def self.ao(data, short_period: 5, long_period: 34)
200
+ Indicators::AO.calculate(normalize_ohlcv(data), short_period: short_period, long_period: long_period)
201
+ end
202
+
203
+ # Calculates the Average True Range (ATR).
204
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
205
+ # @param period [Integer] The ATR period.
206
+ # @return [Array<Float, nil>] The calculated ATR values.
207
+ def self.atr(data, period: 14)
208
+ Indicators::ATR.calculate(normalize_ohlcv(data), period: period)
209
+ end
210
+
211
+ # Calculates Bollinger Bands (BB).
212
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
213
+ # @param period [Integer] The BB period.
214
+ # @param standard_deviations [Numeric] The number of standard deviations.
215
+ # @param field [Symbol] The field to use if data is an array of hashes.
216
+ # @return [Array<Float, nil>] The calculated BB values.
217
+ def self.bb(data, period: 20, standard_deviations: 2, field: :close)
218
+ Indicators::BB.calculate(normalize_series(data, field), period: period, standard_deviations: standard_deviations)
219
+ end
220
+
221
+ # Calculates the Commodity Channel Index (CCI).
222
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
223
+ # @param period [Integer] The CCI period.
224
+ # @return [Array<Float, nil>] The calculated CCI values.
225
+ def self.cci(data, period: 20)
226
+ Indicators::CCI.calculate(normalize_ohlcv(data), period: period)
227
+ end
228
+
229
+ # Calculates the Chaikin Money Flow (CMF).
230
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
231
+ # @param period [Integer] The CMF period.
232
+ # @return [Array<Float, nil>] The calculated CMF values.
233
+ def self.cmf(data, period: 20)
234
+ Indicators::CMF.calculate(normalize_ohlcv(data), period: period)
235
+ end
236
+
237
+ # Calculates the CR Indicator.
238
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
239
+ # @param period [Integer] The CR period.
240
+ # @param field [Symbol] The field to use if data is an array of hashes.
241
+ # @return [Array<Float, nil>] The calculated CR values.
242
+ def self.cr(data, period: 20, field: :close)
243
+ Indicators::CR.calculate(normalize_series(data, field), period: period)
244
+ end
245
+
246
+ # Calculates the Donchian Channel (DC).
247
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
248
+ # @param period [Integer] The DC period.
249
+ # @return [Array<Float, nil>] The calculated DC values.
250
+ def self.dc(data, period: 20)
251
+ Indicators::DC.calculate(normalize_ohlcv(data), period: period)
252
+ end
253
+
254
+ # Calculates Envelopes using EMA.
255
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
256
+ # @param period [Integer] The EMA period.
257
+ # @param percentage [Numeric] The envelope percentage.
258
+ # @param field [Symbol] The field to use if data is an array of hashes.
259
+ # @return [Array<Float, nil>] The calculated envelope values.
260
+ def self.envelopes_ema(data, period: 20, percentage: 2.5, field: :close)
261
+ Indicators::EnvelopesEMA.calculate(normalize_series(data, field), period: period, percentage: percentage)
262
+ end
263
+
264
+ # Calculates Ease of Movement (EOM).
265
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
266
+ # @param period [Integer] The EOM period.
267
+ # @return [Array<Float, nil>] The calculated EOM values.
268
+ def self.eom(data, period: 14)
269
+ Indicators::EOM.calculate(normalize_ohlcv(data), period: period)
270
+ end
271
+
272
+ # Calculates the Force Index (FI).
273
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
274
+ # @param period [Integer] The FI period.
275
+ # @return [Array<Float, nil>] The calculated FI values.
276
+ def self.fi(data, period: 13)
277
+ Indicators::FI.calculate(normalize_ohlcv(data), period: period)
278
+ end
279
+
280
+ # Calculates the Ichimoku Cloud.
281
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
282
+ # @param low_period [Integer] The low period.
283
+ # @param medium_period [Integer] The medium period.
284
+ # @param high_period [Integer] The high period.
285
+ # @return [Array<Float, nil>] The calculated Ichimoku values.
286
+ def self.ichimoku(data, low_period: 9, medium_period: 26, high_period: 52)
287
+ Indicators::Ichimoku.calculate(normalize_ohlcv(data), low_period: low_period, medium_period: medium_period,
288
+ high_period: high_period)
289
+ end
290
+
291
+ # Calculates the Intraday Momentum Index (IMI).
292
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
293
+ # @param period [Integer] The IMI period.
294
+ # @return [Array<Float, nil>] The calculated IMI values.
295
+ def self.imi(data, period: 14)
296
+ Indicators::IMI.calculate(normalize_ohlcv(data), period: period)
297
+ end
298
+
299
+ # Calculates Keltner Channels (KC).
300
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
301
+ # @param period [Integer] The KC period.
302
+ # @param multiplier [Numeric] The multiplier for the channel width.
303
+ # @return [Array<Float, nil>] The calculated KC values.
304
+ def self.kc(data, period: 20, multiplier: 1.5)
305
+ Indicators::KC.calculate(normalize_ohlcv(data), period: period, multiplier: multiplier)
306
+ end
307
+
308
+ # Calculates the Know Sure Thing (KST) oscillator.
309
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
310
+ # @param r1 [Integer] ROC period 1.
311
+ # @param r2 [Integer] ROC period 2.
312
+ # @param r3 [Integer] ROC period 3.
313
+ # @param r4 [Integer] ROC period 4.
314
+ # @param s1 [Integer] Smoothing period 1.
315
+ # @param s2 [Integer] Smoothing period 2.
316
+ # @param s3 [Integer] Smoothing period 3.
317
+ # @param s4 [Integer] Smoothing period 4.
318
+ # @param signal [Integer] Signal line period.
319
+ # @return [Array<Float, nil>] The calculated KST values.
320
+ def self.kst(data, r1: 10, r2: 15, r3: 20, r4: 30, s1: 10, s2: 10, s3: 10, s4: 15, signal: 9)
321
+ Indicators::KST.calculate(normalize_series(data, :close), r1: r1, r2: r2, r3: r3, r4: r4, s1: s1, s2: s2, s3: s3,
322
+ s4: s4, signal: signal)
323
+ end
324
+
325
+ # Calculates the Moving Average Convergence Divergence (MACD).
326
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
327
+ # @param fast_period [Integer] The fast MACD period.
328
+ # @param slow_period [Integer] The slow MACD period.
329
+ # @param signal_period [Integer] The signal line period.
330
+ # @param field [Symbol] The field to use if data is an array of hashes.
331
+ # @return [Array<Float, nil>] The calculated MACD values.
332
+ def self.macd(data, fast_period: 12, slow_period: 26, signal_period: 9, field: :close)
333
+ Indicators::MACD.calculate(normalize_series(data, field), fast_period: fast_period, slow_period: slow_period,
334
+ signal_period: signal_period)
335
+ end
336
+
337
+ # Calculates the Money Flow Index (MFI).
338
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
339
+ # @param period [Integer] The MFI period.
340
+ # @return [Array<Float, nil>] The calculated MFI values.
341
+ def self.mfi(data, period: 14)
342
+ Indicators::MFI.calculate(normalize_ohlcv(data), period: period)
343
+ end
344
+
345
+ # Calculates the Mass Index (MI).
346
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
347
+ # @param period [Integer] The MI period.
348
+ # @return [Array<Float, nil>] The calculated MI values.
349
+ def self.mi(data, period: 25)
350
+ Indicators::MI.calculate(normalize_ohlcv(data), period: period)
351
+ end
352
+
353
+ # Calculates the Negative Volume Index (NVI).
354
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
355
+ # @return [Array<Float, nil>] The calculated NVI values.
356
+ def self.nvi(data)
357
+ Indicators::NVI.calculate(normalize_ohlcv(data))
358
+ end
359
+
360
+ # Calculates the On-Balance Volume (OBV).
361
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
362
+ # @return [Array<Float, nil>] The calculated OBV values.
363
+ def self.obv(data)
364
+ Indicators::OBV.calculate(normalize_ohlcv(data))
365
+ end
366
+
367
+ # Calculates the Mean of On-Balance Volume (OBV Mean).
368
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
369
+ # @param period [Integer] The OBV Mean period.
370
+ # @return [Array<Float, nil>] The calculated OBV Mean values.
371
+ def self.obv_mean(data, period: 10)
372
+ Indicators::OBVMean.calculate(normalize_ohlcv(data), period: period)
373
+ end
374
+
375
+ # Calculates Pivot Points.
376
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
377
+ # @return [Array<Float, nil>] The calculated pivot points.
378
+ def self.pivot_points(data)
379
+ Indicators::PivotPoints.calculate(normalize_ohlcv(data))
380
+ end
381
+
382
+ # Calculates the Price Channel.
383
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
384
+ # @param period [Integer] The price channel period.
385
+ # @return [Array<Float, nil>] The calculated price channel values.
386
+ def self.price_channel(data, period: 20)
387
+ Indicators::PriceChannel.calculate(normalize_ohlcv(data), period: period)
388
+ end
389
+
390
+ # Calculates the QStick indicator.
391
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
392
+ # @param period [Integer] The QStick period.
393
+ # @return [Array<Float, nil>] The calculated QStick values.
394
+ def self.qstick(data, period: 10)
395
+ Indicators::QStick.calculate(normalize_ohlcv(data), period: period)
396
+ end
397
+
398
+ # Calculates the Range Momentum Index (RMI).
399
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
400
+ # @param period [Integer] The RMI period.
401
+ # @param momentum_period [Integer] The momentum period.
402
+ # @return [Array<Float, nil>] The calculated RMI values.
403
+ def self.rmi(data, period: 14, momentum_period: 5)
404
+ Indicators::RMI.calculate(normalize_series(data, :close), period: period, momentum_period: momentum_period)
405
+ end
406
+
407
+ # Calculates the Stochastic Oscillator (SO).
408
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
409
+ # @param k_period [Integer] The %K period.
410
+ # @param k_slowing [Integer] The %K slowing period.
411
+ # @param d_period [Integer] The %D period.
412
+ # @return [Array<Float, nil>] The calculated SO values.
413
+ def self.so(data, k_period: 14, k_slowing: 3, d_period: 3)
414
+ Indicators::SO.calculate(normalize_ohlcv(data), k_period: k_period, k_slowing: k_slowing, d_period: d_period)
415
+ end
416
+
417
+ # Calculates the Ultimate Oscillator (UO).
418
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
419
+ # @param short_period [Integer] The short UO period.
420
+ # @param medium_period [Integer] The medium UO period.
421
+ # @param long_period [Integer] The long UO period.
422
+ # @return [Array<Float, nil>] The calculated UO values.
423
+ def self.uo(data, short_period: 7, medium_period: 14, long_period: 28)
424
+ Indicators::UO.calculate(normalize_ohlcv(data), short_period: short_period, medium_period: medium_period,
425
+ long_period: long_period)
426
+ end
427
+
428
+ # Calculates the Vortex Indicator (VI).
429
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
430
+ # @param period [Integer] The VI period.
431
+ # @return [Array<Float, nil>] The calculated VI values.
432
+ def self.vi(data, period: 14)
433
+ Indicators::VI.calculate(normalize_ohlcv(data), period: period)
434
+ end
435
+
436
+ # Calculates the Volume Oscillator.
437
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
438
+ # @param short_period [Integer] The short oscillator period.
439
+ # @param long_period [Integer] The long oscillator period.
440
+ # @return [Array<Float, nil>] The calculated volume oscillator values.
441
+ def self.volume_oscillator(data, short_period: 20, long_period: 60)
442
+ Indicators::VolumeOscillator.calculate(normalize_ohlcv(data), short_period: short_period, long_period: long_period)
443
+ end
444
+
445
+ # Calculates the Volume Price Trend (VPT).
446
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
447
+ # @return [Array<Float, nil>] The calculated VPT values.
448
+ def self.vpt(data)
449
+ Indicators::VPT.calculate(normalize_ohlcv(data))
450
+ end
451
+
452
+ # Calculates the Volume Weighted Average Price (VWAP).
453
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
454
+ # @return [Array<Float, nil>] The calculated VWAP values.
455
+ def self.vwap(data)
456
+ Indicators::VWAP.calculate(normalize_ohlcv(data))
457
+ end
458
+
459
+ # Calculates Williams %R (WR).
460
+ # @param data [Array<Hash, Numeric>] The input data (array of hashes or numbers).
461
+ # @param period [Integer] The WR period.
462
+ # @return [Array<Float, nil>] The calculated WR values.
463
+ def self.wr(data, period: 14)
464
+ Indicators::WR.calculate(normalize_ohlcv(data), period: period)
465
+ end
466
+
467
+ # ---- Private helpers ----
468
+
469
+ # Normalizes data to a numeric array using Series.
470
+ # @param data [Array] Raw input data.
471
+ # @param field [Symbol] The field to extract.
472
+ # @return [Array<Float>] Normalized numeric array.
473
+ def self.normalize_series(data, field = :close)
474
+ Series.new(data).to_a(field: field)
475
+ end
476
+ private_class_method :normalize_series
477
+
478
+ # Normalizes data to OHLCV hash array using Series.
479
+ # @param data [Array] Raw input data.
480
+ # @return [Array<Hash>] Normalized OHLCV array.
481
+ def self.normalize_ohlcv(data)
482
+ Series.new(data).to_ohlc
483
+ end
484
+ private_class_method :normalize_ohlcv
485
+ end
@@ -0,0 +1,4 @@
1
+ module IndicatorHub
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: indicator_hub
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Shubham Taywade
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-03-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: IndicatorHub provides a clean, idiomatic interface for technical analysis
14
+ by aggregating multiple Ruby gems (ruby-technical-analysis, technical-analysis,
15
+ indicators) and optionally leveraging TA-Lib for high performance.
16
+ email:
17
+ - shubhamtaywade82@gmail.com
18
+ executables:
19
+ - indicator_hub
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - CHANGELOG.md
24
+ - CODE_OF_CONDUCT.md
25
+ - LICENSE.txt
26
+ - README.md
27
+ - Rakefile
28
+ - exe/indicator_hub
29
+ - lib/indicator_hub.rb
30
+ - lib/indicator_hub/calculation_helpers.rb
31
+ - lib/indicator_hub/indicators/adi.rb
32
+ - lib/indicator_hub/indicators/adtv.rb
33
+ - lib/indicator_hub/indicators/adx.rb
34
+ - lib/indicator_hub/indicators/ao.rb
35
+ - lib/indicator_hub/indicators/atr.rb
36
+ - lib/indicator_hub/indicators/base_indicator.rb
37
+ - lib/indicator_hub/indicators/bb.rb
38
+ - lib/indicator_hub/indicators/cci.rb
39
+ - lib/indicator_hub/indicators/cmf.rb
40
+ - lib/indicator_hub/indicators/cmo.rb
41
+ - lib/indicator_hub/indicators/cr.rb
42
+ - lib/indicator_hub/indicators/dc.rb
43
+ - lib/indicator_hub/indicators/dlr.rb
44
+ - lib/indicator_hub/indicators/dpo.rb
45
+ - lib/indicator_hub/indicators/dr.rb
46
+ - lib/indicator_hub/indicators/ema.rb
47
+ - lib/indicator_hub/indicators/envelopes_ema.rb
48
+ - lib/indicator_hub/indicators/eom.rb
49
+ - lib/indicator_hub/indicators/fi.rb
50
+ - lib/indicator_hub/indicators/ichimoku.rb
51
+ - lib/indicator_hub/indicators/imi.rb
52
+ - lib/indicator_hub/indicators/kc.rb
53
+ - lib/indicator_hub/indicators/kst.rb
54
+ - lib/indicator_hub/indicators/macd.rb
55
+ - lib/indicator_hub/indicators/mfi.rb
56
+ - lib/indicator_hub/indicators/mi.rb
57
+ - lib/indicator_hub/indicators/nvi.rb
58
+ - lib/indicator_hub/indicators/obv.rb
59
+ - lib/indicator_hub/indicators/obv_mean.rb
60
+ - lib/indicator_hub/indicators/pivot_points.rb
61
+ - lib/indicator_hub/indicators/price_channel.rb
62
+ - lib/indicator_hub/indicators/qstick.rb
63
+ - lib/indicator_hub/indicators/rmi.rb
64
+ - lib/indicator_hub/indicators/roc.rb
65
+ - lib/indicator_hub/indicators/rsi.rb
66
+ - lib/indicator_hub/indicators/sma.rb
67
+ - lib/indicator_hub/indicators/so.rb
68
+ - lib/indicator_hub/indicators/trix.rb
69
+ - lib/indicator_hub/indicators/tsi.rb
70
+ - lib/indicator_hub/indicators/uo.rb
71
+ - lib/indicator_hub/indicators/vi.rb
72
+ - lib/indicator_hub/indicators/volume_oscillator.rb
73
+ - lib/indicator_hub/indicators/vpt.rb
74
+ - lib/indicator_hub/indicators/vwap.rb
75
+ - lib/indicator_hub/indicators/wilders_smoothing.rb
76
+ - lib/indicator_hub/indicators/wma.rb
77
+ - lib/indicator_hub/indicators/wr.rb
78
+ - lib/indicator_hub/series.rb
79
+ - lib/indicator_hub/talib_adapter.rb
80
+ - lib/indicator_hub/validation.rb
81
+ - lib/indicator_hub/version.rb
82
+ - sig/indicator_hub.rbs
83
+ homepage: https://github.com/shubhamtaywade/indicator_hub
84
+ licenses:
85
+ - MIT
86
+ metadata:
87
+ allowed_push_host: https://rubygems.org
88
+ homepage_uri: https://github.com/shubhamtaywade/indicator_hub
89
+ source_code_uri: https://github.com/shubhamtaywade/indicator_hub/tree/main
90
+ documentation_uri: https://github.com/shubhamtaywade/indicator_hub#readme
91
+ changelog_uri: https://github.com/shubhamtaywade/indicator_hub/blob/main/CHANGELOG.md
92
+ rubygems_mfa_required: 'true'
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: 3.2.0
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.5.11
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: A unified interface for technical analysis indicators in Ruby.
112
+ test_files: []