sqa 0.0.24 → 0.0.31

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/.goose/memory/development.txt +3 -0
  3. data/.semver +6 -0
  4. data/ARCHITECTURE.md +648 -0
  5. data/CHANGELOG.md +82 -0
  6. data/CLAUDE.md +653 -0
  7. data/COMMITS.md +196 -0
  8. data/DATAFRAME_ARCHITECTURE_REVIEW.md +421 -0
  9. data/NEXT-STEPS.md +154 -0
  10. data/README.md +812 -262
  11. data/TASKS.md +358 -0
  12. data/TEST_RESULTS.md +140 -0
  13. data/TODO.md +42 -0
  14. data/_notes.txt +25 -0
  15. data/bin/sqa-console +11 -0
  16. data/data/talk_talk.json +103284 -0
  17. data/develop_summary.md +313 -0
  18. data/docs/advanced/backtesting.md +206 -0
  19. data/docs/advanced/ensemble.md +68 -0
  20. data/docs/advanced/fpop.md +153 -0
  21. data/docs/advanced/index.md +112 -0
  22. data/docs/advanced/multi-timeframe.md +67 -0
  23. data/docs/advanced/pattern-matcher.md +75 -0
  24. data/docs/advanced/portfolio-optimizer.md +79 -0
  25. data/docs/advanced/portfolio.md +166 -0
  26. data/docs/advanced/risk-management.md +210 -0
  27. data/docs/advanced/strategy-generator.md +158 -0
  28. data/docs/advanced/streaming.md +209 -0
  29. data/docs/ai_and_ml.md +80 -0
  30. data/docs/api/dataframe.md +1115 -0
  31. data/docs/api/index.md +126 -0
  32. data/docs/assets/css/custom.css +88 -0
  33. data/docs/assets/js/mathjax.js +18 -0
  34. data/docs/concepts/index.md +68 -0
  35. data/docs/contributing/index.md +60 -0
  36. data/docs/data-sources/index.md +66 -0
  37. data/docs/data_frame.md +317 -97
  38. data/docs/factors_that_impact_price.md +26 -0
  39. data/docs/finviz.md +11 -0
  40. data/docs/fx_pro_bit.md +25 -0
  41. data/docs/genetic_programming.md +104 -0
  42. data/docs/getting-started/index.md +123 -0
  43. data/docs/getting-started/installation.md +229 -0
  44. data/docs/getting-started/quick-start.md +244 -0
  45. data/docs/i_gotta_an_idea.md +22 -0
  46. data/docs/index.md +163 -0
  47. data/docs/indicators/index.md +97 -0
  48. data/docs/indicators.md +110 -24
  49. data/docs/options.md +8 -0
  50. data/docs/strategies/bollinger-bands.md +146 -0
  51. data/docs/strategies/consensus.md +64 -0
  52. data/docs/strategies/custom.md +310 -0
  53. data/docs/strategies/ema.md +53 -0
  54. data/docs/strategies/index.md +92 -0
  55. data/docs/strategies/kbs.md +164 -0
  56. data/docs/strategies/macd.md +96 -0
  57. data/docs/strategies/market-profile.md +54 -0
  58. data/docs/strategies/mean-reversion.md +58 -0
  59. data/docs/strategies/rsi.md +95 -0
  60. data/docs/strategies/sma.md +55 -0
  61. data/docs/strategies/stochastic.md +63 -0
  62. data/docs/strategies/volume-breakout.md +54 -0
  63. data/docs/tags.md +7 -0
  64. data/docs/true_strength_index.md +46 -0
  65. data/docs/weighted_moving_average.md +48 -0
  66. data/examples/README.md +354 -0
  67. data/examples/advanced_features_example.rb +350 -0
  68. data/examples/fpop_analysis_example.rb +191 -0
  69. data/examples/genetic_programming_example.rb +148 -0
  70. data/examples/kbs_strategy_example.rb +208 -0
  71. data/examples/pattern_context_example.rb +300 -0
  72. data/examples/rails_app/Gemfile +34 -0
  73. data/examples/rails_app/README.md +416 -0
  74. data/examples/rails_app/app/assets/javascripts/application.js +107 -0
  75. data/examples/rails_app/app/assets/stylesheets/application.css +659 -0
  76. data/examples/rails_app/app/controllers/analysis_controller.rb +11 -0
  77. data/examples/rails_app/app/controllers/api/v1/stocks_controller.rb +227 -0
  78. data/examples/rails_app/app/controllers/application_controller.rb +22 -0
  79. data/examples/rails_app/app/controllers/backtest_controller.rb +11 -0
  80. data/examples/rails_app/app/controllers/dashboard_controller.rb +21 -0
  81. data/examples/rails_app/app/controllers/portfolio_controller.rb +7 -0
  82. data/examples/rails_app/app/views/analysis/show.html.erb +209 -0
  83. data/examples/rails_app/app/views/backtest/show.html.erb +171 -0
  84. data/examples/rails_app/app/views/dashboard/index.html.erb +118 -0
  85. data/examples/rails_app/app/views/dashboard/show.html.erb +408 -0
  86. data/examples/rails_app/app/views/errors/show.html.erb +17 -0
  87. data/examples/rails_app/app/views/layouts/application.html.erb +60 -0
  88. data/examples/rails_app/app/views/portfolio/index.html.erb +33 -0
  89. data/examples/rails_app/bin/rails +6 -0
  90. data/examples/rails_app/config/application.rb +45 -0
  91. data/examples/rails_app/config/boot.rb +5 -0
  92. data/examples/rails_app/config/database.yml +18 -0
  93. data/examples/rails_app/config/environment.rb +11 -0
  94. data/examples/rails_app/config/routes.rb +26 -0
  95. data/examples/rails_app/config.ru +8 -0
  96. data/examples/realtime_stream_example.rb +274 -0
  97. data/examples/sinatra_app/Gemfile +22 -0
  98. data/examples/sinatra_app/QUICKSTART.md +159 -0
  99. data/examples/sinatra_app/README.md +461 -0
  100. data/examples/sinatra_app/app.rb +344 -0
  101. data/examples/sinatra_app/config.ru +5 -0
  102. data/examples/sinatra_app/public/css/style.css +659 -0
  103. data/examples/sinatra_app/public/js/app.js +107 -0
  104. data/examples/sinatra_app/views/analyze.erb +306 -0
  105. data/examples/sinatra_app/views/backtest.erb +325 -0
  106. data/examples/sinatra_app/views/dashboard.erb +419 -0
  107. data/examples/sinatra_app/views/error.erb +58 -0
  108. data/examples/sinatra_app/views/index.erb +118 -0
  109. data/examples/sinatra_app/views/layout.erb +61 -0
  110. data/examples/sinatra_app/views/portfolio.erb +43 -0
  111. data/examples/strategy_generator_example.rb +346 -0
  112. data/hsa_portfolio.csv +11 -0
  113. data/justfile +0 -0
  114. data/lib/api/alpha_vantage_api.rb +462 -0
  115. data/lib/sqa/backtest.rb +329 -0
  116. data/lib/sqa/data_frame/alpha_vantage.rb +43 -65
  117. data/lib/sqa/data_frame/data.rb +92 -0
  118. data/lib/sqa/data_frame/yahoo_finance.rb +35 -43
  119. data/lib/sqa/data_frame.rb +148 -243
  120. data/lib/sqa/ensemble.rb +359 -0
  121. data/lib/sqa/fpop.rb +199 -0
  122. data/lib/sqa/gp.rb +259 -0
  123. data/lib/sqa/indicator.rb +5 -8
  124. data/lib/sqa/init.rb +15 -8
  125. data/lib/sqa/market_regime.rb +240 -0
  126. data/lib/sqa/multi_timeframe.rb +379 -0
  127. data/lib/sqa/pattern_matcher.rb +497 -0
  128. data/lib/sqa/portfolio.rb +260 -6
  129. data/lib/sqa/portfolio_optimizer.rb +377 -0
  130. data/lib/sqa/risk_manager.rb +442 -0
  131. data/lib/sqa/seasonal_analyzer.rb +209 -0
  132. data/lib/sqa/sector_analyzer.rb +300 -0
  133. data/lib/sqa/stock.rb +67 -125
  134. data/lib/sqa/strategy/bollinger_bands.rb +42 -0
  135. data/lib/sqa/strategy/consensus.rb +5 -2
  136. data/lib/sqa/strategy/kbs_strategy.rb +470 -0
  137. data/lib/sqa/strategy/macd.rb +46 -0
  138. data/lib/sqa/strategy/mp.rb +1 -1
  139. data/lib/sqa/strategy/stochastic.rb +60 -0
  140. data/lib/sqa/strategy/volume_breakout.rb +57 -0
  141. data/lib/sqa/strategy.rb +5 -0
  142. data/lib/sqa/strategy_generator.rb +947 -0
  143. data/lib/sqa/stream.rb +361 -0
  144. data/lib/sqa/version.rb +1 -7
  145. data/lib/sqa.rb +23 -16
  146. data/main.just +81 -0
  147. data/mkdocs.yml +288 -0
  148. data/trace.log +0 -0
  149. metadata +261 -51
  150. data/bin/sqa +0 -6
  151. data/lib/patches/dry-cli.rb +0 -228
  152. data/lib/sqa/activity.rb +0 -10
  153. data/lib/sqa/cli.rb +0 -62
  154. data/lib/sqa/commands/analysis.rb +0 -309
  155. data/lib/sqa/commands/base.rb +0 -139
  156. data/lib/sqa/commands/web.rb +0 -199
  157. data/lib/sqa/commands.rb +0 -22
  158. data/lib/sqa/constants.rb +0 -23
  159. data/lib/sqa/indicator/average_true_range.rb +0 -33
  160. data/lib/sqa/indicator/bollinger_bands.rb +0 -28
  161. data/lib/sqa/indicator/candlestick_pattern_recognizer.rb +0 -60
  162. data/lib/sqa/indicator/donchian_channel.rb +0 -29
  163. data/lib/sqa/indicator/double_top_bottom_pattern.rb +0 -34
  164. data/lib/sqa/indicator/elliott_wave_theory.rb +0 -57
  165. data/lib/sqa/indicator/exponential_moving_average.rb +0 -25
  166. data/lib/sqa/indicator/exponential_moving_average_trend.rb +0 -36
  167. data/lib/sqa/indicator/fibonacci_retracement.rb +0 -23
  168. data/lib/sqa/indicator/head_and_shoulders_pattern.rb +0 -26
  169. data/lib/sqa/indicator/market_profile.rb +0 -32
  170. data/lib/sqa/indicator/mean_reversion.rb +0 -37
  171. data/lib/sqa/indicator/momentum.rb +0 -28
  172. data/lib/sqa/indicator/moving_average_convergence_divergence.rb +0 -29
  173. data/lib/sqa/indicator/peaks_and_valleys.rb +0 -29
  174. data/lib/sqa/indicator/predict_next_value.rb +0 -202
  175. data/lib/sqa/indicator/relative_strength_index.rb +0 -47
  176. data/lib/sqa/indicator/simple_moving_average.rb +0 -24
  177. data/lib/sqa/indicator/simple_moving_average_trend.rb +0 -32
  178. data/lib/sqa/indicator/stochastic_oscillator.rb +0 -68
  179. data/lib/sqa/indicator/true_range.rb +0 -39
  180. data/lib/sqa/trade.rb +0 -26
