Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的最大活动缩进_Python_Pandas_Numpy_Quantitative Finance - Fatal编程技术网

python中的最大活动缩进

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

我最近问了一个问题,在pandas中,where给出了一个非常简洁有效的方法,用DataFrame方法计算它

我想通过询问其他人是如何计算最大活动下降的来进行跟进的

这将计算最大压降。不最大有效水位降 这是我根据Alexander对上述问题的回答为max drawdown实现的:

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
这总是一个令人不安的情况,因为它表明模型中可能发生某种泄漏

混合单周期和多周期归因始终是一个挑战。问题的一部分在于分析的目标,即你想解释什么

如果您查看的是上述情况下的累积回报,则执行分析的一种方法如下:

  • 确保投资组合回报和基准回报均为超额回报,即减去相应期间(如每日、每月等)的适当现金回报

  • 假设你有一个有钱的叔叔借给你1亿美元来启动你的基金。现在,您可以将您的投资组合想象为三笔交易、一笔现金和两笔衍生交易: a) 将1亿美元投资于现金账户,方便地赚取优惠利率。 b) 以1亿美元名义价值进行股权互换 c) 与零贝塔(zero beta)对冲基金进行掉期交易,名义金额为1亿美元

  • 我们可以方便地假设,两项掉期交易都由现金账户进行抵押,并且没有交易成本(如果只有…!)

    在第一天,股指上涨了1%多一点(扣除当天的现金支出后,超额回报率正好是1.00%)。然而,不相关对冲基金的超额回报率为-5%。我们的基金目前为9600万美元

    第二天,我们如何重新平衡?你的计算表明我们从来没有这样做过。每一个都是一个独立的投资组合,永远漂泊。。。然而,就归因而言,我认为每天重新平衡是完全有意义的,也就是说,两种策略中的每一种都是100%

    由于这些只是具有充足现金抵押品的名义风险敞口,我们可以调整金额。因此,我们将不再在第二天对股票指数有1.01亿美元的敞口,对对冲基金有9500万美元的敞口,而是(以零成本)进行再平衡,使我们对每个指数都有9600万美元的敞口

    你可能会问,这在熊猫身上是如何起作用的?您已经计算了
    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