The brief
The risk team's weekly report shows an annual return for every stock it covers. Until now the report multiplied the average daily simple return by 252, the trading days in a year.
For one volatile stock that figure says it gained about 4.9% a year, yet the stock ended the period below where it started. The head of risk wants the report fixed, with a short reason for the gap.
Your task
- Write
daily_returns(prices): a pair of NumPy arrays(simple, log), each one shorter thanprices. RaiseValueErrorfor fewer than two prices, a price of zero or below, or a missing price (nan). - Write
annualise(prices, per_year=252): a dict with three annual figures."log"is the mean log return timesper_year, and"simple"is the simple return it implies."arithmetic"is the old figure, the mean simple return timesper_year. - Write
drag(prices, per_year=252): an estimate of the gap between the arithmetic and log figures. With simple returns and =per_year, it is
per_year is the number of periods in a year: 252 for daily prices, 12 for monthly ones.
The data
PRICES in the code holds 43 daily closing prices of the stock, oldest first, adjusted for splits and dividends.
Hint: Where to start
Case study 1.4.7 defines both returns from the gross return . It also lists the bad prices to check for before computing a single return.
Hint: Annualising
Log returns add across time, so the mean daily log return times 252 is the year's log return. Convert it with (case study 1.4.7). The old figure skips the compounding.
Hint: Why the figures differ
For a small return, (case study 1.4.7). So each day's log return falls short of its simple return by about . Large daily swings make the gap large: this is volatility drag.