The API for Crypto Trading Bots

Crypto trading bots are one of the most commonly used tools used by traders. These applications can provide convenient ways for traders to execute strategies that would be tedious to implement.

Unfortunately, developers are having a tough time building trading applications. It takes a significant amount of time and patience to develop the infrastructure that connects to each exchange. Many teams incorrectly believe there are simple ways to scale trading infrastructure, but quickly learn that it’s far more complicated than it first appears.

Many trading services struggle to scale past even a single exchange integration. Each new exchange integration past the largest exchanges produces lower and lower returns, making it impractical to build a service for more than the top few exchanges.

The following sections will discuss how developers can integrate every major exchange without ever worrying about maintaining and scaling the complex infrastructure that is required for exchanges.

Crypto Trading Bots - The Complete Guide

Problems with Integrating Exchanges

Developers are having a difficult time building trading applications that connect to cryptocurrency exchanges.

When you’re setting out on a journey to build a cryptocurrency trading tool, such as a bot, it’s important to first understand the risks of building the exchange infrastructure from scratch.

Note: These are only some of the issues that should concern you. There are many more that we won’t discuss.

Inconsistency

Every exchange is different. No two exchanges support the same APIs, trading features, data formats, or behavior. There are no standards for how crypto exchanges should be built.

The result is every exchange integration is a new adventure. Not one of those pleasant adventures that make you feel alive inside. It’s like one of those adventures where you get lost for 2 months in the desert and can’t tell the difference between hallucinations and mirages anymore. Literally everything looks like an oasis, but in the end, it’s just more desert.

It can take months to understand the different pitfalls of each exchange. Developing a consistent way of trading on every exchange can seem almost impossible. The infrastructure you develop will need to change time and time again as you uncover new ways that exchanges mess up your previous design.

The inconsistency is not only limited to API endpoints. Assets across exchanges have different ticker symbols, names, and other identifying information. In order to support all of the assets on an exchange, developers need to manually map the assets across exchanges by researching what asset the exchange listed.

Since there are thousands of assets, the process can take weeks. Not to mention, every time an exchange lists a new asset, developers need to validate the new asset.

Automatically mapping assets is nearly impossible. To ensure accuracy, it needs to be a manual process.

The Shrimpy Developer APIs resolve this problem by automatically identifying and tagging assets across exchanges. The behavior for trading and formats we use for data are consistent across every exchange. Any manual processes are handled by the Shrimpy team, so you can focus on feature development.

Maintenance

As we previously mentioned, some exchanges list assets frequently. The process for managing the listing process, tagging assets, and mapping assets across exchanges is largely manual.

That’s not the only maintenance required for building trading infrastructure. Exchanges frequently go down for maintenance, update their APIs, or change the behavior of requests unexpectedly.

Each change made by an exchange requires developers to release updates, redeploy servers, and automatically detect when these changes are made. Under some conditions, exchanges won’t even notify developers when a change is coming. You will wake up one morning and the APIs will be different.

Not to mention the continuous efforts to integrate new features that are supported by the exchange, deprecate old features or endpoints, and update code as the conditions for the exchange change.

The Shrimpy Developer APIs resolve this problem by managing updates, redeploying infrastructure, and integrating new features without ever changing the API interface. Developers can rest easy at night knowing that they will wake up to a product that is humming along.

Rate Limits

Every exchange has different rate limits and rules for how you can interact with the APIs. In order to abide by these rules, developers are often forced to maintain a farm of servers that are required to handle the volume of trades the application executes.

This farm of servers requires coordination and intelligent routing to make sure the service is abiding by the API restrictions while still executing trades for each user in a timely manner.

As your number of users scale, this problem only increases in complexity. Managing hundreds of servers that each independently interface with exchanges becomes a nightmare.

The Shrimpy Developer APIs resolve this problem by managing the server farm for you. Our infrastructure scales with you, so whether you have 1 user or 1,000 users, there are no necessary changes to how you grow your infrastructure.

Cost

The server costs required to manage tens of thousands or hundreds of thousands of users is expensive. In fact, building a robust infrastructure would cost most teams anywhere from $3 - $6 / user / month. Although this sounds high, it is the cost to maintain such a large farm of servers connecting to exchanges.

Unfortunately, that doesn’t even include the development costs. It can be expensive to hire world-class developers who are experienced enough to build the infrastructure you need. The costs only climb as you need additional integrations.

Building infrastructure for exchanges is expensive.

