sqa-tai 0.1.2 → 0.4.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.
@@ -3,6 +3,13 @@
3
3
  module SQA
4
4
  module TAI
5
5
  # Volatility Indicators
6
+ #
7
+ # :reek:DataClump and :reek:LongParameterList -- these methods
8
+ # intentionally mirror TA-Lib's own C function signatures (separate
9
+ # high/low/close/period args, up to 7 for sarext); bundling them into
10
+ # a value object would be a breaking public API change for this gem
11
+ # and its downstream consumers (sqa, sqa-cli, sqa-advisor) and their
12
+ # 133 published indicator doc pages.
6
13
  module VolatilityIndicators
7
14
  # Average True Range
8
15
  # @param high [Array<Float>] High prices
@@ -16,7 +23,7 @@ module SQA
16
23
  validate_prices!(low)
17
24
  validate_prices!(close)
18
25
 
19
- TALibFFI.atr(high, low, close, time_period: period)
26
+ Native.atr([high, low, close], time_period: period)
20
27
  end
21
28
 
22
29
  # True Range
@@ -30,7 +37,7 @@ module SQA
30
37
  validate_prices!(low)
31
38
  validate_prices!(close)
32
39
 
33
- TALibFFI.trange(high, low, close)
40
+ Native.trange([high, low, close])
34
41
  end
35
42
 
36
43
  # Normalized Average True Range
@@ -45,7 +52,7 @@ module SQA
45
52
  validate_prices!(low)
46
53
  validate_prices!(close)
47
54
 
48
- TALibFFI.natr(high, low, close, time_period: period)
55
+ Native.natr([high, low, close], time_period: period)
49
56
  end
50
57
 
51
58
  # Parabolic SAR
@@ -59,7 +66,7 @@ module SQA
59
66
  validate_prices!(high)
60
67
  validate_prices!(low)
61
68
 
62
- TALibFFI.sar(high, low, acceleration: acceleration, maximum: maximum)
69
+ Native.sar([high, low], acceleration:, maximum:)
63
70
  end
64
71
 
65
72
  # Parabolic SAR - Extended
@@ -71,17 +78,18 @@ module SQA
71
78
  # @param acceleration_step [Float] Acceleration step (default: 0.02)
72
79
  # @param acceleration_max [Float] Acceleration max (default: 0.20)
73
80
  # @return [Array<Float>] SAREXT values
74
- def sarext(high, low, start_value: 0.0, offset_on_reverse: 0.0, acceleration_init: 0.02, acceleration_step: 0.02, acceleration_max: 0.20)
81
+ def sarext(high, low, start_value: 0.0, offset_on_reverse: 0.0, acceleration_init: 0.02, acceleration_step: 0.02,
82
+ acceleration_max: 0.20)
75
83
  check_available!
76
84
  validate_prices!(high)
77
85
  validate_prices!(low)
78
86
 
79
- TALibFFI.sarext(high, low,
80
- start_value: start_value,
81
- offset_on_reverse: offset_on_reverse,
82
- af_init: acceleration_init,
83
- af_increment: acceleration_step,
84
- af_max: acceleration_max)
87
+ Native.sarext([high, low],
88
+ start_value:,
89
+ offset_on_reverse:,
90
+ af_init: acceleration_init,
91
+ af_increment: acceleration_step,
92
+ af_max: acceleration_max)
85
93
  end
86
94
 
87
95
  # Acceleration Bands
@@ -97,14 +105,8 @@ module SQA
97
105
  validate_prices!(close)
98
106
  validate_period!(period, [high.size, low.size, close.size].min)
99
107
 
100
- result = TALibFFI.accbands(high, low, close, time_period: period)
101
-
102
- # Handle hash return format from newer ta_lib_ffi versions
103
- if result.is_a?(Hash)
104
- [result[:upper_band], result[:middle_band], result[:lower_band]]
105
- else
106
- result
107
- end
108
+ result = Native.accbands([high, low, close], time_period: period)
109
+ [result[:upper_band], result[:middle_band], result[:lower_band]]
108
110
  end
