Python for markets

A first example: returns and a moving average

4 min

Two of the most common transformations in all of quant work are returns and a moving average. Here is a compact, correct example on a clean OHLCV DataFrame.

Computing returns

A simple (percentage) return is today's close divided by yesterday's, minus one. Log returns are often preferred because they add cleanly across time.

import numpy as np

df["ret"] = df["close"].pct_change()
df["log_ret"] = np.log(df["close"]).diff()

The first row of each is NaN — there is no prior close to compare against. Always drop or handle that first row before summing or modelling.

A simple moving average

A moving average smooths price to reveal trend. The rolling method makes this trivial:

df["sma_20"] = df["close"].rolling(window=20).mean()
df["sma_50"] = df["close"].rolling(window=50).mean()

The first 19 values of sma_20 are NaN because the window is not yet full — that is correct behaviour, not a bug.

Why this matters for the rest of the track

These two lines already contain a trading idea: when sma_20 crosses above sma_50, momentum is turning up. We will turn exactly that into a backtest in the next chapter.

One warning baked in early

Notice that rolling and pct_change only ever look backwards. The moment a calculation uses a future value — even accidentally — your backtest becomes fiction. We make that pitfall explicit next.

Finished reading?
Risk disclaimer

This content is for educational and informational purposes only and is not investment, financial, tax or legal advice. Trading and investing carry risk, including the possible loss of capital. Any performance shown by third-party tools is hypothetical and not a promise of future results. Do your own research and consider professional advice before making any decision.