The Shrimpy Developer APIs are inexpensive. The costs start at $1.40 / user / month and decrease as you on board more users.

User Account Management

Now that we understand the difficulties with managing exchange infrastructure, we will look at examples for how we can leverage the Shrimpy Developer APIs to simplify our development process.

To start, we need to know how to manage users, connect to user exchange accounts, and start accessing their account information.

With the Shrimpy APIs, each user is individually managed so it maps to the way you develop your application. If you have 1,000 users on your application, you will have 1,000 users created with the Shrimpy APIs.

Setting Up Our Python Environment

Before we get started, let’s set up our Python environment by installing the Shrimpy Python Library.

pip install shrimpy-python

Note: The Shrimpy Python Library is designed to work with Python3. If you are using Python2, please update your version of Python.

Shrimpy & Exchange API Keys

Whenever you see the following lines in the script examples, we must input our Shrimpy public and secret API keys. These are generated by signing up for Shrimpy and selecting to create new API keys.

shrimpy_public_key = '...'
shrimpy_secret_key = '...'

In addition to the Shrimpy API keys, we will see places in the code for exchange public and secret API keys. These keys are required to connect to exchange accounts.

exchange_public_key = '...'
exchange_secret_key = '...'

Create User

Every time a user signs up for your services, all you need to do is create a new user with Shrimpy. This process can look like the following.

# import required libraries
import shrimpy

# assign your Shrimpy Master API keys for later use
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

# create the Shrimpy client
client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# create a user which will be linked to our exchange
create_user_response = client.create_user('The Shrimp Master')
user_id = create_user_response['id']

Save the ‘user_id’ so it can be used in later scripts. This is the ID you will use to map your user to the user created with Shrimpy. This mapping can be saved somewhere like a database.

Connect Exchanges

Once you’ve created a user, it’s likely they will want to connect to their various exchanges. Shrimpy allows you to connect up to 20 exchange accounts per user by default (this limit can be increased upon request). The process for linking a new exchange account to a user is straight forward.

# import required libraries
import shrimpy

# assign your Shrimpy Master API keys for later use
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

# assign your exchange keys for which you wish to access the balance data
exchange_name = "bittrex"
exchange_public_key = '...'
exchange_secret_key = '...'

# assign the user_id that was generated in the last script example
user_id = '...'

# if you can't remember your 'user_id', retrieve it from Shrimpy
# it should be the first user if you only created one
users = client.list_users()
user_id = users[0]['id']

# create the Shrimpy client
client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# link our first exchange so we can access balance data
link_account_response = client.link_account(
    user_id,
    exchange_name,
    exchange_public_key,
    exchange_secret_key
)

account_id = link_account_response['id']

Save the ‘account_id’ so we can use it in later scripts. Each exchange account for the user will have a unique ID.

Get Account Balances

Once the exchange account is linked to a user, we can access the balances for this exchange account by running the following script.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# note: since we created a user in our previous example script, 
# we can just retrieve our list of users.
users = client.list_users()
user_id = users[0]['id']

# retrieve the accounts associated with this user
accounts = client.list_accounts(
    user_id
)
account_id = accounts[0]['id']

# access balance data for the user account you previously created
balance = client.get_balance(
    user_id,   # user_id
    account_id # account_id
)

The result of this script is a list of each asset that is owned by the user and the exact quantity of each asset.

Trading & Order Management

Without trading, building a trading bot would be impossible. The Shrimpy Developer APIs provide the most robust options for trading. These options streamline the development process, simplify strategies, and optimize the way trades are executed.

There are a few different order types that are supported by the Shrimpy developer APIs. The most important order types will be included in the discussion here.

Limit Orders

Shrimpy supports two different kinds of limit orders. These are IOC and GTC orders. While they both have the same premise, they have slightly different behaviors that make them ideal for different situations.

Immediate or Cancel (IOC) Orders

IOC orders are designed to execute immediately. The order should be placed at a price that is currently occupied by an open order so the order executes immediately at the specified price or better. If the market moves and the specified price is no longer available, the order will instantly be canceled and the funds locked in the order will be returned to the user.

Executing an IOC order would look something like this with Shrimpy.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# note: since we created a user in our previous example script, 
# we can just retrieve our list of users.
users = client.list_users()
first_user_id = users[0]['id']

# retrieve the accounts associated with this user
accounts = client.list_accounts(
    first_user_id
)
first_account_id = accounts[0]['id']

