Backtrader 文档学习-Target Orders

发布时间:2024年01月24日

Backtrader 文档学习-Target Orders

1. 概述

sizer不能决定操作是买还是卖,意味着需要一个新的概念,通过增加小智能层可以决定买卖,即通过持仓份额可以决定买卖操作。
这就是策略中order_target_xxx方法族的作用。受zipline的方法的启发,提供了简单指定最终target的机会,target实现:

  • size 特定资产组合中的股票、合同数量
  • value 投资组合中资产的货币单位价值
  • percent 投资组合中资产价值的百分比(来自当前投资组合)

在这种情况下,关键是指定最终target,该方法决定操作是买入还是卖出。同样的逻辑适用于3种方法。order_target_size参数设置:

  • 如果目标大于头寸,则发出买入指令,差值为目标-头寸大小 :

    • Pos: 0, target: 7 -> buy(size=7 - 0) -> buy(size=7)
    • Pos: 3, target: 7 -> buy(size=7 - 3) -> buy(size=4)
    • Pos: -3, target: 7 -> buy(size=7 - -3) -> buy(size=10)
    • Pos: -3, target: -2 -> buy(size=-2 - -3) -> buy(size=1)
  • 如果目标小于头寸,则根据头寸大小-目标的差额发出卖出指令:

    • Pos: 0, target: -7 -> sell(size=0 - -7) -> sell(size=7)
    • Pos: 3, target: -7 -> sell(size=3 - -7) -> sell(size=10)
    • Pos: -3, target: -7 -> sell(size=-3 - -7) -> sell(size=4)
    • Pos: 3, target: 2 -> sell(size=3 - 2) -> sell(size=1)
      当使用order_target_value确定价值时,投资组合中资产的当前价值和头寸规模都将被考虑在内,以决定最终的基础操作,理由是:
  • 如果头寸规模为负(空头),目标价值必须大于当前价值,这意味着卖出更多
    按这个逻辑操作:

    • If target > value and size >=0 -> buy
    • If target > value and size < 0 -> sell
    • If target < value and size >= 0 -> sell
    • If target < value and size < 0 -> buy
      order_target_percent 的逻辑与order_target_value的逻辑相同。考虑投资组合的当前总价值来确定资产的目标价值 。

2. 示例

示例中的逻辑相当简单,只是为了测试效果,规则如下:

  • 在奇数月份(1月、3月……),order_target_value =day * 1000,模拟了一个不断增加的target 。
  • 在偶数月份(2月、4月……),order_target_value = 31 - day ,模拟了一个递减的target 。
(1)order_target_size
0001 - 2005-01-03 - Position Size:     00 - Value 1000000.00
0001 - 2005-01-03 - Order Target Size: 03
0002 - 2005-01-04 - Position Size:     03 - Value 999994.39
0002 - 2005-01-04 - Order Target Size: 04
0003 - 2005-01-05 - Position Size:     04 - Value 999992.48
0003 - 2005-01-05 - Order Target Size: 05
0004 - 2005-01-06 - Position Size:     05 - Value 999988.79
0004 - 2005-01-06 - Order Target Size: 06
0005 - 2005-01-07 - Position Size:     06 - Value 999991.41
0005 - 2005-01-07 - Order Target Size: 07
0006 - 2005-01-10 - Position Size:     07 - Value 999993.89
0006 - 2005-01-10 - Order Target Size: 10
0007 - 2005-01-11 - Position Size:     10 - Value 999987.32
0007 - 2005-01-11 - Order Target Size: 11
0008 - 2005-01-12 - Position Size:     11 - Value 999992.38
0008 - 2005-01-12 - Order Target Size: 12
0009 - 2005-01-13 - Position Size:     12 - Value 999982.68
... ... 
0021 - 2005-02-01 - Position Size:     31 - Value 999954.68
0021 - 2005-02-01 - Order Target Size: 30
0022 - 2005-02-02 - Position Size:     30 - Value 999979.65
0022 - 2005-02-02 - Order Target Size: 29
0023 - 2005-02-03 - Position Size:     29 - Value 999966.33
0023 - 2005-02-03 - Order Target Size: 28
0024 - 2005-02-04 - Position Size:     28 - Value 999963.99
0024 - 2005-02-04 - Order Target Size: 27
0025 - 2005-02-07 - Position Size:     27 - Value 999949.19
0025 - 2005-02-07 - Order Target Size: 24
0026 - 2005-02-08 - Position Size:     24 - Value 999947.06

