如何计算7个资产的平均回撤(Average Drawdown)?
代码修正方案
你现有代码的计算逻辑不符合回撤的标准定义,仅用对数收益率的极值做差值除法,既无法得到准确的最大回撤,也不能计算平均回撤。
回撤的标准计算逻辑是:
- 先基于收益率生成累计净值曲线
- 计算累计净值曲线到每个时点的历史最高值
- 用每个时点的累计净值与同期历史最高值的差值,除以同期历史最高值,得到该时点的回撤幅度
- 所有时点回撤的平均值即为平均回撤,回撤的最小值即为最大回撤
修正后完整代码如下:
import datetime as dt import pandas as pd import numpy as np import yfinance as yf end = dt.datetime.today() start = end - dt.timedelta(365) tickers = ["SBUX", "MCD", "CMG", "WEN", "DPZ", "YUM", "DENN"] bench = ['SPY', 'IWM', 'DIA'] table_1 = pd.DataFrame(index=tickers) data = yf.download(tickers+bench, start, end)['Adj Close'] log_returns = np.log(data/data.shift()) # 计算累计净值 cum_return = np.exp(log_returns.cumsum()) # 计算每个时点的历史峰值 peak = cum_return.cummax() # 计算每个时点的回撤 drawdown_series = (cum_return - peak) / peak # 计算7个标的全时段平均回撤 table_1["average_drawdown"] = drawdown_series[tickers].mean() # 可补充计算最大回撤做对比 table_1["max_drawdown"] = drawdown_series[tickers].min()
如果需要只统计净值低于前期峰值时段的平均回撤(排除没有回撤的时段),可以把平均回撤的计算逻辑替换为:
table_1["average_drawdown"] = drawdown_series[tickers].apply(lambda x: x[x<0].mean())
以上计算得到的回撤结果为负数,代表下跌幅度,如果需要正数值可以在计算时额外取绝对值即可。
内容的提问来源于stack exchange,提问作者atrmi
相关产品推荐
相关产品推荐

