Skip to content
/ ibsync Public

Interactive Brokers Synchronous Golang Client

License

Notifications You must be signed in to change notification settings

scmhub/ibsync

Repository files navigation

Go Report Card Go Reference License: MIT

Interactive Brokers Synchronous Golang Client

ibsync is a Go package designed to simplify interaction with the Interactive Brokers API. It is inspired by the great ib_insync Python library and based on ibapi. It provides a synchronous, easy-to-use interface for account management, trade execution, real-time and historical market data within the IB ecosystem.

Caution

This package is in the beta phase. While functional, it may still have bugs or incomplete features. Please test extensively in non-production environments.

Getting Started

Prerequisites

  • Go version 1.23 or higher (recommended)
  • An Interactive Brokers account with TWS or IB Gateway installed and running

Installation

Install the package via go get:

go get -u github.com/scmhub/ibsync

Quick start

Here’s a basic example to connect and get the managed accounts list:

package main

import "github.com/scmhub/ibsync"

func main() {
	// Get the logger (zerolog)
	log := ibapi.Logger()
	ibsync.SetConsoleWriter() // pretty logs to console, for dev and test.

	// New IB client & Connect
	ib := ibsync.NewIB()

	err := ib.Connect()
	if err != nil {
		log.Error().Err(err).Msg("Connect")
		return
	}
	defer ib.Disconnect()

	managedAccounts := ib.ManagedAccounts()
	log.Info().Strs("accounts", managedAccounts).Msg("Managed accounts list")
}

Usage guide

Configuration

Connect with a different configuration.

// New IB client & Connect
ib := ibsync.NewIB()

err := ib.Connect(
    ibsync.NewConfig(
        ibsync.WithHost("10.74.0.9"),       // Default: "127.0.0.1".
        ibsync.WithPort(4002),              // Default: 7497.
        ibsync.WithClientID(5),             // Default: a random number. If set to 0 it will also retreive manual orders.
        ibsync.WithTimeout(1*time.Second),  // Default is 30 seconds.
    ),
)
if err != nil {
	log.Error().Err(err).Msg("Connect")
	return
}
defer ib.Disconnect()

Account

Account value, summary, positions, trades...

// Account Values
accountValues := ib.AccountValues()

// Account Summary
accountSummary := ib.AccountSummary()

// Portfolio
portfolio := ib.Portfolio()

// Positions
// Subscribe to Postion
ib.ReqPositions()
// Position Channel
posChan := ib.PositionChan()

// Trades
trades := ib.Trades()
openTrades := ib.OpenTrades()

Contract details

Request contract details from symbol, exchange

// NewStock("AMD", "", "")
amd := ibsync.NewStock("AMD", "", "")
cd, err := ib.ReqContractDetails(amd)
if err != nil {
	log.Error().Err(err).Msg("request contract details")
	return
}
fmt.Println("number of contract found for request NewStock(\"AMD\", \"\", \"\") :", len(cd))

Pnl

Subscribe to the pnl stream

// Request PnL subscription for the account.
ib.ReqPnL(account, modelCode)

// Get a PnL channel to receive updates...
pnlChan := ib.PnlChan(account, modelCode)

go func() {
	for pnl := range pnlChan {
		fmt.Println("Received PnL from channel:", pnl)
	}
}()

//... Or read the last PnL on the client state
pnl := ib.Pnl(account, modelCode)
fmt.Println("Current PnL:", pnl)

Orders

Place an order and create a new trade. Modify or cancel the trade. Cancel all trades

// Create the contract
eurusd := ibsync.NewForex("EUR", "IDEALPRO", "USD")

// Create the order
order := ibsync.LimitOrder("BUY", ibsync.StringToDecimal("20000"), 1.05)

// Place the order
trade := ib.PlaceOrder(eurusd, order)

go func() {
		<-trade.Done()
		fmt.Println("The trade is done!!!")
	}()

// Cancel the order
ib.CancelOrder(Order, ibsync.NewOrderCancel())

// Cancel all orders
ib.ReqGlobalCancel()

Bar data

Real time and historical bar data.

// Historical data
barChan, _ := ib.ReqHistoricalData(eurusd, endDateTime, duration, barSize, whatToShow, useRTH, formatDate)
var bars []ibsync.Bar
for bar := range barChan {
    bars = append(bars, bar)
}

// Historical data up to date
barChan, cancel := ib.ReqHistoricalDataUpToDate(eurusd, duration, barSize, whatToShow, useRTH, formatDate)
go func() {
    for bar := range barChan {
        bars = append(bars, bar)
    }
}()
time.Sleep(10 * time.Second)
cancel()

// Real time bars
rtBarChan, cancel := ib.ReqRealTimeBars(eurusd, 5, "MIDPOINT", useRTH)
<-rtBarChan
cancel()

Tick data

Real time and historical tick data.

// Snapshot - Market price
snapshot, err := ib.Snapshot(eurusd)
if err != nil {
    panic(fmt.Errorf("snapshot eurusd: %v", err))
}
fmt.Println("Snapshot market price", snapshot.MarketPrice())

// Tick by tick data
tickByTick := ib.ReqTickByTickData(eurusd, "BidAsk", 100, true)
time.Sleep(5 * time.Second)
ib.CancelTickByTickData(eurusd, "BidAsk")

// HistoricalTicks
historicalTicks, err, done := ib.ReqHistoricalTicks(aapl, startDateTime, time.Time{}, 100, true, true)

Scanner

Request scanner parameters and scanner subscritpion

// Scanner Parameters
xml, err := ib.ReqScannerParameters()

// Scanner subscription
scanSubscription := ibsync.NewScannerSubscription()
scanSubscription.Instrument = "STK"
scanSubscription.LocationCode = "STK.US.MAJOR"
scanSubscription.ScanCode = "TOP_PERC_GAIN"

scanData, err := ib.ReqScannerSubscription(scanSubscription)

// Scanner subcscription with filter option
opts := ibsync.ScannerSubscriptionOptions{
	FilterOptions: []ibsync.TagValue{
		{Tag: "changePercAbove", Value: "20"},
		{Tag: "priceAbove", Value: "5"},
		{Tag: "priceBelow", Value: "50"},
	},
}

filterScanData, err := ib.ReqScannerSubscription(scanSubscription, opts)

Documentation

For more information on how to use this package, please refer to the GoDoc documentation and check the examples directory. You can also have a look at the ib_test.go file

Acknowledgments

Notice of Non-Affiliation and Disclaimer

Caution

This project is in the beta phase and is still undergoing testing and development. Users are advised to thoroughly test the software in non-production environments before relying on it for live trading. Features may be incomplete, and bugs may exist. Use at your own risk.

Important

This project is not affiliated with Interactive Brokers Group, Inc. All references to Interactive Brokers, including trademarks, logos, and brand names, belong to their respective owners. The use of these names is purely for informational purposes and does not imply endorsement by Interactive Brokers.

Important

The authors of this package make no guarantees regarding the software's reliability, accuracy, or suitability for any particular purpose, including trading or financial decisions. No liability will be accepted for any financial losses, damages, or misinterpretations arising from the use of this software.

License

Distributed under the MIT License. See LICENSE for more information.

Author

Philippe Chavanne - contact

Releases

No releases published

Packages

No packages published

Languages