Skip to content

目标订单

原文: https://www.backtrader.com/docu/order_target/order_target/

直到版本1.8.10.96通过反向交易者策略方法buysell上实现智能下注。这一切都是为了在方程式中加入一个Sizer,它决定了桩的大小。

规模商不能做的是决定该操作必须是买入还是卖出。这意味着需要一个新的概念,即增加一个小的智能层来做出这样的决策。

这里是策略中的order_target_xxx方法家族发挥作用的地方。受zipline中的启发,这些方法提供了简单指定最终目标的机会,即目标:

  • size->特定资产组合中的股份、合同金额

  • value->组合中资产的货币单位价值

  • percent->当前投资组合中资产价值的百分比(来自当前投资组合)

笔记

这些方法的参考可以在策略中找到。综上所述,这些方法使用的签名buysell相同,但参数size被参数target替换

在本例中,所有操作都是指定最终的目标,该方法决定操作是买入还是卖出。同样的逻辑也适用于这三种方法。让我们从order_target_size开始

  • 如果目标大于发行了买入的头寸,差额为target - position_size

    示例:

    • Pos:0目标7->买入(尺码=7-0)->买入(尺码=7)

    • Pos:3目标7->买入(尺码=7-3)->买入(尺码=4)

    • Pos:-3目标7->买入(尺码=7--3)->买入(尺码=10)

    • Pos:-3目标-2->买入(尺码=-2--3)->买入(尺码=1)

  • 如果目标小于头寸 a卖出并发行差额position_size - target

    示例:

    • 位置:0目标-7->卖出(尺寸=0--7)->卖出(尺寸=7)

    • 位置:3目标-7->卖出(尺码=3--7)->卖出(尺码=10)

    • 位置:-3目标-7->卖出(尺寸=-3--7)->卖出(尺寸=4)

    • 位置:3目标2->卖出(尺码=3-2)->卖出(尺码=1)

当以order_target_value为目标值时,组合中资产的当前价值头寸规模都被考虑在内,以决定最终的基础操作。理由是:

  • 如果头寸大小为负(做空,且目标值必须大于当前值,则表示:卖出更多

因此,逻辑的工作原理如下:

  • 如果target > valuesize >=0->购买

  • 如果target > valuesize < 0->卖出

  • 如果target < valuesize >= 0->卖出

  • 如果target < valuesize < 0->购买

order_target_percent的逻辑与order_target_value的逻辑相同。该方法仅考虑投资组合的当前总价值,以确定资产的目标价值

样本

backtrader尝试为每个新功能提供一个示例,这也不例外。没有任何提示,只是测试一下结果是否符合预期。这个在样本的order_target目录下。

样本中的逻辑相当愚蠢,仅用于测试:

  • 奇数月(1 月、3 月……)内,以为目标(如order_target_value日乘以1000日)

    这模拟了一个不断增加的目标

  • 偶数月(2 月、4 月……)期间,使用31 - day作为目标

    这模拟了一个递减的目标

订单\目标\尺寸

让我们看看一月二月发生了什么。

$ ./order_target.py --target-size -- plot
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
...
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
... 

1 月目标3开始,在本年的第 1交易日开始并增加。而位置大小最初从0移动到3,然后以1为增量。

完成一月最后一个订单是针对31的,并且在进入二月st时报告位置大小,此时新的目标侧被请求为30并且随着位置的变化而变化,递减为“1”。

!image

订单\目标\价值

目标值预计会出现类似行为

$ ./order_target.py --target-value --plot
0001 - 2005-01-03 - Position Size:     00 - Value 1000000.00
0001 - 2005-01-03 - data value 0.00
0001 - 2005-01-03 - Order Target Value: 3000.00
0002 - 2005-01-04 - Position Size:     78 - Value 999854.14
0002 - 2005-01-04 - data value 2853.24
0002 - 2005-01-04 - Order Target Value: 4000.00
0003 - 2005-01-05 - Position Size:     109 - Value 999801.68
0003 - 2005-01-05 - data value 3938.17
0003 - 2005-01-05 - Order Target Value: 5000.00
0004 - 2005-01-06 - Position Size:     138 - Value 999699.57
...
0020 - 2005-01-31 - Position Size:     808 - Value 999206.37
0020 - 2005-01-31 - data value 28449.68
0020 - 2005-01-31 - Order Target Value: 31000.00
0021 - 2005-02-01 - Position Size:     880 - Value 998807.33
0021 - 2005-02-01 - data value 30580.00
0021 - 2005-02-01 - Order Target Value: 30000.00
0022 - 2005-02-02 - Position Size:     864 - Value 999510.21
0022 - 2005-02-02 - data value 30706.56
0022 - 2005-02-02 - Order Target Value: 29000.00
0023 - 2005-02-03 - Position Size:     816 - Value 999130.05
0023 - 2005-02-03 - data value 28633.44
0023 - 2005-02-03 - Order Target Value: 28000.00
... 

还有一行额外的信息告诉你实际的数据值(在投资组合中)是什么。这有助于确定目标值是否已达到。

初始目标为3000.0,报告的初始值为2853.24。这里的问题是这是否足够接近。答案是

  • 样本使用每日酒吧结束时的Market订单和最后可用价格计算满足目标值目标尺寸

  • 执行时使用第二天的open价格,这不太可能是前一天的close

以任何其他方式做这件事都意味着一个人在欺骗他/她自己。

下一个目标值最终值更接近:40003938.17

当切换到二月目标值开始从31000下降到3000029000。从30580.0030706.56再到28633.44数据值也是如此。等待:

  • 30580->30706.56是积极的变化

    的确在这种情况下,为目标值计算出的大小符合开盘价,从而将价值猛增至30706.56

如何避免这种影响:

  • 该示例对订单使用Market类型执行,这种影响无法避免

  • order_target_xxx方法允许指定执行类型价格

    可以指定Limit作为执行顺序,让价格成为收盘价格(如果没有提供其他信息,则由方法选择),甚至提供具体的定价

!image

订单\目标\百分比

在这种情况下,它只是当前投资组合价值的一个百分比。

$ ./order_target.py --target-percent --plot
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
...
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
... 

并且信息已经更改,以查看数据在投资组合中表示的%

!image

样本使用

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

示例代码

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

我们一直在努力

apachecn/AiLearning

【布客】中文翻译组