- def
- return
- default arguments
- ROI
- Sharpe ratio
- annualisation
Functions — Reusable Finance Tools
Scene: month two on the desk. Your PM glances at yesterday's ROI spreadsheet and says: "Great. Now the same numbers for the other 40 positions — with Sharpe ratios. By Friday." Copy-pasting a formula 40 times is how errors are born. The professional move is to write each formula once, give it a name, test it, and call it forever. That is a function — and a quant's most valuable asset is a library of correct, tested financial functions.
Function Anatomy
Pythondef function_name(param1, param2=default) -> return_type: """Docstring describes what this computes.""" result = ... return result # ← the answer leaves the function HERE
🧠 The mental model: a vending machine for numbers
- ›
defbuilds the machine and bolts a name on the front. Nothing runs yet — you have only written the recipe. - ›Arguments are the coins you insert when you call it:
roi(150.0, 174.55). - ›
returnis the slot the answer drops out of. Whatever expression followsreturnis the value the caller receives — the correctness of the whole machine concentrates in that one line. - ›No
return? The machine hums, computes… and swallows the result: Python hands backNone. A function that only prints cannot be reused inside other formulas — return the number and let the caller decide how to display it.
Key Finance Functions
ROI (Return on Investment) — decimal gain per unit invested:
ROI = (exit − entry) / entry
Annualised Sharpe Ratio — excess return per unit of risk:
Sharpe = (r̄ − rf_daily) / σ × √252
where r̄ = mean daily return, rf_daily = daily risk-free rate (annual rate ÷ 252), σ = standard deviation of daily returns.
Why √252? A year has about 252 trading days. Mean returns scale with time (× 252), but volatility scales with the square root of time (× √252) — a random walk drifts linearly yet wobbles like √t. Their ratio therefore scales by 252 ÷ √252 = √252 ≈ 15.87. Skip this step and a genuinely strong Sharpe of 1.33 masquerades as a pitiful 0.08.
📜 The Sharpe Ratio — 60 Years of the Industry Standard
1952 — Harry Markowitz published "Portfolio Selection" in the Journal of Finance. He proved mathematically that you could reduce portfolio risk through diversification without sacrificing expected return. He used variance (σ²) as his risk measure. Nobel economist Milton Friedman, on his dissertation committee, reportedly said "this is not economics" — he was wrong.
1964 — William Sharpe (who had written his UCLA PhD under Markowitz's informal guidance at RAND) generalised MPT into the Capital Asset Pricing Model (CAPM). Two years later, in a 1966 Journal of Business paper on mutual fund performance, he introduced what he called the "reward-to-variability ratio": excess return divided by total volatility.
"It is not the name I gave it. I just called it the reward-to-variability ratio. Others named it after me." — William Sharpe, 1994
1990 — Nobel Prize in Economics awarded jointly to Sharpe, Markowitz, and Merton Miller. The Sharpe ratio became the universal benchmark.
1998 — LTCM's cautionary tale: Long-Term Capital Management reported a Sharpe ratio of approximately 4.35 — extraordinary by any measure. Partners included Scholes and Merton (Nobel 1997). The fund blew up when their correlation assumptions failed simultaneously. The Sharpe ratio rewards high average returns but cannot see tail risk or liquidity risk. A strategy can have a beautiful Sharpe ratio right up until catastrophic loss.
2007 — The Quant Quake: Hundreds of equity market-neutral funds had Sharpe ratios above 2.0 in backtests. In August 2007 (and again in September 2008), these funds experienced simultaneous drawdowns of −20% to −40% in days. Similar models meant similar positions, which meant correlated exits. The Sharpe ratio assumes returns are IID (independent, identically distributed) — markets are not.
The Sharpe ratio is indispensable. It is also incomplete. Professionals supplement it with Sortino (only downside vol), Calmar (return / max drawdown), and Omega (full distribution). You will code all of these in this curriculum.
Your Task
Both functions are already written — but sharpe() has a rookie bug at its most important line. The placeholder return divides the raw mean by the volatility: it ignores the risk-free hurdle and forgets to annualise.
- ›Run the starter as-is: a genuinely strong strategy gets graded
NEEDS WORK. - ›Fix the
# 👉 YOUR TURNline: subtractrf_dailyfrommean_r, then multiply the whole ratio bymath.sqrt(252).
Predict before you run: the mean daily return is ≈ 0.0009 and the daily vol ≈ 0.0084, so the placeholder prints about 0.0009 ÷ 0.0084 ≈ 0.11. After your fix, the excess mean (≈ 0.0007) over the vol gives ≈ 0.084 per day — times √252 ≈ 15.87 gives… what? Do the arithmetic in your head, then run and check which verdict line appears.