Last active
July 26, 2019 08:02
-
-
Save StuartGordonReid/79a0243b2d949adfb386 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy | |
import numpy.random as nrand | |
""" | |
Note - for some of the metrics the absolute value is returns. This is because if the risk (loss) is higher we want to | |
discount the expected excess return from the portfolio by a higher amount. Therefore risk should be positive. | |
""" | |
def dd(returns, tau): | |
# Returns the draw-down given time period tau | |
values = prices(returns, 100) | |
pos = len(values) - 1 | |
pre = pos - tau | |
drawdown = float('+inf') | |
# Find the maximum drawdown given tau | |
while pre >= 0: | |
dd_i = (values[pos] / values[pre]) - 1 | |
if dd_i < drawdown: | |
drawdown = dd_i | |
pos, pre = pos - 1, pre - 1 | |
# Drawdown should be positive | |
return abs(drawdown) | |
def max_dd(returns): | |
# Returns the maximum draw-down for any tau in (0, T) where T is the length of the return series | |
max_drawdown = float('-inf') | |
for i in range(0, len(returns)): | |
drawdown_i = dd(returns, i) | |
if drawdown_i > max_drawdown: | |
max_drawdown = drawdown_i | |
# Max draw-down should be positive | |
return abs(max_drawdown) | |
def average_dd(returns, periods): | |
# Returns the average maximum drawdown over n periods | |
drawdowns = [] | |
for i in range(0, len(returns)): | |
drawdown_i = dd(returns, i) | |
drawdowns.append(drawdown_i) | |
drawdowns = sorted(drawdowns) | |
total_dd = abs(drawdowns[0]) | |
for i in range(1, periods): | |
total_dd += abs(drawdowns[i]) | |
return total_dd / periods | |
def average_dd_squared(returns, periods): | |
# Returns the average maximum drawdown squared over n periods | |
drawdowns = [] | |
for i in range(0, len(returns)): | |
drawdown_i = math.pow(dd(returns, i), 2.0) | |
drawdowns.append(drawdown_i) | |
drawdowns = sorted(drawdowns) | |
total_dd = abs(drawdowns[0]) | |
for i in range(1, periods): | |
total_dd += abs(drawdowns[i]) | |
return total_dd / periods | |
# Example Usage | |
r = nrand.uniform(-1, 1, 50) | |
print("Drawdown(5) =", dd(r, 5)) | |
print("Max Drawdown =", max_dd(r)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment