風險

從指數移動平均線近似 Sharpe 和 Sortino 比率

  • January 29, 2021

因此,我一直在研究“通過直接強化學習交易”Moody 和 Saffell (2001)的論文,該論文詳細描述瞭如何使用時間 t ( ) 的指數移動估計 (EMA)r_t來近似夏普和索蒂諾比率對於投資組合或證券。

注意:在論文中,他將 Sortino 比率稱為“下行偏差比率”或 DDR。我很確定從數學上講,DDR 和 Sortino 比率之間沒有區別。

因此,本文定義了用於近似任一比率的兩個值,即微分夏普比率 ( dsr) 和微分下行偏差率 ( d3r)。這些計算都代表時間t( r_t) 的交易回報對夏普和索提諾比率的影響。用於計算 DSR 和 D3R 的 EMA 是基於圍繞適應率的擴展,η

然後他提出了一個方程,通過該方程我應該能夠在時間使用 DSR 或 D3Rt遞歸地計算目前 Sharpe 或 Sortino 比率的移動近似值,t而無需對所有 t 執行計算以獲得確切的結果。這在具有無限時間範圍的環境中非常方便。t在計算上,如果有數百萬個時間步,數據最終會變得太大而無法重新計算每個時間步的完整夏普或索提諾比率。

$$ S_t |{\eta>0} \approx S_t|{\eta=0} + \eta\frac{\partial S_t}{\partial \eta}|{\eta=0} + O(\eta^2) = S{t-1} + \eta\frac{\partial S_t}{\partial \eta}|{\eta=0} + O(\eta^2) $$ $$ D_t \equiv \frac{\partial S_t}{\partial \eta} = \frac{B{t-1}\Delta A_t - \frac{1}{2}A_{t-1}\Delta B_t}{(B_{t-1} - A_{t-1}^2)^{3/2}} $$ $$ A_t = A_{t-1} + \eta \Delta A_t = A_{t-1} + \eta (R_t - A_{t-1}) $$ $$ B_t = B_{t-1} + \eta \Delta B_t = B_{t-1} + \eta (R_t^2 - B_{t-1}) $$

以上是使用 DSR 計算夏普比率的方程式t。在我看來,較大的值η可能會導致近似值的波動更大,因為它會給 的最新值施加更多“權重” r_t,但總的來說,夏普和索蒂諾比率仍應給出合乎邏輯的結果。相反,我發現調整η會極大地改變近似值,從而為夏普(或索蒂諾)比率提供完全不合邏輯的值。

同樣,以下等式適用於 D3R 並從中近似 DDR(又名 Sortino 比率):

$$ DDR_t \approx DDR_{t-1} + \eta \frac{\partial DDR_t}{\partial \eta}|{\eta=0} + O(\eta^2) $$ $$ D_t \equiv \frac{\partial DDR_t}{\partial \eta} = \ \begin{cases} \frac{R_t - \frac{1}{2}A{t-1}}{DD_{t-1}} & \text{if $R_t > 0$} \ \frac{DD_{t-1}^2 \cdot (R_t - \frac{1}{2}A_{t-1}) - \frac{1}{2}A_{t-1}R_t^2}{DD_{t-1}^3} & \text{if $R_t \leq 0$} \end{cases} $$ $$ A_t = A_{t-1} + \eta (R_t - A_{t-1}) $$ $$ DD_t^2 = DD_{t-1}^2 + \eta (\min{R_t, 0}^2 - DD_{t-1}^2) $$

我想知道我是否誤解了這些計算?η這是我的兩種風險近似值的Python 程式碼self.ram_adaption

def _tiny():
   return np.finfo('float64').eps

def calculate_d3r(rt, last_vt, last_ddt):
   x = (rt - 0.5*last_vt) / (last_ddt + _tiny())
   y = ((last_ddt**2)*(rt - 0.5*last_vt) - 0.5*last_vt*(rt**2)) / (last_ddt**3 + _tiny())
   return (x,y)

