Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP} Preliminary realtime bars support for new IB #671

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

Al4ise
Copy link
Collaborator

@Al4ise Al4ise commented Dec 23, 2024

Description by Korbit AI

What change is being made?

Implement preliminary support for real-time market data bars using a WebSocket client in the Interactive Brokers (IB) API integration.

Why are these changes being made?

This change introduces a WebSocket-based solution for streaming real-time market data bars, addressing the need for timely market updates and overcoming the limitations of the previous polling mechanism. The websocket-client library is added as a new dependency to manage WebSocket connections effectively.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

Copy link
Contributor

korbit-ai bot commented Dec 23, 2024

Important

Required App Permission Update

Noise Reduction Improvements

This update requests write permissions for Commit Statuses in order to send updates directly to your PRs without adding comments that spam notifications. Visit our changelog to learn more.

Click here to accept the updated permissions

To accept the updated permissions, sufficient privileges are required

Copy link
Contributor

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Fix Detected
Functionality Unprotected WebSocket Callback Execution ▹ view
Functionality Missing Error Propagation to Subscribers ▹ view
Error Handling Incorrect WebSocket Error Logging Level ▹ view
Functionality Missing WebSocket Reconnection Logic ▹ view
Third-party Libraries Specify version for 'websocket-client' dependency. ▹ view
Error Handling Insufficient JSONDecodeError Logging ▹ view
Files scanned
File Path Reviewed
setup.py
lumibot/brokers/interactive_brokers_rest.py

Explore our documentation to understand the languages and file types we support and the files we ignore.

Need a new review? Comment /korbit-review on this PR and I'll review your latest changes.

Korbit Guide: Usage and Customization

Interacting with Korbit

  • You can manually ask Korbit to review your PR using the /korbit-review command in a comment at the root of your PR.
  • You can ask Korbit to generate a new PR description using the /korbit-generate-pr-description command in any comment on your PR.
  • Too many Korbit comments? I can resolve all my comment threads if you use the /korbit-resolve command in any comment on your PR.
  • Chat with Korbit on issues we post by tagging @korbit-ai in your reply.
  • Help train Korbit to improve your reviews by giving a 👍 or 👎 on the comments Korbit posts.

Customizing Korbit

  • Check out our docs on how you can make Korbit work best for you and your team.
  • Customize Korbit for your organization through the Korbit Console.

Current Korbit Configuration

General Settings
Setting Value
Review Schedule Automatic excluding drafts
Max Issue Count 10
Automatic PR Descriptions
Issue Categories
Category Enabled
Naming
Database Operations
Documentation
Logging
Error Handling
Systems and Environment
Objects and Data Structures
Readability and Maintainability
Asynchronous Processing
Design Patterns
Third-Party Libraries
Performance
Security
Functionality

Feedback and Support

Note

Korbit Pro is free for open source projects 🎉

Looking to add Korbit to your team? Get started with a free 2 week trial here

Comment on lines +1247 to +1254
try:
data = json.loads(message)
topic = data.get("topic")
if topic and topic.startswith("smd+"):
conid = topic.split("+")[1]
if conid in self.callbacks:
self.callbacks[conid](data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unprotected WebSocket Callback Execution category Functionality

Tell me more
What is the issue?

The callback execution is not protected against slow or blocking callbacks that could affect the WebSocket message processing loop.

Why this matters

If a callback takes too long to process, it will block the WebSocket message processing thread, potentially causing message queuing and memory issues.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +1262 to +1268
logging.info(f"WebSocket error: {error}")

def on_close(self, ws, close_status_code, close_msg):
logging.info("WebSocket connection closed.")
with self.lock:
self.ws = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Error Propagation to Subscribers category Functionality

Tell me more
What is the issue?

WebSocket error and close events are only logged but not propagated to the subscribers, leaving them unaware of connection issues.

Why this matters

Subscribers need to know about connection issues to implement appropriate error handling or retry logic in their applications.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +1262 to +1263
logging.info(f"WebSocket error: {error}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect WebSocket Error Logging Level category Error Handling

Tell me more
What is the issue?

WebSocket errors are logged at INFO level rather than ERROR level and without stack trace information.

Why this matters

WebSocket errors represent connection issues that could disrupt data flow and should be treated as errors with full context for proper debugging.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +1198 to +1210
base_url = self.data_source.base_url
if base_url.startswith("https://"):
ws_url = base_url.replace("https", "wss", 1)
else:
ws_url = base_url.replace("http", "ws", 1)

try:
if not hasattr(self, "wsc") or self.wsc is None:
self.wsc = IBKRWebSocketClient(f"{ws_url}/ws")
self.wsc.connect()

self.wsc.subscribe_to_realtime_bars(conid, callback, fields)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing WebSocket Reconnection Logic category Functionality

Tell me more
What is the issue?

The WebSocket client is not properly handling reconnection scenarios. If the connection drops, there's no automatic reconnection mechanism.

Why this matters

In a production environment, network interruptions are common. Without automatic reconnection, real-time data feeds will stop working until manual intervention.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

setup.py Outdated
@@ -47,6 +47,7 @@
"thetadata",
"holidays",
"psutil",
"websocket-client"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specify version for 'websocket-client' dependency. category Third-party Libraries

Tell me more

It's great that you're adding the 'websocket-client' dependency to enable real-time data functionality! To ensure compatibility and reproducibility, I recommend specifying a version or version range for this dependency in the install_requires list, similar to how versions are specified for the other dependencies. For example, you could use 'websocket-client>=1.0.0' to require version 1.0.0 or higher.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +1248 to +1258
data = json.loads(message)
topic = data.get("topic")
if topic and topic.startswith("smd+"):
conid = topic.split("+")[1]
if conid in self.callbacks:
self.callbacks[conid](data)
else:
logging.debug(f"Received message: {data}")
except json.JSONDecodeError:
logging.info("Received invalid JSON message.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insufficient JSONDecodeError Logging category Error Handling

Tell me more
What is the issue?

The JSONDecodeError exception handler logs at INFO level but provides no details about the invalid message that caused the error.

Why this matters

Without logging the raw message content, debugging invalid JSON messages becomes more difficult as there's no way to identify what caused the parsing failure.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant