# 📉 Returns, Volatility, and Time Series Basics

By Anh Le

Last lesson you ended with a clean, sorted price series. That series is raw material, not an input. A trading rule never says "buy when the price is above 420"; it says "buy when the price rose 2% this week". So this lesson turns prices into returns, then into volatility, and then into the three warnings every beginner needs before trusting a number computed from market data.

By the end you should be able to:

- Convert a price column into simple returns and log returns.
- Decide which return type fits a given job.
- Measure daily volatility and annualize it correctly.
- Name the time series properties that break naive i.i.d. statistics.
- Run all of this on the price data you cleaned for your capstone asset.

## From a price column to a return column

A price tells you where the market is. A return tells you what an owner of the asset actually earned. Almost everything you compute later, from volatility to drawdown to signal strength, is built on returns.

The **simple return** (also called the arithmetic or percentage return) is the percentage change from one period to the next:

$$
r_t = \frac{P_t}{P_{t-1}} - 1
$$

If SPY closes at 420.00 then 424.20, the simple return is 0.01, or 1%.

Why not model prices directly? Two reasons. First, prices are not comparable across assets: a 5 dollar move on a 20 dollar stock is enormous, while the same 5 dollars on a share priced at 2,000 is noise. Returns are already scaled, so you can compare them. Second, prices are **non-stationary**: they trend for decades, so the average price of a series carries no useful information. The average return does.

> **Note:** 
> In pandas, the whole conversion is one line: `df["ret"] = df["close"].pct_change()`. The first row comes back as `NaN` by design, because there is no previous price to divide by.

**Practice (capstone thread).** Your cleaned SPY series shows 420.00 then 424.20. Compute the simple return, then explain in one sentence why you cannot compare that 1% to a 1% move in a different asset without checking its price.

**Click to reveal the answer**

$424.20 / 420.00 - 1 = 0.01$, so 1%. You *can* compare it: a return is already price-scaled, which is exactly why the comparison works and why raw price changes do not.

## Log returns and when to reach for them

The **log return** is the natural logarithm of the price ratio:

$$
r_t^{\log} = \ln\left(\frac{P_t}{P_{t-1}}\right) = \ln(1 + r_t)
$$

For small moves the two are nearly identical: a 1% simple return is a 0.995% log return. They separate on large moves. A 50% loss is a log return near -0.693, and a 100% gain is +0.693, so the log scale is symmetric around zero.

The property that matters is that **log returns add over time**. Simple returns compound by multiplication, so a +2% day followed by a -2% day leaves you at $1.02 \times 0.98 = 0.9996$, a small loss, not flat. The log returns simply sum.

| Job | Use |
| --- | --- |
| Reporting performance to a person | Simple return |
| Summing returns across many periods | Log return |
| Feeding a model or a regression | Log return |
| Comparing one asset to another | Either (both are scaled) |

**Practice.** A price walks 100, then 105, then 110. Compute both daily log returns and confirm they sum to $\ln(110/100)$.

**Click to reveal the answer**

$\ln(1.05) = 0.04879$ on both days, summing to 0.09758. And $\ln(110/100) = 0.09758$. The sum of log returns is the total log return, always.

## Volatility: how wide the returns scatter

Volatility is the _____ of returns. It says nothing about direction, only about the size of the wobble. A daily volatility of 0.01 means a typical day moves about 1%.

Two practical details. Use the sample standard deviation (`ddof=1`, which pandas `.std()` does by default). Then annualize, because a daily number is hard to reason about:

$$
\sigma_{\text{annual}} = \sigma_{\text{daily}} \times \sqrt{252}
$$

The square root is not decoration. Variance grows linearly with time, so standard deviation grows with the square root of time. $\sqrt{252} \approx 15.87$, so 1% daily becomes roughly 15.9% annual.

**Practice.** Your SPY returns show a daily standard deviation of 0.0095. Annualize it, then sanity-check the answer against a typical equity volatility of 15% to 20%.

**Click to reveal the answer**

$0.0095 \times 15.87 \approx 0.151$, about 15.1% annualized. That sits comfortably inside the normal equity range, which is a good sign your data cleaning did not mangle anything.

## Time series properties that break naive statistics

Most textbook formulas assume independent observations drawn from one fixed distribution. Returns violate that in specific, well-known ways, and each violation has a practical consequence.

1. **Non-stationarity in prices.** Prices drift and have unit roots. Regressing one price on another produces impressive-looking relationships that are pure coincidence (spurious regression). Model returns instead.
2. **Volatility clustering.** Large moves follow large moves. Volatility is autocorrelated even when returns are close to uncorrelated, so a single full-sample average volatility describes no actual period. Plot a rolling 20-day volatility and you will see calm stretches and violent ones.
3. **Fat tails.** Equity returns produce far more 3-sigma and 5-sigma days than a normal distribution predicts. Anything that sizes risk using normality will understate bad days.
4. **Autocorrelation and stale prices.** Illiquid assets print prices that lag reality, which creates positive autocorrelation and makes a naive backtest look better than the trade would have been.

