title: Interactive Brokers Python Multiple Symbol Request
body: <p>I was able to piece together a script from IB's documentation/examples and forums on this site.  I am getting the output I want for a single symbol, however, if I use a list of stocks, I cannot figure out a way to pass the ticker symbol through to the DF output file.  My workaround was to create a dictionary that uses the list sequence (see below) however the output from IB's api changes slightly each time rendering the symbols mostly pointless.  The list i am using below normally has 20+ names but may change, i cut it down to make it easier to view.</p>
  <p>@Brian/and or other developers, if there is a way to create either a unique ID/sequence for each symbol call and stamp it to data that is brought back, i can then utilize a dictionary to apply the symbol.  In the other forum, you passed in a line where n_id = n_id +1, if that can be applied and is linked to each specific call which is done in order of the list, then that could work?</p>
  <pre><code>from ibapi.client import EClient
  from ibapi.wrapper import EWrapper
  from ibapi.contract import Contract
  import pandas as pd
  import threading
  import time
  from datetime import timedelta
  import datetime
  
  class IBapi(EWrapper, EClient):
      def __init__(self):
          EClient.__init__(self, self)
          self.data = [] #Initialize variable to store candle
  
      def historicalData(self, reqId, bar):
          #print(f'Time: {bar.date} Close: {bar.close} Volume: {bar.volume}',reqId)
          self.data.append([bar.date, bar.close, bar.volume, reqId])
       
  def run_loop():
      app.run()
  
  app = IBapi()
  app.connect('127.0.0.1', 7496, 123)
  
  #Start the socket in a thread
  api_thread = threading.Thread(target=run_loop, daemon=True)
  api_thread.start()
  
  time.sleep(1) #Sleep interval to allow time for connection to server
  
  symbols = ['SPY','MSFT','GOOG','AAPL','QQQ','IWM','TSLA']
  
  for sym in symbols:
      contract = Contract()
      contract.symbol = str(sym) 
      contract.secType = &quot;STK&quot;
      contract.exchange = &quot;SMART&quot;
      contract.currency = &quot;USD&quot;
      #contract.primaryExchange = &quot;ISLAND&quot;
      app.reqHistoricalData(1, contract, &quot;&quot;, &quot;1 D&quot;, &quot;10 mins&quot;, &quot;ADJUSTED_LAST&quot;, 1, 2, False, [])
  
   time.sleep(5) #sleep to allow enough time for data to be returned
  
  df = pd.DataFrame(app.data, columns=['DateTime', 'ADJUSTED_LAST','Volume','reqId'])
  df['DateTime'] = pd.to_datetime(df['DateTime'],unit='s') #,unit='s') 
  
  df['Count'] = df.groupby('DateTime').cumcount()+1
  sym_dict = {1:'SPY',2:'MSFT',3:'GOOG',4:'AAPL',5:'QQQ',6:'IWM',7:'TSLA'}
  
  df['Ticker'] = df['Count'].map(sym_dict)
  
  print(df)
  </code></pre>
  <p>#edit, adding in @Brian's detail:</p>
  <pre><code>from ibapi.client import EClient
  from ibapi.wrapper import EWrapper
  from ibapi.contract import Contract
  import pandas as pd
  import time
  from datetime import timedelta
  import datetime
  
  start = datetime.datetime.utcnow()
  
  class IBapi(EWrapper, EClient):
      def __init__(self):
          EClient.__init__(self, self)
          self.data = [] 
  
  def error(self, reqId, errorCode, errorString):
      print(&quot;Error. Id: &quot; , reqId, &quot; Code: &quot; , errorCode , &quot; Msg: &quot; , errorString)
  
  def historicalData(self, reqId, bar):
      self.data.append([bar.date, bar.close, bar.volume, sym_dict[reqId]])
      print(&quot;HistoricalData. ReqId:&quot;, sym_dict[reqId], &quot;BarData.&quot;, bar)
   
  # include this callback to track progress and maybe disconnectwhen all are finished
  def historicalDataEnd(self, reqId: int, start: str, end: str):
      print(&quot;finished&quot;, sym_dict[reqId])
  
  def run_loop():
      app.run()
  
  app = IBapi()
  app.connect('127.0.0.1', 7496, 123)
  
  # you should wait for nextValidId instead of sleeping, what if it takes more than 1 second? @john: how do i do this?
  time.sleep(5) @john: how do i do this? wait for nextValidId?
  
  symbols = ['SPY','MSFT','GOOG','AAPL','QQQ','IWM','TSLA']
  
  reqId = 1
  sym_dict = {}
  for sym in symbols:
      contract = Contract()
      contract.symbol = str(sym) 
      sym_dict[reqId] = sym
      contract.secType = &quot;STK&quot;
      contract.exchange = &quot;SMART&quot;
      contract.currency = &quot;USD&quot;
      #contract.primaryExchange = &quot;ISLAND&quot; # you may need this for msft
      app.reqHistoricalData(reqId, contract, &quot;&quot;, &quot;1 D&quot;, &quot;10 mins&quot;, &quot;ADJUSTED_LAST&quot;, 1, 2, False, [])
      reqId += 1
      time.sleep(5)
  
  df = pd.DataFrame(app.data, columns=['DateTime', 'ADJUSTED_LAST','Volume','sym'])
  df['DateTime'] = pd.to_datetime(df['DateTime'],unit='s') #,unit='s') 
  df = df.set_index(['sym','DateTime']).sort_index()
  print(df)
  app.disconnect()
  </code></pre>