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.
- checksums.yaml +4 -4
- data/.goose/memory/development.txt +3 -0
- data/.semver +6 -0
- data/ARCHITECTURE.md +648 -0
- data/CHANGELOG.md +82 -0
- data/CLAUDE.md +653 -0
- data/COMMITS.md +196 -0
- data/DATAFRAME_ARCHITECTURE_REVIEW.md +421 -0
- data/NEXT-STEPS.md +154 -0
- data/README.md +812 -262
- data/TASKS.md +358 -0
- data/TEST_RESULTS.md +140 -0
- data/TODO.md +42 -0
- data/_notes.txt +25 -0
- data/bin/sqa-console +11 -0
- data/data/talk_talk.json +103284 -0
- data/develop_summary.md +313 -0
- data/docs/advanced/backtesting.md +206 -0
- data/docs/advanced/ensemble.md +68 -0
- data/docs/advanced/fpop.md +153 -0
- data/docs/advanced/index.md +112 -0
- data/docs/advanced/multi-timeframe.md +67 -0
- data/docs/advanced/pattern-matcher.md +75 -0
- data/docs/advanced/portfolio-optimizer.md +79 -0
- data/docs/advanced/portfolio.md +166 -0
- data/docs/advanced/risk-management.md +210 -0
- data/docs/advanced/strategy-generator.md +158 -0
- data/docs/advanced/streaming.md +209 -0
- data/docs/ai_and_ml.md +80 -0
- data/docs/api/dataframe.md +1115 -0
- data/docs/api/index.md +126 -0
- data/docs/assets/css/custom.css +88 -0
- data/docs/assets/js/mathjax.js +18 -0
- data/docs/concepts/index.md +68 -0
- data/docs/contributing/index.md +60 -0
- data/docs/data-sources/index.md +66 -0
- data/docs/data_frame.md +317 -97
- data/docs/factors_that_impact_price.md +26 -0
- data/docs/finviz.md +11 -0
- data/docs/fx_pro_bit.md +25 -0
- data/docs/genetic_programming.md +104 -0
- data/docs/getting-started/index.md +123 -0
- data/docs/getting-started/installation.md +229 -0
- data/docs/getting-started/quick-start.md +244 -0
- data/docs/i_gotta_an_idea.md +22 -0
- data/docs/index.md +163 -0
- data/docs/indicators/index.md +97 -0
- data/docs/indicators.md +110 -24
- data/docs/options.md +8 -0
- data/docs/strategies/bollinger-bands.md +146 -0
- data/docs/strategies/consensus.md +64 -0
- data/docs/strategies/custom.md +310 -0
- data/docs/strategies/ema.md +53 -0
- data/docs/strategies/index.md +92 -0
- data/docs/strategies/kbs.md +164 -0
- data/docs/strategies/macd.md +96 -0
- data/docs/strategies/market-profile.md +54 -0
- data/docs/strategies/mean-reversion.md +58 -0
- data/docs/strategies/rsi.md +95 -0
- data/docs/strategies/sma.md +55 -0
- data/docs/strategies/stochastic.md +63 -0
- data/docs/strategies/volume-breakout.md +54 -0
- data/docs/tags.md +7 -0
- data/docs/true_strength_index.md +46 -0
- data/docs/weighted_moving_average.md +48 -0
- data/examples/README.md +354 -0
- data/examples/advanced_features_example.rb +350 -0
- data/examples/fpop_analysis_example.rb +191 -0
- data/examples/genetic_programming_example.rb +148 -0
- data/examples/kbs_strategy_example.rb +208 -0
- data/examples/pattern_context_example.rb +300 -0
- data/examples/rails_app/Gemfile +34 -0
- data/examples/rails_app/README.md +416 -0
- data/examples/rails_app/app/assets/javascripts/application.js +107 -0
- data/examples/rails_app/app/assets/stylesheets/application.css +659 -0
- data/examples/rails_app/app/controllers/analysis_controller.rb +11 -0
- data/examples/rails_app/app/controllers/api/v1/stocks_controller.rb +227 -0
- data/examples/rails_app/app/controllers/application_controller.rb +22 -0
- data/examples/rails_app/app/controllers/backtest_controller.rb +11 -0
- data/examples/rails_app/app/controllers/dashboard_controller.rb +21 -0
- data/examples/rails_app/app/controllers/portfolio_controller.rb +7 -0
- data/examples/rails_app/app/views/analysis/show.html.erb +209 -0
- data/examples/rails_app/app/views/backtest/show.html.erb +171 -0
- data/examples/rails_app/app/views/dashboard/index.html.erb +118 -0
- data/examples/rails_app/app/views/dashboard/show.html.erb +408 -0
- data/examples/rails_app/app/views/errors/show.html.erb +17 -0
- data/examples/rails_app/app/views/layouts/application.html.erb +60 -0
- data/examples/rails_app/app/views/portfolio/index.html.erb +33 -0
- data/examples/rails_app/bin/rails +6 -0
- data/examples/rails_app/config/application.rb +45 -0
- data/examples/rails_app/config/boot.rb +5 -0
- data/examples/rails_app/config/database.yml +18 -0
- data/examples/rails_app/config/environment.rb +11 -0
- data/examples/rails_app/config/routes.rb +26 -0
- data/examples/rails_app/config.ru +8 -0
- data/examples/realtime_stream_example.rb +274 -0
- data/examples/sinatra_app/Gemfile +22 -0
- data/examples/sinatra_app/QUICKSTART.md +159 -0
- data/examples/sinatra_app/README.md +461 -0
- data/examples/sinatra_app/app.rb +344 -0
- data/examples/sinatra_app/config.ru +5 -0
- data/examples/sinatra_app/public/css/style.css +659 -0
- data/examples/sinatra_app/public/js/app.js +107 -0
- data/examples/sinatra_app/views/analyze.erb +306 -0
- data/examples/sinatra_app/views/backtest.erb +325 -0
- data/examples/sinatra_app/views/dashboard.erb +419 -0
- data/examples/sinatra_app/views/error.erb +58 -0
- data/examples/sinatra_app/views/index.erb +118 -0
- data/examples/sinatra_app/views/layout.erb +61 -0
- data/examples/sinatra_app/views/portfolio.erb +43 -0
- data/examples/strategy_generator_example.rb +346 -0
- data/hsa_portfolio.csv +11 -0
- data/justfile +0 -0
- data/lib/api/alpha_vantage_api.rb +462 -0
- data/lib/sqa/backtest.rb +329 -0
- data/lib/sqa/data_frame/alpha_vantage.rb +43 -65
- data/lib/sqa/data_frame/data.rb +92 -0
- data/lib/sqa/data_frame/yahoo_finance.rb +35 -43
- data/lib/sqa/data_frame.rb +148 -243
- data/lib/sqa/ensemble.rb +359 -0
- data/lib/sqa/fpop.rb +199 -0
- data/lib/sqa/gp.rb +259 -0
- data/lib/sqa/indicator.rb +5 -8
- data/lib/sqa/init.rb +15 -8
- data/lib/sqa/market_regime.rb +240 -0
- data/lib/sqa/multi_timeframe.rb +379 -0
- data/lib/sqa/pattern_matcher.rb +497 -0
- data/lib/sqa/portfolio.rb +260 -6
- data/lib/sqa/portfolio_optimizer.rb +377 -0
- data/lib/sqa/risk_manager.rb +442 -0
- data/lib/sqa/seasonal_analyzer.rb +209 -0
- data/lib/sqa/sector_analyzer.rb +300 -0
- data/lib/sqa/stock.rb +67 -125
- data/lib/sqa/strategy/bollinger_bands.rb +42 -0
- data/lib/sqa/strategy/consensus.rb +5 -2
- data/lib/sqa/strategy/kbs_strategy.rb +470 -0
- data/lib/sqa/strategy/macd.rb +46 -0
- data/lib/sqa/strategy/mp.rb +1 -1
- data/lib/sqa/strategy/stochastic.rb +60 -0
- data/lib/sqa/strategy/volume_breakout.rb +57 -0
- data/lib/sqa/strategy.rb +5 -0
- data/lib/sqa/strategy_generator.rb +947 -0
- data/lib/sqa/stream.rb +361 -0
- data/lib/sqa/version.rb +1 -7
- data/lib/sqa.rb +23 -16
- data/main.just +81 -0
- data/mkdocs.yml +288 -0
- data/trace.log +0 -0
- metadata +261 -51
- data/bin/sqa +0 -6
- data/lib/patches/dry-cli.rb +0 -228
- data/lib/sqa/activity.rb +0 -10
- data/lib/sqa/cli.rb +0 -62
- data/lib/sqa/commands/analysis.rb +0 -309
- data/lib/sqa/commands/base.rb +0 -139
- data/lib/sqa/commands/web.rb +0 -199
- data/lib/sqa/commands.rb +0 -22
- data/lib/sqa/constants.rb +0 -23
- data/lib/sqa/indicator/average_true_range.rb +0 -33
- data/lib/sqa/indicator/bollinger_bands.rb +0 -28
- data/lib/sqa/indicator/candlestick_pattern_recognizer.rb +0 -60
- data/lib/sqa/indicator/donchian_channel.rb +0 -29
- data/lib/sqa/indicator/double_top_bottom_pattern.rb +0 -34
- data/lib/sqa/indicator/elliott_wave_theory.rb +0 -57
- data/lib/sqa/indicator/exponential_moving_average.rb +0 -25
- data/lib/sqa/indicator/exponential_moving_average_trend.rb +0 -36
- data/lib/sqa/indicator/fibonacci_retracement.rb +0 -23
- data/lib/sqa/indicator/head_and_shoulders_pattern.rb +0 -26
- data/lib/sqa/indicator/market_profile.rb +0 -32
- data/lib/sqa/indicator/mean_reversion.rb +0 -37
- data/lib/sqa/indicator/momentum.rb +0 -28
- data/lib/sqa/indicator/moving_average_convergence_divergence.rb +0 -29
- data/lib/sqa/indicator/peaks_and_valleys.rb +0 -29
- data/lib/sqa/indicator/predict_next_value.rb +0 -202
- data/lib/sqa/indicator/relative_strength_index.rb +0 -47
- data/lib/sqa/indicator/simple_moving_average.rb +0 -24
- data/lib/sqa/indicator/simple_moving_average_trend.rb +0 -32
- data/lib/sqa/indicator/stochastic_oscillator.rb +0 -68
- data/lib/sqa/indicator/true_range.rb +0 -39
- data/lib/sqa/trade.rb +0 -26
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Risk Management
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Comprehensive risk management tools including VaR, position sizing, and risk metrics.
|
|
6
|
+
|
|
7
|
+
## Value at Risk (VaR)
|
|
8
|
+
|
|
9
|
+
Calculate potential losses at specified confidence level:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
require 'sqa'
|
|
13
|
+
|
|
14
|
+
prices = stock.df["adj_close_price"].to_a
|
|
15
|
+
returns = prices.each_cons(2).map { |a, b| (b - a) / a }
|
|
16
|
+
|
|
17
|
+
# 95% confidence VaR
|
|
18
|
+
var_95 = SQA::RiskManager.var(returns, confidence: 0.95, method: :historical)
|
|
19
|
+
puts "VaR (95%): #{(var_95 * 100).round(2)}%"
|
|
20
|
+
|
|
21
|
+
# Conditional VaR (Expected Shortfall)
|
|
22
|
+
cvar_95 = SQA::RiskManager.cvar(returns, confidence: 0.95)
|
|
23
|
+
puts "CVaR (95%): #{(cvar_95 * 100).round(2)}%"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Position Sizing
|
|
27
|
+
|
|
28
|
+
### Kelly Criterion
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
# Optimal position size based on win rate and payoffs
|
|
32
|
+
position = SQA::RiskManager.kelly_criterion(
|
|
33
|
+
win_rate: 0.60, # 60% win rate
|
|
34
|
+
avg_win: 0.10, # Average 10% gain
|
|
35
|
+
avg_loss: 0.05, # Average 5% loss
|
|
36
|
+
capital: 10_000
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
puts "Kelly Position: $#{position}"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Fixed Fractional
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
# Risk fixed % of capital per trade
|
|
46
|
+
position = SQA::RiskManager.fixed_fractional(
|
|
47
|
+
capital: 10_000,
|
|
48
|
+
risk_percent: 0.02, # Risk 2% per trade
|
|
49
|
+
stop_loss_percent: 0.05 # 5% stop loss
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
shares = (position / current_price).to_i
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Percent Volatility
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
# Size based on volatility
|
|
59
|
+
position = SQA::RiskManager.percent_volatility(
|
|
60
|
+
capital: 10_000,
|
|
61
|
+
target_volatility: 0.02, # 2% target vol
|
|
62
|
+
price_volatility: 0.25 # Stock's 25% annualized vol
|
|
63
|
+
)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Risk Metrics
|
|
67
|
+
|
|
68
|
+
### Sharpe Ratio
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
sharpe = SQA::RiskManager.sharpe_ratio(returns, risk_free_rate: 0.02)
|
|
72
|
+
puts "Sharpe Ratio: #{sharpe.round(2)}"
|
|
73
|
+
|
|
74
|
+
# > 1.0 = Good
|
|
75
|
+
# > 2.0 = Very Good
|
|
76
|
+
# > 3.0 = Excellent
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Sortino Ratio
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
# Like Sharpe but only penalizes downside volatility
|
|
83
|
+
sortino = SQA::RiskManager.sortino_ratio(returns, risk_free_rate: 0.02)
|
|
84
|
+
puts "Sortino Ratio: #{sortino.round(2)}"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Calmar Ratio
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
# Annual return / Maximum drawdown
|
|
91
|
+
prices = stock.df["adj_close_price"].to_a
|
|
92
|
+
calmar = SQA::RiskManager.calmar_ratio(prices)
|
|
93
|
+
puts "Calmar Ratio: #{calmar.round(2)}"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Maximum Drawdown
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
max_dd = SQA::RiskManager.max_drawdown(prices)
|
|
100
|
+
puts "Max Drawdown: #{(max_dd * 100).round(2)}%"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Monte Carlo Simulation
|
|
104
|
+
|
|
105
|
+
```ruby
|
|
106
|
+
# Simulate potential outcomes
|
|
107
|
+
simulations = SQA::RiskManager.monte_carlo_simulation(
|
|
108
|
+
returns: returns,
|
|
109
|
+
initial_value: 10_000,
|
|
110
|
+
periods: 252, # 1 year
|
|
111
|
+
num_simulations: 1000
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Analyze results
|
|
115
|
+
outcomes = simulations.map(&:last).sort
|
|
116
|
+
percentile_5 = outcomes[(outcomes.size * 0.05).to_i]
|
|
117
|
+
percentile_95 = outcomes[(outcomes.size * 0.95).to_i]
|
|
118
|
+
|
|
119
|
+
puts "5th percentile: $#{percentile_5.round(2)}"
|
|
120
|
+
puts "95th percentile: $#{percentile_95.round(2)}"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Complete Example
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
# Comprehensive risk assessment
|
|
127
|
+
class RiskAssessment
|
|
128
|
+
def initialize(stock)
|
|
129
|
+
@stock = stock
|
|
130
|
+
@prices = stock.df["adj_close_price"].to_a
|
|
131
|
+
@returns = calculate_returns
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def assess
|
|
135
|
+
{
|
|
136
|
+
var_95: SQA::RiskManager.var(@returns, confidence: 0.95),
|
|
137
|
+
cvar_95: SQA::RiskManager.cvar(@returns, confidence: 0.95),
|
|
138
|
+
sharpe: SQA::RiskManager.sharpe_ratio(@returns),
|
|
139
|
+
sortino: SQA::RiskManager.sortino_ratio(@returns),
|
|
140
|
+
max_dd: SQA::RiskManager.max_drawdown(@prices),
|
|
141
|
+
volatility: @returns.standard_deviation
|
|
142
|
+
}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def position_size(capital, method: :kelly)
|
|
146
|
+
case method
|
|
147
|
+
when :kelly
|
|
148
|
+
SQA::RiskManager.kelly_criterion(
|
|
149
|
+
win_rate: calculate_win_rate,
|
|
150
|
+
avg_win: calculate_avg_win,
|
|
151
|
+
avg_loss: calculate_avg_loss,
|
|
152
|
+
capital: capital
|
|
153
|
+
)
|
|
154
|
+
when :fixed
|
|
155
|
+
SQA::RiskManager.fixed_fractional(
|
|
156
|
+
capital: capital,
|
|
157
|
+
risk_percent: 0.02,
|
|
158
|
+
stop_loss_percent: 0.05
|
|
159
|
+
)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
private
|
|
164
|
+
|
|
165
|
+
def calculate_returns
|
|
166
|
+
@prices.each_cons(2).map { |a, b| (b - a) / a }
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def calculate_win_rate
|
|
170
|
+
wins = @returns.count { |r| r > 0 }
|
|
171
|
+
wins.to_f / @returns.size
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def calculate_avg_win
|
|
175
|
+
wins = @returns.select { |r| r > 0 }
|
|
176
|
+
wins.sum / wins.size
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def calculate_avg_loss
|
|
180
|
+
losses = @returns.select { |r| r < 0 }
|
|
181
|
+
losses.sum.abs / losses.size
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Usage
|
|
186
|
+
assessment = RiskAssessment.new(stock)
|
|
187
|
+
metrics = assessment.assess
|
|
188
|
+
position = assessment.position_size(10_000, method: :kelly)
|
|
189
|
+
|
|
190
|
+
puts "Risk Metrics:"
|
|
191
|
+
puts " VaR (95%): #{(metrics[:var_95] * 100).round(2)}%"
|
|
192
|
+
puts " Sharpe: #{metrics[:sharpe].round(2)}"
|
|
193
|
+
puts " Max DD: #{(metrics[:max_dd] * 100).round(2)}%"
|
|
194
|
+
puts "\nRecommended Position: $#{position.round(2)}"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Best Practices
|
|
198
|
+
|
|
199
|
+
1. **Diversify**: Don't risk more than 2-5% per trade
|
|
200
|
+
2. **Use Stop Losses**: Always define maximum acceptable loss
|
|
201
|
+
3. **Monitor Correlations**: Avoid correlated positions
|
|
202
|
+
4. **Regular Reassessment**: Update risk metrics monthly
|
|
203
|
+
5. **Stress Testing**: Run Monte Carlo simulations
|
|
204
|
+
|
|
205
|
+
## Related
|
|
206
|
+
|
|
207
|
+
- [Portfolio Optimizer](portfolio-optimizer.md) - Optimal allocation
|
|
208
|
+
- [FPOP](fpop.md) - Risk/reward analysis
|
|
209
|
+
- [Backtesting](backtesting.md) - Test risk management rules
|
|
210
|
+
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Strategy Generator
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Reverse-engineer profitable trades to discover patterns and automatically generate executable trading strategies.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
1. **Identify Profitable Points**: Scan historical data for entry points that led to profitable exits
|
|
10
|
+
2. **Capture Indicator States**: Record all indicator values at those profitable points
|
|
11
|
+
3. **Mine Patterns**: Find common combinations of indicator states
|
|
12
|
+
4. **Generate Strategies**: Create executable strategy code from patterns
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
require 'sqa'
|
|
18
|
+
|
|
19
|
+
# Load stock data
|
|
20
|
+
stock = SQA::Stock.new(ticker: 'AAPL')
|
|
21
|
+
|
|
22
|
+
# Create generator
|
|
23
|
+
generator = SQA::StrategyGenerator.new(
|
|
24
|
+
stock: stock,
|
|
25
|
+
min_gain_percent: 10.0, # Minimum 10% profit
|
|
26
|
+
fpop: 10 # Look ahead 10 periods
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Discover patterns
|
|
30
|
+
patterns = generator.discover_patterns
|
|
31
|
+
|
|
32
|
+
# Generate strategy from first pattern
|
|
33
|
+
strategy_code = generator.generate_strategy(pattern_index: 0)
|
|
34
|
+
puts strategy_code
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
generator = SQA::StrategyGenerator.new(
|
|
41
|
+
stock: stock,
|
|
42
|
+
min_gain_percent: 10.0, # Minimum profit required
|
|
43
|
+
max_loss_percent: -5.0, # Maximum acceptable loss
|
|
44
|
+
fpop: 10, # Future periods to analyze
|
|
45
|
+
min_support: 3 # Minimum pattern occurrences
|
|
46
|
+
)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Discovering Patterns
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
patterns = generator.discover_patterns
|
|
53
|
+
|
|
54
|
+
patterns.each_with_index do |pattern, i|
|
|
55
|
+
puts "\nPattern #{i}:"
|
|
56
|
+
puts " Support: #{pattern[:support]} occurrences"
|
|
57
|
+
puts " Avg Gain: #{pattern[:avg_gain].round(2)}%"
|
|
58
|
+
puts " Win Rate: #{pattern[:win_rate].round(2)}%"
|
|
59
|
+
|
|
60
|
+
puts " Conditions:"
|
|
61
|
+
pattern[:conditions].each do |cond|
|
|
62
|
+
puts " - #{cond[:indicator]}: #{cond[:state]}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Generating Strategy Code
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
strategy_code = generator.generate_strategy(
|
|
71
|
+
pattern_index: 0,
|
|
72
|
+
class_name: 'DiscoveredStrategy'
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Save to file
|
|
76
|
+
File.write('lib/sqa/strategy/discovered_strategy.rb', strategy_code)
|
|
77
|
+
|
|
78
|
+
# Load and use
|
|
79
|
+
require_relative 'lib/sqa/strategy/discovered_strategy'
|
|
80
|
+
signal = SQA::Strategy::DiscoveredStrategy.trade(vector)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Context-Aware Patterns
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
# Include market context in pattern discovery
|
|
87
|
+
patterns = generator.discover_context_aware_patterns(
|
|
88
|
+
analyze_regime: true, # Include bull/bear/sideways
|
|
89
|
+
analyze_seasonal: true, # Include month/quarter
|
|
90
|
+
sector: :technology # Sector classification
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Patterns include context
|
|
94
|
+
pattern = patterns.first
|
|
95
|
+
puts "Valid in: #{pattern.context.valid_months}" # => [10, 11, 12]
|
|
96
|
+
puts "Valid regimes: #{pattern.context.valid_regimes}" # => [:bull]
|
|
97
|
+
puts "Sector: #{pattern.context.sector}" # => :technology
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Walk-Forward Validation
|
|
101
|
+
|
|
102
|
+
```ruby
|
|
103
|
+
# Prevent overfitting with out-of-sample testing
|
|
104
|
+
validated_patterns = generator.walk_forward_validate(
|
|
105
|
+
train_size: 250, # Training period (days)
|
|
106
|
+
test_size: 60 # Testing period (days)
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
validated_patterns.each do |result|
|
|
110
|
+
puts "Pattern #{result[:pattern_index]}:"
|
|
111
|
+
puts " Train Return: #{result[:train_return]}%"
|
|
112
|
+
puts " Test Return: #{result[:test_return]}%"
|
|
113
|
+
puts " Robust: #{result[:robust]}" # true if test performance acceptable
|
|
114
|
+
end
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Example Output
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
# Generated strategy example
|
|
121
|
+
class SQA::Strategy::Pattern_1
|
|
122
|
+
def self.trade(vector)
|
|
123
|
+
return :hold unless valid_data?(vector)
|
|
124
|
+
|
|
125
|
+
# Pattern: Oversold RSI + Bullish MACD + High Volume
|
|
126
|
+
if vector.rsi[:trend] == :over_sold &&
|
|
127
|
+
vector.macd[:crossover] == :bullish &&
|
|
128
|
+
vector.volume_ratio > 1.5
|
|
129
|
+
:buy
|
|
130
|
+
else
|
|
131
|
+
:hold
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
def self.valid_data?(vector)
|
|
138
|
+
vector.respond_to?(:rsi) &&
|
|
139
|
+
vector.respond_to?(:macd) &&
|
|
140
|
+
vector.respond_to?(:volume_ratio)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Best Practices
|
|
146
|
+
|
|
147
|
+
1. **Use Sufficient Data**: At least 1-2 years of historical data
|
|
148
|
+
2. **Validate Patterns**: Use walk-forward testing
|
|
149
|
+
3. **Filter by Support**: Require minimum pattern occurrences (3-5)
|
|
150
|
+
4. **Consider Context**: Include market regime and seasonality
|
|
151
|
+
5. **Backtest Generated Strategies**: Always test before using live
|
|
152
|
+
|
|
153
|
+
## Related
|
|
154
|
+
|
|
155
|
+
- [Genetic Programming](../genetic_programming.md) - Optimize strategy parameters
|
|
156
|
+
- [KBS Strategy](../strategies/kbs.md) - Rule-based strategies
|
|
157
|
+
- [Backtesting](backtesting.md) - Test discovered strategies
|
|
158
|
+
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Real-Time Streaming
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Process live price data with event callbacks and parallel strategy execution for real-time trading signals.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require 'sqa'
|
|
11
|
+
|
|
12
|
+
# Create stream
|
|
13
|
+
stream = SQA::Stream.new(
|
|
14
|
+
ticker: 'AAPL',
|
|
15
|
+
strategies: [SQA::Strategy::RSI, SQA::Strategy::MACD],
|
|
16
|
+
window_size: 50
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Register callback
|
|
20
|
+
stream.on_signal do |signal, data|
|
|
21
|
+
puts "#{Time.now}: Signal = #{signal}"
|
|
22
|
+
puts "Price: #{data[:price]}"
|
|
23
|
+
puts "Volume: #{data[:volume]}"
|
|
24
|
+
|
|
25
|
+
# Execute trade, send alert, log data, etc.
|
|
26
|
+
execute_trade(signal, data) if signal != :hold
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Start receiving updates
|
|
30
|
+
stream.update(price: 150.25, volume: 1_000_000)
|
|
31
|
+
stream.update(price: 150.50, volume: 1_200_000)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
### Rolling Window
|
|
37
|
+
Maintains recent price/volume history:
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
stream = SQA::Stream.new(
|
|
41
|
+
ticker: 'AAPL',
|
|
42
|
+
window_size: 50 # Keep last 50 data points
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Automatically manages memory
|
|
46
|
+
1000.times do |i|
|
|
47
|
+
stream.update(price: 100 + rand, volume: 1000000)
|
|
48
|
+
# Only keeps most recent 50 points
|
|
49
|
+
end
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### On-the-Fly Indicators
|
|
53
|
+
Calculates indicators from rolling window:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
stream.update(price: 150.0, volume: 1_000_000)
|
|
57
|
+
|
|
58
|
+
# Indicators calculated automatically
|
|
59
|
+
# - RSI from last 14 prices
|
|
60
|
+
# - MACD from price history
|
|
61
|
+
# - SMA/EMA from rolling window
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Parallel Strategy Execution
|
|
65
|
+
Runs multiple strategies simultaneously:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
stream = SQA::Stream.new(
|
|
69
|
+
ticker: 'AAPL',
|
|
70
|
+
strategies: [
|
|
71
|
+
SQA::Strategy::RSI,
|
|
72
|
+
SQA::Strategy::MACD,
|
|
73
|
+
SQA::Strategy::BollingerBands
|
|
74
|
+
]
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# All strategies execute on each update
|
|
78
|
+
stream.update(price: 150.0, volume: 1_000_000)
|
|
79
|
+
# Each strategy generates independent signal
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Signal Aggregation
|
|
83
|
+
Combine multiple strategy signals:
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
stream.on_signal do |signals, data|
|
|
87
|
+
# signals = {
|
|
88
|
+
# RSI: :buy,
|
|
89
|
+
# MACD: :hold,
|
|
90
|
+
# BollingerBands: :buy
|
|
91
|
+
# }
|
|
92
|
+
|
|
93
|
+
# Count votes
|
|
94
|
+
buy_votes = signals.values.count(:buy)
|
|
95
|
+
sell_votes = signals.values.count(:sell)
|
|
96
|
+
|
|
97
|
+
# Consensus decision
|
|
98
|
+
if buy_votes >= 2
|
|
99
|
+
execute_buy(data[:price])
|
|
100
|
+
elsif sell_votes >= 2
|
|
101
|
+
execute_sell(data[:price])
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Complete Example
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
# Initialize stream
|
|
110
|
+
stream = SQA::Stream.new(
|
|
111
|
+
ticker: 'AAPL',
|
|
112
|
+
strategies: [
|
|
113
|
+
SQA::Strategy::RSI,
|
|
114
|
+
SQA::Strategy::MACD
|
|
115
|
+
],
|
|
116
|
+
window_size: 100
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Track performance
|
|
120
|
+
trades = []
|
|
121
|
+
|
|
122
|
+
# Register callbacks
|
|
123
|
+
stream.on_signal do |signals, data|
|
|
124
|
+
consensus = calculate_consensus(signals)
|
|
125
|
+
|
|
126
|
+
if consensus == :buy
|
|
127
|
+
trades << {
|
|
128
|
+
action: :buy,
|
|
129
|
+
price: data[:price],
|
|
130
|
+
time: Time.now
|
|
131
|
+
}
|
|
132
|
+
send_alert("BUY signal at $#{data[:price]}")
|
|
133
|
+
elsif consensus == :sell
|
|
134
|
+
trades << {
|
|
135
|
+
action: :sell,
|
|
136
|
+
price: data[:price],
|
|
137
|
+
time: Time.now
|
|
138
|
+
}
|
|
139
|
+
send_alert("SELL signal at $#{data[:price]}")
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Simulate live data feed
|
|
144
|
+
loop do
|
|
145
|
+
# Get current price from API/feed
|
|
146
|
+
current_data = fetch_live_data('AAPL')
|
|
147
|
+
|
|
148
|
+
stream.update(
|
|
149
|
+
price: current_data[:price],
|
|
150
|
+
volume: current_data[:volume]
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
sleep 60 # Update every minute
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Integration Examples
|
|
158
|
+
|
|
159
|
+
### With WebSocket Feed
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
require 'faye/websocket'
|
|
163
|
+
require 'eventmachine'
|
|
164
|
+
|
|
165
|
+
EM.run do
|
|
166
|
+
ws = Faye::WebSocket::Client.new('wss://stream.example.com')
|
|
167
|
+
|
|
168
|
+
ws.on :message do |event|
|
|
169
|
+
data = JSON.parse(event.data)
|
|
170
|
+
stream.update(
|
|
171
|
+
price: data['price'],
|
|
172
|
+
volume: data['volume']
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### With REST API Polling
|
|
179
|
+
|
|
180
|
+
```ruby
|
|
181
|
+
require 'faraday'
|
|
182
|
+
|
|
183
|
+
loop do
|
|
184
|
+
response = Faraday.get("https://api.example.com/quote/AAPL")
|
|
185
|
+
data = JSON.parse(response.body)
|
|
186
|
+
|
|
187
|
+
stream.update(
|
|
188
|
+
price: data['lastPrice'],
|
|
189
|
+
volume: data['volume']
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
sleep 10
|
|
193
|
+
end
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Best Practices
|
|
197
|
+
|
|
198
|
+
1. **Error Handling**: Wrap callbacks in begin/rescue
|
|
199
|
+
2. **Performance**: Limit callback complexity
|
|
200
|
+
3. **Memory**: Use appropriate window_size
|
|
201
|
+
4. **Validation**: Verify data before processing
|
|
202
|
+
5. **Logging**: Track all signals and actions
|
|
203
|
+
|
|
204
|
+
## Related
|
|
205
|
+
|
|
206
|
+
- [Portfolio Management](portfolio.md) - Execute trades from signals
|
|
207
|
+
- [Backtesting](backtesting.md) - Test strategies before going live
|
|
208
|
+
- [Risk Management](risk-management.md) - Position sizing for live trading
|
|
209
|
+
|
data/docs/ai_and_ml.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
## AI and ML in Trading -- Advancing Decision-Making
|
|
2
|
+
|
|
3
|
+
The realm of financial trading has experienced a wonderful transformation with the benefit of algorithmic trading. This innovative approach, which utilizes automated and pre-programmed instructions, has elevated the trading game to new heights. It excels in executing trades with incredible speed and accuracy, focusing on various factors such as price, timing, and volume. The key to its enhanced performance lies in the integration of machine learning (ML) and artificial intelligence (AI). These technologies are useful for the prediction power which was impossible permitting traders to understand the difficulties of the market with enhancement.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Machine learning in Algo trading, in particular, has been a game-changer. It enables systems to learn from historical data, adapt to changing market dynamics, and make informed predictions about future market behaviors. This evolution has not only streamlined trading operations but also opened up new avenues for strategic and dynamic trading decisions, revolutionizing the way financial markets operate.
|
|
7
|
+
|
|
8
|
+
## Applications in Algorithmic Trading
|
|
9
|
+
|
|
10
|
+
Algorithmic trading has revolutionized the financial world by its rapidness and accuracy in the trading procedure. With the integration of artificial intelligence, these systems have become more easier. Here are several key applications of AI in algo trading:
|
|
11
|
+
|
|
12
|
+
## Predictive Analytics for Market Trends
|
|
13
|
+
|
|
14
|
+
AI algorithms analyze vast datasets, including historical price data, news, and economic reports, to predict market trends. Techniques like sentiment analysis are used to gauge market mood from social media and news sources, offering insights into potential market movements. Time-series forecasting models, driven by AI, help in predicting future price movements based on past trends.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Risk Management and Mitigation
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
AI in algo trading enhances the ability to identify and assess risks. By analyzing market conditions and historical data, these systems can predict volatility and potential downturns. Advanced models help in diversifying portfolios to minimize risk and optimize returns. Real-time monitoring tools powered by AI detect anomalies and potential market manipulations, safeguarding investments.
|
|
21
|
+
|
|
22
|
+
## Portfolio Optimization
|
|
23
|
+
|
|
24
|
+
AI systems analyze historical performance data and market conditions to construct optimized portfolios that align with specific investment goals and risk tolerances. These algorithms continuously adjust portfolios in response to market changes, ensuring optimal asset allocation.
|
|
25
|
+
|
|
26
|
+
## Algorithmic Market Making
|
|
27
|
+
|
|
28
|
+
AI-driven algorithms act as market makers, providing liquidity to the market by continuously buying and selling securities. These algorithms adjust bid-ask spreads based on market conditions, balancing profit-making with the need to maintain market stability.
|
|
29
|
+
|
|
30
|
+
## Sentiment Analysis and Behavioral Finance
|
|
31
|
+
|
|
32
|
+
AI tools perform sentiment analysis on news articles, social media, and financial reports to understand market sentiment. Behavioral biases in trading decisions are identified and countered using AI, leading to more rational decision-making.
|
|
33
|
+
|
|
34
|
+
## Fraud Detection and Compliance
|
|
35
|
+
|
|
36
|
+
AI algorithms in algo trading detect patterns indicative of fraudulent activities, enhancing the security of trading platforms. Compliance monitoring is automated, ensuring adherence to regulatory standards and reducing the risk of legal issues.
|
|
37
|
+
|
|
38
|
+
## Customized Trading Solutions
|
|
39
|
+
|
|
40
|
+
AI app development companies enable the creation of personalized trading strategies based on individual investor profiles and preferences. It offers tailored advice and recommendations, improving client engagement and satisfaction.
|
|
41
|
+
|
|
42
|
+
## Real-time Data Processing and Decision Making
|
|
43
|
+
|
|
44
|
+
AI systems process real-time market data to make immediate trading decisions, capitalizing on short-lived trading opportunities. They can adjust strategies instantaneously in response to live market data, maintaining relevance and effectiveness.
|
|
45
|
+
|
|
46
|
+
## Predictive Maintenance in Trading Infrastructure
|
|
47
|
+
|
|
48
|
+
AI is used to predict and prevent system failures in trading infrastructure, ensuring uninterrupted operations. Predictive maintenance minimizes downtime and maintains the reliability of trading systems.
|
|
49
|
+
|
|
50
|
+
# Advancing Decision Making with AI and ML in Algorithmic Trading
|
|
51
|
+
|
|
52
|
+
### Incorporation of AI in Software Development for Trading Systems
|
|
53
|
+
|
|
54
|
+
The evolution of algorithmic trading is significantly influenced by advancements in AI-driven software development. Software development companies are now focusing on integrating AI and ML into trading platforms, enhancing their capability to process and analyze massive data sets rapidly. This integration allows for the creation of more sophisticated and accurate trading models. By adopting AI, these companies can develop software that not only processes historical and real-time market data efficiently but also predicts future market trends, contributing to more informed trading decisions.
|
|
55
|
+
|
|
56
|
+
### Mobile App Development for On-the-Go Trading
|
|
57
|
+
|
|
58
|
+
The demand for [mobile app development services](https://www.nevinainfotech.com/mobile-app-development-service) in the financial sector has reached the heights of the sky mainly for algorithmic trading. These mobile apps, empowered by AI and ML algorithms, provide traders with the flexibility to monitor and execute trades anytime and anywhere. The incorporation of AI in these apps offers real-time analytics, market insights, and personalized notifications, ensuring that traders stay ahead in the fast-paced trading environment. This advancement in mobile technology means that traders can now make data-driven decisions on the go, with AI providing constant insights and updates.
|
|
59
|
+
|
|
60
|
+
### Enhancing Trading Platforms with Dedicated AI Expertise.
|
|
61
|
+
|
|
62
|
+
To harness the full potential of AI and ML in algorithmic trading, it's essential to hire dedicated developers who specialize in AI. Their expertise helps in refining the AI models used in algo trading platforms, ensuring that they are not only efficient but also accurate and reliable. Dedicated developers bring a depth of knowledge in AI and ML, driving innovations that keep trading platforms at the forefront of the financial industry.
|
|
63
|
+
|
|
64
|
+
### Collaboration with Artificial Intelligence Development Companies
|
|
65
|
+
|
|
66
|
+
The partnership between algo trading firms and [artificial intelligence development companies](https://www.nevinainfotech.com/artificial-intelligence-development) is pivotal in advancing trading strategies. These collaborations bring together financial expertise and cutting-edge AI technology. AI development companies provide the technological backbone, developing complex algorithms capable of predictive analytics, risk assessment, and decision automation. It leads to more powerful trading platforms, which can process a huge amount of data and make autonomous, great decisions that would be hard to make for human traders.
|
|
67
|
+
|
|
68
|
+
### Leveraging Algo Trading Platforms for Enhanced Decision-Making
|
|
69
|
+
|
|
70
|
+
Algo trading platforms have become more advanced with the integration of AI and ML, offering traders a myriad of tools for enhanced decision-making. These platforms utilize AI to analyze market conditions, predict price movements, and identify trading opportunities. They can automatically adjust trading strategies in real-time, responding to market changes instantaneously. This level of automation and precision in decision-making permits traders to focus on market opportunities more efficiently, minimizing risks, and enhancing overall trading performance.
|
|
71
|
+
|
|
72
|
+
### Future Trends and Developments in AI and ML for Trading
|
|
73
|
+
|
|
74
|
+
Looking forward, the continued integration of AI and ML in algorithmic trading promises even more sophisticated and efficient trading systems. Growth in areas like deep learning, and natural language processing will again improve the abilities of algo trading platforms. As AI and ML technologies evolve, they will offer more nuanced and complex analysis, leading to even more refined decision-making processes in trading. The ongoing collaboration with dedicated AI developers, and financial experts will be crucial in driving these advancements and shaping the future of algorithmic trading in the financial markets.
|
|
75
|
+
|
|
76
|
+
The advancement of decision-making in algorithmic trading through AI and ML is a multifaceted process that involves the collaboration of software development companies, the creation of mobile trading apps, the hiring of dedicated developers, partnerships with AI development firms, and the continuous improvement of algo trading platforms.
|
|
77
|
+
|
|
78
|
+
### Conclusion:
|
|
79
|
+
|
|
80
|
+
The blend of artificial intelligence and machine learning in algo trading is nothing but a kind of transformation in the financial world. This blend has not just automated the existing processes but has infused them with an unprecedented level of accuracy and sophistication. These advancements empower traders to make decisions swiftly and more accurately, effectively reshaping the entire trading landscape. As we look ahead, the continuous evolution of these technologies heralds a future rich with innovative strategies and heightened efficiency in trading. In this new era, driven by AI and ML, the essence of successful trading will increasingly hinge on the ability to harness data-driven insights and automated decision-making.
|