佣金: 股票 vs 期货#
对于数据代表的含义,“backtrader”试图保持不可知性。 不同的佣金方案可以应用于相同的数据集。
让我们看看如何实现。
使用经纪人快捷方式#
这样可以让最终用户远离“CommissionInfo”对象,因为可以通过单个函数调用创建/设置佣金方案。 在常规的“cerebro”创建/设置过程中,只需在“broker”成员属性上添加一次“setcommission”调用即可。 以下调用在使用“Interactive Brokers”处理“Eurostoxx50”期货时设置了一种通常的佣金方案:
cerebro.broker.setcommission(commission=2.0, margin=2000.0, mult=10.0)
由于大多数用户通常只测试单个工具,因此这就是所做的全部。 如果您给数据提供了一个“name”,因为在图表上同时考虑了几个工具,这个调用可以稍微扩展如下:
cerebro.broker.setcommission(commission=2.0, margin=2000.0, mult=10.0, name=’Eurostoxxx50’)
在这种情况下,这个即时佣金方案只会应用于名称与“Eurostoxx50”匹配的工具。设置佣金参数的含义#
commission
(默认值:0.0
)每次操作 所需的货币单位,可以是绝对值或百分比。
在上面的例子中,每个合同的买入费用为2.0欧元,卖出费用也是2.0欧元。
在这里重要的问题是何时使用绝对值或百分比。
如果
margin
评估为False
(例如,False、0或None),则认为commission
表示price
乘以size
操作值的百分比。如果
margin
是其他值,则认为操作发生在类似”期货”的工具上,而commission
是每个size
合同的固定价格。
margin
(默认值:None
)使用类似”期货”的工具进行操作时需要的保证金。如上所述
如果没有设置 保证金 ,则会将
commission
理解为百分比,并应用于price * size
部分的”买入”或”卖出”操作中。- 如果设置了“margin”,则理解“commission”是一个固定值,乘以“buy”或“sell”操作的“size”组成部分
“mult”(默认值:1.0)
对于像期货这样的工具,确定要应用于盈亏计算的乘法因子。
这就是期货同时具有吸引力和风险的原因。
“name”(默认值:None)
将佣金方案的应用限制在与“name”匹配的工具上
可以在创建数据源期间设置。
如果未设置,则该方案将适用于系统中存在的任何数据。
现在举两个例子:股票与期货#
之前的期货示例::cerebro.broker.setcommission(commission=2.0, margin=2000.0, mult=10.0)
一个股票的例子:
cerebro.broker.setcommission(commission=0.005) # 交易金额的0.5%
注意
第二种语法没有设置 margin 和 mult , backtrader 会根据佣金来智能计算。
要完全指定佣金计划,需要创建 CommissionInfo
的子类。
创建永久佣金计划#
可以通过直接使用 CommissionInfo
类来创建一个更长期的佣金计划。用户可以选择在某个地方进行定义:
import backtrader as bt
commEurostoxx50 = bt.CommissionInfo(commission=2.0, margin=2000.0, mult=10.0)为了在另一个Python模块中稍后使用 ``addcommissioninfo`` :
- ```python
from mycomm import commEurostoxx50
…
cerebro.broker.addcommissioninfo(commEurostoxx50, name=’Eurostoxx50’)
CommissionInfo
是一个对象,它使用与 backtrader
环境中的其他对象相同的 params
声明。因此,上述代码也可以表示为:
- ```python
import backtrader as bt
- class CommEurostoxx50(bt.CommissionInfo):
params = dict(commission=2.0, margin=2000.0, mult=10.0)
然后:
```现在使用 SMA 交叉作为入场/出场信号,将使用相同的数据集测试具有类似期货的佣金方案,然后再测试具有类似股票的方案。
备注
期货头寸不仅可以设置进出行为,还可以在每次发生时设置反转行为。但是,此示例是为了比较佣金方案。
代码(完整策略请参见底部)是相同的,可以在定义策略之前选择方案。
futures_like = True
if futures_like:
commission, margin, mult = 2.0, 2000.0, 10.0
else:
commission, margin, mult = 0.005, None, 1
只需将 futures_like
设置为 false,即可使用类似股票的方案运行。
已添加一些记录代码以评估不同佣金方案的影响。我们只关注前两个操作。
对于期货:
2006-03-09, 买入创建,3757.59
2006-03-10, 买入执行,价格:3754.13,成本:2000.00,佣金 2.00
2006-04-11, 卖出创建,3788.81
2006-04-12, 卖出执行,价格:3786.93,成本:2000.00,佣金 2.00
2006-04-12, 操作利润,总额 328.00,净额 324.00
2006-04-20, 买入创建,3860.00
2006-04-21, 买入执行,价格:3863.57,成本:2000.00,佣金 2.00
2006-04-28, 卖出创建,3839.90
2006-05-02, 卖出执行,价格:3839.24,成本:2000.00,佣金 2.00
2006-05-02, 操作利润,总额 -243.30,净额 -247.30对于股票::
2006-03-09,买入创建,3757.59
2006-03-10,买入执行,价格:3754.13,成本:3754.13,佣金:18.77
2006-04-11,卖出创建,3788.81
2006-04-12,卖出执行,价格:3786.93,成本:3786.93,佣金:18.93
2006-04-12,操作利润,毛利 32.80,净利润 -4.91
2006-04-20,买入创建,3860.00
2006-04-21,买入执行,价格:3863.57,成本:3863.57,佣金:19.32
2006-04-28,卖出创建,3839.90
2006-05-02,卖出执行,价格:3839.24,成本:3839.24,佣金:19.20
2006-05-02,操作利润,毛利 -24.33,净利润 -62.84
第一次操作的价格如下:
买入(执行)-> 3754.13 / 卖出(执行)-> 3786.93
期货利润和损失(含佣金):324.0
股票利润和损失(含佣金):-4.91
嘿!! 佣金完全吃掉了“股票”操作的任何利润, 但对“期货”操作只造成了一个小破坏。
第二次操作:
买入(执行)-> 3863.57 / 卖出(执行)-> 3389.24
期货利润和损失(含佣金):-247.30
股票利润和损失(含佣金):-62.84
对于这个负操作来说,“期货”的损失更大了。但是:
期货累积净盈亏:
324.00 + (-247.30) = 76.70
股票累积净盈亏:
(-4.91) + (-62.84) = -67.75
累积影响可以从下面的图表中看出,同时也可以看出在全年末,期货产生了更大的利润,但也遭受了更大的回撤(承压较大)
但是最重要的是:无论是“期货”还是“股票”…… 都可以进行回测 。
期货佣金#
股票佣金#
代码#
- class backtrader.CommInfoBase(*args, **kwargs)#
Base Class for the Commission Schemes.
Params:
commission
(def:0.0
): base commission value in percentage or monetary unitsmult
(def1.0
): multiplier applied to the asset for value/profitmargin
(def:None
): amount of monetary units needed to open/hold an operation. It only applies if the final_stocklike
attribute in the class is set toFalse
automargin
(def:False
): Used by the methodget_margin
to automatically calculate the margin/guarantees needed with the following policyUse param
margin
if paramautomargin
evaluates toFalse
Use param
mult
*price
ifautomargin < 0
Use param
automargin
*price
ifautomargin > 0
commtype
(def:None
): Supported values areCommInfoBase.COMM_PERC
(commission to be understood as %) andCommInfoBase.COMM_FIXED
(commission to be understood as monetary units)The default value of
None
is a supported value to retain compatibility with the legacyCommissionInfo
object. Ifcommtype
is set to None, then the following applies:margin
isNone
: Internal_commtype
is set toCOMM_PERC
and_stocklike
is set toTrue
(Operating %-wise with Stocks)margin
is notNone
:_commtype
set toCOMM_FIXED
and_stocklike
set toFalse
(Operating with fixed rount-trip commission with Futures)
If this param is set to something else than
None
, then it will be passed to the internal_commtype
attribute and the same will be done with the paramstocklike
and the internal attribute_stocklike
stocklike
(def:False
): Indicates if the instrument is Stock-like or Futures-like (see thecommtype
discussion above)percabs
(def:False
): whencommtype
is set to COMM_PERC, whether the parametercommission
has to be understood as XX% or 0.XXIf this param is
True
: 0.XX If this param isFalse
: XX%interest
(def:0.0
)If this is non-zero, this is the yearly interest charged for holding a short selling position. This is mostly meant for stock short-selling
The formula:
days * price * abs(size) * (interest / 365)
It must be specified in absolute terms: 0.05 -> 5%
备注
the behavior can be changed by overriding the method:
_get_credit_interest
interest_long
(def:False
)Some products like ETFs get charged on interest for short and long positions. If ths is
True
andinterest
is non-zero the interest will be charged on both directionsleverage
(def:1.0
)Amount of leverage for the asset with regards to the needed cash
- - ``_stocklike``
Final value to use for Stock-like/Futures-like behavior
- - ``_commtype``
Final value to use for PERC vs FIXED commissions
- This two are used internally instead of the declared params to enable the
- compatibility check described above for the legacy ``CommissionInfo``
- object#
- class backtrader.CommissionInfo(*args, **kwargs)#
Base Class for the actual Commission Schemes.
CommInfoBase was created to keep suppor for the original, incomplete, support provided by backtrader. New commission schemes derive from this class which subclasses
CommInfoBase
.The default value of
percabs
is also changed toTrue
Params:
percabs
(def: True): whencommtype
is set to COMM_PERC, whether the parametercommission
has to be understood as XX% or 0.XXIf this param is True: 0.XX If this param is False: XX%
- get_leverage()#
Returns the level of leverage allowed for this comission scheme
- getsize(price, cash)#
Returns the needed size to meet a cash operation at a given price
- getoperationcost(size, price)#
Returns the needed amount of cash an operation would cost
- getvaluesize(size, price)#
Returns the value of size for given a price. For future-like objects it is fixed at size * margin
- getvalue(position, price)#
Returns the value of a position given a price. For future-like objects it is fixed at size * margin
- get_margin(price)#
Returns the actual margin/guarantees needed for a single item of the asset at the given price. The default implementation has this policy:
Use param
margin
if paramautomargin
evaluates toFalse
Use param
mult
*price
ifautomargin < 0
Use param
automargin
*price
ifautomargin > 0
- getcommission(size, price)#
Calculates the commission of an operation at a given price
- _getcommission(size, price, pseudoexec)#
Calculates the commission of an operation at a given price
pseudoexec: if True the operation has not yet been executed
- profitandloss(size, price, newprice)#
Return actual profit and loss a position has
- cashadjust(size, price, newprice)#
Calculates cash adjustment for a given price difference
- get_credit_interest(data, pos, dt)#
Calculates the credit due for short selling or product specific
- _get_credit_interest(data, size, price, days, dt0, dt1)#
This method returns the cost in terms of credit interest charged by the broker.
In the case of
size > 0
this method will only be called if the parameter to the classinterest_long
isTrue
The formulat for the calculation of the credit interest rate is:
The formula:
days * price * abs(size) * (interest / 365)
- Params:
data
: data feed for which interest is chargedsize
: current position size. > 0 for long positions and < 0 for short positions (this parameter will not be0
)price
: current position pricedays
: number of days elapsed since last credit calculation (this is (dt0 - dt1).days)dt0
: (datetime.datetime) current datetimedt1
: (datetime.datetime) datetime of previous calculation
dt0
anddt1
are not used in the default implementation and are provided as extra input for overridden methods