python中的最大活动缩进
我最近问了一个问题,在pandas中,where给出了一个非常简洁有效的方法,用DataFrame方法计算它 我想通过询问其他人是如何计算最大活动下降的来进行跟进的 这将计算最大压降。不最大有效水位降 这是我根据Alexander对上述问题的回答为max drawdown实现的:python中的最大活动缩进,python,pandas,numpy,quantitative-finance,Python,Pandas,Numpy,Quantitative Finance,我最近问了一个问题,在pandas中,where给出了一个非常简洁有效的方法,用DataFrame方法计算它 我想通过询问其他人是如何计算最大活动下降的来进行跟进的 这将计算最大压降。不最大有效水位降 这是我根据Alexander对上述问题的回答为max drawdown实现的: def max_drawdown_absolute(returns): r = returns.add(1).cumprod() dd = r.div(r.cummax()).sub(1) md
def max_drawdown_absolute(returns):
r = returns.add(1).cumprod()
dd = r.div(r.cummax()).sub(1)
mdd = dd.min()
end = dd.argmin()
start = r.loc[:end].argmax()
return mdd, start, end
它获取一个返回序列,并返回最大提取量以及发生提取的指数
我们首先生成一系列累积回报,作为回报指数
r = returns.add(1).cumprod()
在每个时间点,通过将当前收益指数水平与之前所有时期的最大收益指数进行比较,计算当前提款
dd = r.div(r.cummax()).sub(1)
最大水位降就是所有计算水位降中的最小值
我的问题:
我想问一下其他人是如何计算最大值的
活动缩编
假设解决方案将扩展到上述解决方案。从一系列投资组合回报和基准回报开始,我们为这两种回报建立累积回报。假设以下变量已在累积收益空间中 从周期j到周期i的有效回报为: 解决方案 这就是我们如何扩展绝对解决方案的方法:
def max_draw_down_relative(p, b):
p = p.add(1).cumprod()
b = b.add(1).cumprod()
pmb = p - b
cam = pmb.expanding(min_periods=1).apply(lambda x: x.argmax())
p0 = pd.Series(p.iloc[cam.values.astype(int)].values, index=p.index)
b0 = pd.Series(b.iloc[cam.values.astype(int)].values, index=b.index)
dd = (p * b0 - b * p0) / (p0 * b0)
mdd = dd.min()
end = dd.argmin()
start = cam.ix[end]
return mdd, start, end
解释
与绝对情况类似,在每个时间点,我们都想知道截至该时间点的最大累积活跃回报率。我们通过p-b
获得了这一系列的累积积极回报。不同的是,我们想要跟踪p和b在这个时候是什么,而不是差异本身
因此,我们在cam
(cumulativeargmax)中生成了一系列“when”以及这些“when”的后续投资组合和基准值系列
p0 = pd.Series(p.ix[cam.values.astype(int)].values, index=p.index)
b0 = pd.Series(b.ix[cam.values.astype(int)].values, index=b.index)
现在可以使用上述公式类似地进行水位下降计算:
dd = (p * b0 - b * p0) / (p0 * b0)
示范
您可能已经注意到,您的单个组件并不等于整个组件,无论是以加法还是几何方式:
>>> cum.tail(1)
Portfolio Benchmark Active
199 1.342179 1.280958 1.025144
这总是一个令人不安的情况,因为它表明模型中可能发生某种泄漏
混合单周期和多周期归因始终是一个挑战。问题的一部分在于分析的目标,即你想解释什么
如果您查看的是上述情况下的累积回报,则执行分析的一种方法如下:
cum['Portfolio']
,这是投资组合的累积超额增长因子(即扣除现金回报后)。如果我们将当天的超额基准和积极回报应用于前一天的投资组合增长因子,我们将计算每日再平衡回报
import numpy as np
import pandas as pd
np.random.seed(314)
df_returns = pd.DataFrame({
'Portfolio': np.random.randn(200) / 100 + 0.001,
'Benchmark': np.random.randn(200) / 100 + 0.001})
df_returns['Active'] = df.Portfolio - df.Benchmark
# Copy return dataframe shape and fill with NaNs.
df_cum = pd.DataFrame()
# Calculate cumulative portfolio growth
df_cum['Portfolio'] = (1 + df_returns.Portfolio).cumprod()
# Calculate shifted portfolio growth factors.
portfolio_return_factors = pd.Series([1] + df_cum['Portfolio'].shift()[1:].tolist(), name='Portfolio_return_factor')
# Use portfolio return factors to calculate daily rebalanced returns.
df_cum['Benchmark'] = (df_returns.Benchmark * portfolio_return_factors).cumsum()
df_cum['Active'] = (df_returns.Active * portfolio_return_factors).cumsum()
现在我们看到,积极回报加上基准回报加上初始现金等于投资组合的现值
>>> df_cum.tail(3)[['Benchmark', 'Active', 'Portfolio']]
Benchmark Active Portfolio
197 0.303995 0.024725 1.328720
198 0.287709 0.051606 1.339315
199 0.292082 0.050098 1.342179
通过构造,df_cum['Portfolio']=1+df_cum['Benchmark']+df_cum['Active']
。
由于这种方法难以计算(没有熊猫!)和理解(大多数人不会获得名义风险敞口),因此行业惯例通常将积极回报定义为一段时间内回报的累积差异。例如,如果一只基金在一个月内上涨了5.0%,而市场下跌了1.0%,那么该月的超额回报通常被定义为+6.0%。然而,这种简单化方法的问题是,由于计算中没有适当考虑到复合和再平衡问题,结果会随着时间的推移而漂移
因此,考虑到我们的df_cum.Active
列,我们可以将提款定义为:
drawdown = pd.Series(1 - (1 + df_cum.Active)/(1 + df_cum.Active.cummax()), name='Active Drawdown')
>>> df_cum.Active.plot(legend=True);drawdown.plot(legend=True)
然后,您可以像以前一样确定提取的起点和终点
将我的累计积极回报贡献与您计算的金额进行比较,您会发现它们最初是相似的,然后随着时间推移而漂移(我的回报计算为绿色):
我用纯Python写的廉价两便士:
def find_drawdown(lista):
peak = 0
trough = 0
drawdown = 0
for n in lista:
if n > peak:
peak = n
trough = peak
if n < trough:
trough = n
temp_dd = peak - trough
if temp_dd > drawdown:
drawdown = temp_dd
return -drawdown
def find_提取(列表a):
峰值=0
槽=0
水位下降=0
对于lista中的n:
def find_drawdown(lista):
peak = 0
trough = 0
drawdown = 0
for n in lista:
if n > peak:
peak = n
trough = peak
if n < trough:
trough = n
temp_dd = peak - trough
if temp_dd > drawdown:
drawdown = temp_dd
return -drawdown