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
data/docs/index.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# SQA - Simple Qualitative Analysis
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>A Powerful Ruby Library for Stock Market Technical Analysis</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Welcome to SQA
|
|
10
|
+
|
|
11
|
+
**SQA (Simple Qualitative Analysis)** is an educational Ruby library designed for stock market technical analysis and trading strategy development. Built with high-performance data structures and seamlessly integrated with TA-Lib, SQA provides a comprehensive toolkit for analyzing historical stock data, implementing trading strategies, and backtesting your ideas.
|
|
12
|
+
|
|
13
|
+
!!! warning "Educational Purpose Only"
|
|
14
|
+
SQA is designed for **educational purposes** only. It should not be used for actual trading without extensive testing and professional financial advice. Trading stocks involves substantial risk of loss.
|
|
15
|
+
|
|
16
|
+
## Why SQA?
|
|
17
|
+
|
|
18
|
+
### :zap: High Performance
|
|
19
|
+
- **Polars DataFrames**: Rust-backed data structures providing 30x faster operations than pure Ruby
|
|
20
|
+
- **TA-Lib Integration**: Access to 150+ battle-tested technical indicators via the `sqa-tai` gem
|
|
21
|
+
- **Efficient Algorithms**: Optimized for large historical datasets
|
|
22
|
+
|
|
23
|
+
### :toolbox: Comprehensive Feature Set
|
|
24
|
+
- **13+ Trading Strategies**: From simple moving averages to advanced machine learning-based strategies
|
|
25
|
+
- **Portfolio Management**: Track positions, calculate P&L, manage commissions
|
|
26
|
+
- **Backtesting Framework**: Simulate strategies with comprehensive performance metrics
|
|
27
|
+
- **Real-Time Streaming**: Process live price data with callback support
|
|
28
|
+
- **Strategy Generation**: Reverse-engineer profitable trades to discover patterns
|
|
29
|
+
- **Genetic Programming**: Evolve optimal strategy parameters
|
|
30
|
+
|
|
31
|
+
### :mortar_board: Educational Focus
|
|
32
|
+
- **Clear Documentation**: Extensive guides and examples
|
|
33
|
+
- **Transparent Algorithms**: Understand how each indicator and strategy works
|
|
34
|
+
- **Modular Design**: Learn by building custom strategies
|
|
35
|
+
- **Risk Disclaimers**: Honest about limitations and risks
|
|
36
|
+
|
|
37
|
+
## Quick Example
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
require 'sqa'
|
|
41
|
+
|
|
42
|
+
# Initialize SQA
|
|
43
|
+
SQA.init
|
|
44
|
+
|
|
45
|
+
# Load stock data
|
|
46
|
+
stock = SQA::Stock.new(ticker: 'AAPL')
|
|
47
|
+
|
|
48
|
+
# Get price data
|
|
49
|
+
prices = stock.df["adj_close_price"].to_a
|
|
50
|
+
|
|
51
|
+
# Calculate RSI indicator
|
|
52
|
+
rsi = SQAI.rsi(prices, period: 14)
|
|
53
|
+
|
|
54
|
+
# Execute RSI trading strategy
|
|
55
|
+
require 'ostruct'
|
|
56
|
+
vector = OpenStruct.new(rsi: { trend: rsi.last < 30 ? :over_sold : :over_bought })
|
|
57
|
+
signal = SQA::Strategy::RSI.trade(vector) # => :buy, :sell, or :hold
|
|
58
|
+
|
|
59
|
+
# Backtest the strategy
|
|
60
|
+
backtest = SQA::Backtest.new(
|
|
61
|
+
stock: stock,
|
|
62
|
+
strategy: SQA::Strategy::RSI,
|
|
63
|
+
initial_cash: 10_000
|
|
64
|
+
)
|
|
65
|
+
results = backtest.run
|
|
66
|
+
|
|
67
|
+
puts "Total Return: #{results.total_return}%"
|
|
68
|
+
puts "Sharpe Ratio: #{results.sharpe_ratio}"
|
|
69
|
+
puts "Max Drawdown: #{results.max_drawdown}%"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Core Features
|
|
73
|
+
|
|
74
|
+
### Data Management
|
|
75
|
+
- **Multiple Data Sources**: Alpha Vantage, Yahoo Finance, CSV imports
|
|
76
|
+
- **Polars DataFrames**: High-performance time series data manipulation
|
|
77
|
+
- **Automatic Updates**: Keep historical data current
|
|
78
|
+
|
|
79
|
+
### Technical Analysis
|
|
80
|
+
- **150+ Indicators**: SMA, EMA, RSI, MACD, Bollinger Bands, Stochastic, ADX, ATR, and more
|
|
81
|
+
- **Custom Calculations**: Build your own indicators
|
|
82
|
+
- **Trend Detection**: Identify market conditions automatically
|
|
83
|
+
|
|
84
|
+
### Trading Strategies
|
|
85
|
+
- **Built-in Strategies**: RSI, MACD, Bollinger Bands, Moving Average crossovers, Volume Breakout
|
|
86
|
+
- **Strategy Framework**: Plugin architecture for custom strategies
|
|
87
|
+
- **Consensus Approach**: Combine multiple strategies
|
|
88
|
+
- **Rule-Based (KBS)**: RETE-based forward-chaining inference engine
|
|
89
|
+
|
|
90
|
+
### Advanced Analytics
|
|
91
|
+
- **Portfolio Tracking**: Monitor positions, P&L, commissions
|
|
92
|
+
- **Backtesting**: Historical simulation with performance metrics
|
|
93
|
+
- **Strategy Generator**: Mine patterns from profitable trades
|
|
94
|
+
- **Genetic Programming**: Evolutionary parameter optimization
|
|
95
|
+
- **FPOP Analysis**: Future Period of Performance calculations
|
|
96
|
+
- **Real-Time Streaming**: Process live data with event callbacks
|
|
97
|
+
|
|
98
|
+
## Architecture
|
|
99
|
+
|
|
100
|
+
```mermaid
|
|
101
|
+
graph TD
|
|
102
|
+
A[Stock Data] --> B[SQA::DataFrame]
|
|
103
|
+
B --> C[Technical Indicators]
|
|
104
|
+
C --> D[Trading Strategies]
|
|
105
|
+
D --> E{Strategy Type}
|
|
106
|
+
E -->|Simple| F[SMA/EMA/RSI]
|
|
107
|
+
E -->|Advanced| G[MACD/Bollinger]
|
|
108
|
+
E -->|Rule-Based| H[KBS Strategy]
|
|
109
|
+
D --> I[Portfolio Management]
|
|
110
|
+
I --> J[Backtesting]
|
|
111
|
+
J --> K[Performance Metrics]
|
|
112
|
+
|
|
113
|
+
L[Real-Time Data] --> M[SQA::Stream]
|
|
114
|
+
M --> D
|
|
115
|
+
|
|
116
|
+
N[Pattern Discovery] --> O[StrategyGenerator]
|
|
117
|
+
O --> P[Generated Strategies]
|
|
118
|
+
P --> D
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Getting Started
|
|
122
|
+
|
|
123
|
+
Ready to dive in? Check out our guides:
|
|
124
|
+
|
|
125
|
+
- **[Installation Guide](getting-started/installation.md)** - Get SQA up and running
|
|
126
|
+
- **[Quick Start](getting-started/quick-start.md)** - Your first analysis in minutes
|
|
127
|
+
- **[Configuration](getting-started/configuration.md)** - Customize SQA for your needs
|
|
128
|
+
- **[Console Usage](getting-started/console-usage.md)** - Interactive exploration with `sqa-console`
|
|
129
|
+
|
|
130
|
+
## Key Resources
|
|
131
|
+
|
|
132
|
+
### For Beginners
|
|
133
|
+
- [Core Concepts](concepts/index.md) - Understand the fundamentals
|
|
134
|
+
- [Technical Indicators](indicators/index.md) - Learn about indicators
|
|
135
|
+
- [Trading Strategies](strategies/index.md) - Explore built-in strategies
|
|
136
|
+
|
|
137
|
+
### For Advanced Users
|
|
138
|
+
- [Portfolio Management](advanced/portfolio.md) - Track your trades
|
|
139
|
+
- [Backtesting](advanced/backtesting.md) - Test strategies historically
|
|
140
|
+
- [Strategy Generator](advanced/strategy-generator.md) - Discover patterns
|
|
141
|
+
- [Genetic Programming](genetic_programming.md) - Optimize parameters
|
|
142
|
+
|
|
143
|
+
### Reference
|
|
144
|
+
- [API Documentation](api/index.md) - Complete API reference
|
|
145
|
+
- [Data Sources](data-sources/index.md) - Working with data
|
|
146
|
+
- [Terms of Use](terms_of_use.md) - Important legal information
|
|
147
|
+
|
|
148
|
+
## Community & Support
|
|
149
|
+
|
|
150
|
+
- **GitHub**: [github.com/madbomber/sqa](https://github.com/madbomber/sqa)
|
|
151
|
+
- **RubyGems**: [rubygems.org/gems/sqa](https://rubygems.org/gems/sqa)
|
|
152
|
+
- **Issues**: Report bugs or request features on [GitHub Issues](https://github.com/madbomber/sqa/issues)
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
SQA is released under the MIT License. See the [LICENSE](https://github.com/madbomber/sqa/blob/main/LICENSE.txt) file for details.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
<p align="center">
|
|
161
|
+
<strong>Remember: The House Always Wins</strong><br>
|
|
162
|
+
<em>Trade responsibly. Never risk more than you can afford to lose.</em>
|
|
163
|
+
</p>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Technical Indicators
|
|
2
|
+
|
|
3
|
+
SQA provides access to 150+ technical indicators via the sqa-tai gem, which wraps the industry-standard TA-Lib library.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
All indicators are available through the `SQAI` module:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require 'sqa'
|
|
11
|
+
|
|
12
|
+
prices = [100, 102, 101, 103, 105, 104, 106]
|
|
13
|
+
|
|
14
|
+
# Simple Moving Average
|
|
15
|
+
sma = SQAI.sma(prices, period: 5)
|
|
16
|
+
|
|
17
|
+
# Relative Strength Index
|
|
18
|
+
rsi = SQAI.rsi(prices, period: 14)
|
|
19
|
+
|
|
20
|
+
# Bollinger Bands (returns 3 arrays: upper, middle, lower)
|
|
21
|
+
upper, middle, lower = SQAI.bbands(prices, period: 20)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Indicator Categories
|
|
25
|
+
|
|
26
|
+
### Overlap Studies (Moving Averages)
|
|
27
|
+
- SMA - Simple Moving Average
|
|
28
|
+
- EMA - Exponential Moving Average
|
|
29
|
+
- WMA - Weighted Moving Average
|
|
30
|
+
- DEMA - Double Exponential Moving Average
|
|
31
|
+
- TEMA - Triple Exponential Moving Average
|
|
32
|
+
- T3 - Triple Exponential Moving Average (T3)
|
|
33
|
+
- MA - Moving Average (configurable type)
|
|
34
|
+
|
|
35
|
+
### Momentum Indicators
|
|
36
|
+
- RSI - Relative Strength Index
|
|
37
|
+
- STOCH - Stochastic Oscillator
|
|
38
|
+
- STOCHF - Stochastic Fast
|
|
39
|
+
- STOCHRSI - Stochastic RSI
|
|
40
|
+
- MACD - Moving Average Convergence Divergence
|
|
41
|
+
- MOM - Momentum
|
|
42
|
+
- ROC - Rate of Change
|
|
43
|
+
- CCI - Commodity Channel Index
|
|
44
|
+
- WILLR - Williams' %R
|
|
45
|
+
|
|
46
|
+
### Volatility Indicators
|
|
47
|
+
- ATR - Average True Range
|
|
48
|
+
- NATR - Normalized Average True Range
|
|
49
|
+
- TRANGE - True Range
|
|
50
|
+
- BBANDS - Bollinger Bands
|
|
51
|
+
|
|
52
|
+
### Volume Indicators
|
|
53
|
+
- AD - Chaikin A/D Line
|
|
54
|
+
- ADOSC - Chaikin A/D Oscillator
|
|
55
|
+
- OBV - On Balance Volume
|
|
56
|
+
|
|
57
|
+
### See Individual Indicators
|
|
58
|
+
|
|
59
|
+
Browse the navigation menu for detailed information about each indicator.
|
|
60
|
+
|
|
61
|
+
## Common Patterns
|
|
62
|
+
|
|
63
|
+
### Single-Value Indicators
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
# Returns array of values
|
|
67
|
+
values = SQAI.rsi(prices, period: 14)
|
|
68
|
+
current_rsi = values.last
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Multi-Value Indicators
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
# MACD returns 3 arrays
|
|
75
|
+
macd_line, signal_line, histogram = SQAI.macd(prices)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Indicators Requiring Multiple Inputs
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
# ATR needs high, low, close
|
|
82
|
+
high = [105, 107, 106, 108]
|
|
83
|
+
low = [103, 104, 103, 105]
|
|
84
|
+
close = [104, 106, 105, 107]
|
|
85
|
+
|
|
86
|
+
atr = SQAI.atr(high, low, close, period: 14)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Full Indicator List
|
|
90
|
+
|
|
91
|
+
To see all available indicators:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
SQAI.methods.grep(/^[a-z]/).sort
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This will list all 150+ indicators in alphabetical order.
|
data/docs/indicators.md
CHANGED
|
@@ -1,33 +1,119 @@
|
|
|
1
|
-
# Indicators
|
|
1
|
+
# Technical Indicators Overview
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## The Philosophy of Indicators
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
An indicator is a formula/metric on a stock's historical activity. It is presumed to be a forecast as to what the stock activity might be in the future. A single indicator is not necessarily an accurate predictor of future events, nor is any specific group of indicators.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
In other words, the future is uncertain. Is it a coin flip? Heads the stock's price goes up. Tails, the stock's price goes down. It's one or the other, right? What if the price never changes? Then it's not a coin flip. Also what is the time frame involved in the forecast? Is it tomorrow, next week, next month, next year, next decade? What is the delta change in price that can be expected?
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
So indicators are like TV weather forecasters. Sometimes they are right. Sometimes they are wrong.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
We are dealing with uncertainty. In uncertainty there is chaos. If it is possible to be right more times than you are wrong, you can make money. If you are always wrong, then always do the opposite and you will make money. When you are wrong more times than you are right... you lose.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
It's a game. Game theory tells us that there are winners and losers. Bookies at the track make money every day by taking a cut of the losers' losses before giving them to the winners. Bookies always win so long as they keep their books balanced. Accounts are important.
|
|
14
14
|
|
|
15
|
+
---
|
|
15
16
|
|
|
17
|
+
## SQA Indicator System
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
SQA provides access to **150+ technical indicators** via the separate **sqa-tai gem**, which wraps the industry-standard TA-Lib library.
|
|
20
|
+
|
|
21
|
+
### Quick Start
|
|
22
|
+
|
|
23
|
+
All indicators are available through the `SQAI` module:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
require 'sqa'
|
|
27
|
+
|
|
28
|
+
# Get price data
|
|
29
|
+
stock = SQA::Stock.new(ticker: 'AAPL')
|
|
30
|
+
prices = stock.df["adj_close_price"].to_a
|
|
31
|
+
|
|
32
|
+
# Calculate indicators
|
|
33
|
+
sma = SQAI.sma(prices, period: 20)
|
|
34
|
+
rsi = SQAI.rsi(prices, period: 14)
|
|
35
|
+
macd_line, signal_line, histogram = SQAI.macd(prices)
|
|
36
|
+
|
|
37
|
+
puts "20-day SMA: #{sma.last}"
|
|
38
|
+
puts "14-day RSI: #{rsi.last}"
|
|
39
|
+
puts "MACD: #{macd_line.last}"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Indicator Categories
|
|
43
|
+
|
|
44
|
+
- **Overlap Studies** - SMA, EMA, WMA, DEMA, TEMA, Bollinger Bands
|
|
45
|
+
- **Momentum Indicators** - RSI, MACD, Stochastic, CCI, Williams %R, Momentum
|
|
46
|
+
- **Volatility Indicators** - ATR, NATR, True Range, Bollinger Bands
|
|
47
|
+
- **Volume Indicators** - OBV, AD, Chaikin Oscillator
|
|
48
|
+
- **Pattern Recognition** - Candlestick patterns, chart patterns
|
|
49
|
+
- **And 100+ more...**
|
|
50
|
+
|
|
51
|
+
### Full Indicator List
|
|
52
|
+
|
|
53
|
+
To see all available indicators:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
SQAI.methods.grep(/^[a-z]/).sort
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Documentation
|
|
62
|
+
|
|
63
|
+
For comprehensive indicator documentation, see:
|
|
64
|
+
|
|
65
|
+
- **[Technical Indicators Guide](indicators/index.md)** - Complete guide with examples
|
|
66
|
+
- **[sqa-tai Gem](https://github.com/MadBomber/sqa-tai)** - Indicator library source code
|
|
67
|
+
- **[TA-Lib Documentation](https://ta-lib.org/)** - Underlying C library reference
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Using Indicators with Strategies
|
|
72
|
+
|
|
73
|
+
Indicators are commonly used within trading strategies:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
require 'sqa'
|
|
77
|
+
|
|
78
|
+
SQA.init
|
|
79
|
+
|
|
80
|
+
# Load stock data
|
|
81
|
+
stock = SQA::Stock.new(ticker: 'AAPL')
|
|
82
|
+
df = stock.df
|
|
83
|
+
prices = df["adj_close_price"].to_a
|
|
84
|
+
|
|
85
|
+
# Calculate indicators
|
|
86
|
+
rsi = SQAI.rsi(prices, period: 14)
|
|
87
|
+
sma_20 = SQAI.sma(prices, period: 20)
|
|
88
|
+
sma_50 = SQAI.sma(prices, period: 50)
|
|
89
|
+
|
|
90
|
+
# Build signal vector
|
|
91
|
+
require 'ostruct'
|
|
92
|
+
vector = OpenStruct.new(
|
|
93
|
+
rsi: rsi.last,
|
|
94
|
+
sma_20: sma_20.last,
|
|
95
|
+
sma_50: sma_50.last,
|
|
96
|
+
price: prices.last
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Execute strategy
|
|
100
|
+
signal = SQA::Strategy::RSI.trade(vector)
|
|
101
|
+
puts "Signal: #{signal}" # => :buy, :sell, or :hold
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Related Documentation
|
|
107
|
+
|
|
108
|
+
- **[DataFrame API](api/dataframe.md)** - Working with price data
|
|
109
|
+
- **[Trading Strategies](strategies/index.md)** - Using indicators in strategies
|
|
110
|
+
- **[Backtesting](advanced/backtesting.md)** - Testing indicator-based strategies
|
|
111
|
+
- **[Strategy Generator](advanced/strategy-generator.md)** - Discovering indicator patterns
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## External Resources
|
|
116
|
+
|
|
117
|
+
- **[TA-Lib Official Site](https://ta-lib.org/)** - Technical Analysis Library
|
|
118
|
+
- **[Investopedia](https://www.investopedia.com/technical-analysis-4689657)** - Technical analysis education
|
|
119
|
+
- **[TradingView](https://www.tradingview.com/)** - Charting platform with indicators
|
data/docs/options.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Bollinger Bands Strategy
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Bollinger Bands strategy uses volatility bands to identify oversold and overbought conditions. The strategy generates buy signals when price touches the lower band and sell signals when price touches the upper band.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
Bollinger Bands consist of three lines:
|
|
10
|
+
|
|
11
|
+
- **Middle Band**: 20-period Simple Moving Average (SMA)
|
|
12
|
+
- **Upper Band**: Middle Band + (2 × Standard Deviation)
|
|
13
|
+
- **Lower Band**: Middle Band - (2 × Standard Deviation)
|
|
14
|
+
|
|
15
|
+
The bands expand and contract based on market volatility. When volatility increases, the bands widen; when volatility decreases, the bands narrow.
|
|
16
|
+
|
|
17
|
+
## Trading Signals
|
|
18
|
+
|
|
19
|
+
### Buy Signal
|
|
20
|
+
Price touches or falls below the **lower band**, indicating an oversold condition.
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
current_price <= lower_band # => :buy
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Sell Signal
|
|
27
|
+
Price touches or exceeds the **upper band**, indicating an overbought condition.
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
current_price >= upper_band # => :sell
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Hold Signal
|
|
34
|
+
Price remains between the bands.
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
lower_band < current_price < upper_band # => :hold
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Parameters
|
|
41
|
+
|
|
42
|
+
| Parameter | Value | Description |
|
|
43
|
+
|-----------|-------|-------------|
|
|
44
|
+
| Period | 20 | Number of periods for SMA calculation |
|
|
45
|
+
| Std Dev | 2.0 | Number of standard deviations for bands |
|
|
46
|
+
|
|
47
|
+
## Usage Example
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
require 'sqa'
|
|
51
|
+
require 'ostruct'
|
|
52
|
+
|
|
53
|
+
# Load stock data
|
|
54
|
+
stock = SQA::Stock.new(ticker: 'AAPL')
|
|
55
|
+
prices = stock.df["adj_close_price"].to_a
|
|
56
|
+
|
|
57
|
+
# Create vector with price data
|
|
58
|
+
vector = OpenStruct.new(prices: prices)
|
|
59
|
+
|
|
60
|
+
# Execute strategy
|
|
61
|
+
signal = SQA::Strategy::BollingerBands.trade(vector)
|
|
62
|
+
puts "Signal: #{signal}" # => :buy, :sell, or :hold
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Backtesting Example
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# Create backtest with Bollinger Bands strategy
|
|
69
|
+
backtest = SQA::Backtest.new(
|
|
70
|
+
stock: stock,
|
|
71
|
+
strategy: SQA::Strategy::BollingerBands,
|
|
72
|
+
initial_cash: 10_000
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
results = backtest.run
|
|
76
|
+
|
|
77
|
+
puts "Total Return: #{results.total_return}%"
|
|
78
|
+
puts "Sharpe Ratio: #{results.sharpe_ratio}"
|
|
79
|
+
puts "Max Drawdown: #{results.max_drawdown}%"
|
|
80
|
+
puts "Win Rate: #{results.win_rate}%"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Characteristics
|
|
84
|
+
|
|
85
|
+
| Attribute | Value |
|
|
86
|
+
|-----------|-------|
|
|
87
|
+
| Complexity | Medium |
|
|
88
|
+
| Best Market | Volatile, range-bound markets |
|
|
89
|
+
| Typical Win Rate | 50-60% |
|
|
90
|
+
| Risk Level | Medium |
|
|
91
|
+
| Time Horizon | Short to medium term |
|
|
92
|
+
|
|
93
|
+
## Strengths
|
|
94
|
+
|
|
95
|
+
- ✅ Works well in ranging markets
|
|
96
|
+
- ✅ Adapts to volatility changes
|
|
97
|
+
- ✅ Provides clear entry/exit points
|
|
98
|
+
- ✅ Simple to understand and implement
|
|
99
|
+
|
|
100
|
+
## Weaknesses
|
|
101
|
+
|
|
102
|
+
- ❌ Less effective in strong trends
|
|
103
|
+
- ❌ Can generate false signals during breakouts
|
|
104
|
+
- ❌ Requires sufficient price history (20+ periods)
|
|
105
|
+
- ❌ May whipsaw in choppy markets
|
|
106
|
+
|
|
107
|
+
## Tips for Best Results
|
|
108
|
+
|
|
109
|
+
1. **Combine with Trend Indicators**: Use with RSI or MACD to filter false signals
|
|
110
|
+
2. **Watch for Band Squeezes**: Narrow bands often precede big moves
|
|
111
|
+
3. **Adjust Parameters**: Consider wider bands (3 std dev) for less frequent signals
|
|
112
|
+
4. **Volume Confirmation**: Look for high volume on band touches for stronger signals
|
|
113
|
+
5. **Avoid in Trends**: Strategy works best in sideways markets
|
|
114
|
+
|
|
115
|
+
## Implementation Details
|
|
116
|
+
|
|
117
|
+
The strategy is implemented in `lib/sqa/strategy/bollinger_bands.rb` and uses TA-Lib's `bbands` indicator via the `sqa-tai` gem:
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
class SQA::Strategy::BollingerBands
|
|
121
|
+
def self.trade(vector)
|
|
122
|
+
# Calculate Bollinger Bands
|
|
123
|
+
upper, middle, lower = SQAI.bbands(
|
|
124
|
+
prices,
|
|
125
|
+
period: 20,
|
|
126
|
+
nbdev_up: 2.0,
|
|
127
|
+
nbdev_down: 2.0
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Compare current price to bands
|
|
131
|
+
# ... (see source for full implementation)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Related Strategies
|
|
137
|
+
|
|
138
|
+
- [RSI Strategy](rsi.md) - Combine for better oversold/overbought detection
|
|
139
|
+
- [Volume Breakout](volume-breakout.md) - Use together to confirm breakouts
|
|
140
|
+
- [Mean Reversion](mean-reversion.md) - Similar range-trading approach
|
|
141
|
+
|
|
142
|
+
## Further Reading
|
|
143
|
+
|
|
144
|
+
- [Bollinger Bands on Wikipedia](https://en.wikipedia.org/wiki/Bollinger_Bands)
|
|
145
|
+
- [John Bollinger's Official Site](https://www.bollingerbands.com/)
|
|
146
|
+
- [Understanding Volatility with Bollinger Bands](../concepts/volatility.md)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Consensus Strategy
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Aggregates signals from multiple strategies and makes trading decisions based on majority vote. Reduces risk of acting on single false signals.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
Executes 5 independent strategies and counts votes:
|
|
10
|
+
- **Majority Buy**: More buy signals than sell → Buy
|
|
11
|
+
- **Majority Sell**: More sell signals than buy → Sell
|
|
12
|
+
- **Tie or No Consensus**: Hold
|
|
13
|
+
|
|
14
|
+
## Trading Signals
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
strategies = [Strategy1, Strategy2, Strategy3, Strategy4, Strategy5]
|
|
18
|
+
votes = strategies.map { |s| s.trade(vector) }
|
|
19
|
+
# votes = [:buy, :buy, :sell, :hold, :buy]
|
|
20
|
+
|
|
21
|
+
# Count: buy=3, sell=1, hold=1
|
|
22
|
+
# Result: :buy (majority)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage Example
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
vector = OpenStruct.new(
|
|
29
|
+
rsi: rsi_data,
|
|
30
|
+
macd: macd_data,
|
|
31
|
+
prices: prices
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
signal = SQA::Strategy::Consensus.trade(vector)
|
|
35
|
+
# Returns :buy, :sell, or :hold based on majority
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Characteristics
|
|
39
|
+
|
|
40
|
+
- **Complexity**: Medium
|
|
41
|
+
- **Best Market**: All markets
|
|
42
|
+
- **Win Rate**: 50-60%
|
|
43
|
+
- **Reduces**: False signals
|
|
44
|
+
|
|
45
|
+
## Strengths
|
|
46
|
+
|
|
47
|
+
✅ Reduces false positives
|
|
48
|
+
✅ More reliable than single strategy
|
|
49
|
+
✅ Democratic decision making
|
|
50
|
+
✅ Can combine different approaches
|
|
51
|
+
|
|
52
|
+
## Weaknesses
|
|
53
|
+
|
|
54
|
+
❌ May be slower to act
|
|
55
|
+
❌ Can dilute strong signals
|
|
56
|
+
❌ Requires multiple data inputs
|
|
57
|
+
|
|
58
|
+
## Tips
|
|
59
|
+
|
|
60
|
+
1. **Diverse Strategies**: Mix trend and momentum strategies
|
|
61
|
+
2. **Odd Number**: Use odd number of strategies to avoid ties
|
|
62
|
+
3. **Weighted Voting**: Consider weighting better-performing strategies
|
|
63
|
+
4. **Threshold**: Require super-majority (e.g., 4 out of 5) for higher conviction
|
|
64
|
+
|