On February 19, 2025, the S&P 500 closed at a record 6,144.15. Seven weeks later, on April 8, it closed at 4,982.77: a close-to-close drawdown of 18.9%, just short of the 20% that would have made it an official bear market. Most of the damage came in four sessions after the April 2 "Liberation Day" tariff announcement, including a 4.8% drop on April 3 and a 6% drop on April 4.
Then, on April 9, the White House announced a 90-day pause on most of the new tariffs, and the index rose 9.5% in one day, its best day since October 2008. By the close on May 27, after the EU tariff delay, it stood at 5,921.54, about 3.6% below the February record.
If you held through it, the whole episode is a dip on a chart. If you sold on April 8, you locked in the loss and missed the best day in 16 years. The difference between those two investors is not a forecast. It is whether they understood the risk they were carrying before the sell-off started.
This cheatsheet covers the metrics that describe that risk, what each one hides, and how to compute them with pandas.
Educational content, not financial advice.
1. Drawdown, max drawdown and the underwater period
| Term | Definition | Example (S&P 500, 2025, closes) |
|---|---|---|
| Running peak | Highest value reached so far | 6,144.15 on February 19 |
| Drawdown | Current value / running peak - 1. Always zero or negative | April 8: 4,982.77 / 6,144.15 - 1 = -18.9% |
| Max drawdown (MDD) | Most negative drawdown over the period | -18.9% (close-to-close, for 2025 so far) |
| Drawdown duration | Time from a peak to the trough | February 19 to April 8: 34 trading days |
| Recovery time | Time from the trough back to the previous peak | Not complete as of May 27 (about 3.6% below) |
| Underwater period | Total time spent below the previous peak: duration plus recovery | February 19 to today, and counting |
Notes that matter in practice:
- Close-to-close vs intraday. Intraday lows were deeper than closing lows in early April. State which one you use; fund factsheets almost always use closes (often monthly), which understates the pain.
- Sampling frequency hides drawdowns. A month-end series can miss a drawdown that started and recovered inside the month.
- Max drawdown is a single event. It depends heavily on the sample period. A 10-year backtest without 2008, 2020 or 2022 in it has an MDD that tells you little about the next crisis.
- Duration is often the harder part. Investors tolerate a sharp 20% drop that recovers in months better than a 20% drop that stays underwater for years. The S&P 500 took until 2013 to regain its 2007 peak on a price basis.
2. The asymmetry of losses
A loss of x requires a gain of x / (1 - x) to get back to even:
| Loss | Gain needed to recover |
|---|---|
| -5% | +5.3% |
| -10% | +11.1% |
| -18.9% (S&P 500, Feb-Apr 2025) | +23.3% |
| -20% | +25% |
| -30% | +42.9% |
| -50% | +100% |
| -80% | +400% |
Two consequences:
- Small losses are cheap, large losses are expensive. The recovery cost grows faster than the loss. That is the mathematical reason risk management focuses on avoiding the large ones.
- Volatility drags on compounding. Gaining 10% then losing 10% leaves you at 0.99, not 1.00. Approximately, geometric return = arithmetic return - variance / 2. Two strategies with the same average return compound differently if their volatility differs.
The rebound from April 8 to May 27 was +18.8%, which sounds like more than the 18.9% lost. It was not enough to recover: the asymmetry in one line.
3. The core risk metrics
| Metric | Formula (annualized from daily data) | What it says | What it hides |
|---|---|---|---|
| Volatility | Std of daily returns x sqrt(252) | Typical size of moves | Up and down moves count equally; fat tails |
| Sharpe ratio | (Mean return - risk-free) / volatility | Return per unit of total volatility | Penalizes upside volatility; assumes roughly normal returns |
| Sortino ratio | (Mean return - target) / downside deviation | Return per unit of bad volatility | Needs a target (0 or risk-free); unstable with few down days |
| Calmar ratio | CAGR / abs(max drawdown), often over 3 years | Return per unit of worst pain | Rests on one event; very period-dependent |
| VaR (95%, 1 day) | Loss exceeded on only 5% of days | "A bad normal day" | Says nothing about how bad the worst 5% are |
| CVaR / Expected Shortfall | Average loss on the days worse than VaR | The size of the tail | Needs many observations to be stable |
| Beta | Cov(asset, market) / Var(market) | Sensitivity to the market | Unstable over time; a low beta can still crash |
| Correlation | Pearson correlation of returns | How assets move together | Changes with regime, especially in crises |
Rules of thumb:
- A Sharpe above 1 on a long, out-of-sample record is good for a diversified strategy. A backtest Sharpe above 3 is usually a bug, overfitting, or a strategy that sells tail risk.
- Use log or simple returns consistently, and annualize with the right factor: 252 for daily, 52 for weekly, 12 for monthly.
- Historical VaR uses the empirical distribution; parametric VaR assumes a normal one. Normal VaR underestimates tail losses for equities, which have fat left tails. CVaR is the better tail measure and is what Basel's market risk framework moved to.
- Report MDD next to any return number. "12% a year" with a -55% drawdown is a different product from "12% a year" with a -15% drawdown.
4. Correlations spike in crises
Diversification is measured in calm markets and needed in stressed ones, and those are not the same correlation matrix. Longin and Solnik (2001) found that correlations between international equity markets rise in bear markets, not in bull markets. In practice, during a sell-off many equity positions behave like one position.
Practical implications:
- Estimate correlations on stress windows (2008, March 2020, 2022, April 2025) as well as full history.
- Count your real bets. Ten tech stocks and a Nasdaq ETF are one bet with extra fees.
- Do not assume the hedge works every time. Bonds hedged equity sell-offs in 2008 and 2020 and fell with them in 2022. Check what a hedge did in the specific kind of shock you worry about (inflation, growth, policy).
5. Position sizing and risk budgeting
Metrics describe risk. Sizing is where you control it.
| Method | Rule | Use it when |
|---|---|---|
| Fixed fractional (per-trade risk) | Size = (equity x risk %) / (entry - stop). Risk 0.5-2% of equity per trade | Discretionary or systematic trading with defined stops |
| Volatility targeting | Weight = target vol / asset vol | Keeping portfolio risk stable as markets calm down or heat up |
| Equal risk contribution (risk parity) | Each position contributes the same share of portfolio volatility | Multi-asset portfolios where one asset would otherwise dominate |
| Drawdown limits | Cut gross exposure at -10%, again at -15%, review at -20% | Rules that must be decided before the drawdown, not during |
| Kelly fraction | Size that maximizes long-run growth given an edge | Theory only; real edges are uncertain, so practitioners use a fraction of Kelly at most |
Example of fixed fractional: a $50,000 account risking 1% per trade, buying at $100 with a stop at $92, can buy 500 / 8 = 62 shares. The stop, not the conviction, sets the size. Note that a stop is not a guaranteed exit price: on gap days like April 3 and 4, prices can open far beyond it.
Risk budgeting at the portfolio level: decide the maximum drawdown you can live with, financially and emotionally, then size the equity allocation so that a historical-scale crash (say -35% to -50% for broad equities) stays inside that budget. If a -50% equity crash would put your portfolio at -30% and you know you would sell at -20%, your allocation is too high, whatever the Sharpe ratio says.
6. The behavioral side: selling at the bottom
Drawdowns are a math problem on a spreadsheet and a psychology problem in real time.
- Loss aversion. Kahneman and Tversky's prospect theory: losses loom larger than equivalent gains, and their later estimates put the weight at roughly twice. An -18.9% drawdown feels larger than the +18.8% rebound that followed.
- The best days cluster near the worst days. April 9 (+9.5%) came one session after the April 8 low. Selling to "wait until things calm down" usually means buying back higher.
- Recency and narrative. In the middle of a sell-off the news explains why it will continue. At the April 8 close, nobody knew that the pause would come the next day.
- Disposition effect. Investors sell winners too early and hold losers too long, the opposite of what most trend and risk rules ask.
Defenses that work better than willpower:
- Write the rules before the drawdown: allocation, rebalancing bands, drawdown limits, what you will do at -10%, -20%, -30%.
- Rebalance mechanically, on a schedule or at bands (for example, plus or minus 5 points from target). It forces buying after falls.
- Size for the worst case you can sit through, not the expected case.
- Keep a cash or bond buffer for known spending, so you never sell equities in a drawdown to pay bills.
- Look less. Checking a portfolio daily during a sell-off increases the urge to act.
7. Computing it with pandas
The code below takes a price series (closes) and returns the drawdown series, max drawdown, longest underwater period, and the ratios from section 3. Feed it real closes from any data source.
import numpy as np
import pandas as pd
TRADING_DAYS = 252
def drawdown_series(prices: pd.Series) -> pd.DataFrame:
"""Running peak, drawdown (as a negative fraction) and underwater flag."""
peak = prices.cummax()
dd = prices / peak - 1.0
return pd.DataFrame({"price": prices, "peak": peak, "drawdown": dd, "underwater": dd < 0})
def max_drawdown(prices: pd.Series) -> tuple[float, pd.Timestamp, pd.Timestamp]:
dd = prices / prices.cummax() - 1.0
trough = dd.idxmin()
peak = prices.loc[:trough].idxmax()
return dd.min(), peak, trough
def longest_underwater(prices: pd.Series) -> int:
"""Longest run of consecutive observations below the previous peak."""
under = (prices < prices.cummax()).astype(int)
runs = under.groupby((under == 0).cumsum()).sum()
return int(runs.max())
def risk_report(prices: pd.Series, rf_annual: float = 0.0, benchmark: pd.Series | None = None) -> dict:
r = prices.pct_change().dropna()
rf_daily = (1 + rf_annual) ** (1 / TRADING_DAYS) - 1
excess = r - rf_daily
years = len(r) / TRADING_DAYS
cagr = (prices.iloc[-1] / prices.iloc[0]) ** (1 / years) - 1
vol = r.std() * np.sqrt(TRADING_DAYS)
sharpe = excess.mean() / r.std() * np.sqrt(TRADING_DAYS)
downside = np.sqrt((np.minimum(excess, 0) ** 2).mean()) * np.sqrt(TRADING_DAYS)
sortino = excess.mean() * TRADING_DAYS / downside
mdd, _, _ = max_drawdown(prices)
calmar = cagr / abs(mdd)
var95 = -np.percentile(r, 5) # historical 1-day VaR, as a positive loss
cvar95 = -r[r <= -var95].mean() # average loss beyond VaR
out = {
"CAGR": cagr, "Volatility": vol, "Sharpe": sharpe, "Sortino": sortino,
"Max drawdown": mdd, "Calmar": calmar, "VaR 95% (1d)": var95,
"CVaR 95% (1d)": cvar95, "Longest underwater": longest_underwater(prices),
}
if benchmark is not None:
b = benchmark.pct_change().dropna().reindex(r.index)
out["Beta"] = r.cov(b) / b.var()
out["Correlation"] = r.corr(b)
return out
# The 2025 sell-off, three closes
spx = pd.Series(
[6144.15, 4982.77, 5921.54],
index=pd.to_datetime(["2025-02-19", "2025-04-08", "2025-05-27"]),
)
print(drawdown_series(spx)["drawdown"].round(4))
# 2025-02-19 0.0000
# 2025-04-08 -0.1890
# 2025-05-27 -0.0362
Implementation notes:
- Sortino's downside deviation here uses all observations with positive excess returns set to zero, which is the standard definition. Some libraries divide only by the count of negative days, which gives a different number. Check before comparing.
- Rolling metrics are more informative than one full-period number:
r.rolling(63).std() * np.sqrt(252)for a 3-month rolling volatility,r.rolling(126).corr(b)for a 6-month rolling correlation that shows crisis spikes. - Use total return series (dividends reinvested) for long periods. Price-only series overstate drawdown durations.
- Beware survivorship. Metrics computed on today's index members or surviving funds look better than what investors actually experienced.
Why this matters
- Drawdown is the risk investors feel. Volatility is an abstraction; -18.9% on a statement is not.
- Losses compound against you. A -50% year needs a +100% year. Avoiding large losses matters more than catching every gain.
- Every ratio hides something. Sharpe hides tails, VaR hides the size of the tail, MDD hides how often, correlation hides regime changes. Use several.
- Sizing is the lever you control. You cannot control the next sell-off, but you can choose how big it is in your portfolio.
- The plan has to be written before the drawdown. Decisions made at the bottom are made by the worst version of yourself.
Final Thoughts
The spring 2025 sell-off was short by historical standards: seven weeks down, a violent one-day reversal, and a steady climb back to within a few percent of the high by late May. Short episodes are where risk metrics are most useful, because they are a cheap rehearsal. Look at what your portfolio did between February 19 and April 8, how you felt on April 8, and what you did about it.
If the numbers and your behavior both stayed inside the plan, the plan is about right. If not, adjust the sizing now, while the market is calm, rather than in the next drawdown.
Sources
- The Motley Fool, The S&P 500 Just Did Something Seen Only 5 Times in 80 Years (April 8, 2025): -4.8% on April 3, -6% on April 4, 10.5% two-day loss.
- Dow Jones Market Data via Tiger Brokers, S&P 500 Falls 1.57% to 4982.77: Data Talk (April 8, 2025): April 8 close and 18.9% decline from the 6,144.15 record of February 19.
- CBS News, Stock market live coverage, April 9, 2025 (April 9, 2025): +9.5%, best day since October 2008, 90-day pause.
- Yahoo Finance, How the S&P 500 recovered all of its losses for the year (May 16, 2025): index turned positive for 2025 in mid-May.
- PBS NewsHour / AP, S&P 500 rallies 2% as Wall Street responds to Trump delay of 50% EU tariffs (May 27, 2025): close of 5,921.54, within 3.6% of the record.
- Sharpe, The Sharpe Ratio (Journal of Portfolio Management, 1994).
- Sortino and Price, Performance Measurement in a Downside Risk Framework (Journal of Investing, 1994).
- Rockafellar and Uryasev, Optimization of Conditional Value-at-Risk (Journal of Risk, 2000): CVaR definition.
- Basel Committee, Minimum capital requirements for market risk (2019): expected shortfall replacing VaR.
- Longin and Solnik, Extreme Correlation of International Equity Markets (Journal of Finance, 2001): correlations rise in bear markets.
- Kahneman and Tversky, Prospect Theory: An Analysis of Decision under Risk (Econometrica, 1979): loss aversion; Tversky and Kahneman, Advances in Prospect Theory (Journal of Risk and Uncertainty, 1992): loss aversion coefficient of about 2.25.
- Shefrin and Statman, The Disposition to Sell Winners Too Early and Ride Losers Too Long (Journal of Finance, 1985).