1.3.0.92版本帶來了混合來自不同時間幀的數據(來自 data feeds 和/或指標)的可能性。
到版本:https://github.com/mementum/backtrader/發佈/標籤/1.3.0.92
背景:指示器是智慧啞物件。
-
他們很聰明,因為他們可以進行複雜的計算。
-
他們是愚蠢的,因為他們不知道哪些來源為計算提供數據。
因此:
- 如果提供這些值的數據源具有不同的時間幀,引擎內部
Cerebro
的長度也不同,則指標將中斷。
計算範例,其中data0
的時間範圍為天, data1
時間範圍為 months
:
pivotpoint = btind.PivotPoint(self.data1) sellsignal = self.data0.close < pivotpoint.s1
這裡,當close低於s1
line(1st支撐位)時,尋求賣出信號
注意
PivotPoint
根據定義,在更大的時間範圍內工作
這將在過去出現以下錯誤:
return self.array[self.idx + ago] IndexError: array index out of range
並且有充分的理由:self.data.close
從第1個瞬間開始提供值,但是PivotPoint
(因此s1
line)只會在整整一個月過去一次時才提供值,這大致相當於22個值self.data0.close
。在此 22 關閉期間,尚無 值s1
,並且嘗試從基礎陣列中獲取它失敗。
Lines 物件支援()
運算符(__call__
Python中的特殊方法)來提供自身的延遲版本:
close1 = self.data.close(-1)
在此示例中,物件close1
(噹通過 [0]
訪問時)始終包含 由 close
傳遞的先前值 (-1
)。該語法已被重用以適應適應時間範圍。讓我們重寫上面的pivotpoint
片段:
pivotpoint = btind.PivotPoint(self.data1) sellsignal = self.data0.close < pivotpoint.s1()
()
瞭解如何在沒有參數的情況下執行 (在後台提供 aNone
)。正在發生以下情況:
pivotpoint.s1()
返回一個內部 LinesCoupler
物件,該物件遵循較大範圍的嚴格程度。該耦合器用實數 s1
中最新傳遞的值填充自身(從預設值 NaN
開始)
但是需要一些額外的東西來使魔術起作用。Cerebro
必須使用以下命令建立:
cerebro = bt.Cerebro(runonce=False)
或通過以下方式執行:
cerebro.run(runonce=False)
在此模式下,指標和後期評估的自動 lines 物件是逐步執行的,而不是在緊密迴圈中執行的。這使得整個操作變慢,但它使它成為可能
底部的示例腳本正在上面斷開,現在運行:
$ ./mixing-timeframes.py
帶輸出:
0021,0021,0001,2005-01-31,2984.75,2935.96,0.00 0022,0022,0001,2005-02-01,3008.85,2935.96,0.00 ... 0073,0073,0003,2005-04-15,3013.89,3010.76,0.00 0074,0074,0003,2005-04-18,2947.79,3010.76,1.00 ...
在交易 74 時,第 1 個 實例 close < s1
的 take palce。
該腳本還提供了對其他可能性的見解:耦合指標的所有 lines 。在我們之前:
self.sellsignal = self.data0.close < pp.s1()
作為替代方案:
pp1 = pp() self.sellsignal = self.data0.close < pp1.s1
現在整個PivotPoint
指標已經耦合,並且可以訪問其任何lines(即p
, , r1
, r2
s1
, ) s2
。該腳本只對以下內容感興趣s1
,並且訪問是直接的:
$ ./mixing-timeframes.py --multi
輸出:
0021,0021,0001,2005-01-31,2984.75,2935.96,0.00 0022,0022,0001,2005-02-01,3008.85,2935.96,0.00 ... 0073,0073,0003,2005-04-15,3013.89,3010.76,0.00 0074,0074,0003,2005-04-18,2947.79,3010.76,1.00 ...
這裡沒有驚喜。和以前一樣。甚至可以繪製「耦合」物件:
$ ./mixing-timeframes.py --multi --plot
完整耦合語法
對於具有多個lineslines物件(例如,指標如下PivotPoint
):
-
obj(clockref=None, line=-1)
clockref
如果clockref
是None
,則周圍的物件(在示例aStrategy
中)將是使較大的時間幀(例如:Months
)適應更小/更快的時間幀(例如:Days
)的引用
如果需要,可以使用其他引用
line
- If the default `-1` is given, all *lines* are coupled. - If another integer (for example, `0` or `1`) a single line will be coupled and fetched by index (from `obj.lines[x]`) - If a string is passed, the line will be fetched by name. In the sample the following could have been done: ``` coupled_s1 = pp(line='s1') ```
對於具有單個line的lines物件(例如,指標中的PivotPoint
lines1
):
obj(clockref=None)
(見上文clockref
)
結論
集成在常規()
語法中,來自不同時間幀的數據可以混合在指標中,同時始終考慮 cerebro
需要使用 runonce=False
實例化或創建的數據。
腳本代碼和用法
可作為樣品在源。backtrader
用法:
$ ./mixing-timeframes.py --help usage: mixing-timeframes.py [-h] [--data DATA] [--multi] [--plot] Sample for pivot point and cross plotting optional arguments: -h, --help show this help message and exit --data DATA Data to be read in (default: ../../datas/2005-2006-day-001.txt) --multi Couple all lines of the indicator (default: False) --plot Plot the result (default: False)
代碼:
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind import backtrader.utils.flushfile class St(bt.Strategy): params = dict(multi=True) def __init__(self): self.pp = pp = btind.PivotPoint(self.data1) pp.plotinfo.plot = False # deactivate plotting if self.p.multi: pp1 = pp() # couple the entire indicators self.sellsignal = self.data0.close < pp1.s1 else: self.sellsignal = self.data0.close < pp.s1() def next(self): txt = ','.join( ['%04d' % len(self), '%04d' % len(self.data0), '%04d' % len(self.data1), self.data.datetime.date(0).isoformat(), '%.2f' % self.data0.close[0], '%.2f' % self.pp.s1[0], '%.2f' % self.sellsignal[0]]) print(txt) def runstrat(): args = parse_args() cerebro = bt.Cerebro() data = btfeeds.BacktraderCSVData(dataname=args.data) cerebro.adddata(data) cerebro.resampledata(data, timeframe=bt.TimeFrame.Months) cerebro.addstrategy(St, multi=args.multi) cerebro.run(stdstats=False, runonce=False) if args.plot: cerebro.plot(style='bar') def parse_args(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Sample for pivot point and cross plotting') parser.add_argument('--data', required=False, default='../../datas/2005-2006-day-001.txt', help='Data to be read in') parser.add_argument('--multi', required=False, action='store_true', help='Couple all lines of the indicator') parser.add_argument('--plot', required=False, action='store_true', help=('Plot the result')) return parser.parse_args() if __name__ == '__main__': runstrat()