- 智慧質押
策略提供了交易方法,即:buy和 sell close。讓我們看看簽名 buy:
def buy(self, data=None,
size=None, price=None, plimit=None,
exectype=None, valid=None, tradeid=0, **kwargs):
請注意,size 如果調用方未指定預設值,則具有預設值 None 。這是 Sizers 發揮重要作用的地方:
size=None要求「戰略」詢問其實際賭注的Sizer
這顯然意味著策略有一個 Sizer:是的,確實如此!後台機制將預設 sizer 添加到策略中,如果使用者尚未添加一個。添加到策略的預設 Sizer 為SizerFix。定義的初始 lines :
class SizerFix(SizerBase):
params = (('stake', 1),)
很容易猜到,這個Sizer只是使用一個stake1單位(無論是股票,合約等)購買/出售。
使用 Sizers
從 Cerebro
Sizers 可以通過2種不同的方法通過 Cerebro 添加:
-
addsizer(sizercls, *args, **kwargs)添加一個 Sizer ,該將應用於添加到 cerebro的任何策略。可以說,這是預設 Sizer。例:
cerebro = bt.Cerebro() cerebro.addsizer(bt.sizers.SizerFix, stake=20) # default sizer for strategies
-
addsizer_byidx(idx, sizercls, *args, **kwargs)Sizer將僅添加到
idx這可以
idx作為返回值從addstrategy獲取。如:cerebro = bt.Cerebro() cerebro.addsizer(bt.sizers.SizerFix, stake=20) # default sizer for strategies idx = cerebro.addstrategy(MyStrategy, myparam=myvalue) cerebro.addsizer_byidx(idx, bt.sizers.SizerFix, stake=5) cerebro.addstrategy(MyOtherStrategy)
在這裡範例中:
-
默認 Sizer 已添加到系統中。這適用於沒有分配特定 Sizer 的所有策略
-
對於 MyStrategy,在收集其插入 idx 後,將添加特定的 sizer (更改
stake參數) -
第二個策略MyOtherStrategy被添加到系統中。沒有為其新增特定的Sizer
-
這意味著:
-
MyStrategy最終將有一個內部特定的 Sizer
-
MyOtherStrategy將獲得預設 sizer
-
-
注意
默認並不意味著策略共用單個Sizer實例。每個策略接收預設sizer的不同實例
若要共用單個實例,要共用 sizer 應為單例類。如何定義一個超出了 backtrader
從戰略
策略類提供了一個 API:setsizer 和(和 getsizer 一個屬性 sizer)來管理 Sizer。簽章:
-
def setsizer(self, sizer):它需要一個已經實例化的 Sizer -
def getsizer(self):返回當前 Sizer 實例 -
sizer它是可以直接獲取/設置的屬性
在這種情況下, Sizer 可以是例如:
-
作為參數傳遞給策略
-
在使用屬性
sizer時__init__進行設置,或setsizer如:class MyStrategy(bt.Strategy): params = (('sizer', None),) def __init__(self): if self.p.sizer is not None: self.sizer = self.p.sizer例如,這將允許在cerebro調用發生的同一級別創建Sizer,並將其作為參數傳遞給系統中的所有策略,從而有效地允許共用Sizer
Sizer 開發
這很容易:
-
子類從
backtrader.Sizer這使您可以訪問
self.strategy並且self.broker在大多數情況下不需要它。可以使用broker-
數據的位置
self.strategy.getposition(data) -
完整的投資組合價值通過以下方式
self.broker.getvalue()請注意,這當然也可以通過以下方式完成
self.strategy.broker.getvalue()
其他一些事情已經在下面作為論據
-
-
重寫方法
_getsizing(self, comminfo, cash, data, isbuy)-
comminfo:傭金信息實例,包含有關數據傭金的資訊,並允許計算位置值,運營成本,操作傭金 -
cash:經紀人的當前可用現金 -
data:操作的目標 -
isbuy:將True用於買入操作和False賣出操作
此方法返回
size買入/賣出操作所需的值返回的符號不相關,即:如果操作是賣出操作(
isbuy將是False),則方法可能返回5或-5。賣出操作將僅使用絕對值。Sizer已經轉到broker並要求委員會提供給定數據,實際現金水準的資訊,並提供對作為操作目標的數據的直接參考 -
讓我們來看看sizer的定義FixedSize:
import backtrader as bt
class FixedSize(bt.Sizer):
params = (('stake', 1),)
def _getsizing(self, comminfo, cash, data, isbuy):
return self.params.stake
這很簡單,因為 Sizer 不進行計算,參數就在那裡。
但該機制應該允許構建複雜的尺寸(又名定位)系統,以管理進入/退出市場時的賭注。
另一個例子:位置反轉器:
class FixedRerverser(bt.FixedSize):
def _getsizing(self, comminfo, cash, data, isbuy):
position = self.broker.getposition(data)
size = self.p.stake * (1 + (position.size != 0))
return size
這個建立在現有FixedSize 的基礎上,繼承 params 並覆蓋 _getsizing :
-
position通過屬性獲取數據broker -
用於
position.size決定是否將固定賭注翻倍 -
返回計算值
這將消除《戰略》的負擔,即決定是否必須逆轉或開倉, Sizer 處於控制之中,可以隨時更換而不影響邏輯。
實用 Sizer 適用性
考慮到複雜的大小調整演算法,可以使用兩種不同的sizers將策略從僅做多轉換為多空。只需改變cerebro執行中的Sizer,策略就會改變行為。一個非常簡單的close交叉SMA演算法:
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()
請注意,該策略如何不考慮當前頭寸(通過查看self.position)來決定是否必須實際完成買入或賣出。僅考慮來自的 CrossOver 信號。 Sizers 將負責一切。
此 sizer 將負責在賣出時僅返回非零大小,如果倉位已經 open:
class LongOnly(bt.Sizer):
params = (('stake', 1),)
def _getsizing(self, comminfo, cash, data, isbuy):
if isbuy:
return self.p.stake
# Sell situation
position = self.broker.getposition(data)
if not position.size:
return 0 # do not sell if nothing is open
return self.p.stake
將它們放在一起(並假設已經導入 backtrader 並且數據已添加到系統中):
... cerebro.addstrategy(CloseSMA) cerebro.addsizer(LongOnly) ... cerebro.run() ...
圖表(從源中包含的範例中對此進行測試)。
長短版本只是將SizerFixedReverser更改為如上所示:
... cerebro.addstrategy(CloseSMA) cerebro.addsizer(FixedReverser) ... cerebro.run() ...
輸出圖表。
請注意差異:
-
重複的交易數量
-
現金水平永遠不會回到價值,因為策略總是在市場上
這兩種方法都是負面的,但這只是一個例子。
Sizer 參考
backtrader類 .Sizer()
這是 Sizers的基類。任何 sizer 都應對此進行子類化並重寫該_getsizing 方法
成員單位:
-
strategy:將由 sizer 正在工作的策略設定允許訪問策略的整個 API,例如,如果需要以下位置
_getsizing的實際數據位置:position = self.strategy.getposition(data)
-
broker:將由 sizer 正在工作的策略設定提供對資訊的訪問,一些複雜的 sizers 可能需要,如投資組合價值,..
_getsizing(通信資訊、現金、數據、購買)
此方法必須由 Sizer 的子類覆蓋,以提供大小調整功能
參數:
* `comminfo`: The CommissionInfo instance that contains information about the commission for the data and allows calculation of position value, operation cost, commision for the operation * `cash`: current available cash in the *broker* * `data`: target of the operation * `isbuy`: will be `True` for *buy* operations and `False` for *sell* operations
該方法必須返回要執行的實際大小(整型)。如果0 返回,則不會執行任何內容。
將使用返回值的絕對值