7

Interactive Brokers から特定の資産の価格を取得する方法を示す多くの例があります。ただし、1 つのアセットの一連のオプション全体を取得したい場合、どの特定のストライクがリストされているかわかりません。先物も同様で、現時点でどの有効期限が利用できるかわかりません。つまり、オプションについては、考えられるすべてのストライクをループしreqMktData、それぞれについて、sleep(1)1 秒あたりのリクエスト数の制限に達するのを避けるために 100 メッセージごとに作成します。明らかに、これらのメッセージの多くは、「要求に対してセキュリティ定義が見つかりませんでした」というエラーで返されます。

これは、存在しないアセットに多くの時間を浪費するため、間違ったアプローチのように見えます。これを行うためのよりクリーンな方法、またはそのような目的のための特別な機能はありますか?

4

3 に答える 3

9

Donn Lee の提案に従って、contractDetailsEnd のハンドラーを実装します。shashkello と 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
于 2014-09-02T16:35:26.320 に答える
4

私が IbPy を使い始めたのはそれほど前のことではありません。またtime.sleep、サンプルと今では上記の回答でイディオムを見ました。ibpyバックグラウンドで実行されているスレッドがあり、メッセージ受信メソッド/関数がそのスレッドで呼び出されるため、ベースのアプローチに移行するのが自然に思えましたqueue

上記の 2 つのコントラクト仕様のコードと以下の出力。

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

出力:

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
于 2016-01-12T22:20:47.287 に答える
3

これは自分で考え出しました。

上場証券の詳細を照会できる機能がありますreqContractDetails。E-mini SPX 先物 (シンボル ES) を要求するサンプル コードを以下に示します。

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

contracts = [] # to store all the contracts
def contractDetailsHandler(msg):
    contracts.append(msg.contractDetails.m_summary)

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

contract = Contract()
contract.m_symbol = "ES"
contract.m_exchange = "GLOBEX"
contract.m_currency = "USD"
contract.m_secType = "FUT"

con.reqContractDetails(1, contract)

time.sleep(2)

con.disconnect()

コントラクトがcontractsリストに保存されたので、次の方法ですべての有効期限を取得できます。

for c in contracts:
    print c.m_expiry

出力:

20140919
20141219
20150320
20150619
20150918

明らかな方法で、これはオプションにも拡張できます。

于 2014-08-18T03:36:15.563 に答える