Numpy 包在 Python 下计算最大回撤的起点、终点和持续时间
随着量化交易的兴起,最大回撤(maximum drawdown)成为了一个重要的衡量交易风险的指标。它可以帮助投资者了解在一个时间段内,投资组合的最大跌幅,以及这个跌幅持续了多久。在 Python 中,我们可以使用 Numpy 包来计算最大回撤的起点、终点和持续时间。
阅读更多:Numpy 教程
什么是最大回撤?
在介绍如何使用 Numpy 包来计算最大回撤之前,我们需要先了解一下什么是最大回撤。
最大回撤指的是在某一时间段内,投资组合净值从高点到低点跌幅的最大值。通俗地说,就是在一段时间内,投资组合总资产价值最多跌了多少。以一只股票为例,假设这只股票的价格走势如下图所示:
假设你在时间点 A 以 50 元的价格买入了这只股票。在接下来的一段时间内,股票的价格不断攀升,最终到达了一个高点 B。在这之后,股票价格开始下跌,一路到达了最低点 C。在这段时间内,你的投资组合净值也从最高点一路跌到了最低点,这个跌幅就是这个时间段的最大回撤。
最大回撤可以衡量投资者的风险承受能力。一个容易受损的投资者可能会在看到投资组合净值的下跌后急于抛售持有资产;而一个风险承受能力更强的投资者则会更加从容应对市场波动。
如何计算最大回撤?
在 Python 中,我们可以使用 Numpy 包来计算最大回撤。具体来说,我们要使用到 Numpy 中的 cummax
和 argmin
函数。
cummax
函数可以计算出一个序列的“累计最大值”序列。例如,对于一个序列 [1, 2, 3, 2, 1, 4, 5]
,其“累计最大值”序列为 [1, 2, 3, 3, 3, 4, 5]
。而 argmin
函数可以返回一个序列中最小值的下标位置。
那么,我们要如何使用这两个函数来计算最大回撤呢?考虑如下的情景:
- 假设我们有一个序列 p,其中 p_i 表示时间 i 的投资组合净值;
- 我们用一个长度为 n 的滑动窗口,来计算滑动窗口内的最大回撤;
- 对于滑动窗口中的每个位置 i,我们用
j
表示滑动窗口中最高点的下标位置; - 那么,以 i 为止的最大回撤就是 \frac{p_i – p_j}{p_j};
5.我们的目标就是找出能够最大化最大回撤的滑动窗口初始位置 j 和结束位置 i。
首先,我们需要计算出 p 的“累计最大值”序列 M。这个序列中,M_i 表示在 p_0 至 p_i 这个区间内的最大值。我们可以这样计算:
import numpy as np
def calculate_drawdown(p):
max_drawdown = 0
start, end = 0, 0
M = np.maximum.accumulate(p)
for i in range(len(p)):
drawdown = (M[i]-p[i])/M[i]
if drawdown > max_drawdown:
max_drawdown = drawdown
start = np.argmax(p[:i+1])
end = i
duration = end - start + 1
return start, end, duration, max_drawdown
接着,我们可以用一个循环来计算出每个滑动窗口的最大回撤。在循环中,我们通过记录最大回撤的值来找到最大回撤的起点和终点。最后,我们计算出持续时间并将结果返回即可。
举例
下面,让我们来看一下具体的例子。假设我们有以下的投资组合净值序列:
p = [10, 8, 12, 5, 9, 11, 15, 3, 9, 6, 7, 13, 10, 14]
我们将滑动窗口的长度设置为 5,然后调用 calculate_drawdown
函数计算最大回撤。输出结果如下:
start: 7
end: 11
duration: 5
maximum drawdown: 0.475609756097561
可以看到,最大回撤的起点是第 7 个时间点,终点是第 11 个时间点,持续时间为 5,最大回撤幅度为 0.4756,即净值跌了 47.56%。
总结
在本篇文章中,我们介绍了什么是最大回撤,以及如何使用 Numpy 包来计算最大回撤的起点、终点和持续时间。感谢您的阅读,希望本文对您有所帮助。