Strategy Optimization 🎯
Introduction to Optimization
Strategy optimization is the process of finding the best parameters for your trading strategy. While Pine Script doesn't provide built-in optimization tools, we can implement smart approaches to test different parameters.
Parameter Testing
Basic Parameter Arrays
//@version=5
strategy("Parameter Testing")
// Define parameter arrays
var int[] maPeriods = array.from(10, 20, 50, 200)
var float[] stopLevels = array.from(1.0, 2.0, 3.0)
// Test different periods
period = input.int(20, "MA Period", options=maPeriods)
stopLevel = input.float(2.0, "Stop Loss %", options=stopLevels)
// Use parameters
ma = ta.sma(close, period)
Multiple Time Frames
//@version=5
strategy("Timeframe Testing", overlay=true)
// Test strategy on different timeframes
timeframe = input.timeframe("D", "Timeframe")
// Get data from different timeframes
higherClose = request.security(syminfo.tickerid, timeframe, close)
higherMA = request.security(syminfo.tickerid, timeframe, ta.sma(close, 20))
Walk-Forward Analysis
In-Sample Testing
//@version=5
strategy("Walk Forward Testing")
// Define testing periods
isInSample = time >= timestamp("2020-01-01") and
time <= timestamp("2021-12-31")
// Only trade during in-sample period
if isInSample
if longCondition
strategy.entry("Long", strategy.long)
Out-of-Sample Testing
//@version=5
strategy("Out of Sample Testing")
// Define different periods
inSampleEnd = timestamp("2021-12-31")
isOutOfSample = time > inSampleEnd
// Track performance separately
var float inSamplePnL = 0.0
var float outSamplePnL = 0.0
if strategy.closedtrades > 0
if time <= inSampleEnd
inSamplePnL := strategy.netprofit
else
outSamplePnL := strategy.netprofit - inSamplePnL
Performance Metrics
Advanced Performance Table
//@version=5
strategy("Performance Analysis")
// Create detailed performance table
var table perfTable = table.new(position.top_right, 4, 5)
if barstate.islast
// Headers
table.cell(perfTable, 0, 0, "Metric", bgcolor=color.blue)
table.cell(perfTable, 1, 0, "All Time", bgcolor=color.blue)
table.cell(perfTable, 2, 0, "Last Month", bgcolor=color.blue)
table.cell(perfTable, 3, 0, "Last Week", bgcolor=color.blue)
// Net Profit
table.cell(perfTable, 0, 1, "Net Profit")
table.cell(perfTable, 1, 1, str.tostring(strategy.netprofit))
// Win Rate
table.cell(perfTable, 0, 2, "Win Rate")
table.cell(perfTable, 1, 2, str.tostring(strategy.wintrades/strategy.closedtrades * 100) + "%")
// Max Drawdown
table.cell(perfTable, 0, 3, "Max DD")
table.cell(perfTable, 1, 3, str.tostring(strategy.max_drawdown))
// Profit Factor
table.cell(perfTable, 0, 4, "Profit Factor")
table.cell(perfTable, 1, 4, str.tostring(strategy.grossprofit/strategy.grossloss))
Monte Carlo Analysis
Simple Monte Carlo
//@version=5
strategy("Monte Carlo", overlay=true)
// Store trade results
var float[] returns = array.new_float(0)
// Record trade returns
if strategy.closedtrades > array.size(returns)
tradeReturn = (strategy.closedtrades.exit_price -
strategy.closedtrades.entry_price) /
strategy.closedtrades.entry_price
array.push(returns, tradeReturn)
// Calculate statistics
if barstate.islast
float sumReturns = array.sum(returns)
float avgReturn = sumReturns / array.size(returns)
float stdDev = ta.stdev(returns, array.size(returns))
Risk Management Optimization
Dynamic Position Sizing
//@version=5
strategy("Position Size Optimization")
// Risk parameters
riskPercent = input.float(1.0, "Risk %", minval=0.1)
maxPositions = input.int(3, "Max Open Positions")
// Calculate optimal position size
atr = ta.atr(14)
riskAmount = strategy.equity * (riskPercent / 100)
positionSize = math.min(
riskAmount / atr,
strategy.equity / close / maxPositions
)
// Enter position with optimized size
if longCondition and strategy.opentrades < maxPositions
strategy.entry("Long", strategy.long, qty=positionSize)
Strategy Robustness
Market Regime Testing
//@version=5
strategy("Market Regime Testing")
// Define market regimes
volatility = ta.atr(14) / close * 100
isHighVol = volatility > ta.sma(volatility, 100)
isTrending = math.abs(ta.sma(close, 20) - ta.sma(close, 50)) >
ta.atr(14) * 2
// Adjust strategy based on regime
if isTrending and not isHighVol
// Full position size
strategy.entry("Long", strategy.long)
else if isTrending and isHighVol
// Reduced position size
strategy.entry("Long", strategy.long, qty=strategy.fixed_size * 0.5)
Optimization Tips
- Avoid over-optimization
- Use walk-forward testing
- Consider different market conditions
- Test robustness across timeframes
- Monitor out-of-sample performance
Common Mistakes
❌ Curve fitting parameters ❌ Ignoring transaction costs in optimization ❌ Not considering market regimes ❌ Over-relying on in-sample results
Next Steps
Ready to learn about strategy deployment? Move on to the next chapter! 🚀