109
111
 
110
112
  # Hilbert Transform - Instantaneous Trendline
@@ -114,7 +116,7 @@ module SQA
114
116
  check_available!
115
117
  validate_prices!(prices)
116
118
 
117
- TALibFFI.ht_trendline(prices)
119
+ Native.ht_trendline(prices)
118
120
  end
119
121
 
120
122
  # MESA Adaptive Moving Average
@@ -126,14 +128,8 @@ module SQA
126
128
  check_available!
127
129
  validate_prices!(prices)
128
130
 
129
- result = TALibFFI.mama(prices, fastlimit: fast_limit, slowlimit: slow_limit)
130
-
131
- # Handle hash return format from newer ta_lib_ffi versions
132
- if result.is_a?(Hash)
133
- [result[:mama], result[:fama]]
134
- else
135
- result
136
- end
131
+ result = Native.mama(prices, fastlimit: fast_limit, slowlimit: slow_limit)
132
+ [result[:mama], result[:fama]]
137
133
  end
138
134
 
139
135
  # Moving Average with Variable Period
@@ -146,7 +142,7 @@ module SQA
146
142
  validate_prices!(prices)
147
143
  validate_prices!(periods)
148
144
 
149
- TALibFFI.mavp(prices, periods, ma_type: ma_type)
145
+ Native.mavp(prices, periods, ma_type:)
150
146
  end
151
147
 
152
148
  # Midpoint over period
@@ -158,7 +154,7 @@ module SQA
158
154
  validate_prices!(prices)
159
155
  validate_period!(period, prices.size)
160
156
 
161
- TALibFFI.midpoint(prices, time_period: period)
157
+ Native.midpoint(prices, time_period: period)
162
158
  end
163
159
 
164
160
  # Midpoint Price over period
@@ -172,7 +168,7 @@ module SQA
172
168
  validate_prices!(low)
173
169
  validate_period!(period, [high.size, low.size].min)
174
170
 
175
- TALibFFI.midprice(high, low, time_period: period)
171
+ Native.midprice([high, low], time_period: period)
176
172
  end
177
173
  end
178
174
  end
@@ -13,7 +13,10 @@ module SQA
13
13
  validate_prices!(close)
14
14
  validate_prices!(volume)
15
15
 
16
- TALibFFI.obv(close, volume)
16
+ # OBV's second parameter is a TA_Input_Price bundle consisting of
17
+ # just the VOLUME flag, so it's still wrapped in an array even
18
+ # though it's a single series.
19
+ Native.obv(close, [volume])
17
20
  end
18
21
 
19
22
  # Chaikin A/D Line
@@ -29,7 +32,7 @@ module SQA
29
32
  validate_prices!(close)
30
33
  validate_prices!(volume)
31
34
 
32
- TALibFFI.ad(high, low, close, volume)
35
+ Native.ad([high, low, close, volume])
33
36
  end
34
37
 
35
38
  # Chaikin A/D Oscillator
@@ -40,6 +43,9 @@ module SQA
40
43
  # @param fast_period [Integer] Fast period (default: 3)
41
44
  # @param slow_period [Integer] Slow period (default: 10)
42
45
  # @return [Array<Float>] ADOSC values
46
+ # :reek:LongParameterList -- mirrors TA-Lib's own ADOSC signature;
47
+ # bundling these would be a breaking public API change (see
48
+ # MomentumIndicators/VolatilityIndicators for the fuller rationale).
43
49
  def adosc(high, low, close, volume, fast_period: 3, slow_period: 10)
44
50
  check_available!
45
51
  validate_prices!(high)
@@ -47,7 +53,7 @@ module SQA
47
53
  validate_prices!(close)
48
54
  validate_prices!(volume)
49
55
 
50
- TALibFFI.adosc(high, low, close, volume, fast_period: fast_period, slow_period: slow_period)
56
+ Native.adosc([high, low, close, volume], fast_period:, slow_period:)
51
57
  end
