Skip to content

Instantly share code, notes, and snippets.

@JacobPlaster
Created January 30, 2019 13:01
Show Gist options
  • Save JacobPlaster/6b7e5890751866a8ebb2bfe911e94fa4 to your computer and use it in GitHub Desktop.
Save JacobPlaster/6b7e5890751866a8ebb2bfe911e94fa4 to your computer and use it in GitHub Desktop.
bfx_go_client_tutorial

Tutorial: Trading cryptos on the Bitfinex platform using Golang

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.

Installing the client

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

Subscribing to BTC/USD price updates

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)
  }
}

Creating a new limit order

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)
  }
}

Get historical candles

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

Thanks for reading!

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment