Skip to content

Latest commit

 

History

History
203 lines (132 loc) · 8.68 KB

CONTRIBUTING.md

File metadata and controls

203 lines (132 loc) · 8.68 KB

Contributing to rust-ibapi

Table of Contents

Overview

The API is designed to provide a robust, efficient, and flexible interface for communicating with TWS (Trader Workstation) or IB Gateway. This API allows developers to build trading applications in Rust, leveraging its performance and safety features. The architecture is built around threads and channels for sending requests and responses between the client and the TWS.

The main thread handles user interactions with the API. The MessageBus runs on a dedicated thread. The MessageBus establishes the connection to TWS, sends messages from the client to TWS, and listens for and routes messages from TWS to the client via channels.

Getting Started

  1. Install Rust.

  2. Install additional development tools:

cargo install cargo-tarpaulin
cargo install cargo-audit
  1. Create a fork of the repository.

  2. Clone your fork and make sure tests are working:

git clone https://github.com/<your-github-username>/rust-ibapi
cd rust-ibapi
cargo test
  1. Set up your development environment:

    • We recommend using an IDE with Rust support, such as VS Code with the rust-analyzer extension.
    • Configure your IDE to use rustfmt and clippy for code formatting and linting.
  2. Make your changes.

  • Ensure tests are still passing and coverage hasn't dropped:
cargo test
cargo tarpaulin -o html
  • The coverage report will be saved as tarpaulin-report.html. Open it in your browser to view the coverage details.
  1. Submit a Pull Request

Coding Standards

We follow the Rust API Guidelines. Please ensure your code adheres to these guidelines. Use cargo fmt to format your code and cargo clippy to catch common mistakes and improve your Rust code.

Core Components

MessageBus

The MessageBus is a crucial component of the API, running on its own dedicated thread. Its responsibilities include:

  • Establishing and maintaining the connection to TWS
  • Sending messages from the client to TWS
  • Listening for messages from TWS
  • Routing incoming messages to the appropriate client channels

Explore MessageBus implementation for more details.

Client

The Client component runs on the main thread and provides the interface for user interactions with the API. It is responsible for:

  • Encoding user requests into the format expected by TWS
  • Sending requests to the MessageBus
  • Receiving responses from the MessageBus via channels
  • Decoding responses and presenting them to the user

Explore Client API for more details.

Request and Response Handling

The API uses a combination of request IDs and channels to manage the flow of messages:

  1. For requests with a request or order ID:
  • The Client generates a unique ID for the request.
  • The MessageBus creates a dedicated channel for responses based on the request ID.
  • Responses related to this request are sent through these channels.
  1. For requests without a request or order ID (due to TWS API design):
  • The MessageBus creates a shared channel for responses of that request type.
  • Responses related to these requests are routed through these shared channels.
  • Note: Since these responses are not tied to specific request IDs, distinguishing between responses from concurrent requests of the same type requires careful handling.

The recommended application design is a separate Client instance per thread to avoid message routing issues.

Extending the API

  1. Define the new API method
  • The API exposed to the user is defined on the Client struct.
  • Define the interface for the new API on the Client struct. The actual implementation of the API is delegated to modules grouped by accounts, contracts, market data, orders and news.
  • Include a docstring describing the API that includes and example of the API usage. for example.
  1. Ensure message identifiers ar defined.
  1. Update the message type to request ID map.
  • When processing messages received from TWS, the request id needs to be determined. This is not the same for all messages.
  • A map of message type to request id position is maintained and may need to be updated.
  1. Add an implementation for the API in the appropriate group.
  • Add an implementation for the API in the appropriate group: accounts, contracts, market data, orders or news.
  • The implementation will provide an encoder to convert the request to the TWS format
  • Send the message using the MessageBus.
  1. Implement a decoder for the response.
  • Implement a decoder for the response received from the MessageBus.
  • Responses contain a channel that can you used to read the results as they become available.
  • For APIs that return a single result, they may simply decode and return the result.
  • For a collection of results, return a Subscription that can be used to iterate over results.
  1. Add test cases.
  • Add test cases for the new functionality.
  • Run coverage analysis. Your addition should improve or maintain the current coverage.
  • Use cargo tarpaulin to generate coverage reports.
  1. Add an example.
  • Add an example showing the API usage to the examples folder.
  • Ensure your example is well-documented and can help users understand how to use the new API method.

Troubleshooting

The following environment variables are useful for troubleshooting:

  • RUST_LOG - Changes the log level. Possible values are trace, debug, info, warn, error.
  • IBAPI_RECORDING_DIR - If this is set, the library logs messages between the library and TWS to the specified directory.

For example, the following sets the log level to debug and instructs the library to log messages between it and TWS to /tmp/tws-messages:

RUST_LOG=debug IBAPI_RECORDING_DIR=/tmp/tws-messages cargo run --bin find_contract_details

Creating and publishing releases.

  1. Ensure build is clean and tests are passing.
cargo build --all-targets
cargo test
  1. Update version number.
  1. Create tag with new version number.
git tag vX.Y.Z
git push origin vX.Y.Z
  1. Create a release.
  1. Publish to crates.io.
  • Before publishing, run a dry run to catch any issues:
cargo publish --dry-run
  • If everything looks good, publish the crate:
cargo publish