Retrieve SP500 index historical data from InteractiveBroker API

107 Views Asked by At

The code below can retrieve historical stock data from InteractiveBroker API. However, it doesn't return value for SP500 whose symbol is 'SPX'. The error is: Error 200, reqId 6: No security definition has been found for the request, contract: Stock(symbol='SPX', exchange='SMART', currency='USD')

What should be changed to get SPX open,high,low,close,vol data? (I include TSLA to show that this code works for stock). Many thanks.

from ib_insync import *;
import pandas as pd;

ib = IB()
ib.connect('127.0.0.1', 7496, clientId=1)

# Import ticklist

ticker_list=['TSLA','SPX']
def extract_data(duration_period, bar_period):
    global full_data

    full_data = pd.DataFrame()
    for i in ticker_list:
        print( '--', i);

        contract = Stock(i, 'SMART', 'USD')

        ib.reqHeadTimeStamp(contract, whatToShow='TRADES', useRTH=True)
        bars = ib.reqHistoricalData(
            contract,
            endDateTime='',
            # durationStr='1 D', barSizeSetting='1 hour',
            durationStr=duration_period, barSizeSetting=bar_period,
            whatToShow='TRADES',
            useRTH=False,
            formatDate=1)
        # print(bars)
        try:
            df = util.df(bars)
            df = df.drop(['average', 'barCount'], axis=1)
            df['ticker'] = i
            full_data = pd.concat([full_data, df])
        except:
            print('error tic: ', i)
    return full_data


extract_data('1 D','1 hour')
print(full_data)

3

There are 3 best solutions below

0
Yuri Ginsburg On

You have contract = Stock(i, 'SMART', 'USD') but SPX is not a stock. Check if there is Index function. Or you can use something like:

contract = Contract()
contract.symbol = "SPX"
contract.secType = "IND"
contract.currency = "USD"
contract.exchange = "CBOE"
0
thetaco On

Your code works for stocks, not indexes. From the documentation you can see differentiation between the two and how to use them:

classib_insync.contract.Stock(symbol='', exchange='', currency='', **kwargs)
classib_insync.contract.Index(symbol='', exchange='', currency='', **kwargs)

Which means you can just add an extra conditional and specify the exchange where you define contract:

    if type == 'Stock':
        contract = Stock(ticker, 'SMART', 'USD')
    elif type == 'Index':
        contract = Index(ticker, 'CBOE', 'USD')
0
Chathura Abeywickrama On

Replace Stock(i, 'SMART', 'USD') with Stock(i, 'CBOE', 'USD') for the SPX contract.

from ib_insync import *
import pandas as pd

ib = IB()
ib.connect('127.0.0.1', 7496, clientId=1)

ticker_list = ['TSLA', 'SPX']


def extract_data(duration_period, bar_period):
    global full_data

    full_data = pd.DataFrame()
    for i in ticker_list:
        print('--', i)

        if i == 'SPX':
            contract = Index(i, 'CBOE', 'USD')
        else:
            contract = Stock(i, 'SMART', 'USD')

        ib.reqHeadTimeStamp(contract, whatToShow='TRADES', useRTH=True)
        bars = ib.reqHistoricalData(
            contract,
            endDateTime='',
            durationStr=duration_period, barSizeSetting=bar_period,
            whatToShow='TRADES',
            useRTH=False,
            formatDate=1)

        try:
            df = util.df(bars)
            df = df.drop(['average', 'barCount'], axis=1)
            df['ticker'] = i
            full_data = pd.concat([full_data, df])
        except:
            print('error tic: ', i)
    return full_data


extract_data('1 D', '1 hour')
print(full_data)