Backtrader智慧質押

  |  

版本 1.6.4.93 標誌著 backtrader 的一個重要里程碑,即使版本號的更改很小。

職位大小調整是閱讀Van K. Tharp的《Trade Your Way To Financial Freedom 》後,為這個專案奠定基礎的事情之一。

這不是Van K. Tharp詳細介紹他的職位調整方法的書,而是在書中提出和討論的主題。關於這一點的範例之一具有此設置

  • 如果不在市場上,扔硬幣決定是否進入

  • 如果已經在市場上,則使用止損控制倉位,止損為2 x ATR,如果價格有利地移動到所持倉位,則該止損會更新

關於這一點的重要部分:

  • 進入市場是隨機的

  • 該方法使用不同的Size方案進行測試,這與動態停止一起使系統有利可圖

遵循建立自己的“系統”(手動/自動/計算機化,技術/基礎化等)的原則, backtrader 誕生是為了有朝一日測試這種情況。

這可以在任何現有的平臺上進行測試,但在此過程中不會有任何樂趣,並且解決了許多挑戰,在啟動時甚至沒有考慮這些挑戰 backtrader

Sizers 從一開始就在平臺上,但由於包括即時交易在內的許多其他事情開始成為障礙,因此隱藏了。但這現在已經結束了,Van K. Tharp的情景將受到考驗。而不是遲早。

與此同時, Sizers 進行樣品測試。

控制定位的Sizers

該示例顯示了一個潛在的用例,在該用例中, Sizers 通過控制大小來更改策略的行為。請查看 backtrader.readthedocs.io 上的文檔,瞭解大小調整介面。

2 sizers

  • LongOnly:如果當前倉位為0,將返回固定大小倉位,如果已經在市場上,將返回相同的固定大小以 close 它。

    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:如果不在市場上,將返回固定大小的股份,如果已經在市場上,將返回兩倍的固定規模的股份,以允許逆轉

    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
    

這2 Sizers 將與一個非常簡單的策略相結合。

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

請注意該策略如何使用 Close-SMA 交叉信號來發出買入和賣出命令,並考慮一件重要的事情:

  • 策略中不執行定位檢查

與以下執行中所示的策略相同,只需使用示例中的此代碼更改 sizer (使用開關--longonly控制),即可將行為從僅做多更改為多短

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

僅長期執行

使用以下命令完成:

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

還有這個輸出。

多空執行

使用以下命令完成:

$ ./sizertest.py --plot

還有這個輸出。

哪個立即顯示:

  • 交易數量翻了一番

  • 現金(除了開始時)永遠不會等於價值,因為策略總是在市場上

示例用法

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

推薦閱讀

相關文章

Backtrader按日線交易

似乎在世界某個地方有一種权益(Interest)可以總結如下: 使用每日柱線引入訂單,但使用開盤價 這來自工單#105订单执行逻辑与当前数据和#101动态投注计算中的對話 backtrader 嘗試盡可能保持現實,並且在處理每日柱線時適用以下前提: 當每日柱被評估時,柱線已經結束 這是有道理的,

Backtrader期貨補償與現貨補償

版本1.9.32.116 增加了對社區中呈現的有趣用例 的支援 以期貨開始交易,包括實物交割 讓一個指標告訴你一些事情 如果需要, close 現貨價格操作,有效地取消實物交割,無論是為了接收貨物還是為了必須交付貨物(並希望獲利)來頭寸。

Backtrader教程:操作平臺

Line 反覆運算器 為了參與操作,plaftorm使用 line 反覆運算器的概念。它們已經鬆散地模仿了Python的反覆運算器,但實際上與它們無關。 策略和指標是 line 反覆運算器。

Backtrader教程:數據饋送 - 擴展 (Extending DataFeed)

GitHub 中的問題實際上是在推動文檔部分的完成,或者説明我瞭解我是否backtrader 具有我從一開始就設想的易用性和靈活性以及在此過程中做出的決定。 在本例中為問題 #9。

Backtrader教程:數據饋送 - 展期交割

並非每個供應商都為可以交易的工具提供連續的未來。有時提供的數據是仍然有效的到期日期的數據,即:仍在交易的日期 這在回溯測試方面並不是很有幫助,因為數據分散在幾個不同的儀器上,這些儀器另外...時間重疊。 能夠正確地將這些儀器的數據從過去連接到連續的流中,可以減輕疼痛。

Backtrader數據多時間幀

有時投資決策是使用不同的時間框架做出的: 每周評估趨勢 每天執行條目 或者5分鐘對60分鐘。 這意味著需要將多個時間幀的數據組合在 backtrader 中以支援此類組合。 對它的本機支持已經內置。

Backtrader智慧質押

版本 1.6.4.93 標誌著 backtrader 的一個重要里程碑,即使版本號的更改很小。 職位大小調整是閱讀Van K. Tharp的《Trade Your Way To Financial Freedom 》後,為這個專案奠定基礎的事情之一。

Backtrader多數據範例

社區中的幾個主題似乎以如何跟蹤訂單為導向,特別是當幾個data feeds在起作用時,還包括當多個訂單一起工作時,

Backtrader教程:數據饋送 - 熊貓

注意 pandas 並且必須安裝其依賴項 支援Pandas Dataframes似乎受到很多人的關注,他們依賴於已經可用的解析代碼來分析不同的數據源(包括CSV)和Pandas提供的其他功能。 數據饋送的重要聲明。 注意 這些只是 聲明。不要盲目複製此代碼。

Backtrader信貸利息

在某些情況下,真實經紀人的現金金額可能會減少,因為資產操作包括利率。例子: 賣空股票 交易所買賣基金包括多頭和空頭 這意味著不僅交易構成了系統的盈利能力,因為信貸上的利息在帳戶上佔有一席之地。 為了涵蓋這種情況, backtrader 包括(從發佈1.8.8.96開始)功能來考慮這一點。