52
58
  end
53
59
  end
data/lib/sqa/tai.rb CHANGED
@@ -1,10 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "tai/version"
4
- require "ta_lib_ffi"
5
-
6
- # Apply monkey patch to fix ta_lib_ffi 0.3.0 multi-array parameter bug
7
- require_relative "../extensions/ta_lib_ffi"
4
+ require_relative "tai/native"
8
5
 
9
6
  # Require all indicator modules
10
7
  require_relative "tai/overlap_studies"
@@ -38,7 +35,7 @@ module SQA
38
35
  class << self
39
36
  # Check if TA-Lib C library is available
40
37
  def available?
41
- defined?(TALibFFI) && TALibFFI.respond_to?(:sma)
38
+ Native.available?
42
39
  rescue LoadError
43
40
  false
44
41
  end
@@ -77,45 +74,57 @@ module SQA
77
74
  # SQA::TAI.help(search: "moving average")
78
75
  #
79
76
  def help(indicator = nil, **options)
80
- # List all indicators
81
- if indicator == :all
82
- return Help.indicators.transform_values { |meta| "#{Help::BASE_URL}/#{meta[:path]}/" }
83
- end
77
+ return help_all_indicators if indicator == :all
78
+ return help_by_category(options[:category]) if options[:category]
79
+ return help_by_search(options[:search]) if options[:search]
84
80
 
85
- # Category listing
86
- if options[:category]
87
- category_indicators = Help.indicators.select { |_k, v| v[:category] == options[:category] }
88
- return category_indicators.transform_values { |meta| "#{Help::BASE_URL}/#{meta[:path]}/" }
89
- end
81
+ help_for_indicator(indicator, options)
82
+ end
83
+
84
+ private
85
+
86
+ # Build a hash of {indicator => url} from a set of indicator metadata entries
87
+ def help_urls_for(meta_entries)
88
+ meta_entries.transform_values { |meta| "#{Help::BASE_URL}/#{meta[:path]}/" }
89
+ end
90
+
91
+ def help_all_indicators
92
+ help_urls_for(Help.indicators)
93
+ end
94
+
95
+ def help_by_category(category)
96
+ category_indicators = Help.indicators.select { |_k, v| v[:category] == category }
97
+ help_urls_for(category_indicators)
98
+ end
90
99
 
91
- # Search
92
- if options[:search]
93
- query = options[:search].downcase
94
- matches = Help.indicators.select do |k, v|
95
- k.to_s.include?(query) || v[:name].downcase.include?(query)
96
- end
97
- return matches.transform_values { |meta| "#{Help::BASE_URL}/#{meta[:path]}/" }
100
+ def help_by_search(search)
101
+ query = search.downcase
102
+ matches = Help.indicators.select do |k, v|
103
+ k.to_s.include?(query) || v[:name].downcase.include?(query)
98
104
  end
105
+ help_urls_for(matches)
106
+ end
99
107
 
100
- # Single indicator
108
+ def help_for_indicator(indicator, options)
101
109
  meta = Help.indicators[indicator]
102
110
  raise ArgumentError, "Unknown indicator: #{indicator}" unless meta
103
111
 
104
112
  resource = Help::Resource.new(indicator, meta[:name], meta[:category], meta[:path])
105
-
106
- # Open in browser if requested
107
113
  resource.open if options[:open]
108
114
 
109
- # Return format
110
- case options[:format]
115
+ format_help_resource(resource, meta, options[:format])
116
+ end
117
+
118
+ # :reek:ControlParameter -- dispatches on the caller-requested output
119
+ # shape (:uri/:hash/default); that's the method's whole job.
120
+ def format_help_resource(resource, meta, format)
121
+ case format
111
122
  when :uri then resource.uri
112
- when :hash then {name: meta[:name], category: meta[:category], url: resource.url}
123
+ when :hash then { name: meta[:name], category: meta[:category], url: resource.url }
113
124
  else resource # Return Help::Resource object (responds to to_s)