data/lib/sqa/stream.rb ADDED
@@ -0,0 +1,361 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thread'
4
+
5
+ =begin
6
+
7
+ Real-Time Stock Price Stream Processor
8
+
9
+ This module provides real-time processing of stock price updates,
10
+ calculating indicators on-the-fly and generating trading signals
11
+ as new market data arrives.
12
+
13
+ Key Features:
14
+ - Event-driven architecture for live data processing
15
+ - Rolling window of recent prices and indicators
16
+ - On-demand indicator calculation
17
+ - Strategy execution on price updates
18
+ - Thread-safe operations
19
+ - Callback system for signal notifications
20
+
21
+ Example:
22
+ stream = SQA::Stream.new(
23
+ ticker: 'AAPL',
24
+ window_size: 100,
25
+ strategies: [SQA::Strategy::RSI, SQA::Strategy::MACD]
26
+ )
27
+
28
+ # Add callback for signals
29
+ stream.on_signal do |signal, data|
30
+ puts "Signal: #{signal} at price #{data[:price]}"
31
+ end
32
+
33
+ # Feed live price data
34
+ stream.update(price: 150.25, volume: 1_000_000, timestamp: Time.now)
35
+
36
+ =end
37
+
38
+ module SQA
39
+ class Stream
40
+ attr_reader :ticker, :window_size, :strategies, :data_buffer, :indicator_cache
41
+
42
+ def initialize(ticker:, window_size: 100, strategies: [])
43
+ @ticker = ticker
44
+ @window_size = window_size
45
+ @strategies = Array(strategies)
46
+ @signal_callbacks = []
47
+ @update_callbacks = []
48
+
49
+ # Thread-safe data structures
50
+ @mutex = Mutex.new
51
+ @data_buffer = {
52
+ prices: [],
53
+ volumes: [],
54
+ highs: [],
55
+ lows: [],
56
+ timestamps: []
57
+ }
58
+
59
+ @indicator_cache = {}
60
+ @last_signal = :hold
61
+ @update_count = 0
62
+ end
63
+
64
+ # Add a strategy to the stream processor
65
+ def add_strategy(strategy)
66
+ @mutex.synchronize do
67
+ @strategies << strategy
68
+ end
69
+ self
70
+ end
71
+
72
+ # Register callback for trading signals
73
+ #
74
+ # Example:
75
+ # stream.on_signal do |signal, data|
76
+ # puts "#{signal.upcase} at $#{data[:price]}"
77
+ # end
78
+ def on_signal(&block)
79
+ @signal_callbacks << block
80
+ self
81
+ end
82
+
83
+ # Register callback for price updates
84
+ #
85
+ # Example:
86
+ # stream.on_update do |data|
87
+ # puts "Price updated: $#{data[:price]}"
88
+ # end
89
+ def on_update(&block)
90
+ @update_callbacks << block
91
+ self
92
+ end
93
+
94
+ # Update stream with new market data
95
+ #
96
+ # Required fields: price
97
+ # Optional fields: volume, high, low, timestamp
98
+ def update(price:, volume: nil, high: nil, low: nil, timestamp: Time.now)
99
+ @mutex.synchronize do
100
+ # Add to buffers
101
+ @data_buffer[:prices] << price.to_f
102
+ @data_buffer[:volumes] << (volume || 0).to_f
103
+ @data_buffer[:highs] << (high || price).to_f
104
+ @data_buffer[:lows] << (low || price).to_f
105
+ @data_buffer[:timestamps] << timestamp
106
+
107
+ # Trim buffers to window size
108
+ trim_buffers
109
+
110
+ # Clear indicator cache (will be recalculated on demand)
111
+ @indicator_cache.clear
112
+
113
+ @update_count += 1
114
+ end
115
+
116
+ # Prepare update data
117
+ update_data = {
118
+ price: price,
119
+ volume: volume,
120
+ high: high,
121
+ low: low,
122
+ timestamp: timestamp,
123
+ count: @update_count
124
+ }
125
+
126
+ # Notify update callbacks
127
+ @update_callbacks.each { |callback| callback.call(update_data) }
128
+
129
+ # Process strategies if we have enough data
130
+ process_strategies if sufficient_data?
131
+
132
+ true
133
+ end
134
+
135
+ # Get current price
136
+ def current_price
137
+ @mutex.synchronize { @data_buffer[:prices].last }
138
+ end
139
+
140
+ # Get recent prices
141
+ def recent_prices(count = nil)
142
+ @mutex.synchronize do
143
+ count ? @data_buffer[:prices].last(count) : @data_buffer[:prices].dup
144
+ end
145
+ end
146
+
147
+ # Get recent volumes
148
+ def recent_volumes(count = nil)
149
+ @mutex.synchronize do
150
+ count ? @data_buffer[:volumes].last(count) : @data_buffer[:volumes].dup
151
+ end
152
+ end
153
+
154
+ # Calculate or retrieve cached indicator
155
+ #
156
+ # Example:
157
+ # rsi = stream.indicator(:rsi, period: 14)
158
+ # sma = stream.indicator(:sma, period: 20)
159
+ def indicator(name, **options)
160
+ cache_key = [name, options].hash
161
+
162
+ @mutex.synchronize do
163
+ return @indicator_cache[cache_key] if @indicator_cache.key?(cache_key)
164
+
165
+ prices = @data_buffer[:prices].dup
166
+ volumes = @data_buffer[:volumes].dup
167
+ highs = @data_buffer[:highs].dup
168
+ lows = @data_buffer[:lows].dup
169
+
170
+ result = calculate_indicator(name, prices, volumes, highs, lows, **options)
171
+ @indicator_cache[cache_key] = result
172
+ result
173
+ end
174
+ end
175
+
176
+ # Get current trading signal from last strategy execution
177
+ def current_signal
178
+ @last_signal
179
+ end
180
+
181
+ # Get statistics about the stream
182
+ def stats
183
+ @mutex.synchronize do
184
+ {
185
+ ticker: @ticker,
186
+ updates: @update_count,
187
+ buffer_size: @data_buffer[:prices].size,
188
+ window_size: @window_size,
189
+ current_price: @data_buffer[:prices].last,
190
+ price_range: price_range,
191
+ last_signal: @last_signal,
192
+ strategies: @strategies.size,
193
+ callbacks: @signal_callbacks.size
194
+ }
195
+ end
196
+ end
197
+
198
+ # Reset the stream (clear all data)
199
+ def reset
200
+ @mutex.synchronize do
201
+ @data_buffer.each { |_, v| v.clear }
202
+ @indicator_cache.clear
203
+ @last_signal = :hold
204
+ @update_count = 0
205
+ end
206
+ self
207
+ end
208
+
209
+ private
210
+
211
+ # Check if we have enough data to run strategies
212
+ def sufficient_data?
213
+ @data_buffer[:prices].size >= 30 # Minimum data points
214
+ end
215
+
216
+ # Trim buffers to maintain window size
217
+ def trim_buffers
218
+ @data_buffer.each do |key, buffer|
219
+ buffer.shift while buffer.size > @window_size
220
+ end
221
+ end
222
+
223
+ # Process all strategies with current data
224
+ def process_strategies
225
+ return if @strategies.empty?
226
+
227
+ # Build vector with current market data and indicators
228
+ vector = build_vector
229
+
230
+ # Execute each strategy
231
+ signals = @strategies.map do |strategy|
232
+ begin
233
+ if strategy.is_a?(Class)
234
+ strategy.trade(vector)
235
+ elsif strategy.respond_to?(:call)
236
+ strategy.call(vector)
237
+ else
238
+ :hold
239
+ end
240
+ rescue => e
241
+ puts "Warning: Strategy #{strategy} failed: #{e.message}"
242
+ :hold
243
+ end
244
+ end
245
+
246
+ # Determine consensus signal
247
+ signal = consensus_signal(signals)
248
+
249
+ # Only emit if signal changed
250
+ if signal != @last_signal
251
+ @last_signal = signal
252
+
253
+ signal_data = {
254
+ signal: signal,
255
+ price: current_price,
256
+ timestamp: @data_buffer[:timestamps].last,
257
+ strategies_vote: signals.tally
258
+ }
259
+
260
+ # Notify signal callbacks
261
+ @signal_callbacks.each { |callback| callback.call(signal, signal_data) }
262
+ end
263
+ end
264
+
265
+ # Build data vector for strategy execution
266
+ def build_vector
267
+ require 'ostruct'
268
+
269
+ prices = @data_buffer[:prices].dup
270
+ volumes = @data_buffer[:volumes].dup
271
+ highs = @data_buffer[:highs].dup
272
+ lows = @data_buffer[:lows].dup
273
+
274
+ OpenStruct.new(
275
+ ticker: @ticker,
276
+ prices: prices,
277
+ volumes: volumes,
278
+ highs: highs,
279
+ lows: lows,
280
+ current_price: prices.last,
281
+
282
+ # Common indicators (lazy calculated)
283
+ rsi: lazy_indicator(:rsi, prices, period: 14),
284
+ sma: lazy_indicator(:sma, prices, period: 20),
285
+ ema: lazy_indicator(:ema, prices, period: 20),
286
+ macd: lazy_indicator(:macd, prices),
287
+ stoch_k: lazy_indicator(:stoch, highs, lows, prices, &:first),
288
+ stoch_d: lazy_indicator(:stoch, highs, lows, prices, &:last),
289
+ bb_upper: lazy_indicator(:bbands, prices, &:first),
290
+ bb_middle: lazy_indicator(:bbands, prices) { |r| r[1] },
291
+ bb_lower: lazy_indicator(:bbands, prices) { |r| r[2] }
292
+ )
293
+ end
294
+
295
+ # Lazy indicator calculation (only if accessed)
296
+ def lazy_indicator(name, *args, **kwargs, &extractor)
297
+ lambda do
298
+ result = calculate_indicator(name, *args, **kwargs)
299
+ extractor ? extractor.call(result) : result
300
+ end.call
301
+ rescue => e
302
+ nil
303
+ end
304
+
305
+ # Calculate technical indicator
306
+ def calculate_indicator(name, prices, volumes = nil, highs = nil, lows = nil, **options)
307
+ case name
308
+ when :rsi
309
+ SQAI.rsi(prices, **options)
310
+ when :sma
311
+ SQAI.sma(prices, **options)
312
+ when :ema
313
+ SQAI.ema(prices, **options)
314
+ when :macd
315
+ SQAI.macd(prices, **options)
316
+ when :stoch
317
+ SQAI.stoch(highs, lows, prices, **options)
318
+ when :bbands
319
+ SQAI.bbands(prices, **options)
320
+ when :adx
321
+ SQAI.adx(highs, lows, prices, **options)
322
+ when :atr
323
+ SQAI.atr(highs, lows, prices, **options)
324
+ else
325
+ # Try to call indicator directly
326
+ if SQAI.respond_to?(name)
327
+ SQAI.send(name, prices, **options)
328
+ else
329
+ raise "Unknown indicator: #{name}"
330
+ end
331
+ end
332
+ end
333
+
334
+ # Determine consensus signal from multiple strategy outputs
335
+ def consensus_signal(signals)
336
+ votes = signals.tally
337
+ buy_votes = votes[:buy] || 0
338
+ sell_votes = votes[:sell] || 0
339
+ hold_votes = votes[:hold] || 0
340
+
341
+ # Majority wins
342
+ if buy_votes > sell_votes && buy_votes > hold_votes
343
+ :buy
344
+ elsif sell_votes > buy_votes && sell_votes > hold_votes
345
+ :sell
346
+ else
347
+ :hold
348
+ end
349
+ end
350
+
351
+ # Calculate price range in buffer
352
+ def price_range
353
+ prices = @data_buffer[:prices]
354
+ return nil if prices.empty?
355
+
356
+ min = prices.min
357
+ max = prices.max
358
+ { min: min, max: max, range: max - min }
359
+ end
360
+ end
361
+ end
data/lib/sqa/version.rb CHANGED
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SQA
4
- VERSION = "0.0.24"
5
-
6
- class << self
7
- def version
8
- @@version ||= VERSION.to_version
9
- end
10
- end
4
+ VERSION = '0.0.31'
11
5
  end
