前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BackTrader 中文文档(十九)

BackTrader 中文文档(十九)

作者头像
ApacheCN_飞龙
发布2024-05-24 15:40:56
470
发布2024-05-24 15:40:56
举报
文章被收录于专栏:信数据得永生信数据得永生

原文:www.backtrader.com/

2016

BTFD - 现实的打击

原文:www.backtrader.com/blog/posts/2016-12-28-btfd-bites/btfd-bites/

之前的帖子设法复制了BTFD策略,发现真正的收益是16x而不是31x

但正如在复制过程中指出的那样:

  • 没有收取任何手续费
  • 使用2x杠杆不收取利息

这引起了一个显而易见的问题:

  • 当收取佣金和利息时,16 倍的收益将有多少?

幸运的是,之前的样本足够灵活,可以进行实验。 为了得到一些视觉反馈和验证,以下代码将添加到策略中

代码语言:javascript
复制
def start(self):
    print(','.join(['TRADE', 'STATUS', 'Value', 'PNL', 'COMMISSION']))

def notify_order(self, order):
    if order.status in [order.Margin]:
        print('ORDER FAILED with status:', order.getstatusname())

def notify_trade(self, trade):
    if trade.isclosed:
        print(','.join(map(str, [
            'TRADE', 'CLOSE',
            self.data.num2date(trade.dtclose).date().isoformat(),
            trade.value,
            trade.pnl,
            trade.commission,
        ]
        )))
    elif trade.justopened:
        print(','.join(map(str, [
            'TRADE', 'OPEN',
            self.data.num2date(trade.dtopen).date().isoformat(),
            trade.value,
            trade.pnl,
            trade.commission,
        ]
        )))

关键在于以下内容:

  • 查看交易如何开启和关闭(价值,利润和损失,价值和佣金)
  • 如果订单因资金不足而被拒绝,则提供反馈Margin 注意 因为将有一个调整要投资的金额,以留出佣金的空间,所以一些订单可能无法被经纪人接受。 这种视觉反馈可以帮助识别情况

验证

首先快速测试以查看某些订单是否被接受。

代码语言:javascript
复制
$ ./btfd.py --comminfo commission=0.001,leverage=2.0 --strat target=1.0

TRADE,STATUS,Value,PNL,COMMISSION
ORDER FAILED with status: Margin
ORDER FAILED with status: Margin
TRADE,OPEN,1990-01-08,199345.2,0.0,199.3452
TRADE,CLOSE,1990-01-10,0.0,-1460.28,397.23012

注意:

  • 我们应用target=1.0,意味着:尝试投资 100%的资本。 这是默认值,但它在这里作为参考。
  • commission=0.0010.1%,以确保我们有时会满足保证金
  • 前两个订单被拒绝了,显示Margin
  • 第三个订单被接受了。 这不是错误。 系统试图投资100%的资本,但资产有一个价格,这是用来计算股份大小的。 大小是从实际可用的现金计算出的潜在大小的结果进行向下舍入。 这次向下舍入为这个第三个订单留下了足够的空间。
  • 交易通知(OPENCLOSE)显示了开仓手续费和最终总手续费,接近200k的价值,展示了2x杠杆的实际效果。 开仓手续费为199.3452,这是杠杆价值的0.1%,即199,345.2

剩余的测试将使用target=0.99x进行,其中x将确保有足够的空间用于选定的手续费。

现实的打击

让我们举一些真实的例子

目标 99.8% - 佣金 0.1%
代码语言:javascript
复制
./btfd.py --comminfo commission=0.001,leverage=2.0 --strat target=0.998 --plot
image
image

霹雳般的! 不仅BTFD策略远未接近16x的收益:它损失了大部分资金

  • 100,000下降到大约4,027

注意

下降到值是非杠杆值,因为这是在平仓时将返回系统的大约值

目标 99.9% - 佣金 0.05%

很可能是佣金过于激进。 让我们去一半

代码语言:javascript
复制
./btfd.py --comminfo commission=0.0005,leverage=2.0 --strat target=0.999 --plot
image
image

NO, NO。佣金并非如此激进,因为系统仍然亏损,从100,000下降到约69,000(非杠杆价值)

目标 99.95% - 佣金 0.025%

佣金再次被除以二