114
125
  end
115
126
  end
116
127
 
117
- private
118
-
119
128
  def validate_prices!(prices)
120
129
  raise InvalidParameterError, "Prices array cannot be nil" if prices.nil?
121
130
  raise InvalidParameterError, "Prices array cannot be empty" if prices.empty?
data/mkdocs.yml CHANGED
@@ -145,33 +145,171 @@ nav:
145
145
  - Installation: getting-started/installation.md
146
146
  - Quick Start: getting-started/quick-start.md
147
147
  - Basic Usage: getting-started/basic-usage.md
148
+ - Pattern Recognition Guide: getting-started/pattern-recognition.md
148
149
  - Help System: getting-started/help.md
150
+ - Concepts:
151
+ - Technical Analysis Basics: basics.md
152
+ - Support and Resistance: concepts/support-resistance.md
149
153
  - Indicators:
150
154
  - Overview: indicators/index.md
151
155
  - Overlap Studies:
152
- - Simple Moving Average: indicators/overlap/sma.md
153
- - Exponential Moving Average: indicators/overlap/ema.md
154
- - Weighted Moving Average: indicators/overlap/wma.md
155
- - Bollinger Bands: indicators/overlap/bbands.md
156
+ - Overview: indicators/overlap/index.md
157
+ - ACCBANDS (Acceleration Bands): indicators/overlap/accbands.md
158
+ - BBANDS (Bollinger Bands): indicators/overlap/bbands.md
159
+ - DEMA (Double Exponential Moving Average): indicators/overlap/dema.md
160
+ - EMA (Exponential Moving Average): indicators/overlap/ema.md
161
+ - HT_TRENDLINE (Hilbert Transform - Instantaneous Trendline): indicators/volatility/ht_trendline.md
162
+ - KAMA (Kaufman Adaptive Moving Average): indicators/overlap/kama.md
163
+ - MA (Moving Average - Generic Interface): indicators/overlap/ma.md
164
+ - MAMA (MESA Adaptive Moving Average): indicators/volatility/mama.md
165
+ - Moving Average with Variable Period (MAVP): indicators/volatility/mavp.md
166
+ - Midpoint Over Period (MIDPOINT): indicators/volatility/midpoint.md
167
+ - Midpoint Price (MIDPRICE): indicators/volatility/midprice.md
168
+ - Parabolic SAR Extended (SAREXT): indicators/volatility/sarext.md
169
+ - SMA (Simple Moving Average): indicators/overlap/sma.md
170
+ - T3 (Tillson T3 Moving Average): indicators/overlap/t3.md
171
+ - TEMA (Triple Exponential Moving Average): indicators/overlap/tema.md
172
+ - TRIMA (Triangular Moving Average): indicators/overlap/trima.md
173
+ - VWAP (Volume-Weighted Average Price): indicators/overlap/vwap.md
174
+ - WMA (Weighted Moving Average): indicators/overlap/wma.md
156
175
  - Momentum:
157
- - RSI: indicators/momentum/rsi.md
158
- - MACD: indicators/momentum/macd.md
159
- - Stochastic: indicators/momentum/stoch.md
160
- - Momentum: indicators/momentum/mom.md
176
+ - ADX (Average Directional Index): indicators/momentum/adx.md
177
+ - Average Directional Movement Index Rating (ADXR): indicators/momentum/adxr.md
178
+ - Absolute Price Oscillator (APO): indicators/momentum/apo.md
179
+ - Aroon Indicator (AROON): indicators/momentum/aroon.md
180
+ - Aroon Oscillator (AROONOSC): indicators/momentum/aroonosc.md
181
+ - Balance of Power (BOP): indicators/momentum/bop.md
182
+ - Commodity Channel Index (CCI): indicators/momentum/cci.md
183
+ - Chande Momentum Oscillator (CMO): indicators/momentum/cmo.md
184
+ - Directional Movement Index (DX): indicators/momentum/dx.md
185
+ - Intraday Momentum Index (IMI): indicators/momentum/imi.md
186
+ - MACD (Moving Average Convergence Divergence): indicators/momentum/macd.md
187
+ - MACD with Controllable MA Type (MACDEXT): indicators/momentum/macdext.md
188
+ - Moving Average Convergence Divergence - Fixed Parameters (MACDFIX): indicators/momentum/macdfix.md
189
+ - MFI (Money Flow Index): indicators/momentum/mfi.md
190
+ - Minus Directional Indicator (MINUS_DI): indicators/momentum/minus_di.md
191
+ - Minus Directional Movement (MINUS_DM): indicators/momentum/minus_dm.md
192
+ - Momentum (MOM): indicators/momentum/mom.md
193
+ - Plus Directional Indicator (+DI): indicators/momentum/plus_di.md
194
+ - Plus Directional Movement (PLUS_DM): indicators/momentum/plus_dm.md
195
+ - Percentage Price Oscillator (PPO): indicators/momentum/ppo.md
196
+ - Rate of Change (ROC): indicators/momentum/roc.md
197
+ - Rate of Change Percentage (ROCP): indicators/momentum/rocp.md
198
+ - Rate of Change Ratio (ROCR): indicators/momentum/rocr.md
199
+ - Rate of Change Ratio 100 Scale (ROCR100): indicators/momentum/rocr100.md
200
+ - RSI (Relative Strength Index): indicators/momentum/rsi.md
201
+ - Stochastic Oscillator (STOCH): indicators/momentum/stoch.md
202
+ - STOCHF (Fast Stochastic Oscillator): indicators/momentum/stochf.md
203
+ - Stochastic Relative Strength Index (STOCHRSI): indicators/momentum/stochrsi.md
204
+ - TRIX (Triple Exponential Average): indicators/momentum/trix.md
205
+ - Ultimate Oscillator (ULTOSC): indicators/momentum/ultosc.md
206
+ - "Williams %R (WILLR)": indicators/momentum/willr.md
161
207
  - Volatility:
162
- - Average True Range: indicators/volatility/atr.md
163
- - True Range: indicators/volatility/trange.md
208
+ - Average True Range (ATR): indicators/volatility/atr.md
209
+ - Keltner Channels: indicators/volatility/keltner.md
210
+ - NATR (Normalized Average True Range): indicators/volatility/natr.md
211
+ - Parabolic SAR (Stop and Reverse): indicators/volatility/sar.md
212
+ - True Range (TRANGE): indicators/volatility/trange.md
164
213
  - Volume:
