Skip to content

施胶机智能定位

原文: https://www.backtrader.com/blog/posts/2016-07-23-sizers-smart-staking/sizers-smart-staking/

1.6.4.93 版标志着backtrader的一个重要里程碑,即使版本编号的变化很小。

Po.T0.职位大小是一个事实上为这个项目奠定了基础的阅读后,T2。交易你的方式金融自由。

这本书并不是Van K.Tharp详细介绍了他职位调整的方法,而是在书中介绍和讨论了这个主题。与此相关的一个示例具有此设置

  • 如果不在市场上,掷硬币决定是否进入

  • 如果已经在市场上,用 2 倍 ATR 的止损点控制仓位,如果价格有利地移动到所采取的仓位,止损点会更新

关于这一点的重要部分:

  • 进入市场是随机的

  • 该方法通过不同的分级方案进行了测试,加上具有动态停止功能,使系统盈利

遵循建立自己的“系统”的原则(无论是手动/自动/计算机化、技术/基础,…)反向交易者诞生的一天就是为了测试这个场景。

这本可以在任何现有平台上进行测试,但在这一过程中都没有乐趣,许多挑战都得到了解决,甚至在启动backtrader时都没有考虑到这些挑战

规模商从一开始就在这个平台上,但由于实时交易等许多其他因素开始阻碍,所以被隐藏起来。但现在一切都结束了,Van K.Tharp场景将接受测试。宁早勿晚。

同时,两台测浆机进行样本测试。

施胶机控制定位

该示例显示了一个潜在的用例,施胶者通过控制施胶来改变策略的行为。查看backtrader.readthedocs.io上的单据,了解分级界面

这两种尺寸:

  • LongOnly:如果当前仓位为 0,则返回固定大小仓位;如果已经在市场上,则返回相同的固定大小仓位以关闭该仓位。

    ```py class LongOnly(bt.Sizer): params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
        if isbuy:
            return self.p.stake
    
        # Sell situation
        position = self.strategy.getposition(data)
        if not position.size:
            return 0  # do not sell if nothing is open
    
        return self.p.stake
    

    ```

  • FixedReverser:如果不在市场上,将返还固定规模的股份;如果已经在市场上,将返还双倍的固定规模股份,以允许反转

    ```py class FixedReverser(bt.Sizer): params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
        position = self.broker.getposition(data)
        size = self.p.stake * (1 + (position.size != 0))
        return size
    

    ```

这两个规模将与一个非常简单的策略相结合。

class CloseSMA(bt.Strategy):
    params = (('period', 15),)

    def __init__(self):
        sma = bt.indicators.SMA(self.data, period=self.p.period)
        self.crossover = bt.indicators.CrossOver(self.data, sma)

    def next(self):
        if self.crossover > 0:
            self.buy()

        elif self.crossover < 0:
            self.sell() 

注意该策略如何使用关闭 SMA交叉信号发出买入卖出命令,需要考虑一个重要事项:

  • 策略中未进行定位检查

在下面的执行中可以看到相同的策略,通过简单地在样本中使用此代码更改测码器(通过开关--longonly控制),将行为从长仅更改为长短

 if args.longonly:
        cerebro.addsizer(LongOnly, stake=args.stake)
    else:
        cerebro.addsizer(FixedReverser, stake=args.stake) 

长时间执行

使用以下命令完成:

$ ./sizertest.py --longonly --plot 

这个输出。

!image

长短执行

使用以下命令完成:

$ ./sizertest.py --plot 

这个输出。

!image

这表明:

  • 交易数量翻了一番

  • 现金(开始时除外)永远不会等于价值,因为策略总是在市场中

样本使用

$ ./sizertest.py --help
usage: sizertest.py [-h] [--data0 DATA0] [--fromdate FROMDATE]
                    [--todate TODATE] [--cash CASH] [--longonly]
                    [--stake STAKE] [--period PERIOD] [--plot [kwargs]]

Sample for sizer

optional arguments:
  -h, --help            show this help message and exit
  --data0 DATA0         Data to be read in (default:
                        ../../datas/yhoo-1996-2015.txt)
  --fromdate FROMDATE   Starting date in YYYY-MM-DD format (default:
                        2005-01-01)
  --todate TODATE       Ending date in YYYY-MM-DD format (default: 2006-12-31)
  --cash CASH           Cash to start with (default: 50000)
  --longonly            Use the LongOnly sizer (default: False)
  --stake STAKE         Stake to pass to the sizers (default: 1)
  --period PERIOD       Period for the Simple Moving Average (default: 15)
  --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 random

import backtrader as bt

class CloseSMA(bt.Strategy):
    params = (('period', 15),)

    def __init__(self):
        sma = bt.indicators.SMA(self.data, period=self.p.period)
        self.crossover = bt.indicators.CrossOver(self.data, sma)

    def next(self):
        if self.crossover > 0:
            self.buy()

        elif self.crossover < 0:
            self.sell()

class LongOnly(bt.Sizer):
    params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
        if isbuy:
            return self.p.stake

        # Sell situation
        position = self.strategy.getposition(data)
        if not position.size:
            return 0  # do not sell if nothing is open

        return self.p.stake

class FixedReverser(bt.Sizer):
    params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
        position = self.broker.getposition(data)
        size = self.p.stake * (1 + (position.size != 0))
        return size

def runstrat(args=None):
    args = parse_args(args)

    cerebro = bt.Cerebro()
    cerebro.broker.set_cash(args.cash)

    dkwargs = dict()
    if args.fromdate:
        fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d')
        dkwargs['fromdate'] = fromdate

    if args.todate:
        todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d')
        dkwargs['todate'] = todate

    data0 = bt.feeds.YahooFinanceCSVData(dataname=args.data0, **dkwargs)
    cerebro.adddata(data0, name='Data0')

    cerebro.addstrategy(CloseSMA, period=args.period)

    if args.longonly:
        cerebro.addsizer(LongOnly, stake=args.stake)
    else:
        cerebro.addsizer(FixedReverser, stake=args.stake)

    cerebro.run()
    if args.plot:
        pkwargs = dict()
        if args.plot is not True:  # evals to True but is not True
            pkwargs = eval('dict(' + args.plot + ')')  # args were passed

        cerebro.plot(**pkwargs)

def parse_args(pargs=None):

    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description='Sample for sizer')

    parser.add_argument('--data0', required=False,
                        default='../../datas/yhoo-1996-2015.txt',
                        help='Data to be read in')

    parser.add_argument('--fromdate', required=False,
                        default='2005-01-01',
                        help='Starting date in YYYY-MM-DD format')

    parser.add_argument('--todate', required=False,
                        default='2006-12-31',
                        help='Ending date in YYYY-MM-DD format')

    parser.add_argument('--cash', required=False, action='store',
                        type=float, default=50000,
                        help=('Cash to start with'))

    parser.add_argument('--longonly', required=False, action='store_true',
                        help=('Use the LongOnly sizer'))

    parser.add_argument('--stake', required=False, action='store',
                        type=int, default=1,
                        help=('Stake to pass to the sizers'))

    parser.add_argument('--period', required=False, action='store',
                        type=int, default=15,
                        help=('Period for the Simple Moving Average'))

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

我们一直在努力

apachecn/AiLearning

【布客】中文翻译组