1月份,该target 从第一个交易日3日开始,仓位3,并不断增加。位置大小最初从0移动到3,然后以1为增量。 1月结束最后一个订单目标是31。
当进入2月1日时头寸规模,此时新的target被要求为30,并随着头寸的减少而递减1。
在这里插入图片描述

(2) order_target_value
0001 - 2005-01-03 - Position Size:     00 - Value 1000000.00
0001 - 2005-01-03 - Order Target Size: 03
0002 - 2005-01-04 - Position Size:     03 - Value 999994.39
0002 - 2005-01-04 - Order Target Size: 04
0003 - 2005-01-05 - Position Size:     04 - Value 999992.48
0003 - 2005-01-05 - Order Target Size: 05
0004 - 2005-01-06 - Position Size:     05 - Value 999988.79
0004 - 2005-01-06 - Order Target Size: 06
0005 - 2005-01-07 - Position Size:     06 - Value 999991.41
0005 - 2005-01-07 - Order Target Size: 07
0006 - 2005-01-10 - Position Size:     07 - Value 999993.89
0006 - 2005-01-10 - Order Target Size: 10
0007 - 2005-01-11 - Position Size:     10 - Value 999987.32
... ...
0020 - 2005-01-31 - Position Size:     28 - Value 999968.70
0020 - 2005-01-31 - Order Target Size: 31
0021 - 2005-02-01 - Position Size:     31 - Value 999954.68
0021 - 2005-02-01 - Order Target Size: 30
0022 - 2005-02-02 - Position Size:     30 - Value 999979.65
0022 - 2005-02-02 - Order Target Size: 29
0023 - 2005-02-03 - Position Size:     29 - Value 999966.33
0023 - 2005-02-03 - Order Target Size: 28
0024 - 2005-02-04 - Position Size:     28 - Value 999963.99
0024 - 2005-02-04 - Order Target Size: 27
0025 - 2005-02-07 - Position Size:     27 - Value 999949.19
0025 - 2005-02-07 - Order Target Size: 24

在这里插入图片描述

(3)order_target_percent
0001 - 2005-01-03 - Position Size:     00 - Value 1000000.00
0001 - 2005-01-03 - data percent 0.00
0001 - 2005-01-03 - Order Target Percent: 0.03
0002 - 2005-01-04 - Position Size:     785 - Value 998532.05
0002 - 2005-01-04 - data percent 0.03
0002 - 2005-01-04 - Order Target Percent: 0.04
0003 - 2005-01-05 - Position Size:     1091 - Value 998007.44
0003 - 2005-01-05 - data percent 0.04
0003 - 2005-01-05 - Order Target Percent: 0.05
0004 - 2005-01-06 - Position Size:     1381 - Value 996985.64
0004 - 2005-01-06 - data percent 0.05
0004 - 2005-01-06 - Order Target Percent: 0.06
0005 - 2005-01-07 - Position Size:     1688 - Value 997708.36
0005 - 2005-01-07 - data percent 0.06
0005 - 2005-01-07 - Order Target Percent: 0.07
0006 - 2005-01-10 - Position Size:     1942 - Value 998397.32
0006 - 2005-01-10 - data percent 0.07
0006 - 2005-01-10 - Order Target Percent: 0.10
... ...
0020 - 2005-01-31 - Position Size:     7985 - Value 991966.28
0020 - 2005-01-31 - data percent 0.28
0020 - 2005-01-31 - Order Target Percent: 0.31
0021 - 2005-02-01 - Position Size:     8733 - Value 988008.94
0021 - 2005-02-01 - data percent 0.31
0021 - 2005-02-01 - Order Target Percent: 0.30
0022 - 2005-02-02 - Position Size:     8530 - Value 995005.45
0022 - 2005-02-02 - data percent 0.30
0022 - 2005-02-02 - Order Target Percent: 0.29
0023 - 2005-02-03 - Position Size:     8120 - Value 991240.75
0023 - 2005-02-03 - data percent 0.29
0023 - 2005-02-03 - Order Target Percent: 0.28
0024 - 2005-02-04 - Position Size:     7910 - Value 990607.25
0024 - 2005-02-04 - data percent 0.28

