在 1.5.0 版之前, backtrader 使用直接的方法來進行時間管理,因為數據源計算的任何日期時間都只是按面值使用。
對於任何使用者輸入也是如此,例如可以提供給任何數據源的參數fromdate
(或 sessionstart
)的情況
考慮到直接控制凍結的數據源以進行回溯測試,這種方法很好。很容易假設輸入日期時間在進入系統之前已經得到處理。
但是在 1.5.0 中,支持實時 數據源,這強制考慮 日期時間管理。如果始終 true以下情況,則不需要進行此類管理:
-
紐約的一位交易者交易ES-Mini。(或其中一個別名)的
US/Eastern
時區 -
柏林的一位交易者交易DAX期貨。在這種情況下,
CET
對於兩個(或Europe/Berling
)時區都適用
上面的直接輸入輸出日期時間方法將起作用,例如,在柏林的交易者總是可以做這樣的事情:
class Strategy(bt.Strategy): def next(self): # The DAX future opens at 08:00 CET if self.data.datetime.time() < datetime.time(8, 30): # don't operate until the market has been running 30 minutes return #
當柏林的同一交易者決定進行交易時,直接接近的問題就浮出水面了ES-Mini
。因為從 DST 更改為 DST 發生在一年中的不同時間點,這會導致時差在一年中的幾個星期內不同步。以下方法並不總是有效:
class Strategy(bt.Strategy): def next(self): # The SPX opens at 09:30 US/Eastern all year long # This is most of the year 15:30 CET # But it is sometimes 16:30 CET or 14:30 CET if a DST switch on-off # has happened in the USA and not in Europe # That's why the code below is unreliable if self.data.datetime.time() < datetime.time(16, 0): # don't operate until the market has been running 30 minutes return #
使用時區進行操作
為了解決上述情況,同時仍與直接輸入輸出時間方法相容,backtrader
為最終使用者提供以下功能
-
默認情況下,平臺不會觸及數據源提供的日期時間
-
最終使用者可以透過以下方式覆寫此輸入:
-
向數據源提供
tzinput
參數。這必須是與介面相容的物件datetime.tzinfo
。最有可能的是,使用者將提供一個pytz.timezone
實例
有了這個決定,內部
backtrader
使用的時間被認為是格式的UTC-like
,即:-
如果數據源已將其
UTC
格式存儲 -
轉換後通過
tzinput
-
它不是真的
UTC
,但它是用戶的參考,因此UTC-like
-
-
如果 data feed 可以自動確定輸出的時區,這將是預設值
這在即時饋送的情況下是有意義的,特別是在像柏林(
CET
時區)的交易者使用US/Eastern
時區交易產品這樣的用例中。因為交易者總是得到正確的時間,在上面的例子中,開盤時間保持不變
09:30 US/Eastern
,而不是15:30 CET
一年中的大部分時間都,但有時16:30 CET
和有時14:30 CET
。 -
如果無法確定,則輸出將是輸入(該)時間內確定的任何內容。
UTC-like
-
最終使用者可以覆蓋和確定輸出的實際時區
- 向數據源提供
tz
參數。這必須是與介面相容的物件datetime.tzinfo
。最有可能的是,使用者將提供一個pytz.timezone
實例
- 向數據源提供
注意
使用者輸入的參數fromdate
或 sessionstart
期望與實際 tz
參數同步,由數據源自動計算,由使用者提供或保留為預設值(None
這意味著日期時間的直接輸入輸出)
考慮到所有這些,讓我們回想一下柏林交易者,交易:US/Eastern
import pytz import bt data = bt.feeds.MyFeed('ES-Mini', tz=pytz.timezone('US/Eastern')) class Strategy(bt.Strategy): def next(self): # This will work all year round. # The data source will return in the frame of the 'US/Eastern' time # zone and the user is quoting '10:00' as reference time # Because in the 'US/Eastern' timezone the SPX index always starts # trading at 09:30, this will always work if self.data.datetime.time() < datetime.time(10, 0): # don't operate until the market has been running 30 minutes return #
對於可以自動確定輸出時區的數據來源:
import bt data = bt.feeds.MyFeedAutoTZ('ES-Mini') class Strategy(bt.Strategy): def next(self): # This will work all year round. # The data source will return in the frame of the 'US/Eastern' time # zone and the user is quoting '10:00' as reference time # Because in the 'US/Eastern' timezone the SPX index always starts # trading at 09:30, this will always work if self.data.datetime.time() < datetime.time(10, 0): # don't operate until the market has been running 30 minutes return #
甚至比上面更少的工作。
顯然MyFeed
, MyFeedAuto
在上面的例子中只是虛擬的名字。
注意
在撰寫本文時,分配中包含的唯一可以自動確定時區的數據源是連接到盈透證券的數據源