Our Golang client is one of our most popular open source projects with over 350 forks/stars on Github. But why Go? Well, it is a seriously quick compiled programming language with great support for concurrency making it perfect for trading.
So what does the Bitfinex Golang client do? Well its a library created by the bitfinex team to help programmers interact with the Bitfinex websocket and rest interface. The lib offers tons of functionaity including creating new trades, managing existing orders, retrieving historical data and a lot more. You can find the client on girhub here: https://github.com/bitfinexcom/bitfinex-api-go
In this tutorial we are going to pull the bitfinex-api-go library, subscribe to new price updates and then begin making trades on the BTC/USD trading pair using the client websocket. We will also explore historical data using the rest interface.
Firstly, before we do anything, we need to pull the client from the Bitfinex repo. Simply run:
go get github.com/bitfinexcom/bitfinex-api-go
In order to access the Golang lib we need to import the package. Once we have done this we can create a new client object and tell it to connect to the Bitfinex websocket.
package main
import (
"context"
"log"
"github.com/bitfinexcom/bitfinex-api-go/v2"
"github.com/bitfinexcom/bitfinex-api-go/v2/websocket"
)
func main() {
client := websocket.New()
err := client.Connect()
if err != nil {
log.Printf("could not connect: %s", err.Error())
return
}
}
Now that we have an open connection to the Bitfinex api we can submit a request to begin receiving new trade updates on the BTCUSD pair. Once the Bitfinex receives this request it will start streaming every single newly executed trade on the given pair to to our client.
_, err = c.SubscribeTrades(context.Background(), bitfinex.TradingPrefix+bitfinex.XRPBTC)
if err != nil {
log.Fatal(err)
}
The client exposes a "Listener" channel which takes in all of the data received via the websocket. We can use this to log all incoming trades to the console
for obj := range c.Listen() {
switch obj.(type) {
case error:
log.Printf("EROR RECV: %s", obj)
default:
log.Printf("MSG RECV: %#v", obj)
}
}
Again, lets create and connect the Client but this time we need to specify our API_KEY and API_SECRET since are going to be creating new orders. In order to get an API key please go to www.bitfinex.com/api log into your Bitfinex account and select “Create New Key”. For this tutorial we need both ‘Read’ and ‘Write’ permissions for ‘Orders’.
package main
import (
"context"
"log"
"github.com/bitfinexcom/bitfinex-api-go/v2"
"github.com/bitfinexcom/bitfinex-api-go/v2/websocket"
)
func main() {
client := websocket.New().Credentials("BFX_KEY", "BFX_SECRET")
err := client.Connect()
if err != nil {
log.Printf("could not connect: %s", err.Error())
return
}
}
Lets create a new function that takes in the websocket client and submits a new order for 0.02 Bitcoin at a price of 5000. Since we don't want to use margin we will specify that the order should be executed on the exchange market.
func SubmitNewOrder(c *websocket.Client) {
or := &bitfinex.OrderNewRequest{
Symbol: "tBTCUSD",
CID: 123,
Amount: 0.02,
Type: "EXCHANGE LIMIT",
Price: 5000,
}
err := c.SubmitOrder(context.Background(), or)
if err != nil {
log.Fatal(err)
}
}
Now when we call this function, we need to be sure that our client has already passed the authentication process. So we will listen for an authentication success response before submitting our new order.
for obj := range client.Listen() {
switch obj.(type) {
case error:
log.Printf("channel closed: %s", obj)
break
case *websocket.AuthEvent:
// on authorize create new order
SubmitNewOrder(client)
default:
log.Printf("MSG RECV: %#v", obj)
}
}
We don't want to make blind trades so we can use the client rest interface to get all of the latest candles. For this we need to create a new instance of the rest client and then call the History
function which will provide us with a set of candles at the given interval for the given trading pair
package main
import (
"log"
bfx "github.com/bitfinexcom/bitfinex-api-go/v2"
"github.com/bitfinexcom/bitfinex-api-go/v2/rest"
"time"
)
func main() {
client := rest.NewClient()
candles, err := c.Candles.History(bfx.TradingPrefix+bfx.BTCUSD, bfx.FiveMinutes)
if err != nil {
log.Fatalf("Failed getting candles: %s", err)
}
log.Printf("length of candles is: %v", len(candles.Snapshot))
log.Printf("first candle is: %#v\n", candles.Snapshot[0])
log.Printf("last candle is: %#v\n", candles.Snapshot[len(candles.Snapshot)-1])
}
The above code takes the most recent batch of candles on the five min interval and logs them to the console
Now you have what it takes to ingest realtime/historical data and submit new orders using our Golang client! As always, if you would like to contribute to the repo then simply open a pull request to https://github.com/bitfinexcom/bitfinex-api-go
If you would like to see more examples or see the full code snippets of this tutorial then please head to https://github.com/bitfinexcom/bitfinex-api-go/tree/master/examples/v2