165
- - On Balance Volume: indicators/volume/obv.md
166
- - Chaikin A/D Line: indicators/volume/ad.md
214
+ - Overview: indicators/volume/index.md
215
+ - AD (Chaikin Accumulation/Distribution Line): indicators/volume/ad.md
216
+ - ADOSC (Chaikin A/D Oscillator): indicators/volume/adosc.md
217
+ - CMF (Chaikin Money Flow): indicators/volume/cmf.md
218
+ - On Balance Volume (OBV): indicators/volume/obv.md
219
+ - Cycle:
220
+ - Overview: indicators/cycle/index.md
221
+ - HT_DCPERIOD (Hilbert Transform - Dominant Cycle Period): indicators/cycle/ht_dcperiod.md
222
+ - HT_DCPHASE (Hilbert Transform - Dominant Cycle Phase): indicators/cycle/ht_dcphase.md
223
+ - HT_PHASOR (Hilbert Transform - Phasor Components): indicators/cycle/ht_phasor.md
224
+ - HT_SINE (Hilbert Transform - Sine Wave Indicator): indicators/cycle/ht_sine.md
225
+ - HT_TRENDMODE (Hilbert Transform - Trend vs Cycle Mode): indicators/cycle/ht_trendmode.md
226
+ - Statistical Functions:
227
+ - Overview: indicators/statistical/index.md
228
+ - Beta Coefficient (BETA): indicators/statistical/beta.md
229
+ - "CORREL (Pearson's Correlation Coefficient)": indicators/statistical/correl.md
230
+ - Linear Regression (LINEARREG): indicators/statistical/linearreg.md
231
+ - Linear Regression Angle (LINEARREG_ANGLE): indicators/statistical/linearreg_angle.md
232
+ - Linear Regression Intercept (LINEARREG_INTERCEPT): indicators/statistical/linearreg_intercept.md
233
+ - Linear Regression Slope (LINEARREG_SLOPE): indicators/statistical/linearreg_slope.md
234
+ - Standard Deviation (STDDEV): indicators/statistical/stddev.md
235
+ - Time Series Forecast (TSF): indicators/statistical/tsf.md
236
+ - Variance (VAR): indicators/statistical/var.md
237
+ - Price Transform:
238
+ - Overview: indicators/price_transform/index.md
239
+ - AVGPRICE (Average Price): indicators/price_transform/avgprice.md
240
+ - Median Price (MEDPRICE): indicators/price_transform/medprice.md
241
+ - Typical Price (TYPPRICE): indicators/price_transform/typprice.md
242
+ - Weighted Close Price (WCLPRICE): indicators/price_transform/wclprice.md
167
243
  - Patterns:
168
244
  - Overview: indicators/patterns/index.md
