Statistical Data Analysis and Inference › Worked Example: Analyzing Simulated Strategy Returns
Quantitative FinanceAll chapters Statistical Data Analysis and Inference › Worked Example: Analyzing Simulated Strategy ReturnsOne section · Sections in this chapter6 / 9 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Let's walk through an illustrative analysis of a seeded synthetic return series with small gains and occasional larger losses.
# Simulate an illustrative i.i.d. return mixture with a heavy left tail
np.random.seed(42)
n_days = 504 # Two years of trading
# Base simulated returns with slight positive drift
base_returns = np.random.normal(0.0003, 0.012, n_days)
# Inject occasional large losses into the synthetic series
crash_mask = np.random.random(n_days) < 0.02 # 2% chance of crash day
base_returns[crash_mask] = np.random.normal(-0.04, 0.015, crash_mask.sum())
strategy_returns = base_returnsStrategy Performance Analysis ================================================== Count: 504 Mean (daily): -0.000211 Mean (annualized, linear): -0.053113 Std Dev (daily): 0.012655 Std Dev (annualized): 0.200888 Skewness: -0.247155 Excess Kurtosis: 1.341945 Min: -0.060398 Max: 0.046533 Sharpe Ratio (simple returns, zero reference): -0.264389


In this simulation, the deliberately injected loss days produce negative sample skewness and higher sample kurtosis. Those results describe only the specified synthetic data-generating process.
# Test whether the modeled gross mean return differs from zero
t_stat, p_val = stats.ttest_1samp(strategy_returns, 0)
# Confidence intervals
n = len(strategy_returns)
se = np.std(strategy_returns, ddof=1) / np.sqrt(n)
t_crit = stats.t.ppf(0.975, n - 1)
mean_return = np.mean(strategy_returns)
ci_daily = (mean_return - t_crit * se, mean_return + t_crit * se)
ci_annual = (ci_daily[0] * 252, ci_daily[1] * 252)Statistical Inference ================================================== t-statistic: -0.3739 p-value (two-tailed): 0.7086 95% CI for mean daily return: [-0.001318, 0.000897] 95% CI for annualized arithmetic mean (simple returns): [-33.22%, 22.60%] Conclusion: Cannot conclude strategy returns differ from zero (p ≥ 0.05) Sharpe Ratio: -0.264 (approximate 95% IID-moment CI: [-1.648, 1.119])
This raw mean-return test is not a test of net profitability. To evaluate net returns, account for transaction costs, implementation constraints, and the return convention. Assess benchmark or factor exposures separately when interpreting risk-adjusted performance; use out-of-sample evidence to assess persistence and account for selection when testing many candidates.
Key Parameters
The key parameters for statistical analysis of returns:
- n: Sample size (number of observations). Under the independent common-variance model, larger samples reduce theoretical mean standard errors. Realized interval width also depends on estimated dispersion and the critical value.
- α (alpha): Significance level for hypothesis tests (commonly 0.05). Lower values reduce Type I error under the null and, with the design and alternative held fixed, reduce power.
- ddof: Degrees of freedom adjustment for variance estimation. For i.i.d. observations,
ddof=1gives the usual unbiased estimator of population variance; taking its square root does not make sample standard deviation exactly unbiased. - periods_per_year: Annualization factor (252 for daily trading data). The code multiplies the mean by this factor and volatility and the Sharpe ratio by its square root; skewness and kurtosis remain unchanged.
- confidence_level: Probability coverage for confidence intervals (commonly 0.95). Higher levels produce wider intervals.