代码语言:javascript
复制
./btfd.py --comminfo commission=0.00025,leverage=2.0 --strat target=0.9995 --plot
image
image

最终系统赚钱了:

  • 最初的100,000被用于3x增益,增加到331,459
  • 但这并不符合资产的表现,该资产已经涨到了超过600k

注意

该示例接受--fromdate YYYY-MM-DD--todate YYYY-MM-DD来选择应用策略的时间段。这将允许对不同日期范围进行类似的场景测试。

结论

当面对佣金时,16x的收益无法持续。对于一些经纪人提供的佣金(无上限且按百分比计算),需要非常好的交易才能确保系统赚钱。

在这种情况下,策略应用于标普 500BTFD策略与指数的表现不相匹配。

没有应用利率。使用佣金已足以看出16x距离任何潜在利润有多远。无论如何,以2%的利率运行将执行如下

代码语言:javascript
复制
./btfd.py --comminfo commission=0.00025,leverage=2.0,interest=0.02,interest_long=True --strat target=0.9995 --plot

interest_long=True 是必须的,因为默认情况下收取利息的行为只针对多头仓位进行。

示例用法

代码语言:javascript
复制
$ ./btfd.py --help
usage: btfd.py [-h] [--offline] [--data TICKER]
               [--fromdate YYYY-MM-DD[THH:MM:SS]]
               [--todate YYYY-MM-DD[THH:MM:SS]] [--cerebro kwargs]
               [--broker kwargs] [--valobserver kwargs] [--strat kwargs]
               [--comminfo kwargs] [--plot [kwargs]]

BTFD - http://dark-bid.com/BTFD-only-strategy-that-matters.html - https://www.
reddit.com/r/algotrading/comments/5jez2b/can_anyone_replicate_this_strategy/

optional arguments:
  -h, --help            show this help message and exit
  --offline             Use offline file with ticker name (default: False)
  --data TICKER         Yahoo ticker to download (default: ^GSPC)
  --fromdate YYYY-MM-DD[THH:MM:SS]
                        Starting date[time] (default: 1990-01-01)
  --todate YYYY-MM-DD[THH:MM:SS]
                        Ending date[time] (default: 2016-10-01)
  --cerebro kwargs      kwargs in key=value format (default: stdstats=False)
  --broker kwargs       kwargs in key=value format (default: cash=100000.0,
                        coc=True)
  --valobserver kwargs  kwargs in key=value format (default:
                        assetstart=100000.0)
  --strat kwargs        kwargs in key=value format (default:
                        approach="highlow")
  --comminfo kwargs     kwargs in key=value format (default: leverage=2.0)
  --plot [kwargs]       kwargs in key=value format (default: )

示例代码

代码语言:javascript
复制
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

# References:
#  - https://www.reddit.com/r/algotrading/comments/5jez2b/can_anyone_replicate_this_strategy/
#  - http://dark-bid.com/BTFD-only-strategy-that-matters.html

import argparse
import datetime

import backtrader as bt

class ValueUnlever(bt.observers.Value):
    '''Extension of regular Value observer to add leveraged view'''
    lines = ('value_lever', 'asset')
    params = (('assetstart', 100000.0), ('lever', True),)

    def next(self):
        super(ValueUnlever, self).next()
        if self.p.lever:
            self.lines.value_lever[0] = self._owner.broker._valuelever

        if len(self) == 1:
            self.lines.asset[0] = self.p.assetstart
        else:
            change = self.data[0] / self.data[-1]
            self.lines.asset[0] = change * self.lines.asset[-1]