169
- - Doji: indicators/patterns/cdl_doji.md
170
- - Hammer: indicators/patterns/cdl_hammer.md
171
- - Engulfing: indicators/patterns/cdl_engulfing.md
245
+ - Two Crows Pattern: indicators/patterns/cdl_2crows.md
246
+ - Three Black Crows Pattern: indicators/patterns/cdl_3blackcrows.md
247
+ - Three Inside Up/Down Pattern: indicators/patterns/cdl_3inside.md
248
+ - Three Line Strike Pattern: indicators/patterns/cdl_3linestrike.md
249
+ - Three Outside Up/Down Pattern: indicators/patterns/cdl_3outside.md
250
+ - Three Stars in the South Pattern: indicators/patterns/cdl_3starsinsouth.md
251
+ - Three White Soldiers Pattern: indicators/patterns/cdl_3whitesoldiers.md
252
+ - Abandoned Baby Pattern: indicators/patterns/cdl_abandonedbaby.md
253
+ - Advance Block Pattern: indicators/patterns/cdl_advanceblock.md
254
+ - Belt Hold Pattern: indicators/patterns/cdl_belthold.md
255
+ - Breakaway Pattern: indicators/patterns/cdl_breakaway.md
256
+ - Closing Marubozu Pattern: indicators/patterns/cdl_closingmarubozu.md
257
+ - Concealing Baby Swallow Pattern: indicators/patterns/cdl_concealbabyswall.md
258
+ - Counterattack Pattern: indicators/patterns/cdl_counterattack.md
259
+ - Dark Cloud Cover Pattern: indicators/patterns/cdl_darkcloudcover.md
260
+ - CDL_DOJI (Doji Candlestick Pattern): indicators/patterns/cdl_doji.md
261
+ - CDL_DOJISTAR (Doji Star Candlestick Pattern): indicators/patterns/cdl_dojistar.md
262
+ - Dragonfly Doji Pattern: indicators/patterns/cdl_dragonflydoji.md
263
+ - Engulfing Pattern: indicators/patterns/cdl_engulfing.md
264
+ - CDL_EVENINGDOJISTAR (Evening Doji Star): indicators/patterns/cdl_eveningdojistar.md
265
+ - CDL_EVENINGSTAR (Evening Star): indicators/patterns/cdl_eveningstar.md
266
+ - CDL_GAPSIDESIDEWHITE (Up/Down-Gap Side-by-Side White Lines): indicators/patterns/cdl_gapsidesidewhite.md
267
+ - CDL_GRAVESTONEDOJI (Gravestone Doji): indicators/patterns/cdl_gravestonedoji.md
268
+ - Hammer Pattern: indicators/patterns/cdl_hammer.md
269
+ - CDL_HANGINGMAN (Hanging Man Candlestick Pattern): indicators/patterns/cdl_hangingman.md
270
+ - CDL_HARAMI (Harami): indicators/patterns/cdl_harami.md
271
+ - CDL_HARAMICROSS (Harami Cross): indicators/patterns/cdl_haramicross.md
272
+ - CDL_HIGHWAVE (High Wave Candle): indicators/patterns/cdl_highwave.md
273
+ - CDL_HIKKAKE (Hikkake Pattern): indicators/patterns/cdl_hikkake.md
274
+ - CDL_HIKKAKEMOD (Modified Hikkake Pattern): indicators/patterns/cdl_hikkakemod.md
275
+ - CDL_HOMINGPIGEON (Homing Pigeon): indicators/patterns/cdl_homingpigeon.md
276
+ - CDL_IDENTICAL3CROWS (Identical Three Crows): indicators/patterns/cdl_identical3crows.md
277
+ - CDL_INNECK (In-Neck Pattern): indicators/patterns/cdl_inneck.md
278
+ - CDL_INSIDE - See Three Inside Up/Down: indicators/patterns/cdl_inside.md
279
+ - CDL_INVERTEDHAMMER (Inverted Hammer): indicators/patterns/cdl_invertedhammer.md
280
+ - CDL_KICKING (Kicking Pattern): indicators/patterns/cdl_kicking.md
281
+ - CDL_KICKINGBYLENGTH (Kicking By Length): indicators/patterns/cdl_kickingbylength.md
282
+ - CDL_LADDERBOTTOM (Ladder Bottom): indicators/patterns/cdl_ladderbottom.md
283
+ - CDL_LONGLEGGEDDOJI (Long-Legged Doji): indicators/patterns/cdl_longleggeddoji.md
284
+ - CDL_LONGLINE (Long Line Candle): indicators/patterns/cdl_longline.md
285
+ - CDL_MARUBOZU (Marubozu): indicators/patterns/cdl_marubozu.md
286
+ - CDL_MATCHINGLOW (Matching Low): indicators/patterns/cdl_matchinglow.md
287
+ - CDL_MATHOLD (Mat Hold): indicators/patterns/cdl_mathold.md
288
+ - CDL_MEETINGLINES (Meeting Lines): indicators/patterns/cdl_meetinglines.md
289
+ - CDL_MORNINGDOJISTAR (Morning Doji Star): indicators/patterns/cdl_morningdojistar.md
290
+ - CDL_MORNINGSTAR (Morning Star): indicators/patterns/cdl_morningstar.md
291
+ - CDL_ONNECK (On-Neck Pattern): indicators/patterns/cdl_onneck.md
292
+ - CDL_PIERCING (Piercing Pattern): indicators/patterns/cdl_piercing.md
293
+ - CDL_RICKSHAWMAN (Rickshaw Man): indicators/patterns/cdl_rickshawman.md
294
+ - CDL_RISEFALL3METHODS (Rising/Falling Three Methods): indicators/patterns/cdl_risefall3methods.md
295
+ - CDL_SEPARATINGLINES (Separating Lines): indicators/patterns/cdl_separatinglines.md
296
+ - CDL_SHOOTINGSTAR (Shooting Star): indicators/patterns/cdl_shootingstar.md
297
+ - CDL_SHORTLINE (Short Line Candle): indicators/patterns/cdl_shortline.md
298
+ - CDL_SPINNINGTOP (Spinning Top): indicators/patterns/cdl_spinningtop.md
299
+ - CDL_STALLEDPATTERN (Stalled Pattern): indicators/patterns/cdl_stalledpattern.md
300
+ - CDL_STICKSANDWICH (Stick Sandwich): indicators/patterns/cdl_sticksandwich.md
301
+ - CDL_TAKURI (Takuri Line (Dragonfly Doji at Support)): indicators/patterns/cdl_takuri.md
302
+ - CDL_TASUKIGAP (Tasuki Gap): indicators/patterns/cdl_tasukigap.md
303
+ - CDL_THRUSTING (Thrusting Pattern): indicators/patterns/cdl_thrusting.md
304
+ - CDL_TRISTAR (Tristar): indicators/patterns/cdl_tristar.md
305
+ - CDL_UNIQUE3RIVER (Unique 3 River): indicators/patterns/cdl_unique3river.md
306
+ - CDL_UPSIDEGAP2CROWS (Upside Gap Two Crows): indicators/patterns/cdl_upsidegap2crows.md
307
+ - CDL_XSIDEGAP3METHODS (Upside/Downside Gap Three Methods): indicators/patterns/cdl_xsidegap3methods.md
172
308
  - API Reference: api-reference.md
