sqa 0.0.32 → 0.0.37

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -1
  3. data/README.md +4 -0
  4. data/Rakefile +52 -10
  5. data/docs/IMPROVEMENT_PLAN.md +531 -0
  6. data/docs/advanced/index.md +1 -13
  7. data/docs/api/index.md +547 -61
  8. data/docs/api-reference/alphavantageapi.md +1057 -0
  9. data/docs/api-reference/apierror.md +31 -0
  10. data/docs/api-reference/index.md +221 -0
  11. data/docs/api-reference/notimplemented.md +27 -0
  12. data/docs/api-reference/sqa.md +267 -0
  13. data/docs/api-reference/sqa_backtest.md +137 -0
  14. data/docs/api-reference/sqa_backtest_results.md +530 -0
  15. data/docs/api-reference/sqa_badparametererror.md +13 -0
  16. data/docs/api-reference/sqa_config.md +538 -0
  17. data/docs/api-reference/sqa_configurationerror.md +13 -0
  18. data/docs/api-reference/sqa_datafetcherror.md +56 -0
  19. data/docs/api-reference/sqa_dataframe.md +752 -0
  20. data/docs/api-reference/sqa_dataframe_alphavantage.md +30 -0
  21. data/docs/api-reference/sqa_dataframe_data.md +325 -0
  22. data/docs/api-reference/sqa_dataframe_yahoofinance.md +25 -0
  23. data/docs/api-reference/sqa_ensemble.md +413 -0
  24. data/docs/api-reference/sqa_fpop.md +211 -0
  25. data/docs/api-reference/sqa_geneticprogram.md +325 -0
  26. data/docs/api-reference/sqa_geneticprogram_individual.md +114 -0
  27. data/docs/api-reference/sqa_marketregime.md +212 -0
  28. data/docs/api-reference/sqa_multitimeframe.md +227 -0
  29. data/docs/api-reference/sqa_patternmatcher.md +195 -0
  30. data/docs/api-reference/sqa_pluginmanager.md +55 -0
  31. data/docs/api-reference/sqa_portfolio.md +455 -0
  32. data/docs/api-reference/sqa_portfolio_position.md +220 -0
  33. data/docs/api-reference/sqa_portfolio_trade.md +332 -0
  34. data/docs/api-reference/sqa_portfoliooptimizer.md +248 -0
  35. data/docs/api-reference/sqa_riskmanager.md +388 -0
  36. data/docs/api-reference/sqa_seasonalanalyzer.md +121 -0
  37. data/docs/api-reference/sqa_sectoranalyzer.md +163 -0
  38. data/docs/api-reference/sqa_stock.md +649 -0
  39. data/docs/api-reference/sqa_strategy.md +178 -0
  40. data/docs/api-reference/sqa_strategy_bollingerbands.md +26 -0
  41. data/docs/api-reference/sqa_strategy_common.md +29 -0
  42. data/docs/api-reference/sqa_strategy_consensus.md +129 -0
  43. data/docs/api-reference/sqa_strategy_ema.md +41 -0
  44. data/docs/api-reference/sqa_strategy_kbs.md +154 -0
  45. data/docs/api-reference/sqa_strategy_macd.md +26 -0
  46. data/docs/api-reference/sqa_strategy_mp.md +41 -0
  47. data/docs/api-reference/sqa_strategy_mr.md +41 -0
  48. data/docs/api-reference/sqa_strategy_random.md +41 -0
  49. data/docs/api-reference/sqa_strategy_rsi.md +41 -0
  50. data/docs/api-reference/sqa_strategy_sma.md +41 -0
  51. data/docs/api-reference/sqa_strategy_stochastic.md +26 -0
  52. data/docs/api-reference/sqa_strategy_volumebreakout.md +26 -0
  53. data/docs/api-reference/sqa_strategygenerator.md +298 -0
  54. data/docs/api-reference/sqa_strategygenerator_pattern.md +264 -0
  55. data/docs/api-reference/sqa_strategygenerator_patterncontext.md +326 -0
  56. data/docs/api-reference/sqa_strategygenerator_profitablepoint.md +424 -0
  57. data/docs/api-reference/sqa_stream.md +256 -0
  58. data/docs/api-reference/sqa_ticker.md +175 -0
  59. data/docs/api-reference/string.md +135 -0
  60. data/docs/assets/images/advanced-workflow.svg +89 -0
  61. data/docs/assets/images/architecture.svg +107 -0
  62. data/docs/assets/images/data-flow.svg +138 -0
  63. data/docs/assets/images/getting-started-workflow.svg +88 -0
  64. data/docs/assets/images/strategy-flow.svg +78 -0
  65. data/docs/assets/images/system-architecture.svg +150 -0
  66. data/docs/concepts/index.md +292 -19
  67. data/docs/getting-started/index.md +1 -14
  68. data/docs/index.md +26 -23
  69. data/docs/llms.txt +109 -0
  70. data/docs/strategies/kbs.md +15 -14
  71. data/docs/strategy.md +381 -3
  72. data/docs/terms_of_use.md +1 -1
  73. data/examples/README.md +10 -0
  74. data/lib/api/alpha_vantage_api.rb +3 -7
  75. data/lib/sqa/config.rb +109 -28
  76. data/lib/sqa/data_frame/data.rb +13 -1
  77. data/lib/sqa/data_frame.rb +168 -26
  78. data/lib/sqa/errors.rb +79 -17
  79. data/lib/sqa/init.rb +70 -15
  80. data/lib/sqa/pattern_matcher.rb +4 -4
  81. data/lib/sqa/portfolio.rb +1 -1
  82. data/lib/sqa/sector_analyzer.rb +3 -11
  83. data/lib/sqa/stock.rb +169 -15
  84. data/lib/sqa/strategy.rb +62 -4
  85. data/lib/sqa/ticker.rb +106 -48
  86. data/lib/sqa/version.rb +1 -1
  87. data/lib/sqa.rb +4 -4
  88. data/mkdocs.yml +68 -81
  89. metadata +89 -21
  90. data/docs/README.md +0 -43
  91. data/examples/sinatra_app/Gemfile +0 -42
  92. data/examples/sinatra_app/Gemfile.lock +0 -268
  93. data/examples/sinatra_app/QUICKSTART.md +0 -169
  94. data/examples/sinatra_app/README.md +0 -471
  95. data/examples/sinatra_app/RUNNING_WITHOUT_TALIB.md +0 -90
  96. data/examples/sinatra_app/TROUBLESHOOTING.md +0 -95
  97. data/examples/sinatra_app/app.rb +0 -404
  98. data/examples/sinatra_app/config.ru +0 -5
  99. data/examples/sinatra_app/public/css/style.css +0 -723
  100. data/examples/sinatra_app/public/debug_macd.html +0 -82
  101. data/examples/sinatra_app/public/js/app.js +0 -107
  102. data/examples/sinatra_app/start.sh +0 -53
  103. data/examples/sinatra_app/views/analyze.erb +0 -306
  104. data/examples/sinatra_app/views/backtest.erb +0 -325
  105. data/examples/sinatra_app/views/dashboard.erb +0 -831
  106. data/examples/sinatra_app/views/error.erb +0 -58
  107. data/examples/sinatra_app/views/index.erb +0 -118
  108. data/examples/sinatra_app/views/layout.erb +0 -61
  109. data/examples/sinatra_app/views/portfolio.erb +0 -43
