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.
- Go version 1.23 or higher (recommended)
- An Interactive Brokers account with TWS or IB Gateway installed and running
Install the package via go get:
go get -u github.com/scmhub/ibsyncHere’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") }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 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()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))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)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()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()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)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)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
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.
Distributed under the MIT License. See LICENSE for more information.
Philippe Chavanne - contact