Python中最大亏损的开始,结束和持续时间

sie*_*gel 19 python numpy time-series algorithmic-trading

给定一个时间序列,我想计算最大亏损,我还想找到最大亏损的起点和终点,这样我就可以计算出持续时间.我想在这样的时间序列图上标记缩编的开始和结束:

一只忙碌的猫http://oi61.tinypic.com/r9h4er.jpg

到目前为止,我已经有了生成随机时间序列的代码,并且我已经有了计算最大亏损的代码.如果有人知道如何确定缩编开始和结束的地方,我真的很感激!

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# create random walk which I want to calculate maximum drawdown for:

T = 50
mu = 0.05
sigma = 0.2
S0 = 20
dt = 0.01
N = round(T/dt)
t = np.linspace(0, T, N)
W = np.random.standard_normal(size = N) 
W = np.cumsum(W)*np.sqrt(dt) ### standard brownian motion ###
X = (mu-0.5*sigma**2)*t + sigma*W 

S = S0*np.exp(X) ### geometric brownian motion ###
plt.plot(S)

# Max drawdown function      

def max_drawdown(X):
    mdd = 0
    peak = X[0]
    for x in X:
        if x > peak: 
            peak = x
        dd = (peak - x) / peak
        if dd > mdd:
            mdd = dd
    return mdd    

drawSeries = max_drawdown(S)
MaxDD = abs(drawSeries.min()*100)
print MaxDD


plt.show()
Run Code Online (Sandbox Code Playgroud)

beh*_*uri 51

只需找出运行最大减去当前值最大的位置:

n = 1000
xs = np.random.randn(n).cumsum()
i = np.argmax(np.maximum.accumulate(xs) - xs) # end of the period
j = np.argmax(xs[:i]) # start of period

plt.plot(xs)
plt.plot([i, j], [xs[i], xs[j]], 'o', color='Red', markersize=10)
Run Code Online (Sandbox Code Playgroud)

缩编

  • 真正干净的解决方案,以最大限度缩减! (6认同)

k0r*_*nik 11

behzad.nouri 解决方案非常干净,但它不是最大的提款(无法发表评论,因为我刚刚开设了我的帐户,并且我没有足够的声誉 atm)。

您最终得到的是名义价值的最大下降,而不是价值的相对下降(百分比下降)。例如,如果您将此应用于长期上升的时间序列(例如股市指数 S&P 500),则最近的价值下降(较高的名义价值下降)将优先于较早的价值下降,如下所示只要名义价值/点的跌幅较高。

例如标准普尔 500 指数:

  • 2007-08年金融危机,下跌56.7%,888.62点
  • 最近的新冠病毒危机,下跌 33.9%,1,1148.75 点

通过将此方法应用于 2000 年之后的时期,您将看到新冠病毒危机,而不是 2007-08 年金融危机

相关代码(来自behzad.nouri)如下:

n = 1000
xs = np.random.randn(n).cumsum()
i = np.argmax(np.maximum.accumulate(xs) - xs) # end of the period
j = np.argmax(xs[:i]) # start of period

plt.plot(xs)
plt.plot([i, j], [xs[i], xs[j]], 'o', color='Red', markersize=10)
Run Code Online (Sandbox Code Playgroud)

您只需将名义价值的下降除以最大累计金额即可获得相对 (%) 回撤。

( np.maximum.accumulate(xs) - xs ) / np.maximum.accumulate(xs)
Run Code Online (Sandbox Code Playgroud)


小智 6

在此基础上,如果对任何人有帮助,我添加了水下分析...

def drawdowns(equity_curve):
    i = np.argmax(np.maximum.accumulate(equity_curve.values) - equity_curve.values) # end of the period
    j = np.argmax(equity_curve.values[:i]) # start of period

    drawdown=abs(100.0*(equity_curve[i]-equity_curve[j]))

    DT=equity_curve.index.values

    start_dt=pd.to_datetime(str(DT[j]))
    MDD_start=start_dt.strftime ("%Y-%m-%d") 

    end_dt=pd.to_datetime(str(DT[i]))
    MDD_end=end_dt.strftime ("%Y-%m-%d") 

    NOW=pd.to_datetime(str(DT[-1]))
    NOW=NOW.strftime ("%Y-%m-%d")

    MDD_duration=np.busday_count(MDD_start, MDD_end)

    try:
        UW_dt=equity_curve[i:].loc[equity_curve[i:].values>=equity_curve[j]].index.values[0]
        UW_dt=pd.to_datetime(str(UW_dt))
        UW_dt=UW_dt.strftime ("%Y-%m-%d")
        UW_duration=np.busday_count(MDD_end, UW_dt)
    except:
        UW_dt="0000-00-00"
        UW_duration=np.busday_count(MDD_end, NOW)

    return MDD_start, MDD_end, MDD_duration, drawdown, UW_dt, UW_duration
Run Code Online (Sandbox Code Playgroud)