Backtrader中文笔记之Sizers
Sizers
Smart Staking
A Strategy offers methods to trade, namely: buy, sell and close. Let’s see the signature of buy:
策略提供了交易的方法,即:買入、賣出和成交。讓我們看看buy的簽名:
def buy(self, data=None,
size=None, price=None, plimit=None,
exectype=None, valid=None, tradeid=0, **kwargs):
Notice that size has a default value of None if the caller does not specify it. This is where Sizers play an important role:
請注意,如果調(diào)用方未指定大小,則size的默認值為None。這就是Sizers發(fā)揮重要作用的地方:
size=None requests that the Strategy asks its Sizer for the actual stake
size=None請求策略向其Sizer請求實際的股份
This obviously implies that Strategies have a Sizer: Yes, indeed!. The background machinery adds a default sizer to a Strategy if the user has not added one. The default Sizer added to a strategy is SizerFix. The initial lines of the definition:
這顯然意味著策略里面有Sizer:是的,確實如此!。如果用戶沒有添加,則后臺機制將默認的大小寫器添加到策略中。添加到策略中的默認Sizer是SizerFix。定義的初始行:
class SizerFix(SizerBase):
params = (('stake', 1),)
It is easy to guess that this Sizer simply buys/sells using a stake of 1 units (be it shares, contracts, …)
很容易猜測,這個規(guī)模的Sizer只是用1個單位的股份進行買賣(無論是股票、合同等)
Using Sizers
From Cerebro
Sizers can be added via Cerebro with 2 different methods:
Sizers有兩個不同的方法通過Cerebro添加
addsizer(sizercls, *args, **kwargs)
Adds a Sizer that will be applied to any strategy added to cerebro. This is, so to to say, the default Sizer. Example:
添加一個Sizer,它將應(yīng)用于添加到大腦的任何策略。可以說,這是默認的Sizer。例子:
cerebro = bt.Cerebro() cerebro.addsizer(bt.sizers.SizerFix, stake=20) # default sizer for strategies
addsizer_byidx(idx, sizercls, *args, **kwargs)
The Sizer will only be added to the Strategy referenced by idx
Sizer只能通過策略返回的參考idx被添加
This idx can be gotten as return value from addstrategy. As in:
這個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)
In this example:
A default Sizer has been added to the system. This one applies to all strategies which don’t have a specific Sizer assigned
系統(tǒng)中已添加了一個默認的Sizer。這一條適用于所有沒有指定特定尺寸的策略。
For MyStrategy and after collecting its insertion idx, a specific sizer (changing the stake param) is added
對于MyStrategy,在收集其插入idx之后,將添加一個特定的sizer(更改stake param)
A 2nd strategy, MyOtherStrategy, is added to the system. No specific Sizer is added for it
第二個策略,MyOtherStrategy,被添加到系統(tǒng)中。沒有為它添加特定的Sizer
This means that:
這意味著
MyStrategy will finally have an internal specific Sizer
MyStrategy最終會有一個內(nèi)部特定的Sizer
MyOtherStrategy will get the default sizer
MyOtherStrategy將獲得默認Sizer
Note
default doesn’t mean that that the strategies share a single Sizer instance. Each strategy receives a different instance of the default sizer
默認并不意味著這些策略共享一個Sizer實例。每個策略都會收到一個不同的默認sizer實例
To share a single instance, the sizer to be shared should be a singleton class. How to define one is outside of the scope of backtrader
要共享單個實例,要共享的sizer應(yīng)該是一個singleton類(單例)。如何定義一個超出了backtrader的范圍
From Strategy
The Strategy class offers an API: setsizer and getsizer (and a property sizer) to manage the Sizer. The signatures:
Strategy類提供了一個API: setzer和getsizer(以及一個屬性sizer)來管理sizer。簽名:
def setsizer(self, sizer): it takes an already instantiated Sizer
def setzer(self,sizer):它需要一個已經(jīng)實例化的sizer
def getsizer(self): returns the current Sizer instance
def getsizer(self):返回當(dāng)前的Sizer實例
sizer it is the property which can be directly get/set
sizer它是可以直接獲取/設(shè)置的屬性
In this scenario the Sizer can be for example:
在這種情況下,Sizer可以是:
Passed to the strategy as a parameter
作為參數(shù)傳遞給策略
Be set during __init__ using the property sizer or setsizer as in:
在初始化期間使用屬性sizer或setsizer進行設(shè)置,如下所示:
class MyStrategy(bt.Strategy):
params = (('sizer', None),)
def __init__(self):
if self.p.sizer is not None:
# 通過property進行設(shè)置
self.sizer = self.p.sizer
This would for example allow to create a Sizer at the same level as the cerebro calls are happening and pass it as a parameter to all strategies that go in the system, which effectevily allows sharing a Sizer
例如,這將在發(fā)生大腦調(diào)用的同一時間級別創(chuàng)建一個Sizer,并將其作為參數(shù)傳遞給系統(tǒng)中的所有策略,從而有效地允許共享一個Sizer。
Sizer Development
Doing it is easy:
這樣做很容易:
Subclass from backtrader.Sizer
子類來自于backtrader.Sizer
This gives you access to self.strategy and self.broker although it shouldn’t be needed in most cases. Things that can be accessed with the broker
這樣你就可以訪問self.strategy以及self.broker雖然在大多數(shù)情況下不需要它。這個可以讓你訪問broker
data’s position with self.strategy.getposition(data)
數(shù)據(jù)的position通過self.strategy.getposition取到(數(shù)據(jù))
complete portfolio value through self.broker.getvalue()
完整的投資價值通過self.broker.getvalue()
Notice this could of course also be done with self.strategy.broker.getvalue()
注意這當(dāng)然也可以用self.strategy.broker.getvalue()
Some of the other things are already below as arguments
其他一些事情已經(jīng)作為論據(jù)在下面了
Override the method _getsizing(self, comminfo, cash, data, isbuy)
重寫方法_getsizing(self, comminfo, cash, data, isbuy)
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
comminfo:包含數(shù)據(jù)傭金信息的CommissionInfo實例,允許計算頭寸值、操作成本、操作傭金
cash: current available cash in the broker
cash:當(dāng)前經(jīng)紀人可用的現(xiàn)金
data: target of the operation
data:操作的目標(biāo)
isbuy: will be True for buy operations and False for sell operations
isbuy:對于buy操作為True,對于sell操作為False
This method returns the desired size for the buy/sell operation
此方法返回buy/sell操作所需的大小
The returned sign is not relevant, ie: if the operation is a sell operation (isbuy will be False) the method may return 5 or -5. Only the absolute value will be used by the sell operation.
返回的符號與此無關(guān),即:如果操作是sell操作(isbuy將為False),則該方法可能返回5或-5。只有絕對值將被sell操作使用。
Sizer has already gone to the broker and requested the commission information for the given data, the actual cash level and provides a direct reference to the data which is the target of the operation
Sizer已經(jīng)去找經(jīng)紀人,要求提供給定數(shù)據(jù)的傭金信息、實際現(xiàn)金水平,并提供直接參考數(shù)據(jù),這是操作的目標(biāo)
Let’s go for the definition of the FixedSize sizer:
讓我們定一個FixedSize
import backtrader as bt
class FixedSize(bt.Sizer):
params = (('stake', 1),)
def _getsizing(self, comminfo, cash, data, isbuy):
return self.params.stake
This is pretty simple in that the Sizer makes no calculations and the parameters are just there.
這很簡單,因為Sizer不進行計算,參數(shù)就在那里。
But the mechanism should allow the construction of complex sizing (aka positioning) systems to manage the stakes when entering/exiting the market.
但該機制應(yīng)允許構(gòu)建復(fù)雜的規(guī)模(又名定位)系統(tǒng),以便在進入/退出市場時管理股權(quán)。
Another example: A position rerverser:
另一個例子:位置變換器:
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
This one builds on the existing FixedSize to inherit the params and overrides _getsizing to:
它基于現(xiàn)有的FixedSize來繼承參數(shù),并重寫_getsizing以:
Get the position of the data via the attribute broker
通過data的屬性broker來獲取持倉情況
Use position.size to decide if to double the fixed stake
使用position.size來計算是否需要兩倍的量
Return the calculated value
返回計算好的值
This would remove the burden from the Strategy to decide if a position has to be reversed or opened, the Sizer is in control and can at any time be replaced without affecting the logic.
這將減輕策略的負擔(dān),以決定是否必須逆轉(zhuǎn)或打開頭寸,規(guī)模大小是在控制之中,可以隨時替換而不影響邏輯。
Practical Sizer Applicability
實際Sizer的適用性
Wihtout considering complex sizing algorithms, two different sizers can be used to turn a strategy from Long-Only to Long-Short. Simply by changing the Sizer in the cerebro execution, the strategy will change behavior. A very simple close crosses SMA algorithm:
在不考慮復(fù)雜的大小調(diào)整算法的情況下,可以使用兩種不同的大小sizers來將策略從“僅多單”轉(zhuǎn)換為“多空單”。通過改變執(zhí)行策略,大腦的行為會改變。一種非常簡單的收盤價超越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()
Notice how the strategy doesn’t consider the current position (by looking at self.position) to decide whether a buy or sell has to actually be done. Only the signal from the CrossOver is considered. The Sizers will be in charge of everything.
注意策略是不考慮當(dāng)前倉位(通過查看自我定位)決定到底是買還是賣。只考慮來自交叉口的信號。所有的事都由Sizers負責(zé)。
This sizer will take care of only returning a non-zero size when selling if a position is already open:
如果倉位已經(jīng)打開,則在賣出時,此sizer只負責(zé)返回非零大小:
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
Putting it all together (and assuming backtrader has already been imported and a data has been added to the system):
把它們放在一起(假設(shè)backtrader已經(jīng)導(dǎo)入,并且數(shù)據(jù)已經(jīng)添加到系統(tǒng)中):
... cerebro.addstrategy(CloseSMA) cerebro.addsizer(LongOnly) ... cerebro.run() ...
The chart (from the sample included in the sources to test this).
圖表(源代碼中包含的樣本)。
The Long-Short version simply changes the Sizer to be the FixedReverser shown above:
長短版只需將Sizer更改為上面顯示的FixedReverser:
... cerebro.addstrategy(CloseSMA) cerebro.addsizer(FixedReverser) ... cerebro.run() ...
The output chart.
Notice the differences:
注意區(qū)別:
The number of trades has duplicated
交易數(shù)量重復(fù)了
The cash level never goes back to be the value because the strategy is always in the market
現(xiàn)金水平永遠不會回到價值,因為策略總是在市場上
Both approaches are anyhow negative, but this is only an example.
這兩種方法都是消極的,但這只是一個例子。
bt.Sizer Reference
class backtrader.Sizer()
This is the base class for Sizers. Any sizer should subclass this and override the _getsizing method
這是sizer的基類。任何sizer都應(yīng)將其子類化并重寫_getsizing方法
Member Attribs:
成員屬性:
strategy: will be set by the strategy in which the sizer is working
策略:在任意一個sizer的工作狀態(tài)都可以設(shè)置策略
Gives access to the entire api of the strategy, for example if the actual data position would be needed in_getsizing:
提供對策略的整個api的訪問權(quán)限,例如,如果需要實際的數(shù)據(jù)倉位就可以通過_getsizing方法
position = self.strategy.getposition(data)
broker: will be set by the strategy in which the sizer is working
broker:在任意一個sizer的工作狀態(tài)都可以設(shè)置broker
Gives access to information some complex sizers may need like portfolio value, ..
提供對一些復(fù)雜規(guī)模公司可能需要的信息的訪問,如投資組合價值。。
_getsizing(comminfo, cash, data, isbuy)
This method has to be overriden by subclasses of Sizer to provide the sizing functionality
此方法必須由Sizer的子類重寫才能提供調(diào)整功能
Params:
參數(shù):
* `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
The method has to return the actual size (an int) to be executed. If 0 is returned nothing will be executed.
該方法必須返回要執(zhí)行的實際大小(int)。如果返回的是0,則不執(zhí)行任何操作。
The absolute value of the returned value will be used
將使用返回值的絕對值
總結(jié)
以上是生活随笔為你收集整理的Backtrader中文笔记之Sizers的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 孙宏斌
- 下一篇: pyinstaller的使用方法 by