class St(bt.Strategy):
    params = (
        ('fall', -0.01),
        ('hold', 2),
        ('approach', 'highlow'),
        ('target', 1.0)
    )

    def __init__(self):
        if self.p.approach == 'closeclose':
            self.pctdown = self.data.close / self.data.close(-1) - 1.0
        elif self.p.approach == 'openclose':
            self.pctdown = self.data.close / self.data.open - 1.0
        elif self.p.approach == 'highclose':
            self.pctdown = self.data.close / self.data.high - 1.0
        elif self.p.approach == 'highlow':
            self.pctdown = self.data.low / self.data.high - 1.0

    def next(self):
        if self.position:
            if len(self) == self.barexit:
                self.close()
        else:
            if self.pctdown <= self.p.fall:
                self.order_target_percent(target=self.p.target)
                self.barexit = len(self) + self.p.hold

    def start(self):
        print(','.join(['TRADE', 'STATUS', 'Value', 'PNL', 'COMMISSION']))

    def notify_order(self, order):
        if order.status in [order.Margin, order.Rejected, order.Canceled]:
            print('ORDER FAILED with status:', order.getstatusname())

    def notify_trade(self, trade):
        if trade.isclosed:
            print(','.join(map(str, [
                'TRADE', 'CLOSE',
                self.data.num2date(trade.dtclose).date().isoformat(),
                trade.value,
                trade.pnl,
                trade.commission,
            ]
            )))
        elif trade.justopened:
            print(','.join(map(str, [
                'TRADE', 'OPEN',
                self.data.num2date(trade.dtopen).date().isoformat(),
                trade.value,
                trade.pnl,
                trade.commission,
            ]
            )))

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

    cerebro = bt.Cerebro()

    # Data feed kwargs
    kwargs = dict()

    # Parse from/to-date
    dtfmt, tmfmt = '%Y-%m-%d', 'T%H:%M:%S'
    for a, d in ((getattr(args, x), x) for x in ['fromdate', 'todate']):
        kwargs[d] = datetime.datetime.strptime(a, dtfmt + tmfmt * ('T' in a))

    if not args.offline:
        YahooData = bt.feeds.YahooFinanceData
    else:
        YahooData = bt.feeds.YahooFinanceCSVData

    # Data feed - no plot - observer will do the job
    data = YahooData(dataname=args.data, plot=False, **kwargs)
    cerebro.adddata(data)

    # Broker
    cerebro.broker = bt.brokers.BackBroker(**eval('dict(' + args.broker + ')'))

    # Add a commission
    cerebro.broker.setcommission(**eval('dict(' + args.comminfo + ')'))

    # Strategy
    cerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))

    # Add specific observer
    cerebro.addobserver(ValueUnlever, **eval('dict(' + args.valobserver + ')'))

    # Execute
    cerebro.run(**eval('dict(' + args.cerebro + ')'))

    if args.plot:  # Plot if requested to
        cerebro.plot(**eval('dict(' + args.plot + ')'))

def parse_args(pargs=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=(' - '.join([
            'BTFD',
            'http://dark-bid.com/BTFD-only-strategy-that-matters.html',
            ('https://www.reddit.com/r/algotrading/comments/5jez2b/'
             'can_anyone_replicate_this_strategy/')]))
        )

    parser.add_argument('--offline', required=False, action='store_true',
                        help='Use offline file with ticker name')

    parser.add_argument('--data', required=False, default='^GSPC',
                        metavar='TICKER', help='Yahoo ticker to download')

    parser.add_argument('--fromdate', required=False, default='1990-01-01',
                        metavar='YYYY-MM-DD[THH:MM:SS]',
                        help='Starting date[time]')

    parser.add_argument('--todate', required=False, default='2016-10-01',
                        metavar='YYYY-MM-DD[THH:MM:SS]',
                        help='Ending date[time]')

    parser.add_argument('--cerebro', required=False, default='stdstats=False',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--broker', required=False,
                        default='cash=100000.0, coc=True',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--valobserver', required=False,
                        default='assetstart=100000.0',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--strat', required=False,
                        default='approach="highlow"',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--comminfo', required=False, default='leverage=2.0',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--plot', required=False, default='',
                        nargs='?', const='volume=False',
                        metavar='kwargs', help='kwargs in key=value format')

    return parser.parse_args(pargs)

if __name__ == '__main__':
    runstrat()

BTFD(买入垃圾… Dip)

原文:www.backtrader.com/blog/posts/2016-12-26-btfd/btfd/

注意

CloseClose方法添加了操作日志(下面的示例也已更新)

Reddit上的一篇帖子呼吁复制BTFD策略,结果证明这是添加另一个功能到backtrader所需的小推动:杠杆

这些链接:

Reddit的帖子中最终没有对Dark Bid的结果进行完全复制。但是这是可以做到的。尽管从一开始就必须指出一些事情:

  • Dark Bid并没有展示真正的图表,并且关于该策略的解释实在是缺乏,大多数人可能会认为它是错误的