# access balance data for the user account you previously created
balance = client.get_balance(
    first_user_id,   # user_id
    first_account_id # account_id
)

# execute a IOC limit order

place_limit_order_response = client.place_limit_order(
    first_user_id,    # user_id
    first_account_id, # account_id
    'ETH',            # base_symbol
    'BTC',            # quote_symbol
    '0.01',           # quantity of base_symbol
    '0.026',          # price
    'SELL',           # side
    'IOC',            # time_in_force
)
limit_order_id = place_limit_order_response['id']

Notice how this exact script can be run for every exchange. You would not need to change anything other than the exchange account you are referencing to execute a trade on another exchange.

This behavior is unique to Shrimpy. Implementing the infrastructure yourself would require you to write custom code for every single exchange.

Note: The price for the trade included here is just an example price. The price should be taken based on the current state of the market. Do not run this script “as is”.

Good Til’ Cancel (GTC)

GTC orders are placed at a specific price and quantity. The order will remain open on the exchange until another trader purchases the order, or until you cancel the order. An open order that is taken by another trader incurs maker trading fees.

Maker fees are typically lower than taker fees on many exchanges since leaving open orders on the exchange adds liquidity to the market. For this reason, many exchanges want to reward the additional liquidity.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# note: since we created a user in our previous example script, 
# we can just retrieve our list of users.
users = client.list_users()
first_user_id = users[0]['id']

# retrieve the accounts associated with this user
accounts = client.list_accounts(
    first_user_id
)
first_account_id = accounts[0]['id']

# access balance data for the user account you previously created
balance = client.get_balance(
    first_user_id,   # user_id
    first_account_id # account_id
)

# execute a GTC limit order

place_limit_order_response = client.place_limit_order(
    first_user_id,    # user_id
    first_account_id, # account_id
    'ETH',            # base_symbol
    'BTC',            # quote_symbol
    '0.01',           # quantity of base_symbol
    '0.026',          # price
    'SELL',           # side
    'GTC',            # time_in_force
)
limit_order_id = place_limit_order_response['id']

Note: The price for the trade included here is just an example price. The price should be taken based on the current state of the market. Do not run this script “as is”.

Read more about Limit Orders

Smart Order Routing

Collecting data across hundreds of trading pairs and analyzing the data for optimized trade routing is complicated. For this reason, Shrimpy offers Smart Order Routing (SOR) right out of the box.

SOR automates the order execution, so you can spend more time managing where the funds should go, rather than how they get there. Shrimpy will intelligently route the order across trading pairs to ensure the best order execution.

Example: Say you want to trade ETH for LTC.

On any given exchange, there may be 10 different paths that can be taken to sell ETH and buy LTC. You could go ETH->BTC->LTC, ETH->LTC, ETH->USDT->LTC, ETH->USDC->LTC, and so on. Each of these will have different rates that are changing constantly.

SOR will automatically evaluate all of these options, break up the orders, and execute the optimal trades.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

# note: since we created a user in our previous example script, 
# we can just retrieve our list of users.
users = client.list_users()
first_user_id = users[0]['id']

# retrieve the accounts associated with this user
accounts = client.list_accounts(
    first_user_id
)
first_account_id = accounts[0]['id']

# access balance data for the user account you previously created
balance = client.get_balance(
    first_user_id,   # user_id
    first_account_id # account_id
)

# execute a market order
smart_order_response = client.create_trade(
    first_user_id,    # user_id
    first_account_id, # account_id
    'BTC',            # from_symbol
    'ETH',            # to_symbol
    '0.01'            # amount of from_symbol
    True              # enable smart_routing
)

API for Smart Order Routing

Live Market Data

In order to execute trades, we need live market data to make quick decisions on how and when to execute orders.

Shrimpy provides both a REST API and a Websocket API to ensure you can build an application with live data that works best for you.

REST API Endpoints

These REST API endpoints provide the easiest way for developers to access market data on-demand without connecting to websockets.

Order Books

You can access the latest order book snapshot by using the following endpoint. This will instantly return the snapshot of the live book that you can use to make decisions on how to execute trades.

import shrimpy

shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

orderbooks = client.get_orderbooks(
    'binance',  # exchange
    'XLM',      # base_symbol
    'BTC',      # quote_symbol
    10          # limit
)

Candlesticks

If you need charts that track the live updates of the market, you can request the latest candlesticks to keep up to date with every movement in the market.

