Algorithmic Trading on Coinbase Exchange

At Coinbase we’re working hard to build the world’s best bitcoin developer platform. Today, we’re adding a Coinbase Exchange gem to our list of supported client libraries. The Coinbase Wallet and Merchant APIs allow developers to securely store, send and receive bitcoin and to accept bitcoin payments. The Coinbase Exchange API allows developers to programmatically trade bitcoin with people around the world.

Customers have given us great feedback about their experiences and what features could make our platform more useful. We’ve learned that too often, people with an interesting trading algorithm in mind turn away because the barriers to entry seem too high. Customers should not feel hampered by technical details pertaining to the frameworks and libraries they use. We wanted to make it easy to build software to communicate with our servers.

When we build client libraries we attempt to automate anything that requires technical knowledge or seems arbitrary, with as light a footprint as possible. A good client library should provide all the functionality of the API, and nothing more. By default, methods should return data in the exact form that the server returns it.

We designed the Coinbase Exchange gem with algorithmic trading in mind. It’s an intuitive, stable interface that integrates with EventMachine for placing real-time trades based on information from our Websocket feed.

Stop-Loss Order Example

To demonstrate how easy it is to use our API, we’ll show how to use our gem to write a program that simulates a stop-loss trade. Let’s assume the price of 1 bitcoin is $250. We’re going to buy 10 bitcoin, and close our position immediately if the price drops below $245.

Setup

The first step is to create API credentials for your account. If you haven’t already, create a new key with Trade and View permissions.

REST Client

Next, let’s initialize our API client and place our initial trade. The gem provides both a synchronous client that’s based on Net::HTTP, as well as an asynchronous client that’s based on EM-HTTP. We’ll use the asynchronous client since we want to react to websocket messages as we receive them.

require 'coinbase/exchange'
require 'eventmachine'

rest_api = Coinbase::Exchange::AsyncClient.new(<api key>, <api secret>, <api pass>)

order = nil
rest_api.bid(10, 250) do |resp|
  order = resp
end

Websocket Client

The Websocket feed provides a real-time feed of all activity on the exchange. This is most frequently used for building a real-time orderbook, but can also be used to track the spot rate or changes to your own orders. We’ll need to listen to the Websocket feed to know as soon as the price drops below $245. Closing our position will require selling 10 bitcoin. We’re going to set the ask price comfortably below $245 to ensure it fills immediately. In this case, we’ll set the ask price to $125.

websocket = Coinbase::Exchange::Websocket.new(keepalive: true)

spot_rate = 0
websocket.match do |msg|
  spot_rate = msg.price
  if spot_rate <= 245
    rest_api.ask(10, 125) do
      EM.stop
    end
  end
end

EM.run { websocket.start! }

Health Monitor

It’s important that we monitor the health of the websocket to ensure that we don’t realize an unintended loss. If the feed stops responding, we’ll need to close our position immediately. We can accomplish this by pinging the websocket periodically.

EM.run do
  websocket.start!

  websocket_ping = Time.now
  EM::PeriodicTimer.new(1) do
    # The Websocket missed 3 consecutive pings
    if Time.now - websocket_ping > 30
      rest_api.ask(10, 125) do
        EM.stop
      end
    end
  end

  EM::PeriodicTimer.new(10) do
    websocket.ping { websocket_ping = Time.now }
  end
end

Conclusion

That’s it. Now you can develop algorithmic trading software using the same interface we offer to professional traders. Please refer to our Github repository and official documentation to learn about what else you can do. We’re excited to see what you build!

require 'coinbase/exchange'
require 'eventmachine'

rest_api = Coinbase::Exchange::AsyncClient.new(<api key>, <api secret>, <api pass>)
websocket = Coinbase::Exchange::Websocket.new(keepalive: true)

spot_rate = nil
websocket.match do |msg|
  spot_rate = msg.price
  if spot_rate <= 245
    rest_api.ask(10, 125) do
      EM.stop
    end
  end
end

order = nil
rest_api.bid(10, 250) do |resp|
  order = resp
end

EM.run do
  websocket.start!

  websocket_ping = Time.now
  EM::PeriodicTimer.new(1) do
    if Time.now - websocket_ping > 30
      rest_api.ask(10, 125) do
        EM.stop
      end
    end
  end

  EM::PeriodicTimer.new(10) do
    websocket.ping { websocket_ping = Time.now }
  end
end

Please note: We’re hiring engineers (both in our San Francisco office and remote anywhere in the world). If you’re interested in speaking with us about a role we’ve set up a coding challenge that you can take in about 30–45 minutes. You can also apply through our careers site if you prefer to start the conversation that way.

Written by John Duhamel