pythonibpy

Downloading stock price data using IBpy


I adapted the following code from http://godelsmarket.blogspot.co.uk/2012/07/non-gui-ib-historical-data-downloader.html. I wanted to download MMM's price data for 20151001.

from time import sleep, strftime, localtime  
from ib.ext.Contract import Contract  
from ib.opt import ibConnection, message  

new_symbolinput = ['MMM']  
newDataList = []  
dataDownload = []  

def historical_data_handler(msg):  
 global newDataList  
 #print msg.reqId, msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume  
 if ('finished' in str(msg.date)) == False:  
   new_symbol = new_symbolinput[msg.reqId]  
   dataStr = '%s, %s, %s, %s, %s, %s, %s' % (new_symbol, strftime("%Y-%m-%d %H:%M:%S", localtime(int(msg.date))), msg.open, msg.high, msg.low, msg.close, msg.volume)  
   newDataList = newDataList + [dataStr]  
 else:  
   new_symbol = new_symbolinput[msg.reqId]  
   filename = 'minutetrades' + new_symbol + '.csv'  
   csvfile = open('csv_day_test/' + filename,'wb')  
   for item in newDataList:  
     csvfile.write('%s \n' % item)  
   csvfile.close()  
   newDataList = []  
   global dataDownload  
   dataDownload.append(new_symbol)  

con = ibConnection()  
con.register(historical_data_handler, message.historicalData)  
print(con.connect())

symbol_id = 0  
for i in new_symbolinput:  
 print(i)
 qqq = Contract()  
 qqq.m_symbol = i  
 qqq.m_secType = 'STK'  
 qqq.m_exchange = 'SMART'  
 qqq.m_currency = 'USD'  
 con.reqHistoricalData(symbol_id, qqq, '20151001', '1 D', '1 min', 'TRADES', 1, 2)  

 symbol_id = symbol_id + 1  
 sleep(0.5)  

print (dataDownload)

However, the output I got yields an empty data list at the end:

Server Version: 68
TWS Time at connection:20151004 09:30:11 EST
True
MMM
[]

What am I doing wrong? Thanks!


Solution

  • First you should register a handler for errors, or else one for all other messages.

    def watchAll(msg):
        print(msg)
    ā€‹
    con = ibConnection()  
    con.registerAll(watchAll)
    con.unregister(watchAll, message.historicalData)
    con.register(historical_data_handler, message.historicalData)  
    

    Then you'd get an error saying your date time format is wrong. Change it to 20151001 00:00:00. You can add a time zone.

    csvfile.write('%s \n' % item) won't work in python3 use csvfile.write(bytes('%s \n' % item,'UTF-8')) and make sure you create the directory. But this binary writing needs to be looked at by a pythonista.

    You changed the sleep to 0.5 from 10. It will work for you because you just want one symbol but the 10 was probably to eliminate pacing errors. You have a limit to much much data you can ask for every minute.

    The var name qqq is strange. It must have been copied from an example where someone downloaded symbol qqq. You should rename it to something like contract.