Stock Universe and “IB reports a holding … adding to Quantopian Blotter”

IB Adding

When running against an Interactive Brokers (IB) paper (or real money) account, Quantopian has a cool feature where it scans the current holdings and populates context.portfolio with current holdings.  You see a log message like “IB reports a holding … adding to Quantopian Blotter”.


A side effect of this is also expansion of your stock universe that is passed to handle_data or your scheduled functions.  If your IB account has existing stocks that are outside of the universe you specified in your initialize segment (eg, using context.secs = [symbol(‘IBM’),symbol(‘HPQ’)] or via Quantopian Pipeline , and you have automated sell logic based on examining context.portfolio.positions, you could sell holdings by mistake.


I learned this by having some “left-overs” in my IB paper account from some other tests and I saw that my algo started closing positions for holdings that were not explicity defined in my algo but were in context.portfolio.positions.  If your mainline logic has sell automation based on a loop like  “for stocks in context.portfolio.positions” - then you risk selling _everything_ in the IB account not just the stocks spelled out in your universe.



For live-trading, by far the best practice is to create an IB sub-account that is used exclusively for algo trading.  If you do want to mix holdings, the be sure to loop thru the universe that was defined in your initialize or before_trading_starts (Pipeline) segment like this  “for stock in context.secs :” instead.


For paper-trading, it is best to always start with no holdings and the cash balance set as you like.  IB does not provide an easy mechanism that I am aware of to liquidate everything.  But with Quantopian we can easily create an IB paper-account cleanup algorithm that closes all positions:


from pytz import timezone
def initialize(context):
    context.boDone = False
    context.counter = 0

def handle_data(context, data):
   now = get_datetime().astimezone(timezone('US/Eastern'))
   iNOO= len(get_open_orders())
   if iNOO == 0 :
      if iNPos == 0 :
         if context.boDone == False :
  'AOK  '+str(now)+' All positions closed')
            context.boDone = True
         for S in context.portfolio.positions:
         m1=' %d ' % iNPos'INF  '+str(now)+m1+' Close Orders Placed')
       context.counter += 1
       if context.counter == 5 :
          m1=' %d ' % iNOO
'INF  '+str(now)+m1+' Orders Pending')
          context.counter = 0




Happy Trading!