data/lib/sqa.rb CHANGED
@@ -30,17 +30,16 @@ $DEBUG_ME = true
30
30
  #############################################
31
31
  ## Additional Libraries
32
32
 
33
- require 'alphavantage'
34
- require 'api_key_manager'
35
- require 'amazing_print'
36
- require 'dry/cli'
33
+ begin
34
+ require 'amazing_print'
35
+ rescue LoadError
36
+ # amazing_print is optional (development dependency)
37
+ end
37
38
  require 'faraday'
38
39
  require 'hashie'
39
40
  require 'lite/statistics'
40
41
  require 'lite/statistics/monkey_patches' # patch to Enumerable
41
42
  require 'nenv'
42
- require 'sem_version'
43
- require 'sem_version/core_ext'
44
43
  require 'tty-table'
45
44
 
46
45
 
@@ -51,9 +50,11 @@ require 'tty-table'
51
50
  # ActiveSupport
52
51
  require_relative "patches/string.rb"
53
52
 
54
- # Adds the global_header, global_footer, header, and footer
55
- # class methods to enhance the HELP/Usage functionality
56
- require_relative "patches/dry-cli.rb"
53
+
54
+ #############################################
55
+ ## API wrappers for External Websites
56
+
57
+ require_relative "api/alpha_vantage_api"
57
58
 
