Backtesting Trading Strategies 📊
Introduction to Backtesting
Backtesting is the process of testing a trading strategy on historical data to evaluate its performance. Pine Script provides powerful tools for implementing and testing trading strategies.
Basic Strategy Structure
//@version=5
strategy("My First Strategy", overlay=true)
// Define strategy parameters
longPeriod = input(20, "Long MA Period")
shortPeriod = input(10, "Short MA Period")
// Calculate indicators
fastMA = ta.sma(close, shortPeriod)
slowMA = ta.sma(close, longPeriod)
// Define entry conditions
longCondition = ta.crossover(fastMA, slowMA)
shortCondition = ta.crossunder(fastMA, slowMA)
// Execute trades
if (longCondition)
strategy.entry("Long", strategy.long)
if (shortCondition)
strategy.entry("Short", strategy.short)
Position Sizing
Fixed Position Size
//@version=5
strategy("Fixed Size Example")
// Fixed position size
fixedSize = input.float(1.0, "Position Size")
if (longCondition)
strategy.entry("Long", strategy.long, qty=fixedSize)
Dynamic Position Sizing
//@version=5
strategy("Dynamic Sizing")
// Risk-based position sizing
riskPercent = input.float(1.0, "Risk %", minval=0.1, maxval=100)
atrPeriod = input.int(14, "ATR Period")
atr = ta.atr(atrPeriod)
// Calculate position size based on ATR
riskAmount = strategy.equity * (riskPercent / 100)
positionSize = riskAmount / atr
if (longCondition)
strategy.entry("Long", strategy.long, qty=positionSize)
Stop Loss and Take Profit
//@version=5
strategy("SL and TP Example", overlay=true)
// Define stop loss and take profit levels
stopLoss = input.float(2.0, "Stop Loss %", minval=0.1)
takeProfit = input.float(4.0, "Take Profit %", minval=0.1)
if (longCondition)
entryPrice = close
strategy.entry("Long", strategy.long)
strategy.exit("Exit", "Long",
stop=entryPrice * (1 - stopLoss/100),
limit=entryPrice * (1 + takeProfit/100))
Strategy Properties
//@version=5
strategy("Strategy Properties Example",
initial_capital=10000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=100,
commission_type=strategy.commission.percent,
commission_value=0.1)
Performance Analysis
Basic Metrics
//@version=5
strategy("Performance Metrics")
// Plot equity curve
plot(strategy.equity, "Equity", color=color.blue)
// Create performance table
var table perfTable = table.new(position.top_right, 3, 4)
if barstate.islast
table.cell(perfTable, 0, 0, "Metric", bgcolor=color.blue, text_color=color.white)
table.cell(perfTable, 1, 0, "Value", bgcolor=color.blue, text_color=color.white)
table.cell(perfTable, 0, 1, "Net Profit")
table.cell(perfTable, 1, 1, str.tostring(strategy.netprofit))
table.cell(perfTable, 0, 2, "Win Rate")
table.cell(perfTable, 1, 2, str.tostring(strategy.wintrades/strategy.closedtrades * 100) + "%")
Advanced Backtesting Features
Time-Based Filters
//@version=5
strategy("Time Filtered Strategy")
// Trading session
sessionInput = input.session("0930-1600", "Trading Session")
inSession = session.ismarket(sessionInput)
// Only trade during session
if longCondition and inSession
strategy.entry("Long", strategy.long)
Risk Management
//@version=5
strategy("Risk Management")
// Maximum drawdown protection
maxDrawdown = input.float(10, "Max Drawdown %")
// Check drawdown before entry
currentDrawdown = (strategy.equity - strategy.equity_high) / strategy.equity_high * 100
if longCondition and currentDrawdown > -maxDrawdown
strategy.entry("Long", strategy.long)
Pro Tips
- Always backtest across different market conditions
- Consider transaction costs and slippage
- Use realistic position sizing
- Test your strategy parameters
Common Pitfalls
❌ Overfitting to historical data ❌ Ignoring transaction costs ❌ Not accounting for market liquidity ❌ Using unrealistic position sizes
Next Steps
Ready to learn about strategy optimization? Move on to the next chapter! 🚀