For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

How to build a commission model for Interactive Brokers (IB)?



  • Hi everyone,

    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()
    
    

    Best,
    Brett


  • administrators

    Thanks for sharing