The habit that protects you: before trusting any metric, plot the returns, plot rolling volatility, and put a histogram against a normal curve.

**Practice.** You compute one volatility number for SPY over twenty years and size every position with it. Which property did you ignore, and what goes wrong in practice?

**Click to reveal the answer**

Volatility clustering. A single average will be too high for calm periods (you under-trade) and far too low during a crisis (you take too much risk exactly when it hurts). Use a rolling or exponentially weighted estimate.

## Rules of thumb that save beginners rework

- Compute returns once, in one place, and check that you have one fewer return than prices.
- Use `.pct_change()` for simple returns and `np.log1p(...)` on simple returns for log returns, avoiding a `log(0)` surprise.
- Check for `NaN` and infinities right after conversion. A single bad price poisons two returns.
- Express volatility per year when you talk about it. "1% daily" and "16% annual" are the same fact.
- Never describe a strategy's risk with one volatility number for a twenty-year window. Look at the rolling series first.
- If your data has multi-day gaps, do not treat the returns as consecutive days: the volatility annualization silently lies.

Log returns are _____ across time, while simple returns compound by multiplication.
Annualizing a daily volatility multiplies it by the square root of _____, roughly 15.87.
The tendency of violent days to follow violent days is called _____.
Equity returns producing more extreme days than a normal curve predicts is known as _____.

Front: Why compute returns instead of using prices?
Back: Returns are scaled across assets and are close to stationary, while prices trend and are not comparable in raw units.

Front: Simple return formula?
Back: P_t / P_(t-1) - 1

Front: Log return formula?
Back: ln(P_t / P_(t-1)), which equals ln(1 + simple return)

Front: When are simple and log returns nearly equal?
Back: When the move is small, roughly a few percent or less.

Front: What is the key advantage of log returns?
Back: They add across time, so the sum of log returns is the total log return.

Front: A +2% day then a -2% day leaves a simple-return portfolio where?
Back: Slightly below flat, at 0.9996, because simple returns compound by multiplication.

Front: Volatility is measured as what?
Back: The standard deviation of returns, using the sample version with ddof=1.

Front: How do you annualize daily volatility?
Back: Multiply by the square root of 252, about 15.87.

Front: Why the square root and not 252?
Back: Variance scales linearly with time, so standard deviation scales with the square root of time.

Front: What does volatility clustering mean?
Back: Large moves follow large moves, so volatility is autocorrelated and a single average hides calm and crisis periods.

Front: What are fat tails?
Back: Far more 3-sigma and 5-sigma days than a normal distribution implies.

Front: Why is regressing one price on another dangerous?
Back: Prices are non-stationary, so the regression can be spurious: a strong fit with no real relationship.

Front: How do stale prices distort a naive backtest?
Back: They create positive autocorrelation, making a slow-moving signal look predictive when it is only lagging reality.

## What to carry into the checkpoint

You now have the three tools this module is built on: a clean price series, a return column derived from it, and a volatility number you can defend. Remember the chain: returns make assets comparable, log returns make time aggregation trivial, annualized volatility makes risk readable, and the time series warnings keep you from trusting a metric that the data does not support.

Next up is the module checkpoint, where you will load, clean, convert, and describe a real price series from start to finish, then explain each number you produce.

---

## Contents

Part of [📊 Quantitative Trading for Beginners: Build and Backtest a Strategy](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy.md)

- **📈 Market Data and Return Statistics**
  - [🧭 What a Quant Strategy Actually Needs](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/what-a-quant-strategy-needs.md)
  - [🗂️ Getting and Cleaning Price Data](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/getting-and-cleaning-price-data.md) (sign-in required)
  - [📉 Returns, Volatility, and Time Series Basics](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/returns-volatility-and-time-series-basics.md) — this lesson
  - [✅ Checkpoint: Market Data and Statistics](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/checkpoint-market-data-and-statistics.md)
- **🧪 Strategy Design and Backtesting**
  - [📝 From Idea to Testable Trading Rules](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/from-idea-to-testable-trading-rules.md)
  - [🧮 Building the Backtest: Fills, Slippage, and Fees](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/building-backtest-fills-slippage-and-fees.md)
  - [🔍 Reading Results and Avoiding Overfitting](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/reading-results-and-avoiding-overfitting.md)
  - [✅ Checkpoint: Strategy Design and Backtesting](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/checkpoint-strategy-design-and-backtesting.md)
- **🛡️ Risk Control and Capstone Build**
  - [⚖️ Position Sizing and Core Risk Metrics](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/position-sizing-and-core-risk-metrics.md)
  - [🏗️ Capstone: Build and Backtest Your Own Strategy](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/capstone-build-and-backtest-your-strategy.md) (premium content)
  - [✅ Checkpoint: Risk and Capstone](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/checkpoint-risk-and-capstone.md) (premium content)
- [Course cheatsheet](https://everwise.study/courses/quantitative-trading-for-beginners-build-and-backtest-a-strategy/cheatsheet.md) (premium content)
