在一些關於改進的ShapeRatio的提示之後, backtrader 已將此分析儀添加到其武器庫中。
文獻位於:
從對數回報的好處開始,並遵循在SharpeRatio方程的分母中具有標準偏差的副作用,本文檔開發了該分析儀的公式和期望。
最重要的屬性之一可能是:
- 跨時間範圍的一致價值
使用SharpeRatio 超額回報與無風險利率/資產的算術平均值除以超額回報與無風險利率/資產的標準偏差。這使得最終值取決於樣本數量和甚至可能是 0的標準偏差。在這種情況下,將是 SharpeRatio 無限的。
backtrader包括一個範例,SharpeRatio用於測試使用範例數據的範例,其中包括和2006的價格2005。不同時間幀的返回值:
-
TimeFrame.Years:11.6473 -
TimeFrame.Months:0.5425 -
TimeFrame.Weeks:0.457 -
TimeFrame.Days:0.4274
注意
為了保持一致性,該比率是年化的。該sharpe-timereturn 範例與執行方式為:
--annualize --timeframe xxx
其中xxx 代表 days、 weeks或 months years (預設值)
在此示例中,有一些明確的東西:
- 時間幀越小,值越小
SharpeRatio
這是由樣本數量引起的,對於較小的時間幀,樣本數量更大,並增加了可變性,從而增加了標準偏差,這是方程中的SharpeRatio 分母。
對標準偏差的變化有很大的敏感性
這正是他們VWR 試圖通過提供跨時間範圍的一致值來解決的。同一策略提供以下值:
-
TimeFrame.Years:1.5368 -
TimeFrame.Months:1.5163 -
TimeFrame.Weeks:1.5383 -
TimeFrame.Days:1.5221
注意
返回VWR (遵循文獻)始終以年化形式返回。該範例通過以下方式執行:
--timeframe xxx
其中xxx代表days、 weeks或 monthsyears
默認值是None 使用數據的基礎時間幀,即 days
一致的值,表明策略在提供一致回報方面的表現可以在任何時間範圍內進行評估。
注意
從理論上講,這些值應該是相同的,但這需要將參數(年化週期數)微調tann 為確切的交易週期。這裡沒有這樣做,因為目的只是看一致性。
結論
為使用者提供了一種新工具,它提供了一種獨立於時間框架的策略評估方法
示例用法
$ ./vwr.py --help
usage: vwr.py [-h] [--data DATA] [--cash CASH] [--fromdate FROMDATE]
[--todate TODATE] [--writercsv]
[--tframe {weeks,months,days,years}] [--sigma-max SIGMA_MAX]
[--tau TAU] [--tann TANN] [--stddev-sample] [--plot [kwargs]]
TimeReturns and VWR
optional arguments:
-h, --help show this help message and exit
--data DATA, -d DATA data to add to the system (default:
../../datas/2005-2006-day-001.txt)
--cash CASH Starting Cash (default: None)
--fromdate FROMDATE, -f FROMDATE
Starting date in YYYY-MM-DD format (default: None)
--todate TODATE, -t TODATE
Starting date in YYYY-MM-DD format (default: None)
--writercsv, -wcsv Tell the writer to produce a csv stream (default:
False)
--tframe {weeks,months,days,years}, --timeframe {weeks,months,days,years}
TimeFrame for the Returns/Sharpe calculations
(default: None)
--sigma-max SIGMA_MAX
VWR Sigma Max (default: None)
--tau TAU VWR tau factor (default: None)
--tann TANN Annualization factor (default: None)
--stddev-sample Consider Bessels correction for stddeviation (default:
False)
--plot [kwargs], -p [kwargs]
Plot the read data applying any kwargs passed For
example: --plot style="candle" (to plot candles)
(default: None)
示例代碼
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import argparse
import datetime
import backtrader as bt
TFRAMES = dict(
days=bt.TimeFrame.Days,
weeks=bt.TimeFrame.Weeks,
months=bt.TimeFrame.Months,
years=bt.TimeFrame.Years)
def runstrat(pargs=None):
args = parse_args(pargs)
# Create a cerebro
cerebro = bt.Cerebro()
if args.cash is not None:
cerebro.broker.set_cash(args.cash)
dkwargs = dict()
# Get the dates from the args
if args.fromdate is not None:
fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d')
dkwargs['fromdate'] = fromdate
if args.todate is not None:
todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d')
dkwargs['todate'] = todate
# Create the 1st data
data = bt.feeds.BacktraderCSVData(dataname=args.data, **dkwargs)
cerebro.adddata(data) # Add the data to cerebro
cerebro.addstrategy(bt.strategies.SMA_CrossOver) # Add the strategy
lrkwargs = dict()
if args.tframe is not None:
lrkwargs['timeframe'] = TFRAMES[args.tframe]
if args.tann is not None:
lrkwargs['tann'] = args.tann
cerebro.addanalyzer(bt.analyzers.Returns, **lrkwargs) # Returns
vwrkwargs = dict()
if args.tframe is not None:
vwrkwargs['timeframe'] = TFRAMES[args.tframe]
if args.tann is not None:
vwrkwargs['tann'] = args.tann
if args.sigma_max is not None:
vwrkwargs['sigma_max'] = args.sigma_max
if args.tau is not None:
vwrkwargs['tau'] = args.tau
cerebro.addanalyzer(bt.analyzers.VWR, **vwrkwargs) # VWR Analyzer
# Add a writer to get output
cerebro.addwriter(bt.WriterFile, csv=args.writercsv, rounding=4)
cerebro.run() # And run it
# Plot if requested
if args.plot:
pkwargs = dict(style='bar')
if args.plot is not True: # evals to True but is not True
npkwargs = eval('dict(' + args.plot + ')') # args were passed
pkwargs.update(npkwargs)
cerebro.plot(**pkwargs)
def parse_args(pargs=None):
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description='TimeReturns and SharpeRatio')
parser.add_argument('--data', '-d',
default='../../datas/2005-2006-day-001.txt',
help='data to add to the system')
parser.add_argument('--cash', default=None, type=float, required=False,
help='Starting Cash')
parser.add_argument('--fromdate', '-f',
default=None,
help='Starting date in YYYY-MM-DD format')
parser.add_argument('--todate', '-t',
default=None,
help='Starting date in YYYY-MM-DD format')
parser.add_argument('--writercsv', '-wcsv', action='store_true',
help='Tell the writer to produce a csv stream')
parser.add_argument('--tframe', '--timeframe', default=None,
required=False, choices=TFRAMES.keys(),
help='TimeFrame for the Returns/Sharpe calculations')
parser.add_argument('--sigma-max', required=False, action='store',
type=float, default=None,
help='VWR Sigma Max')
parser.add_argument('--tau', required=False, action='store',
type=float, default=None,
help='VWR tau factor')
parser.add_argument('--tann', required=False, action='store',
type=float, default=None,
help=('Annualization factor'))
parser.add_argument('--stddev-sample', required=False, action='store_true',
help='Consider Bessels correction for stddeviation')
# Plot options
parser.add_argument('--plot', '-p', nargs='?', required=False,
metavar='kwargs', const=True,
help=('Plot the read data applying any kwargs passed\n'
'\n'
'For example:\n'
'\n'
' --plot style="candle" (to plot candles)\n'))
if pargs is not None:
return parser.parse_args(pargs)
return parser.parse_args()
if __name__ == '__main__':
runstrat()