You are here:  Home » 量化交易与机器学习 » backtrader » 变异加权回报(或VWR) – backtrader中文教程

变异加权回报(或VWR

下面讲的improvedSharpeRatiobacktrader有一些提示加入这个analyzer到其arsenal.

The文献是:

  • 的https://www.crystalbull.com/sharpe-ratio-better-with-log-returns/

用对数收益的好处开始,并按照在侧具有的效果standard deviation中的分母SharpeRatio方程,文档开发式和期望这个analyzer.

一个最重要的特性可能是:

  • A consistent value across timeframes

`的SharpeRatio使用超额收益与风险的算术平均值游离率/资产由standard deviation的超额收益划分相对于无风险利率/资产。这使得最终的价值取决于样品数量和标准偏差,其甚至可以是0。在这情况下,SharpeRatio将infinite.

backtrader包括用于SharpeRatio使用样品测试样品数据,其包括用于20052006的价格。对返回的值不同的timeframes

  • TimeFrame.Years11.6473
  • TimeFrame.Months0.5425
  • TimeFrame.Weeks0.457
  • TimeFrame.Days0.4274

Note

For一致性比率年。该sharpe-timereturn样本并与执行:

--annualize --timeframe xxx

如果xxx表示days, weeks, monthsyears(默认)

在此示例中有一些明确的:

这是由引起的值越小样本的数目是对于较小的较大timeframes,并增加了variability和因此增加了standard
deviation
,它是在SharpeRatioequation.

There是分母一个large sensibilitystandard deviation

这是改变的正是这种什么VWR试图解决通过提供一个一致值跨越timeframes。同样的策略提供了以下值:

  • TimeFrame.Years1.5368
  • TimeFrame.Months1.5163
  • TimeFrame.Weeks1.5383
  • TimeFrame.Days1.5221

Note

TheVWR被返回(文献以下)总是在年形成。将样品与执行:

--timeframe xxx

xxx代表days, weeks, monthsyears

默认是None,它使用底层timeframe的数据的`这是days

一致的值这表明该策略的表现,当谈到以提供稳定的回报可以在任何timeframe.

Note

Theoretically评估值应该是相同的,但是这需要精细调谐tann参数(年度化周期数)与确切的交易时段。这不是在这里完成,因为其目的仅仅是看着consistency.

Conclusion

A新的工具,它提供了一个时间表独立保守的战略评估可用于users

Sample Usage

$ ./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)

Sample Code

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()