Backtrader規範與非規範

  |  

這個問題或多或少地出現了幾次:這樣:

  • backtrader如何最好/規範地實現這一點或那樣?

作為 backtrader 的目標之一,可以靈活地 支援盡可能多的情況和用例,答案很簡單:“至少在幾種方式上”。針對指標進行匯總,對於這些問題最常發生的情況:

  • 方法中__init__ 100% 聲明性

  • 100%逐步next 的方法

  • 對於聲明性部分無法涵蓋所有必需計算的複雜方案,混合上述兩者

快速查看 backtrader 中的內置指標可發現所有這些指標都是以聲明性方式實現的。原因

  1. 更容易做到

  2. 更易於閱讀

  3. 更優雅

  4. 自動管理矢量化和基於偶數的實現

什麼?!?!自動實現的矢量化??

是的。如果指標完全在方法內部__init_ 實現,那麼Python中元類和運算元重載的魔力將提供以下內容

  • 向量化實現(運行回溯測試時的預設設定)

  • 基於事件的實現(例如,用於即時交易)

另一方面,如果在方法中next 實現的指標的任何部分:

  • 這是直接用於基於事件的運行的代碼。

  • 矢量化將通過在每個數據點的next 後台調用方法來類比

    注意

    這意味著,即使特定指標沒有矢量化實現,所有其他擁有它的指標仍將以矢量化方式運行。

資金流量指數:一個例子

社區使用者@Rodrigo Brito 發佈了一個版本的「資金流量指數」 指標,該指標使用該 next 方法進行實施。

代碼

class MFI(bt.Indicator):
    lines = ('mfi', 'money_flow_raw', 'typical', 'money_flow_pos', 'money_flow_neg')

    plotlines = dict(
        money_flow_raw=dict(_plotskip=True),
        money_flow_pos=dict(_plotskip=True),
        money_flow_neg=dict(_plotskip=True),
        typical=dict(_plotskip=True),
    )

    params = (
        ('period', 14),
    )

    def next(self):
        typical_price = (self.data.close[0] + self.data.low[0] + self.data.high[0]) / 3
        money_flow_raw = typical_price * self.data.volume[0]

        self.lines.typical[0] = typical_price
        self.lines.money_flow_raw[0] = money_flow_raw

        self.lines.money_flow_pos[0] = money_flow_raw if self.lines.typical[0] >= self.lines.typical[-1] else 0
        self.lines.money_flow_neg[0] = money_flow_raw if self.lines.typical[0] <= self.lines.typical[-1] else 0

        pos_period = math.fsum(self.lines.money_flow_pos.get(size=self.p.period))
        neg_period = math.fsum(self.lines.money_flow_neg.get(size=self.p.period))

        if neg_period == 0:
            self.lines.mfi[0] = 100
            return

        self.lines.mfi[0] =  100 - 100 / (1 +  pos_period / neg_period)

注意

保持原樣,包括長 lines ,必須水平滾動

@Rodrigo布里托已經注意到,臨時lines的使用(除了mfilines除外)可能是承認優化的東西。確實,但以作者*的拙見,實際上一切都承認一些優化。

為了有共同的工作基礎,可以使用StockCharts的「資金流量指數」定義,並看到上面的實現是好的。這是連結:

有了這個,指標的快速規範實現MFI

class MFI_Canonical(bt.Indicator):
    lines = ('mfi',)
    params = dict(period=14)

    def __init__(self):
        tprice = (self.data.close + self.data.low + self.data.high) / 3.0
        mfraw = tprice * self.data.volume

        flowpos = bt.ind.SumN(mfraw * (tprice > tprice(-1)), period=self.p.period)
        flowneg = bt.ind.SumN(mfraw * (tprice < tprice(-1)), period=self.p.period)

        mfiratio = bt.ind.DivByZero(flowpos, flowneg, zero=100.0)
        self.l.mfi = 100.0 - 100.0 / (1.0 + mfiratio)

人們應該能夠立即注意到

  • 定義了單個 linemfi 。沒有臨時工。

  • 事情看起來更乾淨,不需要[0] 陣列索引

  • 這裡或那裡沒有單曲if

  • 更緊湊,更易讀

如果一個人繪製一個圖表,兩者都針對相同的數據集運行,它看起來像這樣

該圖表顯示,規範版本和非規範版本顯示相同的值和發展,除了在開頭

  • 非規範版本從一開始就提供價值

  • 它傳遞的是無意義的值(100.0 直到它傳遞 1 個額外的值,這也是不好的),因為它不能正確傳遞

相比之下:

  • 規範版本在達到最小預熱期 后自動開始提供值。

  • 不需要人工干預(它必須肯定是「人工智慧」或「機器學習」,...雙關語

查看受影響區域的 close圖片

注意

當然,在非規範版本中,可以通過這樣做來緩解這種情況:

  • 子類化,其中bt.ind.PeriodN已經有一個period參數,並且知道如何處理它(並在 期間__init__調用super

另請注意,規範版本也考慮了公式中可能的零除情況的分步next 代碼。

        if neg_period == 0:
            self.lines.mfi[0] = 100
            return

        self.lines.mfi[0] =  100 - 100 / (1 +  pos_period / neg_period)

而這是另一種方式

        mfiratio = bt.ind.DivByZero(flowpos, flowneg, zero=100.0)
        self.l.mfi = 100.0 - 100.0 / (1.0 + mfiratio)

沒有許多lines,一個return語句和對輸出line的不同賦值,有計算的單個聲明mfiratio和單個賦值(遵循StockCharts公式)到輸出linemfi

結論

希望這能揭示一些在以規範(即:聲明性__init_)或非規範方式(逐步與陣列索引) next實現某些內容時的差異。

推薦閱讀

相關文章

Backtrader規範與非規範

這個問題或多或少地出現了幾次:這樣: backtrader如何最好/規範地實現這一點或那樣? 作為 backtrader 的目標之一,可以靈活地 支援盡可能多的情況和用例,答案很簡單:“至少在幾種方式上”。

Backtrader教程:安裝

要求和版本 backtrader 是獨立的,沒有外部依賴關係(除非要繪圖) 基本要求是: Python 2.7 Python 3.2 / 3.3/ 3.4 / 3.5 pypy/pypy3 如果需要繪圖,則其他要求: Matplotlib >= 1.4.

Backtrader期貨補償與現貨補償

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

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

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

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

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

Backtrader教程:過濾器 - 參考

工作階段篩檢程式 類 backtrader.filters。

Backtrader數據多時間幀

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

Backtrader開場作弊

“發佈”1.9.44.116 添加了對 Cheat-On-Open的支援。這似乎是那些全力以赴的人的需求功能,他們在酒吧 close 后進行了計算,但希望與 open 價格相匹配。 當開盤價跳空(上漲或下跌,取決於是否buysell有效)並且現金不足以進行全面運營時,這樣的用例就會失敗。這將強制代理拒絕該操作。

Backtrader教程:數據饋送 - 熊貓

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

Backtrader教程:指標 - ta-lib

即使 backtrader 提供了已經 high 數量的內置指標,並且開發指標主要是定義輸入,輸出和以自然的方式編寫公式的問題,有些人也希望使用TA-LIB。