Learn how to use the FTX Rest API in Python to trade cryptocurrencies and develop crypto applications in this comprehensive guide.
If you’re new to FTX.US, use the following link to save 5% on all of your trade fees.
You can download the code at Analyzing Alpha GitHub Repo.
What is FTX?
FTX is a cutting-edge cryptocurrency exchange platform. With FTX, you can trade various assets like futures and options on top cryptocurrencies at competitive prices with significant leverage.
Sam Bankman-Fried and Gary Wang founded FTX in May of 2019. Since then, it has become one of the most popular exchanges for traders from all backgrounds who want access to provide liquidity and profitable opportunities when trading these highly volatile markets.
FTX.com is unavailable in the U.S. and others due to location restrictions, which is why the team came up with a solution.
FTX vs. FTX.US
FTX.US is the US-regulated cryptocurrency exchange brought to you by the FTX.com team. It’s built from the ground up to be a market-leading U.S. cryptocurrency exchange.
Should You Use FTX?
FTX and FTX.US are two of the best cryptocurrency exchanges for both discretionary and algorithmic traders due to the depth of the order book and the availability of assets to trade.
This isn’t a surprise considering Sam came from Jane Street Capital, which earned the top spot when we surveyed proprietary trading firms and is also backed by legends such as Paul Tudor Jones.
Why You Shouldn’t Use FTX
From an algorithmic trading perspective, the only downside to using FTX or FTX.US is that it doesn’t provide a trading test server.
With this out of the way, let’s get to the code.
FTX REST API Python Tutorial
This tutorial aims to teach you how to use the FTX Rest API. FTX provides many different API endpoints, including:
- Markets
- Futures
- Account
- Wallet
- Orders
- Fills
I’m going to show you how to interact with the Market API. You’ll be able to work with the other components of the FTX API without breaking a sweat in roughly 30 minutes.
Let’s get started.
Set up your Python Environment
The first thing you’ll want to do is create a python virtual environment and activate it.
$ mkdir project_dir
$ cd project_dir
$ python3 -m venv venv
$ source ./venv/bin/activate
We’ll then use pip to install all of the necessary packages. I will demo using the API within Jupyter Notebook, so I’ll install that, too.
pip install -U pip
pip install notebook pandas requests ciso8601
We’ll also want to download the Python FTX API client. You can do that by downloading the raw file from the FTX GitHub Repo or using curl.
curl is a handy *nix command-line utility that allows you to transfer data over various protocols. It stands for “Client URL”.
curl https://raw.githubusercontent.com/ftexchange/ftx/master/rest/client.py -o client.py
Let’s create a python file named local_settings.py to store our API key. Creating a dictionary to store local settings is helpful, and you can save the contents into git with git-crypt.
ftx = {
'apy_key':'',
'api_secret':''
}
With the environment set up, let’s get a free API key. I will be using FTX.US, but you can follow the same steps if you’re not a U.S. resident at the FTX.com exchange.
Get FTX.US API Key
You will first need to register for an account.
You’ll then want to go to settings found within the dropdown menu when clicking your login name and selecting API.
You’ll then want to create an API key. If you’re not going to place trades, select a read-only key; otherwise, you’ll need a key with trading permissions. If you’re inclined, you can also have both.
Get Required Imports
import datetime
import requests
import pandas as pd
from client import FtxClient
from local_settings import ftx as settings
Using the FTX Market API
Using the Markets API is easy. The Markets API allows us to get all of the market data. We’ll be greeted with the following information when we make a request.
Field | Type | Value | Description |
---|---|---|---|
name | string | BTC-0628 | e.g. “BTC/USD” for spot, “BTC-PERP” for futures |
baseCurrency | string | BTC | spot markets only |
quoteCurrency | string | USD | spot markets only |
quoteVolume24h | number | 28914.76 | |
change1h | number | 0.012 | change in the past hour |
change24h | number | 0.0299 | change in the past 24 hours |
changeBod | number | 0.0156 | change since start of day (00:00 UTC) |
highLeverageFeeExempt | boolean | false | |
minProvideSize | number | 0.001 | Minimum maker order size (if >10 orders per hour fall below this size) |
type | string | future | “future” or “spot” |
underlying | string | BTC | future markets only |
enabled | boolean | true | |
ask | number | 3949.25 | best ask |
bid | number | 3949.00 | best bid |
last | number | 3949.00 | last traded price |
postOnly | boolean | false | if the market is in post-only mode (all orders get modified to be post-only, in addition to other settings they may have) |
price | number | 10579.52 | current price |
priceIncrement | number | 0.25 | |
sizeIncrement | number | 0.0001 | |
restricted | boolean | false | if the market has nonstandard restrictions on which jurisdictions can trade it |
volumeUsd24h | number | 28914.76 | USD volume in past 24 hours |
Get All Market Data
Let’s start by getting all available markets. We need to use the requests library to request the appropriate API endpoint.
# GET /markets
api_url = 'https://ftx.us/api'
api = '/markets'
url = api_url+api
url
'https://ftx.us/api/markets'
Now we’ll use requests to get the market response data.
markets = requests.get(url).json()
data = markets['result']
data
{'name': 'AAVE/USD',
'enabled': True,
'postOnly': False,
'priceIncrement': 0.01,
'sizeIncrement': 0.01,
'minProvideSize': 0.01,
'last': 146.85,
'bid': 147.07,
'ask': 147.21,
'price': 147.07,
'type': 'spot',
...
Since JSON format isn’t that easy to read, let’s convert it into a pandas dataframe.
df = pd.DataFrame(data)
df = df.set_index('name')
# using iloc to make it readable
df.iloc[:,:4].head()
enabledpostOnlypriceIncrementsizeIncrement
name
AAVE/USDTrue False 0.010000 0.010
AAVE/USDTTrue False 0.010000 0.010
AUD/USDTrue False 0.000100 1.000
BAT/USDTrue False 0.000025 1.000
BCH/BTCTrue False 0.000001 0.001
Pretty easy, right? This will become second nature soon enough.
Get an Individual Market Data
You can use the following to get a single market.
# GET /markets/{market_name}
market_name = 'ETH/USD'
path = f'/markets/{market_name}'
url = api_url + path
url
'https://ftx.us/api/markets/ETH/USD'
Now let’s make the request and output the response as a dataframe.
res = requests.get(url).json()
df = pd.DataFrame(res)['result']
df
ask 2478.3
baseCurrency ETH
bid 2478.0
change1h 0.010768
change24h 0.044292
changeBod 0.017785
enabled True
highLeverageFeeExempt True
largeOrderThreshold 5000.0
last 2477.1
minProvideSize 0.001
name ETH/USD
postOnly False
price 2478.0
priceIncrement 0.1
quoteCurrency USD
quoteVolume24h 88033400.0916
restricted False
sizeIncrement 0.001
type spot
underlying None
volumeUsd24h 88033400.0916
Name: result, dtype: object
Get Historical Data
You can also get historical data for any of the markets. Let’s get the data as daily bars starting from 2022.
# GET /markets/{market_name}/candles?resolution={resolution}&start_time={start_time}&end_time={end_time}
# Days is 60 seconds * 60 minutes * 24
resolution = 60*60*24
resolution
86400
start = datetime.datetime(2022,1,1).timestamp()
start
1641013200.0
We’ll now construct the URL string and request as we’ve done above.
path = f'/markets/{market_name}/candles?resolution={resolution}&start={start}'
url = api_url + path
url
'https://ftx.us/api/markets/ETH/USD/candles?resolution=86400&start=1641013200.0'
And we’ll put the data into the dataframe and clean up the index.
res = requests.get(url).json()
df = pd.DataFrame(res['result'])
df['date'] = pd.to_datetime(df['startTime'])
df = df.set_index('date')
df = df.drop(columns=['startTime', 'time'])
df
open high low close volume
date
2020-03-23 00:00:00+00:00130.355 136.935 129.625 136.775 0.0
2020-03-24 00:00:00+00:00136.770 144.210 132.855 138.790 0.0
2020-03-25 00:00:00+00:00138.785 142.980 132.750 136.115 0.0
2020-03-26 00:00:00+00:00136.105 140.125 133.615 138.890 0.0
2020-03-27 00:00:00+00:00138.890 141.955 129.320 131.425 0.0
Get Order Book Data
We can also get the order book at varying depths.
Name | Type | Value | Description |
---|---|---|---|
market_name | string | BTC-0628 | Required. Name of the market. |
depth | number | 35 | max 100, default 20 |
Let’s take a look at the order book for ETH/USD.
# GET /markets/{market_name}/orderbook?depth={depth}
depth = 20
path = f'/markets/{market_name}/orderbook?depth={depth}'
url = api_url + path
url
'https://ftx.us/api/markets/ETH/USD/orderbook?depth=20'
res = requests.get(url).json()
bids = pd.DataFrame(res['result']['bids'])
asks = pd.DataFrame(res['result']['asks'])
bids.columns = ['Bid Price', 'Bid Amount']
asks.columns = ['Ask Price','Ask Amount']
bids.head()
Bid PriceBid Amount02475.819.02512475.30.22422475.24.40032475.01.80042474.925.617
Let’s merge the two dataframes on their range indices.
df = pd.merge(bids, asks, left_index=True, right_index=True)
df.head()
Bid PriceBid AmountAsk PriceAsk Amount
02475.8 19.025 2477.6 90.957
12475.3 0.224 2477.9 4.400
22475.2 4.400 2478.2 1.800
32475.0 1.800 2478.5 0.035
42474.9 25.617 2479.2 89.517
And we can get the summary statistics using describe. Notice the depth as the count variable.
df.describe()
Bid PriceBid AmountAsk PriceAsk Amount
count20.000000 20.000000 20.000000 20.000000
mean2469.810000 32.653350 2483.470000 91.586000
std5.285322 81.233445 4.152374 123.888884
min2460.500000 0.142000 2477.600000 0.018000
25%2464.675000 1.105000 2480.100000 1.944000
50%2471.650000 2.419000 2483.600000 4.700000
75%2474.600000 9.818750 2486.300000 217.624250
max2475.800000 291.635000 2490.600000 322.424000
Now let’s merge the two dataframes and rename the columns.
df = pd.merge(bids, asks, left_index=True, right_index=True)
df.head()
Bid PriceBid AmountAsk PriceAsk Amount
02475.8 19.025 2477.6 90.957
12475.3 0.224 2477.9 4.400
22475.2 4.400 2478.2 1.800
32475.0 1.800 2478.5 0.035
42474.9 25.617 2479.2 89.517
Get Trades
Getting the recent trades for any market is also easy.
Name | Type | Value | Description |
---|---|---|---|
market_name | string | BTC-0628 | name of the market |
start_time | number | 1559881511 | optional |
end_time | number | 1559881711 | optional |
# GET /markets/{market_name}/trades
path = f'/markets/{market_name}/trades'
url = api_url + path
url
'https://ftx.us/api/markets/ETH/USD/trades'
res = requests.get(url).json()
df = pd.DataFrame(res['result'])
df.head()
id price size side liquidation time
0231386382481.70.044 buy False 2022-01-28T20:34:04.660049+00:00
1231386322480.818.422 buy False 2022-01-28T20:34:00.089735+00:00
2231386252481.80.026 buy False 2022-01-28T20:33:59.123590+00:00
3231386242481.80.018 buy False 2022-01-28T20:33:59.123590+00:00
4231385252481.74.400 sell False 2022-01-28T20:33:22.179278+00:00
Working with FTX Futures
Now that you’ve learned how to use the Markets API, using the Futures API is just as easy. I’ll get you started. One thing to note is that futures are not available through the ftx.us API.
First, check out the futures API documentation. You’ll notice we need to make a get request to /futures. Let’s create the request URL and use requests to get the data.
url = 'https://ftx.com/api/futures'
res = requests.get(url).json()
res
'success': True,
'result': [{'name': '1INCH-PERP',
'underlying': '1INCH',
'description': '1INCH Token Perpetual Futures',
'type': 'perpetual',
'expiry': None,
'perpetual': True,
'expired': False,
...
df = pd.DataFrame(res['result'])
df.head()
df = pd.DataFrame(res['result'])
# Using iloc to make it readable
df.iloc[:,:4].head()
name underlying description type
01INCH-PERP1INCH1INCH Token Perpetual Futures perpetual
11INCH-03251INCH1INCH Token March 2022 Futures future
2AAPL-0325AAPLApple March 2022 Futures future
3AAVE-PERPAAVEAave Perpetual Futures perpetual
4AAVE-0325AAVEAave March 2022 Futures future
The Bottom Line
FTX and its U.S. counterpart FTX.US are two of the best exchanges in the crypto space. If you’re interested in algo trading or simply looking for a great data source, FTX has an easy-to-use REST API to get you what you need.