173
309
  - Examples:
174
310
  - Trend Analysis: examples/trend-analysis.md
175
311
  - Momentum Trading: examples/momentum-trading.md
176
312
  - Volatility Analysis: examples/volatility-analysis.md
313
+ - Trend Following: examples/trend-following.md
314
+ - Adaptive Indicators: examples/adaptive-indicators.md
177
315
  - Contributing: contributing.md
data/sqa-tai.gemspec ADDED
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/sqa/tai/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "sqa-tai"
7
+ spec.version = SQA::TAI::VERSION
8
+ spec.authors = ["Dewayne VanHoozer"]
9
+ spec.email = ["dvanhoozer@gmail.com"]
10
+
11
+ spec.summary = "SQA::TAI - Technical Analysis Indicators"
12
+ spec.description = "An SQA-specific Fiddle binding directly against the installed TA-Lib C library, providing many " \
13
+ "technical analysis indicators for stock analysis. Part of the SQA (Simple Qualitative Analysis) ecosystem."
14
+ spec.homepage = "https://github.com/MadBomber/sqa-tai"
15
+ spec.license = "MIT"
16
+
17
+ spec.required_ruby_version = ">= 3.4.0"
18
+
19
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = spec.homepage
22
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
23
+ spec.metadata["documentation_uri"] = "https://madbomber.github.io/sqa-tai"
24
+ spec.metadata['rubygems_mfa_required'] = 'true'
25
+
26
+ spec.files = Dir.chdir(__dir__) do
27
+ `git ls-files -z`.split("\x0").reject do |f|
28
+ (File.expand_path(f) == __FILE__) ||
29
+ f.start_with?(*%w[test/ spec/ features/ .git .github/ docs/])
30
+ end
31
+ end
32
+
33
+ spec.require_paths = ["lib"]
34
+
35
+ # Core dependency
36
+ spec.add_dependency "fiddle" # Ruby 3.5+ moved this to a bundled (not default) gem
37
+ spec.add_dependency "myway_config" # XDG-aware configuration management (extends anyway_config)
38
+
39
+ # Development dependencies
40
+ spec.add_development_dependency "bundler"
41
+ spec.add_development_dependency "rake"
42
+ spec.add_development_dependency "minitest", "~> 5.0"
43
+ spec.add_development_dependency "minitest-reporters"
44
+ spec.add_development_dependency "simplecov"
45
+ spec.add_development_dependency "debug"
46
+ spec.add_development_dependency "debug_me"
47
+ spec.add_development_dependency "flog"
48
+ spec.add_development_dependency "flay"
49
+ spec.add_development_dependency "racc" # flog/flay transitively need this on Ruby 4+
50
+ spec.add_development_dependency "reek" # code smell gate (rake reek_check)
51
+ spec.add_development_dependency "rubocop"
52
+ spec.add_development_dependency "fasterer" # performance-hint gate (asgard fasterer_check); not in bundle by
53
+ # default, so `bundle exec fasterer` silently fails into fasterer_output.txt without this
54
+ end