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
@@ -0,0 +1,416 @@
1
+ # SQA Rails Application
2
+
3
+ A comprehensive Rails 7.1 web application for stock market technical analysis using the SQA library. Features interactive charts, strategy backtesting, and market analysis with a modern, responsive UI.
4
+
5
+ ## Features
6
+
7
+ ### 📊 Interactive Dashboard
8
+ - Candlestick & line charts with Plotly.js
9
+ - Volume analysis with color-coded bars
10
+ - Technical indicators (RSI, MACD, SMA, EMA, Bollinger Bands)
11
+ - Key metrics cards (52-week high/low, RSI, market regime)
12
+ - Real-time price information
13
+ - Strategy comparison
14
+
15
+ ### 🤖 Strategy Backtesting
16
+ - 6 built-in strategies (RSI, MACD, SMA, EMA, Bollinger Bands, KBS)
17
+ - Detailed performance metrics
18
+ - Strategy comparison and ranking
19
+ - Visual strategy selection
20
+ - Comprehensive backtest results
21
+
22
+ ### 📈 Market Analysis
23
+ - Market regime detection (bull/bear/sideways)
24
+ - Seasonal pattern analysis
25
+ - FPOP (Future Period) analysis
26
+ - Risk metrics (VaR, Sharpe ratio, max drawdown)
27
+
28
+ ### 🎨 Modern Rails UI
29
+ - Responsive design
30
+ - MVC architecture
31
+ - RESTful API endpoints
32
+ - Rails 7.1 conventions
33
+ - Turbo & Stimulus ready
34
+
35
+ ## Installation
36
+
37
+ ### Prerequisites
38
+
39
+ - Ruby >= 3.2
40
+ - Rails >= 7.1
41
+ - SQLite3
42
+ - TA-Lib library
43
+ - Redis (for KBS)
44
+
45
+ ### Install TA-Lib
46
+
47
+ **macOS:**
48
+ ```bash
49
+ brew install ta-lib
50
+ ```
51
+
52
+ **Ubuntu/Debian:**
53
+ ```bash
54
+ sudo apt-get install ta-lib-dev
55
+ ```
56
+
57
+ ### Install Dependencies
58
+
59
+ ```bash
60
+ cd examples/rails_app
61
+ bundle install
62
+ ```
63
+
64
+ ### Database Setup
65
+
66
+ ```bash
67
+ rails db:create
68
+ rails db:migrate
69
+ ```
70
+
71
+ ### Set Up API Keys
72
+
73
+ ```bash
74
+ export AV_API_KEY="your_api_key_here"
75
+ ```
76
+
77
+ Get a free API key from [Alpha Vantage](https://www.alphavantage.co/support/#api-key)
78
+
79
+ ### Start Redis
80
+
81
+ ```bash
82
+ redis-server
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ ### Start the Application
88
+
89
+ ```bash
90
+ rails server
91
+ ```
92
+
93
+ Or using bin/rails:
94
+ ```bash
95
+ ./bin/rails server
96
+ ```
97
+
98
+ The application will start on `http://localhost:3000`
99
+
100
+ ### Navigate the App
101
+
102
+ 1. **Home Page** (`/`) - Landing page with quick links
103
+ 2. **Dashboard** (`/dashboard/:ticker`) - Interactive charts and metrics
104
+ 3. **Analysis** (`/analyze/:ticker`) - Market analysis and insights
105
+ 4. **Backtest** (`/backtest/:ticker`) - Strategy backtesting interface
106
+ 5. **Portfolio** (`/portfolio`) - Portfolio optimization (coming soon)
107
+
108
+ ## Rails Structure
109
+
110
+ ```
111
+ rails_app/
112
+ ├── app/
113
+ │ ├── controllers/
114
+ │ │ ├── application_controller.rb
115
+ │ │ ├── dashboard_controller.rb
116
+ │ │ ├── analysis_controller.rb
117
+ │ │ ├── backtest_controller.rb
118
+ │ │ ├── portfolio_controller.rb
119
+ │ │ └── api/
120
+ │ │ └── v1/
121
+ │ │ └── stocks_controller.rb # API endpoints
122
+ │ ├── views/
123
+ │ │ ├── layouts/
124
+ │ │ │ └── application.html.erb # Main layout
125
+ │ │ ├── dashboard/
126
+ │ │ │ ├── index.html.erb # Home page
127
+ │ │ │ └── show.html.erb # Stock dashboard
128
+ │ │ ├── analysis/
129
+ │ │ │ └── show.html.erb # Analysis page
130
+ │ │ ├── backtest/
131
+ │ │ │ └── show.html.erb # Backtest page
132
+ │ │ ├── portfolio/
133
+ │ │ │ └── index.html.erb # Portfolio page
134
+ │ │ └── errors/
135
+ │ │ └── show.html.erb # Error page
136
+ │ └── assets/
137
+ │ ├── stylesheets/
138
+ │ │ └── application.css # Main stylesheet
139
+ │ └── javascripts/
140
+ │ └── application.js # Main JavaScript
141
+ ├── config/
142
+ │ ├── application.rb # App configuration
143
+ │ ├── boot.rb # Boot configuration
144
+ │ ├── environment.rb # Environment setup
145
+ │ ├── database.yml # Database config
146
+ │ └── routes.rb # Routes definition
147
+ ├── db/ # Database files
148
+ ├── public/ # Static files
149
+ ├── bin/
150
+ │ └── rails # Rails script
151
+ ├── Gemfile # Ruby dependencies
152
+ ├── config.ru # Rack config
153
+ └── README.md # This file
154
+ ```
155
+
156
+ ## Routes
157
+
158
+ | Route | Method | Controller#Action | Description |
159
+ |-------|--------|-------------------|-------------|
160
+ | `/` | GET | `dashboard#index` | Home page |
161
+ | `/dashboard/:ticker` | GET | `dashboard#show` | Stock dashboard |
162
+ | `/analyze/:ticker` | GET | `analysis#show` | Market analysis |
163
+ | `/backtest/:ticker` | GET | `backtest#show` | Strategy backtesting |
164
+ | `/portfolio` | GET | `portfolio#index` | Portfolio optimization |
165
+ | `/api/v1/stock/:ticker` | GET | `api/v1/stocks#show` | Get stock data |
166
+ | `/api/v1/indicators/:ticker` | GET | `api/v1/stocks#indicators` | Get indicators |
167
+ | `/api/v1/backtest/:ticker` | POST | `api/v1/stocks#backtest` | Run backtest |
168
+ | `/api/v1/analyze/:ticker` | GET | `api/v1/stocks#analyze` | Get analysis |
169
+ | `/api/v1/compare/:ticker` | POST | `api/v1/stocks#compare` | Compare strategies |
170
+
171
+ ## API Endpoints
172
+
173
+ ### GET /api/v1/stock/:ticker
174
+
175
+ Returns stock price data with OHLCV (Open, High, Low, Close, Volume).
176
+
177
+ **Example:**
178
+ ```bash
179
+ curl http://localhost:3000/api/v1/stock/AAPL
180
+ ```
181
+
182
+ **Response:**
183
+ ```json
184
+ {
185
+ "ticker": "AAPL",
186
+ "current_price": 175.50,
187
+ "change": 2.30,
188
+ "change_percent": 1.33,
189
+ "high_52w": 198.23,
190
+ "low_52w": 124.17,
191
+ "dates": ["2023-01-01", ...],
192
+ "open": [170.0, ...],
193
+ "high": [172.0, ...],
194
+ "low": [169.5, ...],
195
+ "close": [171.0, ...],
196
+ "volume": [50000000, ...]
197
+ }
198
+ ```
199
+
200
+ ### GET /api/v1/indicators/:ticker
201
+
202
+ Returns calculated technical indicators.
203
+
204
+ **Example:**
205
+ ```bash
206
+ curl http://localhost:3000/api/v1/indicators/AAPL
207
+ ```
208
+
209
+ ### POST /api/v1/backtest/:ticker
210
+
211
+ Runs a backtest for the specified strategy.
212
+
213
+ **Example:**
214
+ ```bash
215
+ curl -X POST http://localhost:3000/api/v1/backtest/AAPL \
216
+ -H "Content-Type: application/json" \
217
+ -d '{"strategy":"RSI"}'
218
+ ```
219
+
220
+ ### GET /api/v1/analyze/:ticker
221
+
222
+ Returns market analysis including regime, seasonal patterns, FPOP, and risk metrics.
223
+
224
+ ### POST /api/v1/compare/:ticker
225
+
226
+ Compares all available strategies and returns results sorted by return.
227
+
228
+ ## Technology Stack
229
+
230
+ ### Backend
231
+ - **Rails 7.1** - Full-stack web framework
232
+ - **SQLite3** - Database
233
+ - **Puma** - Web server
234
+ - **SQA Library** - Stock analysis and backtesting
235
+ - **TA-Lib** - Technical analysis indicators
236
+ - **Polars** - High-performance DataFrames
237
+ - **Redis** - KBS blackboard persistence
238
+
239
+ ### Frontend
240
+ - **Plotly.js** - Interactive financial charts
241
+ - **Turbo** - Single-page application speed
242
+ - **Stimulus** - JavaScript framework
243
+ - **Font Awesome** - Icons
244
+ - **Custom CSS3** - Responsive styling
245
+
246
+ ## Development
247
+
248
+ ### Rails Console
249
+
250
+ ```bash
251
+ rails console
252
+ ```
253
+
254
+ ### Run Tests
255
+
256
+ ```bash
257
+ rails test
258
+ ```
259
+
260
+ ### Database Operations
261
+
262
+ ```bash
263
+ rails db:create # Create database
264
+ rails db:migrate # Run migrations
265
+ rails db:reset # Reset database
266
+ ```
267
+
268
+ ### Check Routes
269
+
270
+ ```bash
271
+ rails routes
272
+ ```
273
+
274
+ ## Configuration
275
+
276
+ ### Environment Variables
277
+
278
+ - `AV_API_KEY` - Alpha Vantage API key
279
+ - `RAILS_ENV` - Rails environment (development/production/test)
280
+ - `RAILS_MAX_THREADS` - Maximum threads (default: 5)
281
+
282
+ ### Database
283
+
284
+ Edit `config/database.yml` to configure database settings.
285
+
286
+ ### Asset Pipeline
287
+
288
+ Assets are automatically compiled in development. For production:
289
+
290
+ ```bash
291
+ rails assets:precompile
292
+ ```
293
+
294
+ ## Deployment
295
+
296
+ ### Using Rails Server
297
+
298
+ ```bash
299
+ rails server -e production -p 3000
300
+ ```
301
+
302
+ ### Using Puma
303
+
304
+ ```bash
305
+ puma -C config/puma.rb
306
+ ```
307
+
308
+ ### Using Docker
309
+
310
+ ```dockerfile
311
+ FROM ruby:3.3
312
+ WORKDIR /app
313
+ COPY Gemfile* ./
314
+ RUN bundle install
315
+ COPY . .
316
+ RUN rails assets:precompile
317
+ EXPOSE 3000
318
+ CMD ["rails", "server", "-b", "0.0.0.0"]
319
+ ```
320
+
321
+ ## Troubleshooting
322
+
323
+ ### TA-Lib Not Found
324
+
325
+ ```bash
326
+ # Reinstall TA-Lib
327
+ brew reinstall ta-lib # macOS
328
+ sudo apt-get install --reinstall ta-lib-dev # Ubuntu
329
+ ```
330
+
331
+ ### Redis Connection Error
332
+
333
+ ```bash
334
+ # Start Redis
335
+ redis-server &
336
+ ```
337
+
338
+ ### Database Issues
339
+
340
+ ```bash
341
+ # Reset database
342
+ rails db:reset
343
+ ```
344
+
345
+ ### Port Already in Use
346
+
347
+ ```bash
348
+ # Kill process on port 3000
349
+ lsof -ti:3000 | xargs kill -9
350
+ ```
351
+
352
+ ## Differences from Sinatra App
353
+
354
+ | Feature | Sinatra App | Rails App |
355
+ |---------|-------------|-----------|
356
+ | Framework | Lightweight | Full-featured |
357
+ | Structure | Flat | MVC architecture |
358
+ | Routing | Manual | Rails conventions |
359
+ | Database | Optional | Built-in (SQLite) |
360
+ | Asset Pipeline | Manual | Sprockets |
361
+ | ORM | None | Active Record |
362
+ | Testing | Manual | Built-in (Minitest) |
363
+ | Generators | None | Rails generators |
364
+ | Conventions | Minimal | Rails conventions |
365
+
366
+ ## Performance Tips
367
+
368
+ 1. **Enable Caching** - Use Rails caching for API responses
369
+ 2. **Database Indexes** - Add indexes for frequently queried fields
370
+ 3. **Asset Compression** - Use asset minification in production
371
+ 4. **CDN** - Serve static assets from CDN
372
+ 5. **Background Jobs** - Use Sidekiq for long-running tasks
373
+
374
+ ## Security
375
+
376
+ - CSRF protection enabled
377
+ - API authentication recommended for production
378
+ - Environment variables for sensitive data
379
+ - Input validation on ticker symbols
380
+ - HTTPS recommended for production
381
+
382
+ ## Contributing
383
+
384
+ Improvements welcome! Areas for contribution:
385
+
386
+ - [ ] Portfolio optimization interface
387
+ - [ ] User authentication and sessions
388
+ - [ ] Saved watchlists
389
+ - [ ] Real-time WebSocket updates
390
+ - [ ] Background job processing
391
+ - [ ] API rate limiting
392
+ - [ ] Caching layer
393
+ - [ ] Additional strategies
394
+
395
+ ## License
396
+
397
+ MIT License - Same as SQA library
398
+
399
+ ## Credits
400
+
401
+ - **SQA Library** - Stock analysis framework
402
+ - **Rails** - Web framework
403
+ - **Plotly.js** - Interactive charts
404
+ - **TA-Lib** - Technical analysis
405
+ - **Font Awesome** - Icons
406
+
407
+ ## Links
408
+
409
+ - [SQA Repository](https://github.com/MadBomber/sqa)
410
+ - [Rails Documentation](https://guides.rubyonrails.org/)
411
+ - [Plotly.js Documentation](https://plotly.com/javascript/)
412
+ - [TA-Lib](http://ta-lib.org/)
413
+
414
+ ---
415
+
416
+ **Disclaimer:** This software is for educational and research purposes only. Do not use for actual trading without proper due diligence. The authors are not responsible for financial losses.
@@ -0,0 +1,107 @@
1
+ // Global functions for modal and navigation
2
+
3
+ function showTickerModal() {
4
+ document.getElementById('tickerModal').style.display = 'block';
5
+ document.getElementById('tickerInput').focus();
6
+ }
7
+
8
+ function closeTickerModal() {
9
+ document.getElementById('tickerModal').style.display = 'none';
10
+ }
11
+
12
+ function searchTicker(event) {
13
+ event.preventDefault();
14
+
15
+ const input = event.target.querySelector('input[type="text"]');
16
+ const ticker = input.value.trim().toUpperCase();
17
+
18
+ if (!ticker) {
19
+ alert('Please enter a stock ticker symbol');
20
+ return false;
21
+ }
22
+
23
+ // Validate ticker format (letters and optional dot)
24
+ if (!/^[A-Z]{1,5}(\.[A-Z]{1,2})?$/.test(ticker)) {
25
+ alert('Please enter a valid ticker symbol (e.g., AAPL, BRK.A)');
26
+ return false;
27
+ }
28
+
29
+ // Navigate to dashboard
30
+ window.location.href = `/dashboard/${ticker}`;
31
+ return false;
32
+ }
33
+
34
+ // Close modal when clicking outside
35
+ window.onclick = function(event) {
36
+ const modal = document.getElementById('tickerModal');
37
+ if (event.target === modal) {
38
+ closeTickerModal();
39
+ }
40
+ }
41
+
42
+ // Keyboard shortcuts
43
+ document.addEventListener('keydown', function(event) {
44
+ // Ctrl/Cmd + K to open search
45
+ if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
46
+ event.preventDefault();
47
+ showTickerModal();
48
+ }
49
+
50
+ // Escape to close modal
51
+ if (event.key === 'Escape') {
52
+ closeTickerModal();
53
+ }
54
+ });
55
+
56
+ // Utility functions
57
+ function formatCurrency(value) {
58
+ return new Intl.NumberFormat('en-US', {
59
+ style: 'currency',
60
+ currency: 'USD'
61
+ }).format(value);
62
+ }
63
+
64
+ function formatPercent(value) {
65
+ return `${value >= 0 ? '+' : ''}${value.toFixed(2)}%`;
66
+ }
67
+
68
+ function formatNumber(value) {
69
+ return new Intl.NumberFormat('en-US').format(value);
70
+ }
71
+
72
+ // Show loading indicator
73
+ function showLoading(elementId) {
74
+ const element = document.getElementById(elementId);
75
+ if (element) {
76
+ element.innerHTML = '<p class="loading"><i class="fas fa-spinner fa-spin"></i> Loading...</p>';
77
+ }
78
+ }
79
+
80
+ // Show error message
81
+ function showError(elementId, message) {
82
+ const element = document.getElementById(elementId);
83
+ if (element) {
84
+ element.innerHTML = `<p class="error"><i class="fas fa-exclamation-circle"></i> ${message}</p>`;
85
+ }
86
+ }
87
+
88
+ // Debounce function for performance
89
+ function debounce(func, wait) {
90
+ let timeout;
91
+ return function executedFunction(...args) {
92
+ const later = () => {
93
+ clearTimeout(timeout);
94
+ func(...args);
95
+ };
96
+ clearTimeout(timeout);
97
+ timeout = setTimeout(later, wait);
98
+ };
99
+ }
100
+
101
+ // Console welcome message
102
+ console.log('%cSQA Analytics', 'font-size: 24px; font-weight: bold; color: #2196F3;');
103
+ console.log('%cPowered by Ruby & Plotly.js', 'font-size: 14px; color: #666;');
104
+ console.log('');
105
+ console.log('Keyboard shortcuts:');
106
+ console.log(' Ctrl/Cmd + K: Open ticker search');
107
+ console.log(' Escape: Close modal');