How to build a commission model for Interactive Brokers (IB)?
Thanks again for the great library! I'm just getting my feet wet but I really like it.
I needed a commission model for trading IB's US securities using their fixed rate plan. I'm sure there is one on here somewhere but it wasn't in the first few pages of search results so I wrote my own. Because of how awesome Backtrader is, it was easy to do!
Here it is for anyone else:
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt class IBCommision(bt.CommInfoBase): """A :class:`IBCommision` charges the way interactive brokers does. """ params = ( #('stocklike', True), #('commtype', bt.CommInfoBase.COMM_PERC), #('percabs', True), # Float. The amount charged per share. Ex: 0.005 means $0.005 ('per_share', 0.005), # Float. The minimum amount that will be charged. Ex: 1.0 means $1.00 ('min_per_order', 1.0), # Float. The maximum that can be charged as a percent of the trade value. Ex: 0.005 means 0.5% ('max_per_order_abs_pct', 0.005), ) def _getcommission(self, size, price, pseudoexec): """ :param size: current position size. > 0 for long positions and < 0 for short positions (this parameter will not be 0) :param price: current position price :param pseudoexec: :return: the commission of an operation at a given price """ commission = size * self.p.per_share order_price = price * size commission_as_percentage_of_order_price = commission / order_price if commission < self.p.min_per_order: commission = self.p.min_per_order elif commission_as_percentage_of_order_price > self.p.max_per_order_abs_pct: commission = order_price * self.p.max_per_order_abs_pct return commission
And here's a unit test for it:
import unittest from maroma.ibcommission import IBCommision class TestIBCommission(unittest.TestCase): def test_IBCommission(self): ib_comm = IBCommision() # test per_share commission # 1,000 Shares @ USD 25 Share Price = USD 5.00 commission = ib_comm.getcommission(1000, 25.00) self.assertEqual(commission, 5.00) # test min_per_order commission # 100 Shares @ USD 25 Share Price = USD 1.00 commission = ib_comm.getcommission(100, 25.00) self.assertEqual(commission, 1.00) # test maxPerOrderPct commission # 1,000 Shares @ USD 0.25 Share Price = USD 1.25 commission = ib_comm.getcommission(1000, .25) self.assertEqual(commission, 1.25) if __name__ == '__main__': unittest.main()
Thanks for sharing
Great design! Friendly reminders:
Change commission to abs(commission) avoid sell/short results a negative commission...(and you know the consequence)
This commission does not include the cost of exchange (I.e nasdaq/amex). Additional mapping or charges are needed