Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting parameters of listed options & futures in Interactive Brokers API

There are a lot of examples showing how to get particular asset's price from Interactive Brokers. However, when I want to get the whole chain of options for one asset, I don't know which particular strikes are listed. Same for futures, I don't know which expirations are available at the moment. So, i.e., for options, I just loop through all possible strikes and reqMktData for each, also making a sleep(1) every 100 messages to avoid hitting the limit for number of requests per second. Obviously, many of these messages return with error "No security definition has been found for the request".

This looks like the wrong approach as it wastes lots of time on non-existing assets. Is there any more clean way to do this, or a special function for such purpose?

like image 952
sashkello Avatar asked Aug 14 '14 03:08

sashkello


People also ask

How do you calculate the value of stock options?

Multiply your ownership stake by the company's current $1 billion valuation to find that your options are theoretically worth $10,000 minus the costs to exercise (strike price and taxes; more on that below). You should play around with different figures for the company's valuation at exit.

Where can I find delta for options?

The formula for delta can be derived by dividing the change in the value of the option by the change in the value of its underlying stock. Important: Delta is used to measure the theoretical change in the value of option price given a change in the price of the underlying security.

How do you Analyse option data?

The first step in analyzing options to make earnings predictions is to identify unusual activity and validate it using open interest and average volume data. The goal in this step is to find some specific options that may be telling for the future and create an initial list of targets for further analysis.


2 Answers

Implementing handler for contractDetailsEnd as suggested by Donn Lee. Thanks to both shashkello and Donn Lee.

from ib.ext.Contract import Contract
from ib.ext.ContractDetails import ContractDetails
from ib.opt import ibConnection, message
import time

def watcher(msg):
    print msg

def contractDetailsHandler(msg):
    contracts.append(msg.contractDetails.m_summary)

def contractDetailsEndHandler(msg):
    global DataWait
    DataWait =  False

con = ibConnection()
con.registerAll(watcher)
con.register(contractDetailsHandler, 'ContractDetails')
con.register(contractDetailsEndHandler, 'ContractDetailsEnd')

con.connect()

contract = Contract()
contract.m_exchange     = "SMART"
contract.m_secType      =  "OPT"
contract.m_symbol       = "VTR"
#contract.m_multiplier   = "100"
contract.m_currency     = "USD"


con.reqContractDetails(1, contract)

contracts = [] # to store all the contracts

DataWait = True  ;  i = 0
while DataWait and i < 90:
    i += 1 ; print i,
    time.sleep(1)

con.disconnect()
con.close()

print contracts
like image 115
Michael G. Avatar answered Nov 10 '22 06:11

Michael G.


I started working with IbPy not that long ago and also saw the time.sleep idiom in the samples and now in the answers above. Because ibpy has a thread running in the background and the message receiving methods/functions are therefore called in that thread it seemed natural to move to a queue based approach.

Here the code and below the output for the two contract specifications from above.

from __future__ import (absolute_import, division, print_function,)
#                        unicode_literals)

import sys

if sys.version_info.major == 2:
    import Queue as queue
else:  # >= 3
    import queue


import ib.opt
import ib.ext.Contract


class IbManager(object):
    def __init__(self, timeout=20, **kwargs):
        self.q = queue.Queue()
        self.timeout = 20

        self.con = ib.opt.ibConnection(**kwargs)
        self.con.registerAll(self.watcher)

        self.msgs = {
            ib.opt.message.error: self.errors,
            ib.opt.message.contractDetails: self.contractDetailsHandler,
            ib.opt.message.contractDetailsEnd: self.contractDetailsHandler
        }

        self.skipmsgs = tuple(self.msgs.keys())

        for msgtype, handler in self.msgs.items():
            self.con.register(handler, msgtype)

        self.con.connect()

    def watcher(self, msg):
        if isinstance(msg, ib.opt.message.error):
            if msg.errorCode > 2000:  # informative message
                print('-' * 10, msg)

        elif not isinstance(msg, self.skipmsgs):
            print('-' * 10, msg)

    def errors(self, msg):
        if msg.id is None:  # something is very wrong in the connection to tws
            self.q.put((True, -1, 'Lost Connection to TWS'))
        elif msg.errorCode < 1000:
            self.q.put((True, msg.errorCode, msg.errorMsg))

    def contractDetailsHandler(self, msg):
        if isinstance(msg, ib.opt.message.contractDetailsEnd):
            self.q.put((False, msg.reqId, msg))
        else:
            self.q.put((False, msg.reqId, msg.contractDetails))

    def get_contract_details(self, symbol, sectype, exch='SMART', curr='USD'):
        contract = ib.ext.Contract.Contract()
        contract.m_symbol = symbol
        contract.m_exchange = exch
        contract.m_currency = curr
        contract.m_secType = sectype

        self.con.reqContractDetails(1, contract)

        cdetails = list()
        while True:
            try:
                err, mid, msg = self.q.get(block=True, timeout=self.timeout)
            except queue.Empty:
                err, mid, msg = True, -1, "Timeout receiving information"
                break

            if isinstance(msg, ib.opt.message.contractDetailsEnd):
                mid, msg = None, None
                break

            cdetails.append(msg)  # must be contractDetails

        # return list of contract details, followed by:
        #   last return code (False means no error / True Error)
        #   last error code or None if no error
        #   last error message or None if no error
        # last error message

        return cdetails, err, mid, msg


ibm = IbManager(clientId=5001)

cs = (
    ('VTR', 'OPT', 'SMART'),
    ('ES', 'FUT', 'GLOBEX'),
)

for c in cs:
    cdetails, err, errid, errmsg = ibm.get_contract_details(*c)

    if err:
        print('Last Error %d: %s' % (errid, errmsg))

    print('-' * 50)
    print('-- ', c)
    for cdetail in cdetails:
        # m_summary is the contract in details
        print('Expiry:', cdetail.m_summary.m_expiry)


sys.exit(0)  # Ensure ib thread is terminated

The output:

Server Version: 76
TWS Time at connection:20160112 23:17:15 CET
---------- <managedAccounts accountsList=D999999>
---------- <nextValidId orderId=1>
---------- <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfuture>
---------- <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
---------- <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:cashfarm>
---------- <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm.us>
---------- <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ushmds.us>
---------- <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ilhmds>
---------- <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:cashhmds>
---------- <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ethmds>
--------------------------------------------------

--  ('VTR', 'OPT', 'SMART')
Expiry: 20160219
Expiry: 20160219
...
...
...
Expiry: 20160819
Expiry: 20160819
--------------------------------------------------
--  ('ES', 'FUT', 'GLOBEX')
Expiry: 20160318
Expiry: 20160617
Expiry: 20160916
Expiry: 20161216
Expiry: 20170317
like image 45
mementum Avatar answered Nov 10 '22 04:11

mementum