58
59
 
59
60
  #############################################
@@ -64,19 +65,25 @@ require_relative "sqa/errors"
64
65
 
65
66
  require_relative 'sqa/init.rb'
66
67
 
67
-
68
- # TODO: Some of these components make direct calls to the
69
- # Alpha Vantage API. Convert them to use the
70
- # alphavantage gem.
71
-
72
68
  require_relative "sqa/config"
73
- require_relative "sqa/constants" # SMELL: more app than gem
74
69
  require_relative "sqa/data_frame"
75
70
  require_relative "sqa/indicator"
71
+ require_relative "sqa/fpop"
72
+ require_relative "sqa/market_regime"
73
+ require_relative "sqa/seasonal_analyzer"
74
+ require_relative "sqa/sector_analyzer"
76
75
  require_relative "sqa/portfolio"
76
+ require_relative "sqa/backtest"
77
77
  require_relative "sqa/strategy"
78
78
  require_relative "sqa/stock"
79
79
  require_relative "sqa/ticker"
80
- require_relative "sqa/trade" # SMELL: Not really a core gem; more of an application thing
80
+ require_relative "sqa/stream"
81
+ require_relative "sqa/gp"
82
+ require_relative "sqa/strategy_generator"
83
+ require_relative "sqa/risk_manager"
84
+ require_relative "sqa/portfolio_optimizer"
85
+ require_relative "sqa/ensemble"
86
+ require_relative "sqa/multi_timeframe"
87
+ require_relative "sqa/pattern_matcher"
81
88
 