让我们直接在这里查看图表(请记住,图表来自Dark Bid BTFD帖子)

image
image

大多数人可能会做出以下解释:

  • 在收盘时购买:这部分很清楚。在收盘竞价时购买
  • 当标普至少下跌 1%:在大多数情况下,这意味着当前收盘价比前一次收盘价1%
  • 持有 2 天:这里的解释将是在 2 个交易会话后在收盘时卖出
  • 2x 杠杆:每个购买操作都是 2 倍杠杆(或*100%*信用)

附加信息:

  • 数据似乎从1990-01-01运行到2016-09-30
  • 起始现金价值似乎从100,000开始

注意

请注意,没有收取任何佣金信用利息

下面的示例已配置为获胜设置,但第一次执行将遵守解释的规则。

代码语言:javascript
复制
$ ./btfd.py --plot --strat approach="'closeclose'"

注意

该示例接受一个--offline参数,以使用之前从Yahoo下载的文件来加速测试。如果不使用,将每次都从Yahoo下载默认日期和默认股票代码为^GSPC的数据。

image
image

休斯顿,我们有问题!尽管没有预期的那么大。观察结果:

  • 我们的资产已经从100,000增加到602,816,这似乎与上面的BTFD图表完全吻合
  • 另一方面,我们的100,000现金只增加到357,277,这似乎低于预期值的10x,预期值为3,000,000(或3M
  • 在这种情况下,valuevalue_unlever相等,这意味着策略不在市场中

但是最有趣的是:红色线显示的时间内的价值明显不同

  • 我们的线路有非常快速的上涨下跌 这是由于杠杆。当策略购买时,2x杠杆允许购买两倍的资产。 但是当策略处于现金状态时,现金的价值并不是其价值的两倍。
  • BTFD行没有展现出这种行为,因为它始终始终是杠杆的

好的。BTFD谜题的第一部分… 已解决!但我们仍然有一个问题,这是匹配Dark Bid实现的性能。毫不犹豫,使用默认的获胜设置运行样本。

代码语言:javascript
复制
$ ./btfd.py --plot --strat approach="'highlow'"

注意

如果在策略中没有approach参数运行样本,则approach=highlow是默认设置

image
image

在这种情况下:

  • 使用highlow之间的差异。 当然,这并不是*“下跌至少 1%,如BTFD图表所示。这是不同的情况,因为low可能也发生在high之前,许多人会认为这是上涨而不是下跌*。

注意

该策略允许这些方法:closeclosehighlowhighcloseopenclose

但是:

  • 该系统的value3,184,118。这是一个赢家,因为对BTFD图表的视觉检查显示最终值超过了3M
  • 系统的未杠杆价值value_unlever)是:1,592,608,这不是上述情况。这只是告诉我们策略正在市场上

显然,在大约 1 或 2 天内,该策略将出售头寸,实际现金价值将约为1,592,608,绝不接近3,184,118

1.5M的值是原始Reddit帖子达到的最佳观察结果。

结论

