获取 SPY 股价

Get SPY share price

我已经创建了一个 demo 帐户,我正在尝试使用以下代码接收延迟报价,但到目前为止都失败了。

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

class Downloader(object):
    field4price = ''

    def __init__(self):
        self.tws = ibConnection('localhost', 7496, 9003)
        self.tws.register(self.tickPriceHandler, 'TickPrice')
        self.tws.connect()
        self._reqId = 5 # current request id

    def tickPriceHandler(self,msg):
        if msg.field == 4:
            self.field4price = msg.price
            #print '[debug]', msg

    def requestData(self,contract): 
        self.tws.reqMarketDataType(3)
        self.tws.reqMktData(self._reqId, contract, '', 1)
        self._reqId+=1

if __name__=='__main__':
    dl = Downloader()
    c = Contract()
    c.m_symbol = 'SPY'
    c.m_secType = 'STK'
    c.m_exchange = 'SMART'
    c.m_currency = 'USD'
    dl.requestData(c)
    sleep(3)
    print('Price - field 4: ', dl.field4price)

由于我使用的是模拟账户,因此我必须处理延迟数据,因此我添加了 self.tws.reqMarketDataType(3)(参见 link)。我的问题是 dl.field4price return 是 SPY 符号的空列表,这是不可能的。考虑到前面的代码,我怎样才能得到 SPY 的股价?我做错了吗?

我不知道你有没有想出来,但是 IB 已经强制升级了,所以我现在使用的是 963 版本。我只是添加了我的建议并将延迟的请求添加到旧示例中。我使用加拿大股票,因为我没有订阅,但也许这根本不重要。

from ibapi import wrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper #just for decorator
from ibapi.common import *
from ibapi.contract import *
from ibapi.ticktype import *

class TestApp(wrapper.EWrapper, EClient):
    def __init__(self):
        wrapper.EWrapper.__init__(self)
        EClient.__init__(self, wrapper=self)
        self.count = 0

    @iswrapper
    def nextValidId(self, orderId:int):
        print("nextValidOrderId:", orderId)
        self.nextValidOrderId = orderId

        #here is where you start using api
        contract = Contract()
        contract.symbol = "RY"
        contract.secType = "STK"
        contract.currency = "CAD"
        contract.exchange = "SMART"
        self.reqMarketDataType(3)
        self.reqMktData(1101, contract, "", False, None)

    @iswrapper
    def error(self, reqId:TickerId, errorCode:int, errorString:str):
        print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    @iswrapper
    def tickPrice(self, reqId: TickerId , tickType: TickType, price: float,
                  attrib:TickAttrib):
        print("Tick Price. Ticker Id:", reqId,
              "tickType:", TickTypeEnum.to_str(tickType),
              "Price:", price)
        #just disconnect after a bit
        self.count += 1
        if self.count > 10 : self.disconnect()

#I use jupyter but here is where you use if __name__ == __main__:
app = TestApp()
app.connect("127.0.0.1", 7497, clientId=123)
print("serverVersion:%s connectionTime:%s" % app.serverVersion(),app.twsConnectionTime()))
app.run()

这是输出的一部分,请注意您可以使用 ib 的枚举类型来获取报价类型的名称。

Error. Id: 1101 Code: 10167 Msg: Requested market data is not subscribed. Displaying delayed market data... Tick Price. Ticker Id: 1101 tickType: DELAYED_BID Price: 97.02 Tick Price. Ticker Id: 1101 tickType: DELAYED_ASK Price: 97.02 Tick Price. Ticker Id: 1101 tickType: DELAYED_LAST Price: 0.0

我打字的时候是 9:40,所以市场是开盘的,但还没有延迟 15 分钟。 0.0 的 DELAYED_LAST 需要过滤掉。我不认为我曾经见过 0.0 的实时最后,所以要小心。

我等到了 9:45,我收到了

Tick Price. Ticker Id: 1101 tickType: DELAYED_LAST Price: 97.63

准时。

因为我的开发工作大部分是在 RTH 之外进行的, 类型 4(最后价格)并不总是可用。 因此,我尝试使用类型 9(收盘价)作为替代方案。 全部资料可见here

亚历克斯