Event-Driven Backtester シリーズの最後の記事では,ExecutionHandler の基本的な階層を考慮した.この記事では,ポートフォリオオブジェクトの以前に構築された株式曲線 DataFrame を使用して,バックテスト後の戦略のパフォーマンスを評価する方法について議論します.
シャープ比率は,以下のような方法で計算されます.
株式曲線のリターンストリームが Ra で,適切な金利や株式指数などのベンチマークが Rb である.
最大引き上げと引き上げ期間は,投資家がしばしばポートフォリオのリスクを評価するために使用する2つの追加指標である.前者数値は,株式曲線のパフォーマンスの最高峰から最低点までの減少であり,後者は,発生する取引期間の数で定義される.
この記事では,Pythonベースのイベント駆動バックテスト用パッケージで使用するためのポートフォリオパフォーマンスの指標として,シャープ比率,最大引き下げおよび引き上げ期間を実装します.
新しいファイルを作成します.performance.py計算を重くするクラスのほとんどと同様に NumPy と pandas をインポートする必要があります.
# performance.py
import numpy as np
import pandas as pd
シャープ比率はリスクと報酬の指標であることに注意してください (実際は多くの指標のうちの1つです).
通常,この値は252に設定され,これは1年あたり米国での取引日数である.しかし,あなたの戦略が1時間以内に取引される場合,それを正しく年化するためにシャープを調整する必要があります.したがって,あなたは252
create_sharpe_ratio関数は,返済と呼ばれるパンダシリーズオブジェクトで動作し,単に,周期パーセント返済の平均値と周期パーセント返済標準偏差の割合を計算します.
# performance.py
def create_sharpe_ratio(returns, periods=252):
"""
Create the Sharpe ratio for the strategy, based on a
benchmark of zero (i.e. no risk-free rate information).
Parameters:
returns - A pandas Series representing period percentage returns.
periods - Daily (252), Hourly (252*6.5), Minutely(252*6.5*60) etc.
"""
return np.sqrt(periods) * (np.mean(returns)) / np.std(returns)
シャープ比率は,リターン単位ごとにどれだけのリスク (資産経路標準偏差によって定義される) がかかっているのかを特徴づけているが,引き下げは,株式曲線に沿った最大峰から底辺までの減少値として定義される.
create_drawdowns関数は,最大引き上げと最大引き上げ期間の両方を提供します.前者は上記最大のピークから底まで減少であり,後者は,この減少が起こる期間数として定義されます.
引き下げ期間について,いくつかの細かい解釈が必要であり,それは取引期間を数え,したがって"日"などの時間単位に直接変換できないからです.
この関数は,各取引の
引き下げは,単に現在のHWMと株式曲線の差である.この値がマイナスである場合,次のHWMに到達するまで発生するすべてのバーで期間が増加する.この関数は,2つのシリーズのそれぞれの最大値を返します:
# performance.py
def create_drawdowns(equity_curve):
"""
Calculate the largest peak-to-trough drawdown of the PnL curve
as well as the duration of the drawdown. Requires that the
pnl_returns is a pandas Series.
Parameters:
pnl - A pandas Series representing period percentage returns.
Returns:
drawdown, duration - Highest peak-to-trough drawdown and duration.
"""
# Calculate the cumulative returns curve
# and set up the High Water Mark
# Then create the drawdown and duration series
hwm = [0]
eq_idx = equity_curve.index
drawdown = pd.Series(index = eq_idx)
duration = pd.Series(index = eq_idx)
# Loop over the index range
for t in range(1, len(eq_idx)):
cur_hwm = max(hwm[t-1], equity_curve[t])
hwm.append(cur_hwm)
drawdown[t]= hwm[t] - equity_curve[t]
duration[t]= 0 if drawdown[t] == 0 else duration[t-1] + 1
return drawdown.max(), duration.max()
これらのパフォーマンス指標を利用するには,バックテストが行われ,つまり適切な株式曲線が利用可能になった後に計算する方法が必要です!
また,計算を特定のオブジェクト階層と関連付ける必要があります.パフォーマンスメアはポートフォリオに基づいて計算されるので,この記事で議論したポートフォリオクラス階層上の方法にパフォーマンス計算を結びつけるのが意味があります.
まず最初に オープンにすることportfolio.py前回の記事で議論したように,性能機能をインポートします.
# portfolio.py
.. # Other imports
from performance import create_sharpe_ratio, create_drawdowns
Portfolio は抽象的なベースクラスであるため,その派生クラスの一つにメソッドをアタッチしたい.この場合は NaivePortfolio です.したがって,Sharpe と引き下げ情報を生成するためにポートフォリオの株式曲線に作用するoutput_summary_stats というメソッドを作成します.
この方法は単純です.単に2つのパフォーマンスメーターを利用し,それらを直接株式曲線 DataFrame に適用し,統計を形式に適した方法でタプルリストとして出力します:
# portfolio.py
..
..
class NaivePortfolio(object):
..
..
def output_summary_stats(self):
"""
Creates a list of summary statistics for the portfolio such
as Sharpe Ratio and drawdown information.
"""
total_return = self.equity_curve['equity_curve'][-1]
returns = self.equity_curve['returns']
pnl = self.equity_curve['equity_curve']
sharpe_ratio = create_sharpe_ratio(returns)
max_dd, dd_duration = create_drawdowns(pnl)
stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)),
("Sharpe Ratio", "%0.2f" % sharpe_ratio),
("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)),
("Drawdown Duration", "%d" % dd_duration)]
return stats
明らかにこれはポートフォリオのための非常に単純なパフォーマンス分析です.それは取引レベルの分析や他のリスク/報酬の測定を考慮しません.しかし,より多くの方法を追加して拡張することは簡単です.performance.pyそして必要に応じて output_summary_stat に組み込む.