I created a custom Forex commission scheme and thought I would share. If anyone has suggestions for improvements, they would be welcome.
This scheme intends to setup a backtrader commision scheme for applying forex commission where the commission is hidden in the spread.
The scheme has two limitations. The first is that the account currency is assumed to be the same as either the base currency or the counter currrency. Otherwise an exchange rate would be needed for the account currency.
The second is that scheme assumes a fixed spread. Therefore it might not be the most accurate commission scheme if you are closing positions around news releases.
One other note, the scheme applies half the commission when buying and half when selling. The other option would have been to apply the full scheme on only one direction (i.e the buy or the sell side)
class forexSpreadCommisionScheme(bt.CommInfoBase): ''' This commission scheme attempts to calcuate the commission hidden in the spread by most forex brokers. It assumes a mid point data is being used. *New Params* spread: Float, the spread in pips of the instrument JPY_pair: Bool, states whether the pair being traded is a JPY pair acc_counter_currency: Bool, states whether the account currency is the same as the counter currency. If false, it is assumed to be the base currency ''' params = ( ('spread', 2.0), ('stocklike', False), ('JPY_pair', False), ('acc_counter_currency', True), ('commtype', bt.CommInfoBase.COMM_FIXED), ) def _getcommission(self, size, price, pseudoexec): ''' This scheme will apply half the commission when buying and half when selling. If JPY pair change the multiplier accordingly. If account currency is same as the base currency, change pip value calc. ''' if self.p.JPY_pair == True: multiplier = 0.01 else: multiplier = 0.0001 if self.p.acc_counter_currency == True: comm = abs((self.p.spread * (size * multiplier)/2)) else: comm = abs((self.p.spread * ((size / price) * multiplier)/2)) return comm
Here is an example of adding it to a strategy
#Add the new commissions scheme comminfo = forexSpreadCommisionScheme(spread=3, acc_counter_currency=False) cerebro.broker.addcommissioninfo(comminfo)