Open vepak opened 4 years ago
What does the subscription request look like? Also, what's the error you're getting? Keep in mind that it may be hard to test during the weekend, the API seems to give very different results on the weekend compared to the weekdays.
Hi Alex,
Here is the subscription request:
ws.send("s+md+59392609")
as mentioned here https://interactivebrokers.github.io/cpwebapi/RealtimeSubscription.html s - Subscribe md - Market Data 59392609 - conId
As you mentioned I waited until Monday morning in India when market opens at NSE and tried agin.
I don't see any errors, but I'm not getting any response in on_message function. I've market data subscription for the markets as I'm getting individual ticker details.
Whenever you got some time could you try connecting over websockets?
Thank you, Vamsi.
hey, just checking if you have endpoint for websockets in your lib? Thanks!
I have the same issue and have tried opening a ticket with IBKR last week. No answers yet.
Same issue. I can connect to the socket and send subscription messages but no response data is received.
@sandybradley @benjaminpolk @vepak I believe that is more like a ssl cert issue. I created a self-signed-cert and managed to receive response
Code snippet:
import asyncio
import pathlib
import ssl
import websockets
import os
ssl_context = ssl.SSLContext(ssl.CERT_REQUIRED)
localhost_pem = pathlib.Path(__file__).with_name("self-signed-cert.pem")
ssl_context.load_verify_locations(localhost_pem)
# To allow https connection
if (not os.environ.get('PYTHONHTTPSVERIFY', '') and getattr(ssl, '_create_unverified_context', None)):
ssl._create_default_https_context = ssl._create_unverified_context
async def receive_messages(websocket):
while True:
try:
response = await websocket.recv()
except websockets.ConnectionClosed:
print(f"Terminated")
break
print(f"< {response}")
async def ib_websocket_connection():
uri = "wss://localhost:5000/v1/api/ws"
async with websockets.connect(
uri, ssl=ssl_context
) as websocket:
# Send market data subscription request
await websocket.send('smd+265598+{"fields":["31","83"]}')
await receive_messages(websocket)
asyncio.get_event_loop().run_until_complete(ib_websocket_connection())
asyncio.get_event_loop().run_forever()
Hello @pandaxbacon @areed1192 , I am getting this exact same data with the "topic : system, hb : 12234567", however, this is really not the data I am looking for. I am more specifically looking for tick data.
I am using the web socket API in javascript and in my case the data comes in as a blob which I then convert to json. Can you please share your thoughts, I have been on this for some time now.
@pandaxbacon Random question, did generating the self-signed certificate alleviate issues when navigating to the login page. I remember it always was warning issues that it wasn't a secure page.
I want get the same response using websocket.WebSocketApp and run_forever. How did should will refactor the code to?
import websocket as ws
import json
import ssl
wss = 'wss://localhost:500/v1/api/ws'
conn = ws.create_connection(wss,sslopt={"cert_reqs":ssl.CERT_NONE})
conn.send('smd+265598+{"fields":["31","83"]}')
conn.recv()
hi, by any chance was someone able to resolve this issue and if yes could you share the code ? i used ws:// connection instead of wss:// (no encryption in transit between client and gateway) but still getting only Unsolicited Message Types. if i sent 'smd+265598+{"fields":["31","83"]}' i receive answer always only once.
Hi. I think I made the code work and I am successfully receiving the streaming prices.
You can see my working code below. Hope it helps.
import json, os, websocket, time, syslog, ssl
from dotenv import load_dotenv
from datetime import datetime
#from lib.tickle import tickle
def subscribe():
start_time = time.time()
def on_message(ws, binarymessage):
message = binarymessage.decode()
syslog.syslog(syslog.LOG_INFO, message)
m = json.loads(message)
print (message)
if ("topic" in m) and (m["topic"] == "sts") and ("args" in m) and ("authenticated" in m["args"]) and (m["args"]["authenticated"] == True):
s = """smd+270639+{"tempo":1000,"snapshot":true,"fields":["31","70","71","82","84","85","86","87","88","7295","7296","7674","7675","7676","7677","TimestampBase","TimestampDelta","6509"]}"""
syslog.syslog(syslog.LOG_INFO, "Sending: {}".format(s))
ws.send(s)
if ((datetime.now().minute == 0) and (time.time() - start_time > 3 * 60)) or (time.time() - start_time > 60 * 60):
syslog.syslog(syslog.LOG_INFO, "Periodical restart of the streamer")
ws.close()
exit()
return
def on_error(ws, error):
syslog.syslog(syslog.LOG_ERR, "received error as {}".format(error))
def on_close(ws, close_status_code, close_msg):
syslog.syslog(syslog.LOG_INFO, "Connection closed {}".format(close_msg))
def on_open(ws):
#response = tickle()
#r = json.loads(response.text)
#print (response.text)
return
def ex_callback(callback, *args):
"""
Monkey patch for WebSocketApp._callback() because it swallows
exceptions.
"""
if callback is not None:
callback(ws, *args)
#websocket.enableTrace(True)
url = "wss://localhost:5000/v1/api/ws"
ws = websocket.WebSocketApp(url,
on_message = on_message,
on_error = on_error,
on_close = on_close,
on_open = on_open
)
ws._callback = ex_callback
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
if __name__ == "__main__":
subscribe()
This is very helpful, does anyone know how this is done in .NET? something like websocket sharpe
Hi Alex, Great lib, thank you for making this. After watching your video series, I'm trying to get continuous market data from IB Websocket API. I could able to connect to Client Portal gateway and also connection to websocket is successful, but I'm not able to subscribe to any quotes. Below is the code I used.
Any guidance on where I might be doing wrong/missing? Thank you.