完整的BTFD谜团已解决。关键在于:

  • 图表中绘制的value线不是真实的,因为它始终杠杆,而不仅仅是在购买时
  • 方法实际上不是在资产*至少下跌 1%*时购买,如通常理解的那样(前一次收盘价到当前收盘价),而是在资产的highlow之间至少有 1%的差异时购买
  • 实际收益大约为16 倍(从100,000增加到大约1,592,000),在任何情况下都不会达到31 倍(从100,000增加到3.1M

样本用法

代码语言:javascript
复制
$ ./btfd.py --help
usage: btfd.py [-h] [--offline] [--data TICKER]
               [--fromdate YYYY-MM-DD[THH:MM:SS]]
               [--todate YYYY-MM-DD[THH:MM:SS]] [--cerebro kwargs]
               [--broker kwargs] [--valobserver kwargs] [--strat kwargs]
               [--comminfo kwargs] [--plot [kwargs]]

BTFD - http://dark-bid.com/BTFD-only-strategy-that-matters.html - https://www.
reddit.com/r/algotrading/comments/5jez2b/can_anyone_replicate_this_strategy/

optional arguments:
  -h, --help            show this help message and exit
  --offline             Use offline file with ticker name (default: False)
  --data TICKER         Yahoo ticker to download (default: ^GSPC)
  --fromdate YYYY-MM-DD[THH:MM:SS]
                        Starting date[time] (default: 1990-01-01)
  --todate YYYY-MM-DD[THH:MM:SS]
                        Ending date[time] (default: 2016-10-01)
  --cerebro kwargs      kwargs in key=value format (default: stdstats=False)
  --broker kwargs       kwargs in key=value format (default: cash=100000.0,
                        coc=True)
  --valobserver kwargs  kwargs in key=value format (default:
                        assetstart=100000.0)
  --strat kwargs        kwargs in key=value format (default:
                        approach="highlow")
  --comminfo kwargs     kwargs in key=value format (default: leverage=2.0)
  --plot [kwargs]       kwargs in key=value format (default: )

样本代码

代码语言:javascript
复制
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

# References:
#  - https://www.reddit.com/r/algotrading/comments/5jez2b/can_anyone_replicate_this_strategy/
#  - http://dark-bid.com/BTFD-only-strategy-that-matters.html

import argparse
import datetime

import backtrader as bt

class ValueUnlever(bt.observers.Value):
    '''Extension of regular Value observer to add leveraged view'''
    lines = ('value_lever', 'asset')
    params = (('assetstart', 100000.0), ('lever', True),)

    def next(self):
        super(ValueUnlever, self).next()
        if self.p.lever:
            self.lines.value_lever[0] = self._owner.broker._valuelever

        if len(self) == 1:
            self.lines.asset[0] = self.p.assetstart
        else:
            change = self.data[0] / self.data[-1]
            self.lines.asset[0] = change * self.lines.asset[-1]

class St(bt.Strategy):
    params = (
        ('fall', -0.01),
        ('hold', 2),
        ('approach', 'highlow'),
        ('target', 1.0),
        ('prorder', False),
        ('prtrade', False),
        ('prdata', False),
    )

    def __init__(self):
        if self.p.approach == 'closeclose':
            self.pctdown = self.data.close / self.data.close(-1) - 1.0
        elif self.p.approach == 'openclose':
            self.pctdown = self.data.close / self.data.open - 1.0
        elif self.p.approach == 'highclose':
            self.pctdown = self.data.close / self.data.high - 1.0
        elif self.p.approach == 'highlow':
            self.pctdown = self.data.low / self.data.high - 1.0

    def next(self):
        if self.position:
            if len(self) == self.barexit:
                self.close()
                if self.p.prdata:
                    print(','.join(str(x) for x in
                                   ['DATA', 'CLOSE',
                                    self.data.datetime.date().isoformat(),
                                    self.data.close[0],
                                    float('NaN')]))
        else:
            if self.pctdown <= self.p.fall:
                self.order_target_percent(target=self.p.target)
                self.barexit = len(self) + self.p.hold

                if self.p.prdata:
                    print(','.join(str(x) for x in
                                   ['DATA', 'OPEN',
                                    self.data.datetime.date().isoformat(),
                                    self.data.close[0],
                                    self.pctdown[0]]))

    def start(self):
        if self.p.prtrade:
            print(','.join(
                ['TRADE', 'Status', 'Date', 'Value', 'PnL', 'Commission']))
        if self.p.prorder:
            print(','.join(
                ['ORDER', 'Type', 'Date', 'Price', 'Size', 'Commission']))
        if self.p.prdata:
            print(','.join(['DATA', 'Action', 'Date', 'Price', 'PctDown']))

    def notify_order(self, order):
        if order.status in [order.Margin, order.Rejected, order.Canceled]:
            print('ORDER FAILED with status:', order.getstatusname())
        elif order.status == order.Completed:
            if self.p.prorder:
                print(','.join(map(str, [
                    'ORDER', 'BUY' * order.isbuy() or 'SELL',
                    self.data.num2date(order.executed.dt).date().isoformat(),
                    order.executed.price,
                    order.executed.size,
                    order.executed.comm,
                ]
                )))

    def notify_trade(self, trade):
        if not self.p.prtrade:
            return

        if trade.isclosed:
            print(','.join(map(str, [
                'TRADE', 'CLOSE',
                self.data.num2date(trade.dtclose).date().isoformat(),
                trade.value,
                trade.pnl,
                trade.commission,
            ]
            )))
        elif trade.justopened:
            print(','.join(map(str, [
                'TRADE', 'OPEN',
                self.data.num2date(trade.dtopen).date().isoformat(),
                trade.value,
                trade.pnl,
                trade.commission,
            ]
            )))

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

    cerebro = bt.Cerebro()

    # Data feed kwargs
    kwargs = dict()

    # Parse from/to-date
    dtfmt, tmfmt = '%Y-%m-%d', 'T%H:%M:%S'
    for a, d in ((getattr(args, x), x) for x in ['fromdate', 'todate']):
        kwargs[d] = datetime.datetime.strptime(a, dtfmt + tmfmt * ('T' in a))

    if not args.offline:
        YahooData = bt.feeds.YahooFinanceData
    else:
        YahooData = bt.feeds.YahooFinanceCSVData

    # Data feed - no plot - observer will do the job
    data = YahooData(dataname=args.data, plot=False, **kwargs)
    cerebro.adddata(data)

    # Broker
    cerebro.broker = bt.brokers.BackBroker(**eval('dict(' + args.broker + ')'))

    # Add a commission
    cerebro.broker.setcommission(**eval('dict(' + args.comminfo + ')'))

    # Strategy
    cerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))

    # Add specific observer
    cerebro.addobserver(ValueUnlever, **eval('dict(' + args.valobserver + ')'))

    # Execute
    cerebro.run(**eval('dict(' + args.cerebro + ')'))

    if args.plot:  # Plot if requested to
        cerebro.plot(**eval('dict(' + args.plot + ')'))