This endpoint returns the last 1,000 candlesticks. If you need more candlesticks, you must use the “Historical Candlestick” endpoint.

import shrimpy

shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

candles = client.get_candles(
    'binance',  # exchange
    'XLM',      # base_trading_symbol
    'BTC',      # quote_trading_symbol
    '15m'       # interval
)

Websocket Endpoints

Real-time trading applications require real-time market data on a continuous basis. The easiest way to implement these strategies is by leveraging the order book and trade data websockets. These websockets keep subscribers up to date with every trade that is executed and every order that is placed on the exchange.

Order Book Websocket

The order book websocket will continuously send the latest changes to the order book. Shrimpy always immediately sends the updates as they become available.

import shrimpy


public_key = '...'
private_key = '...'

# This is a sample handler, it simply prints the incoming error message to the console
def error_handler(err):
    print(err)


# This is a sample handler, it simply prints the incoming message to the console
def handler(msg):
    print(msg)


api_client = shrimpy.ShrimpyApiClient(public_key, private_key)
raw_token = api_client.get_token()
client = shrimpy.ShrimpyWsClient(error_handler, raw_token['token'])

subscribe_data = {
    "type": "subscribe",
    "exchange": "binance",
    "pair": "ltc-btc",
    "channel": "orderbook"
}

# Start processing the Shrimpy websocket stream!
client.connect()
client.subscribe(subscribe_data, handler)

# Once complete, stop the client
client.disconnect()

Trade Websocket

The trade websocket sends each of the trades that are executed on the exchange. This tick-by-tick trade data provides the fastest way to view each trade that is made by all participants in the market.

import shrimpy


public_key = '...'
private_key = '...'

# This is a sample handler, it simply prints the incoming error message to the console
def error_handler(err):
    print(err)


# This is a sample handler, it simply prints the incoming message to the console
def handler(msg):
    print(msg)


api_client = shrimpy.ShrimpyApiClient(public_key, private_key)
raw_token = api_client.get_token()
client = shrimpy.ShrimpyWsClient(error_handler, raw_token['token'])

subscribe_data = {
    "type": "subscribe",
    "exchange": "binance",
    "pair": "ltc-btc",
    "channel": "trade"
}

# Start processing the Shrimpy websocket stream!
client.connect()
client.subscribe(subscribe_data, handler)

# Once complete, stop the client
client.disconnect()

Historical Market Data

Each of these historical data endpoints provides various data that can be used to evaluate the market at different times, backtest strategies, and analyze performance.

Historical Candlesticks (OHLCV)

Historical candlesticks can be used for charting, analysis, and developing new trading strategies. In Shrimpy, historical candlesticks are available for 1m5m15m1h6h, or 1d intervals. These intervals have been standardized across exchanges to prevent inconsistencies.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

candles = client.get_historical_candles(
    'Binance',
    'LTC',
    'BTC',
    '2019-05-19T00:00:00.000Z',
    '2019-05-20T00:00:00.000Z',
    100,
    '15m'
)

Historical Order Books

Historical order book snapshots are available across all exchange markets. These snapshots are taken on a 1-minute interval to provide one of the highest resolution order book snapshot periods available in the market. The depth of the order book is capped to the top 20 on each side of the order book.

Order book snapshots can be used to develop backtesting solutions, analyze the market over the long term, or research practical trading patterns.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

historical_orderbooks = client.get_historical_orderbooks(
    'Binance',
    'LTC',
    'BTC',
    '2019-05-19T00:00:00.000Z',
    '2019-05-20T00:00:00.000Z',
    100
)

Historical Tick-By-Tick Trades

Historical tick-by-tick trading data is often used by traders as a factor in building new trading strategies. This historical data is a complete history of every trade that was executed on an exchange’s trading pair.

import shrimpy

# use your Shrimpy API public and private keys to create the client
shrimpy_public_key = '...'
shrimpy_secret_key = '...'

client = shrimpy.ShrimpyApiClient(shrimpy_public_key, shrimpy_secret_key)

trades = client.get_historical_trades(
    'Binance',
    'LTC',
    'BTC',
    '2019-05-19T00:00:00.000Z',
    '2019-05-20T00:00:00.000Z',
    100
)

About Shrimpy

Shrimpy is an account aggregating platform for cryptocurrency. It is designed for both professional and novice traders to come and learn about the growing crypto industry. Trade with ease, track your performance, and analyze the market. Shrimpy is the trusted platform for trading over $13B in digital assets.

Follow us on Twitter for updates!