@@ -0,0 +1,413 @@
1
+ # 📦 SQA::Ensemble
2
+
3
+ !!! note "Description"
4
+ Ensemble - Combine multiple trading strategies
5
+
6
+ Provides methods for:
7
+ - Majority voting
8
+ - Weighted voting based on past performance
9
+ - Meta-learning (strategy selection)
10
+ - Strategy rotation based on market conditions
11
+ - Confidence-based aggregation
12
+
13
+ !!! abstract "Source Information"
14
+ **Defined in:** `lib/sqa/ensemble.rb:22`
15
+
16
+ **Inherits from:** `Object`
17
+
18
+ ## 🏭 Class Methods
19
+
20
+ ### `.trade(vector)`
21
+
22
+ Make ensemble compatible with Backtest (acts like a strategy)
23
+
24
+ !!! info "Parameters"
25
+
26
+ | Name | Type | Description |
27
+ |------|------|-------------|
28
+ | `vector` | `OpenStruct` | Market data |
29
+ !!! success "Returns"
30
+
31
+ **Type:** `Symbol`
32
+
33
+
34
+
35
+ Trading signal
36
+
37
+ ??? info "Source Location"
38
+ `lib/sqa/ensemble.rb:275`
39
+
40
+ ---
41
+
42
+ ## 🔨 Instance Methods
43
+
44
+ ### `#strategies()`
45
+
46
+ Returns the value of attribute strategies.
47
+
48
+
49
+
50
+
51
+ ??? info "Source Location"
52
+ `lib/sqa/ensemble.rb:23`
53
+
54
+ ---
55
+
56
+ ### `#strategies=(value)`
57
+
58
+ Sets the attribute strategies
59
+
60
+ !!! info "Parameters"
61
+
62
+ | Name | Type | Description |
63
+ |------|------|-------------|
64
+ | `value` | `Any` | the value to set the attribute strategies to. |
65
+
66
+
67
+ ??? info "Source Location"
68
+ `lib/sqa/ensemble.rb:23`
69
+
70
+ ---
71
+
72
+ ### `#weights()`
73
+
74
+ Returns the value of attribute weights.
75
+
76
+
77
+
78
+
79
+ ??? info "Source Location"
80
+ `lib/sqa/ensemble.rb:23`
81
+
82
+ ---
83
+
84
+ ### `#weights=(value)`
85
+
86
+ Sets the attribute weights
87
+
88
+ !!! info "Parameters"
89
+
90
+ | Name | Type | Description |
91
+ |------|------|-------------|
92
+ | `value` | `Any` | the value to set the attribute weights to. |
93
+
94
+
95
+ ??? info "Source Location"
96
+ `lib/sqa/ensemble.rb:23`
97
+
98
+ ---
99
+
100
+ ### `#performance_history()`
101
+
102
+ Returns the value of attribute performance_history.
103
+
104
+
105
+
106
+
107
+ ??? info "Source Location"
108
+ `lib/sqa/ensemble.rb:23`
109
+
110
+ ---
111
+
112
+ ### `#performance_history=(value)`
113
+
114
+ Sets the attribute performance_history
115
+
116
+ !!! info "Parameters"
117
+
118
+ | Name | Type | Description |
119
+ |------|------|-------------|
120
+ | `value` | `Any` | the value to set the attribute performance_history to. |
121
+
122
+
123
+ ??? info "Source Location"
124
+ `lib/sqa/ensemble.rb:23`
125
+
126
+ ---
127
+
128
+ ### `#initialize(strategies:, voting_method: = :majority, weights: = nil)`
129
+
130
+ Initialize ensemble
131
+
132
+ !!! info "Parameters"
133
+
134
+ | Name | Type | Description |
135
+ |------|------|-------------|
136
+ | `strategies` | `Array<Class>` | Array of strategy classes |
137
+ | `voting_method` | `Symbol` | :majority, :weighted, :unanimous, :confidence |
138
+ | `weights` | `Array<Float>` | Optional weights for weighted voting |
139
+ !!! success "Returns"
140
+
141
+ **Type:** `Ensemble`
142
+
143
+
144
+
145
+ a new instance of Ensemble
146
+
147
+ ??? info "Source Location"
148
+ `lib/sqa/ensemble.rb:32`
149
+
150
+ ---
151
+
152
+ ### `#signal(vector)`
153
+
154
+ Generate ensemble signal
155
+
156
+ !!! info "Parameters"
157
+
158
+ | Name | Type | Description |
159
+ |------|------|-------------|
160
+ | `vector` | `OpenStruct` | Market data vector |
161
+ !!! success "Returns"
162
+
163
+ **Type:** `Symbol`
164
+
165
+
166
+
167
+ :buy, :sell, or :hold
168
+
169
+ ??? info "Source Location"
170
+ `lib/sqa/ensemble.rb:46`
171
+
172
+ ---
173
+
174
+ ### `#majority_vote(vector)`
175
+
176
+ Majority voting
177
+
178
+ !!! info "Parameters"
179
+
180
+ | Name | Type | Description |
181
+ |------|------|-------------|
182
+ | `vector` | `OpenStruct` | Market data |
183
+ !!! success "Returns"
184
+
185
+ **Type:** `Symbol`
186
+
187
+
188
+
189
+ Signal with most votes
190
+
191
+ ??? info "Source Location"
192
+ `lib/sqa/ensemble.rb:67`
193
+
194
+ ---
195
+
196
+ ### `#weighted_vote(vector)`
197
+
198
+ Weighted voting based on strategy performance
199
+
200
+ !!! info "Parameters"
201
+
202
+ | Name | Type | Description |
203
+ |------|------|-------------|
204
+ | `vector` | `OpenStruct` | Market data |
205
+ !!! success "Returns"
206
+
207
+ **Type:** `Symbol`
208
+
209
+
210
+
211
+ Weighted signal
212
+
213
+ ??? info "Source Location"
214
+ `lib/sqa/ensemble.rb:84`
215
+
216
+ ---
217
+
218
+ ### `#unanimous_vote(vector)`
219
+
220
+ Unanimous voting (all strategies must agree)
221
+
222
+ !!! info "Parameters"
223
+
224
+ | Name | Type | Description |
225
+ |------|------|-------------|
226
+ | `vector` | `OpenStruct` | Market data |
227
+ !!! success "Returns"
228
+
229
+ **Type:** `Symbol`
230
+
231
+
232
+
233
+ :buy/:sell only if unanimous, otherwise :hold
234
+
235
+ ??? info "Source Location"
236
+ `lib/sqa/ensemble.rb:104`
237
+
238
+ ---
239
+
240
+ ### `#confidence_vote(vector)`
241
+
242
+ Confidence-based voting
243
+
244
+ Weight votes by strategy confidence scores.
245
+
246
+ !!! info "Parameters"
247
+
248
+ | Name | Type | Description |
249
+ |------|------|-------------|
250
+ | `vector` | `OpenStruct` | Market data |
251
+ !!! success "Returns"
252
+
253
+ **Type:** `Symbol`
254
+
255
+
256
+
257
+ Signal weighted by confidence
258
+
259
+ ??? info "Source Location"
260
+ `lib/sqa/ensemble.rb:125`
261
+
262
+ ---
263
+
264
+ ### `#update_weight(strategy_index, performance)`
265
+
266
+ Update strategy weights based on performance
267
+
268
+ Adjust weights to favor better-performing strategies.
269
+
270
+ !!! info "Parameters"
271
+
272
+ | Name | Type | Description |
273
+ |------|------|-------------|
274
+ | `strategy_index` | `Integer` | Index of strategy |
275
+ | `performance` | `Float` | Performance metric (e.g., return) |
276
+
277
+
278
+ ??? info "Source Location"
279
+ `lib/sqa/ensemble.rb:147`
280
+
281
+ ---
282
+
283
+ ### `#update_confidence(strategy_class, correct)`
284
+
285
+ Update confidence score for strategy
286
+
287
+ !!! info "Parameters"
288
+
289
+ | Name | Type | Description |
290
+ |------|------|-------------|
291
+ | `strategy_class` | `Class` | Strategy class |
292
+ | `correct` | `Boolean` | Was the prediction correct? |
293
+
294
+
295
+ ??? info "Source Location"
296
+ `lib/sqa/ensemble.rb:160`
297
+
298
+ ---
299
+
300
+ ### `#select_strategy(market_regime:, volatility: = :medium)`
301
+
302
+ Select best strategy for current market conditions
303
+
304
+ Meta-learning approach: choose the strategy most likely to succeed.
305
+
306
+ !!! info "Parameters"
307
+
308
+ | Name | Type | Description |
309
+ |------|------|-------------|
310
+ | `market_regime` | `Symbol` | Current market regime (:bull, :bear, :sideways) |
311
+ | `volatility` | `Symbol` | Volatility regime (:low, :medium, :high) |
312
+ !!! success "Returns"
313
+
314
+ **Type:** `Class`
315
+
316
+
317
+
318
+ Best strategy class for conditions
319
+
320
+ ??? info "Source Location"
321
+ `lib/sqa/ensemble.rb:181`
322
+
323
+ ---
324
+
325
+ ### `#rotate(stock)`
326
+
327
+ Rotate strategies based on market conditions
328
+
329
+ !!! info "Parameters"
330
+
331
+ | Name | Type | Description |
332
+ |------|------|-------------|
333
+ | `stock` | `SQA::Stock` | Stock object |
334
+ !!! success "Returns"
335
+
336
+ **Type:** `Class`
337
+
338
+
339
+
340
+ Strategy to use
341
+
342
+ ??? info "Source Location"
343
+ `lib/sqa/ensemble.rb:213`
344
+
345
+ ---
346
+
347
+ ### `#statistics()`
348
+
349
+ Get ensemble statistics
350
+
351
+
352
+ !!! success "Returns"
353
+
354
+ **Type:** `Hash`
355
+
356
+
357
+
358
+ Performance statistics
359
+
360
+ ??? info "Source Location"
361
+ `lib/sqa/ensemble.rb:227`
362
+
363
+ ---
364
+
365
+ ### `#backtest_comparison(stock, initial_capital: = 10_000)`
366
+
367
+ Backtest ensemble vs individual strategies
368
+
369
+ !!! info "Parameters"
370
+
371
+ | Name | Type | Description |
372
+ |------|------|-------------|
373
+ | `stock` | `SQA::Stock` | Stock to backtest |
374
+ | `initial_capital` | `Float` | Starting capital |
375
+ !!! success "Returns"
376
+
377
+ **Type:** `Hash`
378
+
379
+
380
+
381
+ Comparison results
382
+
383
+ ??? info "Source Location"
384
+ `lib/sqa/ensemble.rb:245`
385
+
386
+ ---
387
+
388
+ ### `#trade(vector)`
389
+
390
+ Instance method for compatibility
391
+
392
+
393
+
394
+
395
+ ??? info "Source Location"
396
+ `lib/sqa/ensemble.rb:283`
397
+
398
+ ---
399
+
400
+ ## 📝 Attributes
401
+
402
+ ### 🔄 `strategies` <small>read/write</small>
403
+
404
+ Returns the value of attribute strategies.
405
+
406
+ ### 🔄 `weights` <small>read/write</small>
407
+
408
+ Returns the value of attribute weights.
409
+
410
+ ### 🔄 `performance_history` <small>read/write</small>
411
+
412
+ Returns the value of attribute performance_history.
413
+
@@ -0,0 +1,211 @@
1
+ # 🔧 SQA::FPOP
2
+
3
+ !!! abstract "Source Information"
4
+ **Defined in:** `lib/sqa/fpop.rb:28`
5
+
6
+ ## 🏭 Class Methods
7
+
8
+ ### `.fpl(price, fpop: = 14)`
9
+
10
+ Calculate Future Period Loss/Profit for each point in price series
11
+
12
+ For each price point, looks ahead fpop periods and calculates:
13
+ - Minimum percentage change (worst loss)
14
+ - Maximum percentage change (best gain)
15
+
16
+ !!! info "Parameters"
17
+
18
+ | Name | Type | Description |
19
+ |------|------|-------------|
20
+ | `price` | `Array<Numeric>` | Array of prices |
21
+ | `fpop` | `Integer` | Future Period of Performance (days to look ahead) |
22
+ !!! success "Returns"
23
+
24
+ **Type:** `Array<Array<Float, Float>>`
25
+
26
+
27
+
28
+ Array of [min_delta, max_delta] pairs
29
+ !!! example "Usage Examples"
30
+
31
+ ```ruby
32
+ SQA::FPOP.fpl([100, 105, 95, 110], fpop: 2)
33
+ # => [[-5.0, 5.0], [-9.52, 4.76], [15.79, 15.79]]
34
+ ```
35
+ ??? info "Source Location"
36
+ `lib/sqa/fpop.rb:44`
37
+
38
+ ---
39
+
40
+ ### `.fpl_analysis(price, fpop: = 14)`
41
+
42
+ Perform comprehensive FPL analysis with risk metrics and classification
43
+
44
+ !!! info "Parameters"
45
+
46
+ | Name | Type | Description |
47
+ |------|------|-------------|
48
+ | `price` | `Array<Numeric>` | Array of prices |
49
+ | `fpop` | `Integer` | Future Period of Performance |
50
+ !!! success "Returns"
51
+
52
+ **Type:** `Array<Hash>`
53
+
54
+
55
+
56
+ Array of analysis hashes containing:
57
+ - :min_delta - Worst percentage loss during fpop
58
+ - :max_delta - Best percentage gain during fpop
59
+ - :risk - Volatility range (max - min)
60
+ - :direction - Movement classification (:UP, :DOWN, :UNCERTAIN, :FLAT)
61
+ - :magnitude - Average expected movement
62
+ - :interpretation - Human-readable summary
63
+ !!! example "Usage Examples"
64
+
65
+ ```ruby
66
+ analysis = SQA::FPOP.fpl_analysis([100, 110, 120], fpop: 2)
67
+ analysis.first
68
+ # => {
69
+ # min_delta: 10.0,
70
+ # max_delta: 20.0,
71
+ # risk: 10.0,
72
+ # direction: :UP,
73
+ # magnitude: 15.0,
74
+ # interpretation: "UP: 15.0% (±5.0% risk)"
75
+ # }
76
+ ```
77
+ ??? info "Source Location"
78
+ `lib/sqa/fpop.rb:85`
79
+
80
+ ---
81
+
82
+ ### `.determine_direction(min_delta, max_delta)`
83
+
84
+ Determine directional bias from min/max deltas
85
+
86
+ !!! info "Parameters"
87
+
88
+ | Name | Type | Description |
89
+ |------|------|-------------|
90
+ | `min_delta` | `Float` | Minimum percentage change |
91
+ | `max_delta` | `Float` | Maximum percentage change |
92
+ !!! success "Returns"
93
+
94
+ **Type:** `Symbol`
95
+
96
+
97
+
98
+ :UP, :DOWN, :UNCERTAIN, or :FLAT
99
+
100
+ ??? info "Source Location"
101
+ `lib/sqa/fpop.rb:108`
102
+
103
+ ---
104
+
105
+ ### `.calculate_magnitude(min_delta, max_delta)`
106
+
107
+ Calculate average expected movement (magnitude)
108
+
109
+ !!! info "Parameters"
110
+
111
+ | Name | Type | Description |
112
+ |------|------|-------------|
113
+ | `min_delta` | `Float` | Minimum percentage change |
114
+ | `max_delta` | `Float` | Maximum percentage change |
115
+ !!! success "Returns"
116
+
117
+ **Type:** `Float`
118
+
119
+
120
+
121
+ Average of min and max deltas
122
+
123
+ ??? info "Source Location"
124
+ `lib/sqa/fpop.rb:126`
125
+
126
+ ---
127
+
128
+ ### `.build_interpretation(min_delta, max_delta)`
129
+
130
+ Build human-readable interpretation string
131
+
132
+ !!! info "Parameters"
133
+
134
+ | Name | Type | Description |
135
+ |------|------|-------------|
136
+ | `min_delta` | `Float` | Minimum percentage change |
137
+ | `max_delta` | `Float` | Maximum percentage change |
138
+ !!! success "Returns"
139
+
140
+ **Type:** `String`
141
+
142
+
143
+
144
+ Formatted interpretation
145
+
146
+ ??? info "Source Location"
147
+ `lib/sqa/fpop.rb:136`
148
+
149
+ ---
150
+
151
+ ### `.filter_by_quality(analysis, min_magnitude: = nil, max_risk: = nil, directions: = [:UP, :DOWN, :UNCERTAIN, :FLAT])`
152
+
153
+ Filter FPL analysis results by criteria
154
+
155
+ Useful for finding high-quality trading opportunities
156
+
157
+ !!! info "Parameters"
158
+
159
+ | Name | Type | Description |
160
+ |------|------|-------------|
161
+ | `analysis` | `Array<Hash>` | FPL analysis results |
162
+ | `min_magnitude` | `Float` | Minimum average movement (default: nil) |
163
+ | `max_risk` | `Float` | Maximum acceptable risk (default: nil) |
164
+ | `directions` | `Array<Symbol>` | Acceptable directions (default: [:UP, :DOWN, :UNCERTAIN, :FLAT]) |
165
+ !!! success "Returns"
166
+
167
+ **Type:** `Array<Integer>`
168
+
169
+
170
+
171
+ Indices of points that meet criteria
172
+ !!! example "Usage Examples"
173
+
174
+ ```ruby
175
+ analysis = SQA::FPOP.fpl_analysis(prices, fpop: 10)
176
+ indices = SQA::FPOP.filter_by_quality(
177
+ analysis,
178
+ min_magnitude: 5.0,
179
+ max_risk: 10.0,
180
+ directions: [:UP]
181
+ )
182
+ ```
183
+ ??? info "Source Location"
184
+ `lib/sqa/fpop.rb:163`
185
+
186
+ ---
187
+
188
+ ### `.risk_reward_ratios(analysis)`
189
+
190
+ Calculate risk-reward ratio for each analysis point
191
+
192
+ !!! info "Parameters"
193
+
194
+ | Name | Type | Description |
195
+ |------|------|-------------|
196
+ | `analysis` | `Array<Hash>` | FPL analysis results |
197
+ !!! success "Returns"
198
+
199
+ **Type:** `Array<Float>`
200
+
201
+
202
+
203
+ Risk-reward ratios (magnitude / risk)
204
+
205
+ ??? info "Source Location"
206
+ `lib/sqa/fpop.rb:182`
207
+
208
+ ---
209
+
210
+ ## 📝 Attributes
211
+