使用python計算最大回撤

使用python計算最大回撤

1. 單期簡單收益率

Rt=PtPt1Pt1R_{t}=\dfrac {P _{t}-P_{t-1}}{P_{t-1}}
說明:

  1. RtR_t 爲單期簡單收益率
  2. PtP_t 爲t期的價格
  3. Pt1P_{t-1} 爲t-1期的價格
import datetime
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
price = pd.Series([3.42,3.51,3.68,3.43,3.56,3.67], index=[datetime.date(2015,7,x) for x in range(3,9)])
price
2015-07-03    3.42
2015-07-04    3.51
2015-07-05    3.68
2015-07-06    3.43
2015-07-07    3.56
2015-07-08    3.67
dtype: float64

利用ffn庫計算單期簡單收益

import ffn
r = ffn.to_returns(price)
r
2015-07-03         NaN
2015-07-04    0.026316
2015-07-05    0.048433
2015-07-06   -0.067935
2015-07-07    0.037901
2015-07-08    0.030899
dtype: float64

2. 最大回撤

最大回撤(Maximum Drawdown, MDD) 用來衡量投資(特別是基金)的表現,

2.1 回撤:某資產在時刻T的回撤是指資產在(0,T)的最高峯值與現在價值PTP_T之間的回落值,用數學公式表達爲:

D(T)=max{0,maxt(0,T)PtPT}D\left( T\right) =\max \left\{ 0,\max _{t\in (0,T)}P_t-P_{T}\right\}

2.2 對應的回撤率爲:

d(T)=D(T)maxt(0,T)ptd\left(T\right) = \dfrac {D\left( T\right) }{\max _{t\in \left( 0,T\right) }p_{t}}

知道回撤的含義之後,最大回撤就比較容易理解了,資產在T時刻的最大回撤MDD(T),就是資產在時段(0,T)內回撤的最大值,對應的數學公式爲:

MDD(T)=maxτ(0,T)D(τ)=maxτ(0,T)[maxt(0,τ)PtPτ]MDD\left(T\right) = {\max _{\tau \in \left(0,T\right)}} D\left(\tau\right) = {\max _{\tau \in \left(0,T\right)}} \begin{aligned} \left[ \max _{t\in \left( 0,\tau \right) }P_{t}-P_{\tau}\right] \end{aligned}

相應的最大回撤率爲:
mdd(T)=maxτ(0,T)d(τ)MDD(T)maxt(0,T)Ptmdd\left(T\right) = {\max _{\tau \in \left(0,T\right)}} d\left(\tau \right) \dfrac {MDD\left(T\right)}{\max _{t \in \left(0,T\right)}P_t}

直觀的講,MDD(T)對應的是在(0,T)時段內資產價值從最高峯迴落到最低谷的幅度。最大回撤常用來描述投資者在持有資產是可能面臨的最大虧損。

2.3 利用收益率計算最大回撤

如果某資產的收益率序列爲R1,R2,…,RT,在初始時刻0時,我們投資1元在該資產上並一直持有到T時刻,則初始值爲1元的資產價值就會隨時間變化爲:(1+R1),(1+R1)(1+R2),(1+R1)(1+R2)(1+R3),…,k=1T(1+Rk)\prod _{k=1}^{T}\left( 1+R_{k}\right)

時刻T對應的回撤值爲:
D(T)=max{0,maxt(0,T)k=1t(1+Rk)k=1T(1+Rk)}D(T) = \max \left\{ 0, \max _{t \in (0,T)} \prod _{k=1}^{t}\left( 1+R_{k}\right) - \prod _{k=1}^{T}\left( 1+R_{k}\right) \right\}

相應的回撤率爲:
d(T)=D(T)maxt(0,T)k=1t(1+Rk)d(T) = \dfrac {D\left( T\right) }{\max _{t\in \left( 0,T\right) }\prod _{k=1}^{t}\left( 1+R_{k}\right) }

最大回撤爲:
MDD(T)=maxτ(0,T)D(τ)=maxτ(0,T)[maxt(0,τ)k=1t(1+Rk)k=1τ(1+Rk)]MDD(T) = \max _{\tau \in \left( 0,T\right) }D\left( \tau \right) = \max _{\tau \in \left( 0,T\right) } \begin{aligned} \left[\max _{t\in \left( 0,\tau \right) }\prod _{k=1}^{t}\left( 1+R_{k}\right) - \prod _{k=1}^{\tau}\left( 1+R_{k}\right) \right]\end{aligned}

相應的最大回撤率爲:
mdd(T)=maxτ(0,T)d(τ)=MDD(T)maxt(0,T)k=1t(1+Rk)mdd(T) = \max _{\tau \in \left( 0,T\right) }d(\tau) = \dfrac {MDD(T)}{\max _{t \in \left( 0,T\right) }\prod _{k=1}^{t}\left( 1+R_{k}\right)}

value = (1 + r).cumprod()
value
2015-07-03         NaN
2015-07-04    1.026316
2015-07-05    1.076023
2015-07-06    1.002924
2015-07-07    1.040936
2015-07-08    1.073099
dtype: float64
D = value.cummax() - value
D
2015-07-03         NaN
2015-07-04    0.000000
2015-07-05    0.000000
2015-07-06    0.073099
2015-07-07    0.035088
2015-07-08    0.002924
dtype: float64
d = D / (D + value)
d
2015-07-03         NaN
2015-07-04    0.000000
2015-07-05    0.000000
2015-07-06    0.067935
2015-07-07    0.032609
2015-07-08    0.002717
dtype: float64
MDD = D.max()
MDD
0.07309941520467844
mdd =d.max()
mdd
# 對應的最大回撤率值爲
0.06793478260869572
# 採用ffn庫計算收益率累積最大回撤
ffn.calc_max_drawdown(value)
-0.06793478260869568
from empyrical import max_drawdown
# 使用 empyrical 計算收益率序列最大回撤
max_drawdown(r)
-0.06793478260869572
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章