Expectancy in Python
The average amount a strategy expects to win or lose per unit risked on each trade.
Definition
Expectancy is the statistical expected value of a trading strategy, expressed in dollars (or as a ratio per dollar risked). It synthesizes Win Rate and the average win/loss magnitudes into a single actionable number that answers the core question: 'On average, how much do I make or lose each time I take a trade?' A positive expectancy is the minimum requirement for a viable strategy. It is directly related to the Kelly Criterion for optimal position sizing.
Quantitative Formula
Where is the win rate (as a decimal), is the average profit of winning trades, and is the absolute average loss of losing trades. The result represents the expected P&L per trade. A normalized version divides by to express expectancy as a multiple of average risk.
Why It Matters in Backtesting
A strategy with 40% win rate, average win of \$300, and average loss of \$100 has an Expectancy of \$80 per trade — it is solidly profitable despite losing 60% of the time. In backtesting, Expectancy quantifies edge in the most direct way possible and is robust to position sizing assumptions. It is the foundation of the Kelly Criterion for optimal bet sizing in live deployment.
Python Implementation
import pandas as pd
def calculate_expectancy(trade_pnl: pd.Series) -> dict:
"""
Calculates raw and normalized Expectancy from closed trade P&L.
trade_pnl: Series where each value is the profit or loss of one closed trade.
"""
wins = trade_pnl[trade_pnl > 0]
losses = trade_pnl[trade_pnl < 0]
win_rate = len(wins) / len(trade_pnl) if len(trade_pnl) > 0 else 0.0
avg_win = wins.mean() if len(wins) > 0 else 0.0
avg_loss = losses.abs().mean() if len(losses) > 0 else 0.0
expectancy = (win_rate * avg_win) - ((1 - win_rate) * avg_loss)
normalized = expectancy / avg_loss if avg_loss != 0 else 0.0
return {
"expectancy_per_trade": expectancy,
"normalized_expectancy": normalized, # In units of average risk
"win_rate": win_rate,
"avg_win": avg_win,
"avg_loss": avg_loss
}Test this in a live environment
Stop running Jupyter notebooks locally. Paste this Expectancy code directly into Valetha's Strategy Lab and run a full historical backtest in seconds.
Open the Python Strategy Lab