Strategy Generator¶
Overview¶
Reverse-engineer profitable trades to discover patterns and automatically generate executable trading strategies.
How It Works¶
- Identify Profitable Points: Scan historical data for entry points that led to profitable exits
- Capture Indicator States: Record all indicator values at those profitable points
- Mine Patterns: Find common combinations of indicator states
- Generate Strategies: Create executable strategy code from patterns
Quick Start¶
require 'sqa'
# Load stock data
stock = SQA::Stock.new(ticker: 'AAPL')
# Create generator
generator = SQA::StrategyGenerator.new(
stock: stock,
min_gain_percent: 10.0, # Minimum 10% profit
fpop: 10 # Look ahead 10 periods
)
# Discover patterns
patterns = generator.discover_patterns
# Generate strategy from first pattern
strategy_code = generator.generate_strategy(pattern_index: 0)
puts strategy_code
Configuration¶
generator = SQA::StrategyGenerator.new(
stock: stock,
min_gain_percent: 10.0, # Minimum profit required
max_loss_percent: -5.0, # Maximum acceptable loss
fpop: 10, # Future periods to analyze
min_support: 3 # Minimum pattern occurrences
)
Discovering Patterns¶
patterns = generator.discover_patterns
patterns.each_with_index do |pattern, i|
puts "\nPattern #{i}:"
puts " Support: #{pattern[:support]} occurrences"
puts " Avg Gain: #{pattern[:avg_gain].round(2)}%"
puts " Win Rate: #{pattern[:win_rate].round(2)}%"
puts " Conditions:"
pattern[:conditions].each do |cond|
puts " - #{cond[:indicator]}: #{cond[:state]}"
end
end
Generating Strategy Code¶
strategy_code = generator.generate_strategy(
pattern_index: 0,
class_name: 'DiscoveredStrategy'
)
# Save to file
File.write('lib/sqa/strategy/discovered_strategy.rb', strategy_code)
# Load and use
require_relative 'lib/sqa/strategy/discovered_strategy'
signal = SQA::Strategy::DiscoveredStrategy.trade(vector)
Context-Aware Patterns¶
# Include market context in pattern discovery
patterns = generator.discover_context_aware_patterns(
analyze_regime: true, # Include bull/bear/sideways
analyze_seasonal: true, # Include month/quarter
sector: :technology # Sector classification
)
# Patterns include context
pattern = patterns.first
puts "Valid in: #{pattern.context.valid_months}" # => [10, 11, 12]
puts "Valid regimes: #{pattern.context.valid_regimes}" # => [:bull]
puts "Sector: #{pattern.context.sector}" # => :technology
Walk-Forward Validation¶
# Prevent overfitting with out-of-sample testing
validated_patterns = generator.walk_forward_validate(
train_size: 250, # Training period (days)
test_size: 60 # Testing period (days)
)
validated_patterns.each do |result|
puts "Pattern #{result[:pattern_index]}:"
puts " Train Return: #{result[:train_return]}%"
puts " Test Return: #{result[:test_return]}%"
puts " Robust: #{result[:robust]}" # true if test performance acceptable
end
Example Output¶
# Generated strategy example
class SQA::Strategy::Pattern_1
def self.trade(vector)
return :hold unless valid_data?(vector)
# Pattern: Oversold RSI + Bullish MACD + High Volume
if vector.rsi[:trend] == :over_sold &&
vector.macd[:crossover] == :bullish &&
vector.volume_ratio > 1.5
:buy
else
:hold
end
end
private
def self.valid_data?(vector)
vector.respond_to?(:rsi) &&
vector.respond_to?(:macd) &&
vector.respond_to?(:volume_ratio)
end
end
Best Practices¶
- Use Sufficient Data: At least 1-2 years of historical data
- Validate Patterns: Use walk-forward testing
- Filter by Support: Require minimum pattern occurrences (3-5)
- Consider Context: Include market regime and seasonality
- Backtest Generated Strategies: Always test before using live
Related¶
- Genetic Programming - Optimize strategy parameters
- KBS Strategy - Rule-based strategies
- Backtesting - Test discovered strategies