sqa 0.0.37 → 0.0.38

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/docs/api-reference/alphavantageapi.md +105 -105
  4. data/docs/api-reference/apierror.md +2 -2
  5. data/docs/api-reference/index.md +2 -2
  6. data/docs/api-reference/notimplemented.md +2 -2
  7. data/docs/api-reference/sqa.md +12 -12
  8. data/docs/api-reference/sqa_backtest.md +43 -9
  9. data/docs/api-reference/sqa_backtest_results.md +34 -34
  10. data/docs/api-reference/sqa_badparametererror.md +1 -1
  11. data/docs/api-reference/sqa_config.md +31 -31
  12. data/docs/api-reference/sqa_configurationerror.md +1 -1
  13. data/docs/api-reference/sqa_datafetcherror.md +3 -3
  14. data/docs/api-reference/sqa_dataframe.md +63 -36
  15. data/docs/api-reference/sqa_dataframe_alphavantage.md +2 -2
  16. data/docs/api-reference/sqa_dataframe_data.md +18 -18
  17. data/docs/api-reference/sqa_dataframe_yahoofinance.md +2 -2
  18. data/docs/api-reference/sqa_ensemble.md +21 -21
  19. data/docs/api-reference/sqa_fpop.md +8 -8
  20. data/docs/api-reference/sqa_geneticprogram.md +20 -20
  21. data/docs/api-reference/sqa_geneticprogram_individual.md +8 -8
  22. data/docs/api-reference/sqa_marketregime.md +10 -10
  23. data/docs/api-reference/sqa_multitimeframe.md +11 -11
  24. data/docs/api-reference/sqa_patternmatcher.md +9 -9
  25. data/docs/api-reference/sqa_pluginmanager.md +4 -4
  26. data/docs/api-reference/sqa_portfolio.md +84 -27
  27. data/docs/api-reference/sqa_portfolio_position.md +12 -12
  28. data/docs/api-reference/sqa_portfolio_trade.md +16 -16
  29. data/docs/api-reference/sqa_portfoliooptimizer.md +10 -10
  30. data/docs/api-reference/sqa_riskmanager.md +12 -12
  31. data/docs/api-reference/sqa_seasonalanalyzer.md +6 -6
  32. data/docs/api-reference/sqa_sectoranalyzer.md +9 -9
  33. data/docs/api-reference/sqa_stock.md +48 -36
  34. data/docs/api-reference/sqa_strategy.md +8 -8
  35. data/docs/api-reference/sqa_strategy_bollingerbands.md +2 -2
  36. data/docs/api-reference/sqa_strategy_common.md +3 -3
  37. data/docs/api-reference/sqa_strategy_consensus.md +12 -12
  38. data/docs/api-reference/sqa_strategy_ema.md +4 -4
  39. data/docs/api-reference/sqa_strategy_kbs.md +11 -11
  40. data/docs/api-reference/sqa_strategy_macd.md +2 -2
  41. data/docs/api-reference/sqa_strategy_mp.md +4 -4
  42. data/docs/api-reference/sqa_strategy_mr.md +4 -4
  43. data/docs/api-reference/sqa_strategy_random.md +4 -4
  44. data/docs/api-reference/sqa_strategy_rsi.md +4 -4
  45. data/docs/api-reference/sqa_strategy_sma.md +4 -4
  46. data/docs/api-reference/sqa_strategy_stochastic.md +2 -2
  47. data/docs/api-reference/sqa_strategy_volumebreakout.md +2 -2
  48. data/docs/api-reference/sqa_strategygenerator.md +19 -19
  49. data/docs/api-reference/sqa_strategygenerator_pattern.md +17 -17
  50. data/docs/api-reference/sqa_strategygenerator_patterncontext.md +21 -21
  51. data/docs/api-reference/sqa_strategygenerator_profitablepoint.md +27 -27
  52. data/docs/api-reference/sqa_stream.md +18 -18
  53. data/docs/api-reference/sqa_ticker.md +8 -8
  54. data/docs/api-reference/string.md +11 -11
  55. data/docs/file_formats.md +250 -0
  56. data/lib/sqa/backtest.rb +32 -0
  57. data/lib/sqa/data_frame.rb +25 -0
  58. data/lib/sqa/portfolio.rb +54 -0
  59. data/lib/sqa/stock.rb +11 -0
  60. data/lib/sqa/version.rb +1 -1
  61. data/mkdocs.yml +1 -0
  62. metadata +2 -2
  63. data/docs/IMPROVEMENT_PLAN.md +0 -531