def calculate_dsr(rt, last_vt, last_wt):
   delta_vt = rt - last_vt
   delta_wt = rt**2 - last_wt
   return (last_wt * delta_vt - 0.5 * last_vt * delta_wt) / ((last_wt - last_vt**2)**(3/2) + _tiny())

rt = np.log(rt)

dsr = calculate_dsr(rt, self.last_vt, self.last_wt)
d3r_cond1, d3r_cond2 = calculate_d3r(rt, self.last_vt, self.last_ddt)
d3r = d3r_cond1 if (rt > 0) else d3r_cond2

self.last_vt += self.ram_adaption * (rt - self.last_vt)
self.last_wt += self.ram_adaption * (rt**2 - self.last_wt)

self.last_dt2 += self.ram_adaption * (np.minimum(rt, 0)**2 - self.last_dt2)
self.last_ddt = math.sqrt(self.last_dt2)

self.last_sr += self.ram_adaption * dsr
self.last_ddr += self.ram_adaption * d3r

請注意,我的值會在值表示利潤和平均損失的位置上下rt波動(而完美表示沒有變化)。我首先通過取自然對數來獲得對數回報。只是一個非常小的值(類似於),以避免被零除。1.0``>1``<1``1.0``rt``_tiny()``2e-16

我的問題是:

  1. 我希望近似的夏普和索提諾比率落在 0.0 到 3.0 的範圍內(給予或索取),相反,我得到一個單調遞減的索提諾比率,以及一個可以爆炸到巨大值(超過 100)的夏普比率,具體取決於我的適應率η。適應率η應該影響近似中的雜訊,但不要讓它像那樣爆炸。
  2. D3R 的(平均)負數大於正數,最終近似於一個接近線性的排序比率,如果讓它迭代足夠長的時間可以達到完全無意義的值,例如 -1000。
  3. 近似值偶爾會有非常大的跳躍,我覺得只能用我的計算中的一些錯誤來解釋。近似的夏普和索蒂諾比率應該有一個有點嘈雜但穩定的演變,沒有像我的圖表中看到的那樣的大規模跳躍。

由於平均負 D3R,Sortino 比率單調遞減 夏普比率大爆發,適應率相對較高 η=0.1

最後,如果有人知道我在哪裡可以找到其他現有的程式碼實現,其中 DSR 或 D3R 用於近似 Sharpe/Sortino 比率,將不勝感激。我能夠從 AchillesJJ 找到此頁面,但它並沒有真正遵循 Moody 提出的方程式,因為他正在重新計算所有先前時間步的完整平均值,以達到每個時間步的 DSR t。核心思想是能夠通過使用指數移動平均線來避免這樣做。

對於仍在關注此內容的任何人:

我發現方程式和我的程式碼工作正常;問題是我必須在進行風險計算之前調整收益以避免 float32 精度數據失去,而且我的價值η太高了。降低我的η值以<= 0.0001產生完全合乎邏輯的銳化和排序近似值。作為旁注,這也允許我的神經網路直接從邊緣銳化和排序計算中學習,這很棒。

同樣,使用對數返回對於 sortino 近似是有問題的,所以我有效地將其更改為rt = (rt - 1) * scaling_factor使 sortino 近似不再傾向於負值。

如果我的唯一目標是在我的神經網路中使用 DSR/D3R 作為損失計算,那麼對數回報本來可以很好地工作,但是為了獲得良好的 sortino 近似值,它不起作用,因為它非常強調負回報並平滑正回報。

如果您擔心在大量且不斷增加的數據上計算 Sharpe/Sortino 的計算效率,您可以使用增量/線上方法來計算整個數據集的均值、標準差等。然後只需對整個數據集的 Sharpe/Sortino 使用最新的線上計算值。這將避免舊數據的權重小於新數據的問題,這在使用 EMA 時是隱含的。

我對數據科學 SE 的回答位於https://datascience.stackexchange.com/questions/77470/how-to-perform-a-running-moving-standardization-for-feature-scaling-of-a-growi/77476# 77476提供了更多詳細資訊和連結。

引用自:https://quant.stackexchange.com/questions/57568