82
89
 
data/main.just ADDED
@@ -0,0 +1,81 @@
1
+ # aia/main.just
2
+ #
3
+ # Support man pages with ...
4
+ # gem install kramdown-man
5
+ #
6
+
7
+ RR := env_var('RR')
8
+
9
+ with ~/.justfile
10
+
11
+ # FIXME: justprep module process still has an issue with ~ and $HOME
12
+ # FIXME: justprep does not like more than one space between module name and path.
13
+
14
+ module repo /Users/dewayne/sandbox/git_repos/repo.just
15
+ module gem /Users/dewayne/sandbox/git_repos/gem.just
16
+ module version /Users/dewayne/just_modules/version.just
17
+ module git /Users/dewayne/just_modules/git.just
18
+
19
+
20
+ # Install Locally
21
+ install: update_toc_in_readmen create_man_page flay
22
+ rake install
23
+
24
+
25
+ # Create the TOC
26
+ update_toc_in_readmen:
27
+ rake toc
28
+
29
+
30
+ # Preview man page
31
+ preview_man_page:
32
+ kramdown-man {{RR}}/man/aia.1.md
33
+
34
+ # Static Code Check
35
+ flay: coverage
36
+ flay {{RR}}
37
+
38
+
39
+ # View coverage report
40
+ coverage: test
41
+ open {{RR}}/coverage/index.html
42
+
43
+
44
+ # Run Unit Tests
45
+ test:
46
+ rake test
47
+
48
+
49
+ # View man page
50
+ view_man_page: create_man_page
51
+ man {{RR}}/man/aia.1
52
+
53
+
54
+ # Create man page
55
+ create_man_page:
56
+ rake man
57
+
58
+ ##########################################
59
+
60
+ # Tag the current commit, push it, then bump the version
61
+ tag_push_and_bump: tag push bump
62
+
63
+
64
+ # Create a git tag for the current version
65
+ tag:
66
+ git tag $(semver)
67
+
68
+ # Push the git current working directory and all tags
69
+ push:
70
+ git push
71
+ git push origin --tags
72
+
73
+
74
+ alias inc := bump
75
+
76
+ # Increament version's level: major.minor.patch
77
+ @bump level='patch':
78
+ semver increment {{level}}
79
+ echo "Now working on: $(semver)"
80
+ git add {{RR}}/.semver
81
+