11个版本

0.4.3 2024年5月21日
0.4.2 2024年2月23日
0.4.1 2023年9月15日
0.4.0 2023年8月29日
0.1.1 2023年4月9日

#10 in 金融

Download history 2/week @ 2024-04-26 2/week @ 2024-05-03 17/week @ 2024-05-10 179/week @ 2024-05-17 54/week @ 2024-05-24 67/week @ 2024-05-31 25/week @ 2024-06-07 7/week @ 2024-06-14 3/week @ 2024-06-21 23/week @ 2024-07-19 163/week @ 2024-07-26

每月186次下载
用于 golden

MIT 许可证

465KB
8K SLoC

Build License:MIT crates.io Documentation Coverage Status

简介

Rust语言的Interactive Brokers TWS API实现。这不是官方TWS API的直接移植。它提供了一个同步API,简化了交易策略的开发。

这是一个正在进行中的项目,并使用TWS 10.19进行了测试。此实现的参考主要基于C#源代码

此处跟踪开放问题。如果在运行过程中遇到问题或需要缺少的功能,请在报告新问题之前检查问题列表

欢迎贡献。

示例

以下示例展示了API的风格。这不是交易策略推荐,也不是一个完整的实现。

use std::collections::VecDeque;

use ibapi::contracts::Contract;
use ibapi::market_data::realtime::{BarSize, Bar, WhatToShow};
use ibapi::orders::{order_builder, Action, OrderNotification};
use ibapi::Client;

fn main() {
    let client = Client::connect("127.0.0.1:4002", 100).unwrap();

    let symbol = "TSLA";
    let contract = Contract::stock(symbol); // defaults to USD and SMART exchange.

    let bars = client.realtime_bars(&contract, BarSize::Sec5, WhatToShow::Trades, false).unwrap();

    let mut channel = BreakoutChannel::new(30);

    for bar in bars {
        channel.add_bar(&bar);

        // Ensure enough bars and no open positions.
        if !channel.ready() || has_position(&client, symbol) {
            continue;
        }

        let action = if bar.close > channel.high() {
            Action::Buy
        } else if bar.close < channel.low() {
            Action::Sell
        } else {
            continue;
        };

        let order_id = client.next_order_id();
        let order = order_builder::market_order(action, 100.0);

        let notices = client.place_order(order_id, &contract, &order).unwrap();
        for notice in notices {
            if let OrderNotification::ExecutionData(data) = notice {
                println!("{} {} shares of {}", data.execution.side, data.execution.shares, data.contract.symbol);
            } else {
                println!("{:?}", notice);
            }
        }
    }
}

fn has_position(client: &Client, symbol: &str) -> bool {
    if let Ok(mut positions) = client.positions() {
        positions.find(|p| p.contract.symbol == symbol).is_some()
    } else {
        false
    }
}

struct BreakoutChannel {
    ticks: VecDeque<(f64, f64)>,
    size: usize,
}

impl BreakoutChannel {
    fn new(size: usize) -> BreakoutChannel {
        BreakoutChannel {
            ticks: VecDeque::with_capacity(size + 1),
            size,
        }
    }

    fn ready(&self) -> bool {
        self.ticks.len() >= self.size
    }

    fn add_bar(&mut self, bar: &Bar) {
        self.ticks.push_back((bar.high, bar.low));

        if self.ticks.len() > self.size {
            self.ticks.pop_front();
        }
    }

    fn high(&self) -> f64 {
        self.ticks.iter().map(|x| x.0).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
    }

    fn low(&self) -> f64 {
        self.ticks.iter().map(|x| x.1).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
    }
}

可用API

账户

合约

历史市场数据

实时市场数据

订单

依赖项

~1.6–2.4MB
~42K SLoC