Once you have started to get to grips with the basics, the logical next step is to add another level of realism to the backtests through commissions. Some strategies which trade frequently can look great on an initial backtest however, once commissions are factored in, the performance can take a serious nose dive! In this post, we will take a look at setting up some simple commission schemes and discussing when you might want to develop your own scheme. Backtrader has built-in support for two common types of commission scheme. The first type is a stocks/equities commission scheme. The second is targeted towards trading futures instruments. Each of these commission schemes is well-defined with good supporting documentation. Having said that, in my opinion, the implementation is a little rigid (which we will discuss later).
How commissions are appliedOne important thing to note before we begin is that commission you set up is applied on both the buy and sell sides. You may be thinking duh, but stay with me. This can sometimes be easy to forget and leave you scratching your head when checking the dollar amount deducted from the gross profit.
- When you are using a commission scheme that deducts a percentage, it might appear that the dollar amount deducted is slightly different to the percentage setup in cerebro. That is likely due to the fact the price was different when buying the instrument to the price when selling (and vice versa). In other words, you are not deducting a percentage from the gross profit, you are deducting it from the value of each transaction.
- If you are applying a fixed commission, remember to factor in the total round trip cost and halve the total final commission you want to be deducted from the PnL.
Simple setupIf you simply want to trade equities and your broker charges you on a percentage basis only, the simplest way to add commissions is to do it during
cerebrosetup with the line:
cerebro.broker.setcommission(commission=0.01)This will add a 1% commission to both the buy and sell side. So 2% in total. In my experience, I have not found any broker in my region that applies a limitless fixed percentage to equities. If you are in the same boat, the default setup is unlikely to be of much use.
What about Futures?For futures, we can use the same broker method
setcommission()and populate it with some additional values.
cerebro.broker.setcommission(commission=10, margin=2000, mult=10)In this case, the
commissionis assumed to be a fixed commission per contract. This means if your size == 1, then the commission would be 10 on both the buy and sell side. If it was 5, the commission would be 50 on each side of the trade. The
marginis a goodwill deposit you must pay to open the position. It is not the same type of margin you find in the FX, spread betting and CFD world. For more on setting up margin from an FX perspective, see this article Backtrader: Oanda Margin and Leverage Finally, the variable
multmeans “multiplier”. Final profits and/or losses shall be multiplied by this number.
Selecting stocks or futuresIf you didn’t notice, the same variable
commissionis used for assigning a fixed commission for futures instruments and a percentage based commission in equities. So how does Backtrader decide what to do with the value you give it? It looks at the
marginvariable. If the
marginvariable is set, it assumes you are trading a futures contract and sets the commission to be fixed. This means you cannot set a fixed commission scheme without deducting a goodwill margin deposit. If you try setting
margin=0that will evaluate as false and apply a percentage based scheme.
Isn’t this awkward for brokers who charge fixed commissions?Yes. … It is for this reason that I mentioned that the implementation is a little rigid. It would be nice to be able to assign a fixed commission without requiring a margin deposit. Don’t worry though, the platform has been designed very well and is open to creating our own commission schemes. Below there is a quick example of how to add a fixed commission to each transaction. Additionally, there is also another code snippet example showing how to use a mixture of a percentage commission and a fixed commission. Code Snippet: Stamp Duty Commission Scheme
Fixed Commission SchemeThe example below provides the code required to set a fixed commission on both the buy and sell side.
class FixedCommisionScheme(bt.CommInfoBase): ''' This is a simple fixed commission scheme ''' params = ( ('commission', 5), ('stocklike', True), ('commtype', bt.CommInfoBase.COMM_FIXED), ) def _getcommission(self, size, price, pseudoexec): return self.p.commission
Code BreakdownIn the code above we create a commission scheme class and inherit from Backtrader’s
CommInfoBaseobject. All we have to do then is override the
_getcommission()method and define what is returned when it is called by the broker. Some parameter defaults have been set for this scheme. They are
commtype. For a full list of all parameters available take a look at the Backtrader CommInfoBase Docs. In the example above,
stocklikeindicates whether the instrument being traded is a stock/equity and
commtypeallows us to force the
commissionto be a fixed value rather than a percentage. Every time a commission is calculated, the
_getcommission()method is called. When it is called, the
priceof the instrument is passed to it. From this, you can make your commission calculations and
returna value. Note that you can the parameters defined above the
_getcommission()method. A good example would be to define a
maxcommissionparameter (or whatever you want to call it). You could use this to limit a percentage based commission to a maximum value. Once you have defined the commission scheme, you can add it to cerebro with the following lines of code:
#Set commissions comminfo = FixedCommisionScheme() cerebro.broker.addcommissioninfo(comminfo)This will apply the default values to the scheme and will result in a flat commission being applied to each buy/sell operation.