def parse_args(pargs=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=(' - '.join([
            'BTFD',
            'http://dark-bid.com/BTFD-only-strategy-that-matters.html',
            ('https://www.reddit.com/r/algotrading/comments/5jez2b/'
             'can_anyone_replicate_this_strategy/')]))
        )

    parser.add_argument('--offline', required=False, action='store_true',
                        help='Use offline file with ticker name')

    parser.add_argument('--data', required=False, default='^GSPC',
                        metavar='TICKER', help='Yahoo ticker to download')

    parser.add_argument('--fromdate', required=False, default='1990-01-01',
                        metavar='YYYY-MM-DD[THH:MM:SS]',
                        help='Starting date[time]')

    parser.add_argument('--todate', required=False, default='2016-10-01',
                        metavar='YYYY-MM-DD[THH:MM:SS]',
                        help='Ending date[time]')

    parser.add_argument('--cerebro', required=False, default='stdstats=False',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--broker', required=False,
                        default='cash=100000.0, coc=True',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--valobserver', required=False,
                        default='assetstart=100000.0',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--strat', required=False,
                        default='approach="highlow"',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--comminfo', required=False, default='leverage=2.0',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--plot', required=False, default='',
                        nargs='?', const='volume=False',
                        metavar='kwargs', help='kwargs in key=value format')

    return parser.parse_args(pargs)

if __name__ == '__main__':
    runstrat()

操作日志

CloseClose方法

执行:

代码语言:javascript
复制
$ ./btfd.py --strat approach="'closeclose'",prorder=True,prdata=True

结果:

代码语言:javascript
复制
ORDER,Type,Date,Price,Size,Commission
DATA,Action,Date,Price,PctDown
DATA,OPEN,1990-01-09,349.62,-0.0117866530993
ORDER,BUY,1990-01-09,349.62,572,0.0
...
DATA,CLOSE,1990-01-11,348.53,nan
ORDER,BUY,2016-09-09,2127.81,336,0.0
DATA,CLOSE,2016-09-13,2127.02,nan
ORDER,SELL,2016-09-13,2127.02,-336,0.0
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2016
  • BTFD - 现实的打击
    • 验证
      • 现实的打击
        • 目标 99.8% - 佣金 0.1%
        • 目标 99.9% - 佣金 0.05%
        • 目标 99.95% - 佣金 0.025%
      • 结论
        • 示例用法
          • 示例代码
          • BTFD(买入垃圾… Dip)
            • 结论
              • 样本用法
                • 样本代码
                  • 操作日志
                    • CloseClose方法
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档