@@ -5,7 +5,7 @@
5
5
  Extends Hashie::Dash for property-based configuration with coercion.
6
6
 
7
7
  !!! abstract "Source Information"
8
- **Defined in:** `lib/sqa/config.rb:54`
8
+ **Defined in:** [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
9
9
 
10
10
  **Inherits from:** `Hashie::Dash`
11
11
 
@@ -26,7 +26,7 @@ Creates a new Config instance and assigns it to SQA.config.
26
26
  The new config instance
27
27
 
28
28
  ??? info "Source Location"
29
- `lib/sqa/config.rb:255`
29
+ [`lib/sqa/config.rb:255`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L255)
30
30
 
31
31
  ---
32
32
 
@@ -44,7 +44,7 @@ Returns whether the configuration has been initialized.
44
44
  true if reset has been called
45
45
 
46
46
  ??? info "Source Location"
47
- `lib/sqa/config.rb:263`
47
+ [`lib/sqa/config.rb:263`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L263)
48
48
 
49
49
  ---
50
50
 
@@ -62,7 +62,7 @@ Returns whether the configuration has been initialized.
62
62
  Current command (nil, 'analysis', or 'web')
63
63
 
64
64
  ??? info "Source Location"
65
- `lib/sqa/config.rb:54`
65
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
66
66
 
67
67
  ---
68
68
 
@@ -78,7 +78,7 @@ Returns whether the configuration has been initialized.
78
78
  Current command (nil, 'analysis', or 'web')
79
79
 
80
80
  ??? info "Source Location"
81
- `lib/sqa/config.rb:54`
81
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
82
82
 
83
83
  ---
84
84
 
@@ -94,7 +94,7 @@ Returns whether the configuration has been initialized.
94
94
  Path to configuration file
95
95
 
96
96
  ??? info "Source Location"
97
- `lib/sqa/config.rb:54`
97
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
98
98
 
99
99
  ---
100
100
 
@@ -110,7 +110,7 @@ Returns whether the configuration has been initialized.
110
110
  Path to configuration file
111
111
 
112
112
  ??? info "Source Location"
113
- `lib/sqa/config.rb:54`
113
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
114
114
 
115
115
  ---
116
116
 
@@ -126,7 +126,7 @@ Returns whether the configuration has been initialized.
126
126
  Path to dump current configuration
127
127
 
128
128
  ??? info "Source Location"
129
- `lib/sqa/config.rb:54`
129
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
130
130
 
131
131
  ---
132
132
 
@@ -142,7 +142,7 @@ Returns whether the configuration has been initialized.
142
142
  Path to dump current configuration
143
143
 
144
144
  ??? info "Source Location"
145
- `lib/sqa/config.rb:54`
145
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
146
146
 
147
147
  ---
148
148
 
@@ -158,7 +158,7 @@ Returns whether the configuration has been initialized.
158
158
  Directory for data storage (default: ~/sqa_data)
159
159
 
160
160
  ??? info "Source Location"
161
- `lib/sqa/config.rb:54`
161
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
162
162
 
163
163
  ---
164
164
 
@@ -174,7 +174,7 @@ Returns whether the configuration has been initialized.
174
174
  Directory for data storage (default: ~/sqa_data)
175
175
 
176
176
  ??? info "Source Location"
177
- `lib/sqa/config.rb:54`
177
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
178
178
 
179
179
  ---
180
180
 
@@ -190,7 +190,7 @@ Returns whether the configuration has been initialized.
190
190
  Portfolio CSV filename (default: portfolio.csv)
191
191
 
192
192
  ??? info "Source Location"
193
- `lib/sqa/config.rb:54`
193
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
194
194
 
195
195
  ---
196
196
 
@@ -206,7 +206,7 @@ Returns whether the configuration has been initialized.
206
206
  Portfolio CSV filename (default: portfolio.csv)
207
207
 
208
208
  ??? info "Source Location"
209
- `lib/sqa/config.rb:54`
209
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
210
210
 
211
211
  ---
212
212
 
@@ -222,7 +222,7 @@ Returns whether the configuration has been initialized.
222
222
  Trades CSV filename (default: trades.csv)
223
223
 
224
224
  ??? info "Source Location"
225
- `lib/sqa/config.rb:54`
225
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
226
226
 
227
227
  ---
228
228
 
@@ -238,7 +238,7 @@ Returns whether the configuration has been initialized.
238
238
  Trades CSV filename (default: trades.csv)
239
239
 
240
240
  ??? info "Source Location"
241
- `lib/sqa/config.rb:54`
241
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
242
242
 
243
243
  ---
244
244
 
@@ -254,7 +254,7 @@ Returns whether the configuration has been initialized.
254
254
  Log level (:debug, :info, :warn, :error, :fatal)
255
255
 
256
256
  ??? info "Source Location"
257
- `lib/sqa/config.rb:54`
257
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
258
258
 
259
259
  ---
260
260
 
@@ -270,7 +270,7 @@ Returns whether the configuration has been initialized.
270
270
  Log level (:debug, :info, :warn, :error, :fatal)
271
271
 
272
272
  ??? info "Source Location"
273
- `lib/sqa/config.rb:54`
273
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
274
274
 
275
275
  ---
276
276
 
@@ -286,7 +286,7 @@ Returns whether the configuration has been initialized.
286
286
  Enable debug mode
287
287
 
288
288
  ??? info "Source Location"
289
- `lib/sqa/config.rb:54`
289
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
290
290
 
291
291
  ---
292
292
 
@@ -302,7 +302,7 @@ Returns whether the configuration has been initialized.
302
302
  Enable debug mode
303
303
 
304
304
  ??? info "Source Location"
305
- `lib/sqa/config.rb:54`
305
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
306
306
 
307
307
  ---
308
308
 
@@ -318,7 +318,7 @@ Returns whether the configuration has been initialized.
318
318
  Enable verbose output
319
319
 
320
320
  ??? info "Source Location"
321
- `lib/sqa/config.rb:54`
321
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
322
322
 
323
323
  ---
324
324
 
@@ -334,7 +334,7 @@ Returns whether the configuration has been initialized.
334
334
  Enable verbose output
335
335
 
336
336
  ??? info "Source Location"
337
- `lib/sqa/config.rb:54`
337
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
338
338
 
339
339
  ---
340
340
 
@@ -350,7 +350,7 @@ Returns whether the configuration has been initialized.
350
350
  Plotting library to use (:gruff)
351
351
 
352
352
  ??? info "Source Location"
353
- `lib/sqa/config.rb:54`
353
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
354
354
 
355
355
  ---
356
356
 
@@ -366,7 +366,7 @@ Returns whether the configuration has been initialized.
366
366
  Plotting library to use (:gruff)
367
367
 
368
368
  ??? info "Source Location"
369
- `lib/sqa/config.rb:54`
369
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
370
370
 
371
371
  ---
372
372
 
@@ -382,7 +382,7 @@ Returns whether the configuration has been initialized.
382
382
  Skip API updates if cached data exists
383
383
 
384
384
  ??? info "Source Location"
385
- `lib/sqa/config.rb:54`
385
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
386
386
 
387
387
  ---
388
388
 
@@ -398,7 +398,7 @@ Returns whether the configuration has been initialized.
398
398
  Skip API updates if cached data exists
399
399
 
400
400
  ??? info "Source Location"
401
- `lib/sqa/config.rb:54`
401
+ [`lib/sqa/config.rb:54`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L54)
402
402
 
403
403
  ---
404
404
 
@@ -421,7 +421,7 @@ Automatically applies environment variable overrides.
421
421
  a new instance of Config
422
422
 
423
423
  ??? info "Source Location"
424
- `lib/sqa/config.rb:120`
424
+ [`lib/sqa/config.rb:120`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L120)
425
425
 
426
426
  ---
427
427
 
@@ -439,7 +439,7 @@ Returns whether debug mode is enabled.
439
439
  true if debug mode is on
440
440
 
441
441
  ??? info "Source Location"
442
- `lib/sqa/config.rb:127`
442
+ [`lib/sqa/config.rb:127`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L127)
443
443
 
444
444
  ---
445
445
 
@@ -457,7 +457,7 @@ Returns whether verbose mode is enabled.
457
457
  true if verbose mode is on
458
458
 
459
459
  ??? info "Source Location"
460
- `lib/sqa/config.rb:131`
460
+ [`lib/sqa/config.rb:131`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L131)
461
461
 
462
462
  ---
463
463
 
@@ -474,7 +474,7 @@ Supports YAML (.yml, .yaml), TOML (.toml), and JSON (.json) formats.
474
474
 
475
475
 
476
476
  ??? info "Source Location"
477
- `lib/sqa/config.rb:141`
477
+ [`lib/sqa/config.rb:141`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L141)
478
478
 
479
479
  ---
480
480
 
@@ -491,7 +491,7 @@ Format is determined by file extension.
491
491
 
492
492
 
493
493
  ??? info "Source Location"
494
- `lib/sqa/config.rb:178`
494
+ [`lib/sqa/config.rb:178`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L178)
495
495
 
496
496
  ---
497
497
 
@@ -508,7 +508,7 @@ Allows external code to register new configuration options.
508
508
 
509
509
 
510
510
  ??? info "Source Location"
511
- `lib/sqa/config.rb:206`
511
+ [`lib/sqa/config.rb:206`](https://github.com/madbomber/sqa/blob/main/lib/sqa/config.rb#L206)
512
512
 
513
513
  ---
514
514
 
@@ -5,7 +5,7 @@
5
5
  Common causes include missing API keys or invalid data directories.
6
6
 
7
7
  !!! abstract "Source Information"
8
- **Defined in:** `lib/sqa/errors.rb:46`
8
+ **Defined in:** [`lib/sqa/errors.rb:46`](https://github.com/madbomber/sqa/blob/main/lib/sqa/errors.rb#L46)
9
9
 
10
10
  **Inherits from:** `StandardError`
11
11
 
@@ -5,7 +5,7 @@
5
5
  Wraps the original exception for debugging purposes.
6
6
 
7
7
  !!! abstract "Source Information"
8
- **Defined in:** `lib/sqa/errors.rb:26`
8
+ **Defined in:** [`lib/sqa/errors.rb:26`](https://github.com/madbomber/sqa/blob/main/lib/sqa/errors.rb#L26)
9
9
 
10
10
  **Inherits from:** `StandardError`
11
11
 
@@ -23,7 +23,7 @@
23
23
  The original exception that caused this error
24
24
 
25
25
  ??? info "Source Location"
26
- `lib/sqa/errors.rb:28`
26
+ [`lib/sqa/errors.rb:28`](https://github.com/madbomber/sqa/blob/main/lib/sqa/errors.rb#L28)
27
27
 
28
28
  ---
29
29
 
@@ -46,7 +46,7 @@ Creates a new DataFetchError.
46
46
  a new instance of DataFetchError
47
47
 
48
48
  ??? info "Source Location"
49
- `lib/sqa/errors.rb:34`
49
+ [`lib/sqa/errors.rb:34`](https://github.com/madbomber/sqa/blob/main/lib/sqa/errors.rb#L34)
50
50
 
51
51
  ---
52
52
 
@@ -1,12 +1,12 @@
1
1
  # 📦 SQA::DataFrame
2
2
 
3
3
  !!! note "Description"
4
- The website financial.yahoo.com no longer supports an API.
5
- To get recent stock historical price updates you have
6
- to scrape the webpage.
4
+ High-performance DataFrame wrapper around Polars for time series data manipulation.
5
+ Provides convenience methods for stock market data while leveraging Polars' Rust-backed
6
+ performance for vectorized operations.
7
7
 
8
8
  !!! abstract "Source Information"
9
- **Defined in:** `lib/sqa/data_frame.rb:28`
9
+ **Defined in:** [`lib/sqa/data_frame.rb:28`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L28)
10
10
 
11
11
  **Inherits from:** `Object`
12
12
 
@@ -30,7 +30,7 @@ Checks if a value appears to be a date string.
30
30
  true if value matches YYYY-MM-DD format
31
31
 
32
32
  ??? info "Source Location"
33
- `lib/sqa/data_frame.rb:246`
33
+ [`lib/sqa/data_frame.rb:246`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L246)
34
34
 
35
35
  ---
36
36
 
@@ -59,7 +59,7 @@ We only apply them if the CSV has old-format column names that need migration.
59
59
  Loaded DataFrame
60
60
 
61
61
  ??? info "Source Location"
62
- `lib/sqa/data_frame.rb:283`
62
+ [`lib/sqa/data_frame.rb:283`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L283)
63
63
 
64
64
  ---
65
65
 
@@ -88,7 +88,7 @@ Creates a DataFrame from an array of hashes.
88
88
  df = SQA::DataFrame.from_aofh(data)
89
89
  ```
90
90
  ??? info "Source Location"
91
- `lib/sqa/data_frame.rb:302`
91
+ [`lib/sqa/data_frame.rb:302`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L302)
92
92
 
93
93
  ---
94
94
 
@@ -112,7 +112,7 @@ Creates a DataFrame from a CSV file.
112
112
  New DataFrame instance
113
113
 
114
114
  ??? info "Source Location"
115
- `lib/sqa/data_frame.rb:324`
115
+ [`lib/sqa/data_frame.rb:324`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L324)
116
116
 
117
117
  ---
118
118
 
@@ -136,7 +136,7 @@ Creates a DataFrame from a JSON file.
136
136
  New DataFrame instance
137
137
 
138
138
  ??? info "Source Location"
139
- `lib/sqa/data_frame.rb:335`
139
+ [`lib/sqa/data_frame.rb:335`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L335)
140
140
 
141
141
  ---
142
142
 
@@ -158,7 +158,7 @@ Generates a mapping of original keys to underscored keys.
158
158
  Mapping from original to underscored keys
159
159
 
160
160
  ??? info "Source Location"
161
- `lib/sqa/data_frame.rb:344`
161
+ [`lib/sqa/data_frame.rb:344`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L344)
162
162
 
163
163
  ---
164
164
 
@@ -185,7 +185,7 @@ Converts a key string to underscored snake_case format.
185
185
  underscore_key("Close Price") # => :close_price
186
186
  ```
187
187
  ??? info "Source Location"
188
- `lib/sqa/data_frame.rb:359`
188
+ [`lib/sqa/data_frame.rb:359`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L359)
189
189
 
190
190
  ---
191
191
 
@@ -212,7 +212,7 @@ Converts a key string to underscored snake_case format.
212
212
  underscore_key("Close Price") # => :close_price
213
213
  ```
214
214
  ??? info "Source Location"
215
- `lib/sqa/data_frame.rb:371`
215
+ [`lib/sqa/data_frame.rb:371`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L371)
216
216
 
217
217
  ---
218
218
 
@@ -235,7 +235,7 @@ Normalizes all keys in a hash to snake_case format.
235
235
  Hash with normalized keys
236
236
 
237
237
  ??? info "Source Location"
238
- `lib/sqa/data_frame.rb:378`
238
+ [`lib/sqa/data_frame.rb:378`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L378)
239
239
 
240
240
  ---
241
241
 
@@ -258,7 +258,7 @@ Renames keys in a hash according to a mapping.
258
258
  Modified hash
259
259
 
260
260
  ??? info "Source Location"
261
- `lib/sqa/data_frame.rb:389`
261
+ [`lib/sqa/data_frame.rb:389`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L389)
262
262
 
263
263
  ---
264
264
 
@@ -282,7 +282,7 @@ Converts array of hashes to hash of arrays format.
282
282
  Hash with column names as keys and arrays as values
283
283
 
284
284
  ??? info "Source Location"
285
- `lib/sqa/data_frame.rb:400`
285
+ [`lib/sqa/data_frame.rb:400`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L400)
286
286
 
287
287
  ---
288
288
 
@@ -300,7 +300,7 @@ Converts array of hashes to hash of arrays format.
300
300
  The underlying Polars DataFrame
301
301
 
302
302
  ??? info "Source Location"
303
- `lib/sqa/data_frame.rb:33`
303
+ [`lib/sqa/data_frame.rb:33`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L33)
304
304
 
305
305
  ---
306
306
 
@@ -316,7 +316,7 @@ Sets the attribute data
316
316
 
317
317
 
318
318
  ??? info "Source Location"
319
- `lib/sqa/data_frame.rb:33`
319
+ [`lib/sqa/data_frame.rb:33`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L33)
320
320
 
321
321
  ---
322
322
 
@@ -348,7 +348,7 @@ Creates a new DataFrame instance.
348
348
  df = SQA::DataFrame.new(data, transformers: { "price" => ->(v) { v.to_f } })
349
349
  ```
350
350
  ??? info "Source Location"
351
- `lib/sqa/data_frame.rb:47`
351
+ [`lib/sqa/data_frame.rb:47`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L47)
352
352
 
353
353
  ---
354
354
 
@@ -372,7 +372,7 @@ Applies transformer functions to specified columns in place.
372
372
  df.apply_transformers!({ "price" => ->(v) { v.to_f }, "volume" => ->(v) { v.to_i } })
373
373
  ```
374
374
  ??? info "Source Location"
375
- `lib/sqa/data_frame.rb:65`
375
+ [`lib/sqa/data_frame.rb:65`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L65)
376
376
 
377
377
  ---
378
378
 
@@ -396,7 +396,7 @@ Renames columns according to the provided mapping in place.
396
396
  df.rename_columns!({ "open" => "open_price", "close" => "close_price" })
397
397
  ```
398
398
  ??? info "Source Location"
399
- `lib/sqa/data_frame.rb:82`
399
+ [`lib/sqa/data_frame.rb:82`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L82)
400
400
 
401
401
  ---
402
402
 
@@ -420,7 +420,7 @@ Appends another DataFrame to this one in place.
420
420
  df1.append!(df2)
421
421
  ```
422
422
  ??? info "Source Location"
423
- `lib/sqa/data_frame.rb:107`
423
+ [`lib/sqa/data_frame.rb:107`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L107)
424
424
 
425
425
  ---
426
426
 
@@ -444,7 +444,7 @@ Appends another DataFrame to this one in place.
444
444
  df1.append!(df2)
445
445
  ```
446
446
  ??? info "Source Location"
447
- `lib/sqa/data_frame.rb:124`
447
+ [`lib/sqa/data_frame.rb:124`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L124)
448
448
 
449
449
  ---
450
450
 
@@ -464,9 +464,27 @@ will produce a warning and force ascending order to prevent silent calculation e
464
464
  | `sort_column` | `String` | Column to use for deduplication and sorting (default: "timestamp") |
465
465
  | `descending` | `Boolean` | Sort order - false for ascending (oldest first, TA-Lib compatible), true for descending |
466
466
 
467
+ !!! example "Usage Examples"
467
468
 
469
+ ```ruby
470
+ stock = SQA::Stock.new(ticker: 'AAPL')
471
+ df = stock.df
472
+ df.size # => 252
473
+
474
+ # Fetch recent data (may have overlapping dates)
475
+ new_df = SQA::DataFrame::AlphaVantage.recent('AAPL', from_date: Date.today - 7)
476
+ df.concat_and_deduplicate!(new_df)
477
+ # Duplicates removed, data sorted ascending (oldest first)
478
+ df.size # => 255 (only 3 new unique dates added)
479
+ ```
480
+
481
+ ```ruby
482
+ df.concat_and_deduplicate!(new_df) # Sorted ascending automatically
483
+ prices = df["adj_close_price"].to_a
484
+ rsi = SQAI.rsi(prices, period: 14) # Works correctly with ascending data
485
+ ```
468
486
  ??? info "Source Location"
469
- `lib/sqa/data_frame.rb:135`
487
+ [`lib/sqa/data_frame.rb:135`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L135)
470
488
 
471
489
  ---
472
490
 
@@ -484,7 +502,7 @@ Returns the column names of the DataFrame.
484
502
  List of column names
485
503
 
486
504
  ??? info "Source Location"
487
- `lib/sqa/data_frame.rb:159`
505
+ [`lib/sqa/data_frame.rb:159`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L159)
488
506
 
489
507
  ---
490
508
 
@@ -503,7 +521,7 @@ Alias for {#columns}.
503
521
  List of column names
504
522
 
505
523
  ??? info "Source Location"
506
- `lib/sqa/data_frame.rb:167`
524
+ [`lib/sqa/data_frame.rb:167`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L167)
507
525
 
508
526
  ---
509
527
 
@@ -522,7 +540,7 @@ Alias for {#columns}.
522
540
  List of column names
523
541
 
524
542
  ??? info "Source Location"
525
- `lib/sqa/data_frame.rb:170`
543
+ [`lib/sqa/data_frame.rb:170`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L170)
526
544
 
527
545
  ---
528
546
 
@@ -544,7 +562,7 @@ Converts the DataFrame to a Ruby Hash.
544
562
  df.to_h # => { timestamp: ["2024-01-01", ...], close_price: [100.0, ...] }
545
563
  ```
546
564
  ??? info "Source Location"
547
- `lib/sqa/data_frame.rb:179`
565
+ [`lib/sqa/data_frame.rb:179`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L179)
548
566
 
549
567
  ---
550
568
 
@@ -562,9 +580,18 @@ Writes the DataFrame to a CSV file.
562
580
  **Type:** `void`
563
581
 
564
582
 
583
+ !!! example "Usage Examples"
565
584
 
585
+ ```ruby
586
+ stock = SQA::Stock.new(ticker: 'AAPL')
587
+ stock.df.to_csv('aapl_prices.csv')
588
+ ```
589
+
590
+ ```ruby
591
+ df.to_csv(Pathname.new('data/exports/prices.csv'))
592
+ ```
566
593
  ??? info "Source Location"
567
- `lib/sqa/data_frame.rb:187`
594
+ [`lib/sqa/data_frame.rb:187`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L187)
568
595
 
569
596
  ---
570
597
 
@@ -582,7 +609,7 @@ Returns the number of rows in the DataFrame.
582
609
  Row count
583
610
 
584
611
  ??? info "Source Location"
585
- `lib/sqa/data_frame.rb:194`
612
+ [`lib/sqa/data_frame.rb:194`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L194)
586
613
 
587
614
  ---
588
615
 
@@ -600,7 +627,7 @@ Returns the number of rows in the DataFrame.
600
627
  Row count
601
628
 
602
629
  ??? info "Source Location"
603
- `lib/sqa/data_frame.rb:197`
630
+ [`lib/sqa/data_frame.rb:197`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L197)
604
631
 
605
632
  ---
606
633
 
@@ -618,7 +645,7 @@ Returns the number of rows in the DataFrame.
618
645
  Row count
619
646
 
620
647
  ??? info "Source Location"
621
- `lib/sqa/data_frame.rb:198`
648
+ [`lib/sqa/data_frame.rb:198`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L198)
622
649
 
623
650
  ---
624
651
 
@@ -636,7 +663,7 @@ Returns the number of columns in the DataFrame.
636
663
  Column count
637
664
 
638
665
  ??? info "Source Location"
639
- `lib/sqa/data_frame.rb:203`
666
+ [`lib/sqa/data_frame.rb:203`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L203)
640
667
 
641
668
  ---
642
669
 
@@ -664,7 +691,7 @@ FPL Analysis - Calculate Future Period Loss/Profit
664
691
  fpl_data = stock.df.fpl(fpop: 10)
665
692
  ```
666
693
  ??? info "Source Location"
667
- `lib/sqa/data_frame.rb:218`
694
+ [`lib/sqa/data_frame.rb:218`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L218)
668
695
 
669
696
  ---
670
697
 
@@ -694,7 +721,7 @@ FPL Analysis with risk metrics and classification
694
721
  analysis.first[:risk] # => Volatility range
695
722
  ```
696
723
  ??? info "Source Location"
697
- `lib/sqa/data_frame.rb:236`
724
+ [`lib/sqa/data_frame.rb:236`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L236)
698
725
 
699
726
  ---
700
727
 
@@ -719,7 +746,7 @@ This allows direct access to Polars methods like filter, select, etc.
719
746
  Result from Polars DataFrame method
720
747
 
721
748
  ??? info "Source Location"
722
- `lib/sqa/data_frame.rb:257`
749
+ [`lib/sqa/data_frame.rb:257`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L257)
723
750
 
724
751
  ---
725
752
 
@@ -742,7 +769,7 @@ Checks if the DataFrame responds to a method.
742
769
  true if method is available
743
770
 
744
771
  ??? info "Source Location"
745
- `lib/sqa/data_frame.rb:267`
772
+ [`lib/sqa/data_frame.rb:267`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame.rb#L267)
746
773
 
747
774
  ---
748
775
 
@@ -1,7 +1,7 @@
1
1
  # 📦 SQA::DataFrame::AlphaVantage
2
2
 
3
3
  !!! abstract "Source Information"
4
- **Defined in:** `lib/sqa/data_frame/alpha_vantage.rb:9`
4
+ **Defined in:** [`lib/sqa/data_frame/alpha_vantage.rb:9`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame/alpha_vantage.rb#L9)
5
5
 
6
6
  **Inherits from:** `Object`
7
7
 
@@ -22,7 +22,7 @@ Note: Alpha Vantage returns data newest-first, but we sort ascending for TA-Lib
22
22
 
23
23
 
24
24
  ??? info "Source Location"
25
- `lib/sqa/data_frame/alpha_vantage.rb:46`
25
+ [`lib/sqa/data_frame/alpha_vantage.rb:46`](https://github.com/madbomber/sqa/blob/main/lib/sqa/data_frame/alpha_vantage.rb#L46)
26
26
 
27
27
  ---
28
28