在这里插入图片描述

3. 代码

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import argparse
from datetime import datetime

import backtrader as bt


class TheStrategy(bt.Strategy):
    '''
    This strategy is loosely based on some of the examples from the Van
    K. Tharp book: *Trade Your Way To Financial Freedom*. The logic:

      - Enter the market if:
        - The MACD.macd line crosses the MACD.signal line to the upside
        - The Simple Moving Average has a negative direction in the last x
          periods (actual value below value x periods ago)

     - Set a stop price x times the ATR value away from the close

     - If in the market:

       - Check if the current close has gone below the stop price. If yes,
         exit.
       - If not, update the stop price if the new stop price would be higher
         than the current
    '''

    params = (
        ('use_target_size', False),
        ('use_target_value', False),
        ('use_target_percent', False),
    )

    def notify_order(self, order):
        if order.status == order.Completed:
            pass

        if not order.alive():
            self.order = None  # indicate no order is pending

    def start(self):
        self.order = None  # sentinel to avoid operrations on pending order

    def next(self):
        dt = self.data.datetime.date()

        portfolio_value = self.broker.get_value()
        print('%04d - %s - Position Size:     %02d - Value %.2f' %
              (len(self), dt.isoformat(), self.position.size, portfolio_value))

        data_value = self.broker.get_value([self.data])

        if self.p.use_target_value:
            print('%04d - %s - data value %.2f' %
                  (len(self), dt.isoformat(), data_value))

        elif self.p.use_target_percent:
            port_perc = data_value / portfolio_value
            print('%04d - %s - data percent %.2f' %
                  (len(self), dt.isoformat(), port_perc))

        if self.order:
            return  # pending order execution

        size = dt.day
        if (dt.month % 2) == 0:
            size = 31 - size

        if self.p.use_target_size:
            target = size
            print('%04d - %s - Order Target Size: %02d' %
                  (len(self), dt.isoformat(), size))

            self.order = self.order_target_size(target=size)

        elif self.p.use_target_value:
            value = size * 1000

            print('%04d - %s - Order Target Value: %.2f' %
                  (len(self), dt.isoformat(), value))

            self.order = self.order_target_value(target=value)

        elif self.p.use_target_percent:
            percent = size / 100.0

            print('%04d - %s - Order Target Percent: %.2f' %
                  (len(self), dt.isoformat(), percent))

            self.order = self.order_target_percent(target=percent)


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

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

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

    # data
    data = bt.feeds.YahooFinanceCSVData(dataname=args.data, **dkwargs)
    cerebro.adddata(data)

    # strategy
    cerebro.addstrategy(TheStrategy,
                        use_target_size=args.target_size,
                        use_target_value=args.target_value,
                        use_target_percent=args.target_percent)

    cerebro.run()

    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='Sample for Order Target')

    parser.add_argument('--data', required=False,
                        default='./datas/yhoo-1996-2015.txt',
                        help='Specific 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=1000000,
                        help='Ending date in YYYY-MM-DD format')

    pgroup = parser.add_mutually_exclusive_group(required=True)

    pgroup.add_argument('--target-size', required=False, action='store_true',
                        help=('Use order_target_size'))

    pgroup.add_argument('--target-value', required=False, action='store_true',
                        help=('Use order_target_value'))

    pgroup.add_argument('--target-percent', required=False,
                        action='store_true',
                        help=('Use order_target_percent'))

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

4. Help

python ./order_target.py --help
usage: order_target.py [-h] [--data DATA] [--fromdate FROMDATE]
                       [--todate TODATE] [--cash CASH]
                       (--target-size | --target-value | --target-percent)
                       [--plot [kwargs]]

Sample for Order Target

optional arguments:
  -h, --help            show this help message and exit
  --data DATA           Specific 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           Ending date in YYYY-MM-DD format (default: 1000000)
  --target-size         Use order_target_size (default: False)
  --target-value        Use order_target_value (default: False)
  --target-percent      Use order_target_percent (default: False)
  --plot [kwargs], -p [kwargs]
                        Plot the read data applying any kwargs passed For
                        example: --plot style="candle" (to plot candles)
                        (default: None)
文章来源:https://blog.csdn.net/qq_39065491/article/details/135813054
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。