Backtrader逃離 OHLC 土地

  |  

backtrader的概念和開發過程中應用的關鍵概念之一是靈活性。 Python 的元編程和自省功能曾經是(現在仍然是)保持許多東西靈活同時仍然能夠交付的基礎。

一篇舊帖子顯示了擴展概念。

基礎知識:

from backtrader.feeds import GenericCSVData

class GenericCSV_PE(GenericCSVData):
    lines = ('pe',)  # Add 'pe' to already defined lines

完畢。 backtrader在後台定義了最常用的:OHLC。

如果我們深入研究GenericCSV_PE的最後一個方面,繼承的加上新定義的的總和將產生以下

('close', 'open', 'high', 'low', 'volume', 'openinterest', 'datetime', 'pe',)

這可以隨時使用getlinealiases方法檢查(適用於 DataFeeds、Indicators、Strategies 和Observers

該機制是靈活的,通過深入了解內部結構,您實際上可以獲得任何東西,但事實證明這還不夠。

Ticket #60詢問是否支持高頻數據,即:Bid/Ask 數據。這意味著 OHLC 形式的預定義層次結構是不夠的。買入價和賣出價、交易量和交易數量可以根據現有的 OHLC 字段進行調整,但感覺不自然。如果只關心買價和賣價,就會有太多的領域沒有觸及。

這需要一個已與Release 1.2.1.88一起實施的解決方案。這個想法可以概括為:

  • 現在不僅可以擴展現有的層次結構,還可以用新的層次結構替換層次結構

只有一個約束:

  • 必須存在一個datetime時間字段(希望包含有意義的datetime時間信息)

    之所以如此,是因為backtrader需要一些東西來進行同步(多個數據、多個時間框架、重新採樣、重放),就像阿基米德需要槓桿一樣。

這是它的工作原理:

from backtrader.feeds import GenericCSVData

class GenericCSV_BidAsk(GenericCSVData):
    linesoverride = True
    lines = ('bid', 'ask', 'datetime')  # Replace hierarchy with this one

完畢。

好吧,不完全。但這僅僅是因為我們正在考慮從 csv 源加載。由於linesoverride= True設置,層次結構實際上已經被出價替換,詢問日期時間定義。

原始的GenericCSVData類解析 csv 文件並需要提示與對應的字段所在的位置。原來的定義是:

class GenericCSVData(feed.CSVDataBase):
    params = (
        ('nullvalue', float('NaN')),
        ('dtformat', '%Y-%m-%d %H:%M:%S'),
        ('tmformat', '%H:%M:%S'),

        ('datetime', 0),
        ('time', -1),  # -1 means not present
        ('open', 1),
        ('high', 2),
        ('low', 3),
        ('close', 4),
        ('volume', 5),
        ('openinterest', 6),
    )

輕觸即可完成新的層次結構重新定義類:

from backtrader.feeds import GenericCSVData

class GenericCSV_BidAsk(GenericCSVData):
    linesoverride = True
    lines = ('bid', 'ask', 'datetime')  # Replace hierarchy with this one

    params = (('bid', 1), ('ask', 2))

表明買價是 csv 流中的第 1 字段,而賣價是第 2 字段。我們沒有改變基類中的 datetime #0 定義。

為這種場合製作一個小數據文件有助於:

TIMESTAMP,BID,ASK
02/03/2010 16:53:50,0.5346,0.5347
02/03/2010 16:53:51,0.5343,0.5347
02/03/2010 16:53:52,0.5543,0.5545
02/03/2010 16:53:53,0.5342,0.5344
02/03/2010 16:53:54,0.5245,0.5464
02/03/2010 16:53:54,0.5460,0.5470
02/03/2010 16:53:56,0.5824,0.5826
02/03/2010 16:53:57,0.5371,0.5374
02/03/2010 16:53:58,0.5793,0.5794
02/03/2010 16:53:59,0.5684,0.5688

在方程中添加一個小測試腳本(為那些直接訪問源代碼中的示例的人提供更多內容)(參見最後的完整代碼):

$ ./bidask.py

輸出不言自明:

 1: 2010-02-03T16:53:50 - Bid 0.5346 - 0.5347 Ask
 2: 2010-02-03T16:53:51 - Bid 0.5343 - 0.5347 Ask
 3: 2010-02-03T16:53:52 - Bid 0.5543 - 0.5545 Ask
 4: 2010-02-03T16:53:53 - Bid 0.5342 - 0.5344 Ask
 5: 2010-02-03T16:53:54 - Bid 0.5245 - 0.5464 Ask
 6: 2010-02-03T16:53:54 - Bid 0.5460 - 0.5470 Ask
 7: 2010-02-03T16:53:56 - Bid 0.5824 - 0.5826 Ask
 8: 2010-02-03T16:53:57 - Bid 0.5371 - 0.5374 Ask
 9: 2010-02-03T16:53:58 - Bid 0.5793 - 0.5794 Ask
10: 2010-02-03T16:53:59 - Bid 0.5684 - 0.5688 Ask

瞧!買入/賣出價格已被正確讀取、解析和解釋,並且該策略已經能夠通過 self.data 訪問數據饋送中的 .bid 和 .ask

不過,重新定義線條層次結構會引發一個廣泛的問題,那就是已經預定義的指標的使用。

  • 示例:隨機指標是一個依靠收盤價、最高價和最低價來計算其輸出的指標

    即使我們將 Bid 作為收盤價(因為是第一個),也只有一個其他價格元素(Ask)而不是另外兩個。從概念上講,Ask 與高低無關

    從事這些領域工作並在高頻交易領域進行操作(或研究)的人很可能並不關心隨機指標作為選擇指標

  • 移動平均線等其他指標非常好。他們對這些領域的含義或暗示沒有任何假設,並且很樂意接受任何東西。因此可以這樣做:

    mysma = backtrader.indicators.SMA(self.data.bid, period=5)
    

    最後5 個投標價格的移動平均線將被交付

測試腳本已經支持添加 SMA。讓我們執行:

$ ./bidask.py --sma --period=3

輸出:

 3: 2010-02-03T16:53:52 - Bid 0.5543 - 0.5545 Ask - SMA: 0.5411
 4: 2010-02-03T16:53:53 - Bid 0.5342 - 0.5344 Ask - SMA: 0.5409
 5: 2010-02-03T16:53:54 - Bid 0.5245 - 0.5464 Ask - SMA: 0.5377
 6: 2010-02-03T16:53:54 - Bid 0.5460 - 0.5470 Ask - SMA: 0.5349
 7: 2010-02-03T16:53:56 - Bid 0.5824 - 0.5826 Ask - SMA: 0.5510
 8: 2010-02-03T16:53:57 - Bid 0.5371 - 0.5374 Ask - SMA: 0.5552
 9: 2010-02-03T16:53:58 - Bid 0.5793 - 0.5794 Ask - SMA: 0.5663
10: 2010-02-03T16:53:59 - Bid 0.5684 - 0.5688 Ask - SMA: 0.5616

筆記

繪圖仍然依賴於數據饋送中存在的openhigh價、 lowclosevolume

某些情況可以通過簡單地在關閉時繪製一條並僅採用對像中定義的第一條線來直接覆蓋。但是必須開發一個健全的模型。對於即將發布的backtrader版本

測試腳本用法:

$ ./bidask.py --help
usage: bidask.py [-h] [--data DATA] [--dtformat DTFORMAT] [--sma]
                 [--period PERIOD]

Bid/Ask Line Hierarchy

optional arguments:
  -h, --help            show this help message and exit
  --data DATA, -d DATA  data to add to the system (default:
                        ../../datas/bidask.csv)
  --dtformat DTFORMAT, -dt DTFORMAT
                        Format of datetime in input (default: %m/%d/%Y
                        %H:%M:%S)
  --sma, -s             Add an SMA to the mix (default: False)
  --period PERIOD, -p PERIOD
                        Period for the sma (default: 5)

以及測試腳本本身(包含在backtrader資源中)

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


class BidAskCSV(btfeeds.GenericCSVData):
    linesoverride = True  # discard usual OHLC structure
    # datetime must be present and last
    lines = ('bid', 'ask', 'datetime')
    # datetime (always 1st) and then the desired order for
    params = (
        # (datetime, 0), # inherited from parent class
        ('bid', 1),  # default field pos 1
        ('ask', 2),  # default field pos 2
    )


class St(bt.Strategy):
    params = (('sma', False), ('period', 3))

    def __init__(self):
        if self.p.sma:
            self.sma = btind.SMA(self.data, period=self.p.period)

    def next(self):
        dtstr = self.data.datetime.datetime().isoformat()
        txt = '%4d: %s - Bid %.4f - %.4f Ask' % (
            (len(self), dtstr, self.data.bid[0], self.data.ask[0]))

        if self.p.sma:
            txt += ' - SMA: %.4f' % self.sma[0]
        print(txt)


def parse_args():
    parser = argparse.ArgumentParser(
        description='Bid/Ask Line Hierarchy',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )

    parser.add_argument('--data', '-d', action='store',
                        required=False, default='../../datas/bidask.csv',
                        help='data to add to the system')

    parser.add_argument('--dtformat', '-dt',
                        required=False, default='%m/%d/%Y %H:%M:%S',
                        help='Format of datetime in input')

    parser.add_argument('--sma', '-s', action='store_true',
                        required=False,
                        help='Add an SMA to the mix')

    parser.add_argument('--period', '-p', action='store',
                        required=False, default=5, type=int,
                        help='Period for the sma')

    return parser.parse_args()


def runstrategy():
    args = parse_args()

    cerebro = bt.Cerebro()  # Create a cerebro

    data = BidAskCSV(dataname=args.data, dtformat=args.dtformat)
    cerebro.adddata(data)  # Add the 1st data to cerebro
    # Add the strategy to cerebro
    cerebro.addstrategy(St, sma=args.sma, period=args.period)
    cerebro.run()


if __name__ == '__main__':
    runstrategy()

推薦閱讀

相關文章

Backtrader按日線交易

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

Backtrader寫下來

隨著 1.1.7.88 版本的發布, backtrader有了一個新的補充:作家這可能早就到期了,應該已經存在了,問題 #14中的討論也應該已經開始了開發。但遲到總比沒有好。

Backtrader同步不同市場

使用次數越多, backtrader 必須面對的想法和意外場景的混合就越多。對於每個新平臺,一個挑戰是要看看平臺是否能夠達到開發開始時設定的期望,靈活性和易用性是目標,Python被選為基石。 工單#76 提出了一個問題,即是否可以完成具有不同交易日曆的同步市場。

Backtrader教程:過濾器 - 參考

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

Backtrader跨越數位

《backtrader》的發佈1.9.27.105糾正了一個疏忽。這是一個疏忽,因為拼圖的所有部分都已到位,但啟動並不是在所有角落都進行的。 該機制使用一個名為的屬性_mindatas,因此讓我們將其稱為: mindatas。 社區問了這個問題,答案並不是很到位。

Backtrader教程:日期時間 - 管理

在 1.5.0 版之前, backtrader 使用直接的方法來進行時間管理,因為數據源計算的任何日期時間都只是按面值使用。 對於任何使用者輸入也是如此,例如可以提供給任何數據源的參數fromdate (或 sessionstart)的情況 考慮到直接控制凍結的數據源以進行回溯測試,這種方法很好。

Backtrader教程:經紀商

經紀商模擬器該類比支援不同的訂單類型,根據當前現金檢查提交的訂單現金需求,跟蹤每次反覆運算的cerebro 現金和價值,並在不同數據上保持當前位置。

Backtrader卡爾曼等

注意 對以下指令的支援從提交開始 發佈1.9.30.x 將是包含它的第1個版本 。 backtrader的原始目標之一是成為純python,即:僅使用標準發行版中可用的軟體包。只有一個例外是matplotlib在沒有重新發明輪子的情況下進行繪圖。

Backtrader信號策略

操作 backtrader 也是可能的,而無需編寫策略。雖然這是首選方式,但由於構成機器的對象層次結構,使用信號也是可能的。

Backtrader開發指標

經過 backtrader 微調(因為它已經運行了一段時間),我決定不僅通過GitHub分享它,還告訴世界它在那裡,並在“Reddit”中發佈它的存在。 在評論了為什麼交易/演算法交易平臺會彈出,以及關於支持許多同時交易的即時交易的平臺的私人問題之後,我得出的結論是,我自己的孩子應該擁有自己的博客。 我們來了。