NAV Navbar
python

Introduction

Welcome to the FPG REST API! Floating Point Group provides a single point of access to cryptocurrency markets with powerful algorithmic tools, providing exchange connectivity, data ingestion, optimal order execution, and liquidity management. This API provides access to:

Real-Time Cryptocurrency Market Data

Order Management and Execution Engine

Account Management

Help us improve our product! Please don't hesitate to reach out with suggestions, bug reports, or any other questions/comments. Please feel free to drop us suggestions via this form

Notes

Any response field with a "falsy" value (e.g. empty string, empty array, null) is simply omitted from the response.

Base URLs

Beta API

https://{user_name}-staging.floating.group/v1

Live API

https://{user_name}.floating.group/v1

Authentication

The FPG API uses an HMAC-based auth scheme to validate the identity of a caller. Your API key and secret will be delivered to you upon registration. In the event that your credentials are lost or compromised, FPG will provide you with a new set of keys.

Creating a request

All requests must be authenticated and include the following headers:

Example Authentication Framework


import json, hmac, hashlib, time, requests
from requests.auth import AuthBase

# Before implementation, set environment variables API_KEY and API_SECRET

API_KEY =  # from environment variable
API_SECRET =  # from environment variable

class FPGAuth(AuthBase):
    def __init__(self, api_key, secret_key):
        self.api_key = api_key
        self.secret_key = secret_key

    def __call__(self, request):
        timestamp = str(int(time.time()))
        message = timestamp + self.api_key + request.path_url
        signature = hmac.new(
            bytearray(self.secret_key, 'utf-8'),
            bytearray(message, 'utf-8'),
            hashlib.sha256
        ).hexdigest()

        request.headers.update({
            'FPG-ACCESS-SIGN': signature,
            'FPG-ACCESS-TIMESTAMP': timestamp,
            'FPG-ACCESS-KEY': self.api_key,
        })
        return request

auth = FPGAuth(API_KEY, API_SECRET)

# Hit an error trying to fetch a nonexistent order
user_name = # FPG user name
base_url = f'https://{user_name}-staging.floating.group/v1'
r = requests.get(base_url + '/orders/foo', auth=auth)
print(r.status_code)
print(r.json())

Output

404
{'error': {'message': 'Order "orders/foo" does not exist.'}}

Market Data

GetExchange

Fetches all available currency markets on an exchange

See all symbols available for querying for market data.

Note that for an invalid exchange name, it will return an error stating that no data was found.

Further, not all symbols or exchanges that data is provided for are available for trading.

Request

import requests
exchangeName = "kraken"
r = requests.get(base_url + f'/v1/exchanges/{exchangeName}', auth=auth)
print(r.json())

GET /exchanges/{exchange}

Response

{"exchange":
  {
    "name": "KRAKEN",
    "symbols": [
      "EUR-GBP",
      "LINK-EUR",
      "ATOM-EUR",
      "ICX-EUR",
      "LSK-USD",
      ...
      "OMG-EUR",
      "EUR-CHF",
      "ZEC-EUR"
    ]
  }
}

Response

Field Type Description
name string name of the exchange
symbols List[symbol] List of market symbols available to be queried
error Error A human-readable error message

ListExchanges

List all exchanges and markets available for data querying.

GET /exchanges

Request

import requests
r = requests.get(base_url + f'/v1/exchanges', auth=auth)
print(r.json())

Response

{"exchanges": [
  {
    "name": "BINANCE",
    "symbols": [
      "VIB-BTC",
      "ERD-BTC",
      "KEY-USDT",
      "DASH-BNB"
    ]
  },
  {
    "name": "COINBASEPRO",
    "symbols": [
      "BAT-USDC",
      "GNT-USDC",
      "KNC-USD"
    ]
  }]
}

Response

Field Type Description
exchanges ListExchangeMarkets List of markets available for data coverage
error Error A human-readable error message

GetOrderbook

Get one or multiple orderbooks for a given market across multiple exchanges

GET /book/{symbol}

Parameters

Name In Type Required Description
symbol path string true A market symbol, represented as {base}-{quote}. Must represent a valid market for all requested exchanges.
exchanges query array[string] true A list of exchange names.
consolidated query boolean(boolean) false A boolean flag to request an aggregated orderbook response.

Request

import requests

base = 'BTC'
quote = 'USD'
symbol = f'{base}-{quote}'
exchangeA = 'KRAKEN'
exchangeB = 'GEMINI'

r = requests.get(base_url + f'/book/{symbol}?exchanges={exchangeA}&exchanges={exchangeB}', auth=auth)

print(r.json())

Response

{
  "orderbooks": [
    {
      "level": "ORDERBOOK_LEVEL_TWO",
      "exchangeName": "KRAKEN",
      "symbol": "BTC-USD",
      "updateType": "ORDERBOOK_UPDATE_TYPE_SNAPSHOT",
      "timestamp": "2019-05-16T22:11:35.397Z",
      "sequenceHigh": "0",
      "sequenceLow": "0",
      "bids": [
        {
          "price": 7902.9,
          "size": 1.894
        }
      ],
      "asks": [
        {
          "price": 7905.6,
          "size": 0.184
        }
      ]
    }
  ]
}

Response

Field Type Description
orderbooks List[Orderbook] List of orderbooks
error Error A human-readable error message

Private Data

GetBalance

Get balance across multiple exchanges

Balance is split into three catagories: free, used, and total. Total should always equal free + used.

GET /v1/balances

Parameters

Name In Type Required Description
exchanges query array[string] false A list of exchange names. All exchanges with balance returned if not provided

Request

import requests

exchangeA = 'COINBASEPRO'
exchangeB = 'GEMINI'

r = requests.get(base_url + f'/v1/balances?exchanges={exchangeA}&exchanges={exchangeB}', auth=auth)

print(r.json())

GET /orders

Response

{
  "balance": {
    "coinbasepro": {
      "currencies": {
        "USDC": {
          "free": "1000",
          "total": "1000"
        }, 
        ...
        "USD": {
          "free": "17376.89",
          "total": "17376.89"
        }
      }
    },
    "consolidated": {
      "currencies": {
        "ZEC": {
          "free": "200",
          "total": "200"
        },
        ...
        "USD": {
          "free": "47183.6729",
          "used": "579.3000",
          "total": "47762.9729"
        },
        "USDC": {
          "free": "1000",
          "total": "1000"
        }
      }
    },
    "gemini": {
      "currencies": {
        "USD": {
          "free": "3566450.78",
          "used": "579820.30",
          "total": "4146271.08"
        },
        ...
        "ETH": {
          "free": "200",
          "total": "200"
        }
      }
   }
  }
}

Response

Name In Type Required Description
exchanges query array[string] false A list of exchange names.
Field Type Description
balance map<string,Balance> Balance of all requested exchanges
error Error A human-readable error message

ListRecords

List records in user's ledger in reverse chronological order by createdTime

Request

import requests

r = requests.get(base_url + '/v1/records', auth=auth)

print(r.json())

Response

{
  "records": [
    {
      "id": "10004",
      "createdTime": "2019-05-14T19:57:38.123Z",
      "status": "FREE",
      "currency": "USD",
      "amount": "-30000",
      "recordType": "Order",
      "exchangeName": "KRAKEN",
      "relatedInfo": "313aa279-62b1-475a-b702-633b1fd369db",
    },
    {
      "id": "10005",
      "createdTime": "2019-05-14T19:57:38.123Z",
      "status": "FREE",
      "currency": "BTC",
      "amount": "3",
      "recordType": "Order",
      "exchangeName": "KRAKEN",
      "relatedTxid": "10004",
      "relatedInfo": "313aa279-62b1-475a-b702-633b1fd369db",
    }
  ]
}

Parameters

Name In Type Required Description
filterBy query string false filter by record type ("order", "transaction""), empty means no filter

Response

Field Type Description
records ListRecord] requested records
error Error A human-readable error message

Orders

CreateOrder

Submit an order

Body

body = {
  "base": "BTC",
  "quote": "USD",
  "size": "6",
  "price": "5000",
  "algo": "ACTIVE",
  "orderType": "BUY",
  "exchangeNames": [
    "GEMINI", "KRAKEN"
  ]
}

Request

import requests

r = requests.post(base_url + '/orders', json=body, auth=auth)
print(r.json())

POST /orders

Parameters

Name In Type Required Description
order body Order true An order

Response

{
  "order": {
    "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a",
    "userName": "fizz",
    "createdTime": "2019-05-14T19:57:38.123Z",
    "status": "FPGOS_RUNNING",
    "base": "BTC",
    "quote": "USD",
    "size": "6",
    "price": "5000",
    "algo": "ACTIVE",
    "orderType": "BUY",
    "exchangeNames": [
      "KRAKEN", "GEMINI"
    ],
    "expectedStartTime": "2019-05-14T19:57:38.123Z",
    "expectedEndTime": "2019-05-14T19:57:38.123Z",
    "executionStartTime": "2019-05-14T19:57:38.123Z",
    "executionEndTime": "2019-05-14T19:57:38.123Z"
  },
  "suborders": [
    {
      "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/460ab297-bb33-41e3-ab75-50cdf7971917",
      "createdTime": "2019-05-21T12:05:42.382Z",
      "status": "FPGEOS_SCHEDULED",
      "base": "BTC",
      "quote": "USD",
      "algo": "ACTIVE",
      "orderType": "BUY",
      "exchangeName": "KRAKEN",
      "expectedSize": "6",
      "expectedPrice": "5000",
      "expectedStartTime": "2019-05-21T12:05:42.382Z",
      "expectedEndTime": "2019-05-21T12:05:42.382Z",
      "executionStartTime": "2019-05-21T12:05:42.382Z",
      "executionEndTime": "2019-05-21T12:05:42.382Z",
      "exchangeOrderId": "87654321"
    },
    {
      "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/ae6a5449-ff00-486a-835a-702eee9cba32",
      "createdTime": "2019-05-21T19:57:38.123Z",
      "status": "FPGEOS_SCHEDULED",
      "base": "BTC",
      "quote": "USD",
      "algo": "ACTIVE",
      "orderType": "BUY",
      "exchangeName": "GEMINI",
      "expectedSize": "6",
      "expectedPrice": "5000",
      "expectedStartTime": "2019-05-21T19:57:38.123Z",
      "expectedEndTime": "2019-05-21T19:57:38.123Z",
      "executionStartTime": "2019-05-21T19:57:38.123Z",
      "executionEndTime": "2019-05-21T19:57:38.123Z",
      "exchangeOrderId": "12345678"
    }
  ]
}

Response

Field Type Description
order Order The submitted order
suborders List[SubOrder] List of generated suborders in chronological order by expectedStartTime
error Error A human-readable error message

GetOrder

Get order by resource name

Request

import requests
order_id = 'af0a83a7-4a39-4f80-a607-4b50c3046e5a'
order = f'orders/{order_id}'
r = requests.get(base_url + f'/{order}', auth=auth)
print(r.json())

GET /{order}

Parameters

Name In Type Required Description
order path string true The order name

Detailed descriptions

order: The order resource name, in the format orders/{order} (e.g. order=orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a).

Response

{
  "suborders": [
    {
      "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/ae6a5449-ff00-486a-835a-702eee9cba37",
      "createdTime": "2019-05-14T19:57:38.123Z",
      "status": "FPGEOS_SCHEDULED",
      "base": "BTC",
      "quote": "USD",
      "algo": "ACTIVE",
      "orderType": "BUY",
      "exchangeName": "KRAKEN",
      "expectedSize": "5",
      "expectedPrice": "5000",
      "expectedStartTime": "2019-05-14T19:57:38.123Z",
      "expectedEndTime": "2019-05-14T19:57:38.123Z",
      "executionStartTime": "2019-05-14T19:57:38.123Z",
      "executionEndTime": "2019-05-14T19:57:38.123Z",
      "exchangeOrderId": "12345678"
    }
  ],
  "order": {
    "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a",
    "userName": "",
    "createdTime": "2019-05-14T19:57:38.123Z",
    "status": "FPGOS_RUNNING",
    "base": "BTC",
    "quote": "USD",
    "size": "5",
    "price": "5000",
    "algo": "ACTIVE",
    "orderType": "BUY",
    "exchangeNames": [
      "KRAKEN", "GEMINI"
    ],
    "execution_average_price": "5000",
    "execution_cost": "10000",
    "execution_fee": "20",
    "execution_size": "2",
    "expectedStartTime": "2019-05-14T19:57:38.123Z",
    "expectedEndTime": "2019-05-14T19:57:38.123Z",
    "executionStartTime": "2019-05-14T19:57:38.123Z",
    "executionEndTime": "2019-05-14T19:57:38.123Z"
  }
}

Response

Field Type Description
order Order Order
error Error A human-readable error message

CancelOrder

Cancel order by resource name

Request

import requests

order_id = 'orders/69d6c60d-e658-4577-8bce-40a80541c0f7'
r = requests.patch(base_url + '/v1/orders/{order_id}', auth=auth)
print(r.json())

PATCH /{order}

Parameters

Name In Type Required Description
order path string true The order name

Detailed descriptions

order: The order resource name, in the format orders/{order} (e.g. order=orders/1c45e8f7-76f1-4c65-9f7f-b301d3574317).

Response


{
  "order": [
    {
      "name": "orders/69d6c60d-e658-4577-8bce-40a80541c0f7",
      "userName": "users/fpg",
      "createdTime": "2019-08-14T03:05:28.688Z",
      "status": "FPGOS_PENDING_CANCEL",
      "base": "LTC",
      "quote": "USD",
      "size": "0.5",
      "price": "40",
      "algo": "DMA",
      "orderType": "BUY",
      "exchangeNames": [
        "BINANCE"
      ],
      "expectedStartTime": "2019-08-14T03:05:28.688Z",
      "expectedEndTime": "2019-08-14T03:05:28.688Z"
    }
  ]
}

ListOrders

List orders in reverse chronological order by createdTime

Request

import requests
status="FPGOS_RUNNING"
r = requests.get(base_url + f'/v1/orders?status={status}', auth=auth)
print(r.json())

GET /v1/orders

Parameters

Name In Type Required Description
status query string false The status of orders to request. Always appended with "FPGOS_". Can be: "SUBMITTING", "RUNNING", "COMPLETE", "PENDING_CANCEL", "CANCELLED", or "FAILED"

Response

{
  "orders": [
    {
      "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a",
      "userName": "users/fpg",
      "createdTime": "2019-05-14T19:57:38.123Z",
      "status": "FPGOS_COMPLETE",
      "base": "BTC",
      "quote": "USD",
      "size": "0.0021",
      "price": "9700.00",
      "algo": "DMA",
      "orderType": "BUY",
      "exchangeNames": ["KRAKEN"],
      "executionAveragePrice": "6619.05",
      "executionCost": "13.9",
      "executionSize": "0.0021",
      "executionFee": "20.12",
      "expectedStartTime": "2019-05-14T19:57:38.123Z",
      "expectedEndTime": "2019-05-14T19:57:38.123Z",
      "executionStartTime": "2019-05-14T19:57:38.123Z",
      "executionEndTime": "2019-05-14T19:57:38.123Z"
    }
  ]
}

Response

Field Type Description
orders List[Order] List of orders
error Error A human-readable error message

GetSubOrder

Get suborder by resource name

Request

import requests
order_id = 'af0a83a7-4a39-4f80-a607-4b50c3046e5a'
suborder_id = 'ae6a5449-ff00-486a-835a-702eee9cba37'
suborder = f'orders/{order_id}/suborders/{suborder_id}'
r = requests.get(base_url + f'/{suborder}', auth=auth)
print(r.json())

GET /{suborder}

Parameters

Name In Type Required Description
suborder path string true The suborder name

Detailed descriptions

suborder: The suborder resource name. It must have the format orders/{order}/suborders/{suborder}.

Response

{
  "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/ae6a5449-ff00-486a-835a-702eee9cba37",
  "createdTime": "2019-05-14T19:57:38.123Z",
  "status": "SCHEDULED",
  "base": "BTC",
  "quote": "USD",
  "algo": "ACTIVE",
  "orderType": "BUY",
  "exchangeName": "KRAKEN",
  "expectedSize": "5",
  "expectedPrice": "5000",
  "expectedStartTime": "2019-05-14T19:57:38.123Z",
  "expectedEndTime": "2019-05-14T19:57:38.123Z",
  "executionStartTime": "2019-05-14T19:57:38.123Z",
  "executionEndTime": "2019-05-14T19:57:38.123Z",
  "exchangeOrderId": "12345678"
}

Response

Field Type Description
suborder Suborder Suborder
error Error A human-readable error message

ListSuborders

List suborders in chronological order by expectedStartTime

Request

import requests
order_id = 'af0a83a7-4a39-4f80-a607-4b50c3046e5a'
order = f'orders/{order_id}'
r = requests.get(base_url + f'/{order}/suborders', auth=auth)
print(r.json())

GET /{order}/suborders

Parameters

Name In Type Required Description
order path string true The name of the order to get suborders for

Detailed descriptions

order: The name of the order to get suborders for. It must have the format orders/{order}.

Response

{
  "suborders": [
    {
      "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/ae6a5449-ff00-486a-835a-702eee9cba37",
      "createdTime": "2019-05-14T19:57:38.123Z",
      "status": "FPGEOS_SCHEDULED",
      "base": "BTC",
      "quote": "USD",
      "algo": "ACTIVE",
      "orderType": "BUY",
      "exchangeName": "KRAKEN",
      "expectedSize": "5",
      "expectedPrice": "5000",
      "expectedStartTime": "2019-05-14T19:57:38.123Z",
      "expectedEndTime": "2019-05-14T19:57:38.123Z",
      "executionStartTime": "2019-05-14T19:57:38.123Z",
      "executionEndTime": "2019-05-14T19:57:38.123Z",
      "exchangeOrderId": "12345678"
    }
  ]
}

Response

Field Type Description
suborders List[SubOrder] List of suborders
error Error A human-readable error message

Transactions

GetDepositAddress

Get a deposit address

Request

import requests

exchangeName = 'GEMINI'
currency = 'BTC'
url_path = f'/v1/transactions/deposit?exchangeName={exchangeName}&currency={currency}'

r = requests.get(base_url + url_path, auth=auth)
print(r.json())

GET /v1/transactions/deposit

Parameters

Name In Type Required Description
exchangeName query string true Exchange name
currency query string true Currency name

Response

{
  "depositAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
}

Response

Field Type Description
depositAddress string deposit address for a given currency and exchange
error Error A human-readable error message

CreateWithdraw

Create a withdraw request to an exchange

Body

body = {
  "amount": 1000,
  "exchangeName": GEMINI,
  "currency": BTC,
  "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
}

Request

import requests

url_path = f'/v1/transactions/withdraw'

r = requests.get(base_url, json=body, auth=auth)
print(r.json())

POST /v1/transactions/withdraw

Parameters

Name In Type Required Description
amount body float true Withdraw amount
exchangeName body string true Exchange name
currency body string true Currency name
address body string true Withdrawal address

Response

{
  "createdtime": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
  "exchangeName": "GEMINI",
  "currency": "BTC",
  "depositAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
}

Response

Field Type Description
createdTime string(date-time) Time that the order was created at
exchangeName string The name of the exchange that the suborder is executing on, limited to Order's exchanges
currency string Currency
depositAddress string Deposit Address
error Error A human-readable error message

Users

CreateUser

Create a user

Body

body = {
  "permission_level": "ADMIN"
}

Request

import requests

r = requests.post(base_url + '/v1/users', json=body, auth=auth)
print(r.json())

POST /v1/users

Parameters

Name In Type Required Description
permissionLevel body string False Permissionlevel for the created User: Default is TRADER

Response

{
"user": {
  "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b",
  "tenant": "fpg-staging",
  "permissionLevel": "ADMIN",
  "keys": [
      {
          "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
          "publicKey": "blah-blah-blah",
          "secret": "blah blah blah blah",
          "description": "Nice keys"
      }
    ]
  }
}

Response

Field Type Description
user User User
error Error A human-readable error message

GetUser

Get a user

Body

body = {
  "permission_level": "ADMIN"
}

Request

import requests

user = '21c482ec-d87b-4f5d-9b85-3aa6228f018b'
url_path = f'/v1/users/{user}'
r = requests.post(base_url + url_path, auth=auth)
print(r.json())

GET /v1/{user=users/*}

Parameters

Name In Type Required Description
user query string True A user

Response

{
"user": {
  "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b",
  "tenant": "fpg-staging",
  "permissionLevel": "ADMIN",
  "keys": [
      {
        "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
        "publicKey": "blah-blah-blah",
        "secret": "blah blah blah blah",
        "description": "Nice keys"
      }
    ]
  }
}

Response

Field Type Description
user User A user
error Error A human-readable error message

ListUsers

List users

Request

import requests

user = '21c482ec-d87b-4f5d-9b85-3aa6228f018b'
url_path = f'/v1/users'
r = requests.get(base_url + url_path, auth=auth)
print(r.json())

GET /v1/users

Parameters

Name In Type Required Description
pageSize query number(double) False A user

Response

{
"users": [
{
  "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b",
  "tenant": "fpg-staging",
  "permissionLevel": "ADMIN",
  "keys": [
      {
        "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
        "publicKey": "blah-blah-blah",
        "secret": "blah blah blah blah",
        "description": "Nice keys"
      }
    ]
  },
{
  "name": "users/06947fbd-28ab-4066-9d4a-a94eeed5adfa",
  "tenant": "fpg-staging",
  "permissionLevel": "ADMIN",
  "keys": [
      {
        "name": "users/06947fbd-28ab-4066-9d4a-a94eeed5adfa/keys/43ccd6d4-b18e-40d3-965e-a31434288056",
        "publicKey": "blah-blah-blah",
        "secret": "blah blah blah blah",
        "description": "Nice keys"
      }
    ]
  }
}

Response

Field Type Description
users List[User] List of users
error Error A human-readable error message

CreateKey

Create keypair for user

Request

import requests

user = '21c482ec-d87b-4f5d-9b85-3aa6228f018b'
url_path = f'/v1/user=users/{user}}/keys'
r = requests.post(base_url + url_path, auth=auth)
print(r.json())

POST /v1/{user=users/*}/keys

Parameters

Name In Type Required Description
user query string True A user
description body string False Description of user

Response

{
"users": [
{
  "key":
    {
      "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
      "publicKey": "3da93a46-64b0-453a-9755-3e911f889bf3",
      "secret": "5c66af0f-66cd-4597-b975-91762c0de5f2",
      "description": "Nice keys"
    }
}
}

Response

Field Type Description
key Key FPG API Key
error Error A human-readable error message

DeleteKey

Delete key for user

Request

import requests
key = "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
url_path = f'/v1/{key}'
r = requests.delete(base_url + url_path, auth=auth)
print(r.json())

DELETE /v1/{key=users/*/keys/*}

Parameters

Name In Type Required Description
key query string True A user's key

Response

{
"users": [
  {
    "key":
      {
        "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
        "publicKey": "3da93a46-64b0-453a-9755-3e911f889bf3",
        "secret": "5c66af0f-66cd-4597-b975-91762c0de5f2",
        "description": "Nice keys"
      }
  }
]
}

Response

Field Type Description
key Key FPG API Key
error Error A human-readable error message

ListKeys

List keys for user

Request

import requests
user = "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b",
url_path = f'/v1/{user}/keys'
r = requests.get(base_url + url_path, auth=auth)
print(r.json())

GET /v1/{key=users/*/keys}

Parameters

Name In Type Required Description
key query string True A user's key

Response

{
"users": [
  {
    "key":
      {
        "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
        "publicKey": "3da93a46-64b0-453a-9755-3e911f889bf3",
        "secret": "5c66af0f-66cd-4597-b975-91762c0de5f2",
        "description": "Nice keys"
      }
  },
  ...
]
}

Response

Field Type Description
key Key FPG API Key
error Error A human-readable error message

Types

Exchange Markets

{
  "name": "BINANCE",
  "symbols": [
    "VIB-BTC",
    "ERD-BTC",
    "KEY-USDT",
    "DASH-BNB"
  ]
}

Properties

Field Type Description
name string name of the exchange
symbols List[symbol] List of market symbols available to be queried
error Error A human-readable error message

Orderbook

{
  "id": "659482",
  "level": "ORDERBOOK_LEVEL_TWO",
  "exchangeName": "BINANCE",
  "baseQuote": "ETH-BTC",
  "updateType": "ORDERBOOK_LEVEL_TWO",
  "timestamp": "2019-05-16T22:30:33.687Z",
  "sequenceHigh": "0",
  "sequenceLow": "0",
  "bids": [
    {
      "price": 0.033872,
      "size": 0.209
    }
  ],
  "asks": [
    {
      "price": 0.033888,
      "size": 1.456
    }
  ]
}

Properties

Name Type Required Restrictions Description
id string((uint64)) false none FPG internal ID
level ([OrderbookLevel])(#schemaorderbooklevel) false ORDERBOOK_LEVEL_TWO Orderbook level
exchangeName string false none none
baseQuote string false none none
updateType OrderbookUpdateType false ORDERBOOK_UPDATE_TYPE_SNAPSHOT Orderbook update type
timestamp string(date-time) false none Latest timestamp produced by the consolidated exchanges
sequenceHigh string(uint64) false none none
sequenceLow string(uint64) false none none
bids List[OrderbookEntry] false none Bids, descending
asks List[OrderbookEntry] false none Asks, ascending

OrderbookEntry

{
  "price": 240.46,
  "size": 1.125,
  "exchangeName": "COINBASEPRO"
}

Properties

Name Type Required Restrictions Description
price number(double) false none none
size number(double) false none none
exchangeName string false none none

Balance

{
    "balance": {
        "coinbasepro": {
            "currencies": {
                "USDC": {
                    "free": "1000",
                    "total": "1000"
                }, 
                "EUR": {
                    "free": "1000",
                    "total": "1000"
                }, 
                "BTC": {
                    "free": "992371.3043",
                    "used": "70.3888",
                    "total": "992441.6931"
                }, 
                "ETH": {
                    "free": "1000",
                    "total": "1000"
                }, 
                "USD": {
                    "free": "7376.89",
                    "total": "7376.89"
                }
            }
        }
    }
}

Properties

Name Type Required Restrictions Description
currencies map<string,CurrencyBalance> true none Balance of currency at specific exchange

Currency Balance

{
    "BTC": {
        "free": "992371.3043",
        "used": "70.3888",
        "total": "992441.6931"
    } 
}

Properties

Name Type Required Restrictions Description
free string(float) true none Amount of free currency
used string(float) true none Amount of used currency
total string(float) true none Amount of total currency
Name Type Required Restrictions Description
currencies map<string,CurrencyBalance> true none Balance of currency at specific exchange

Record

{
  "id": "10005",
  "createdTime": "2019-05-14T19:57:38.123Z",
  "status": "FREE",
  "currency": "BTC",
  "amount": "3",
  "recordType": "Order",
  "exchangeName": "KRAKEN",
  "relatedId": "10004",
  "relatedInfo": "313aa279-62b1-475a-b702-633b1fd369db",
}


Properties

Name Type Required Restrictions Description
id number(integer) true none Record ID
createdTime string true none Time that the record was created on our system
status string(float) true free, scheduled, running Status of a record
currency string true Exchange dependent Currency
recordType string true order, transaction Type of action that created the record
size string(float) true none Requested size of the order
exchangeName string true Binance, Coinbase Pro, Kraken, Gemini Exchange name
relatedId number(integer) false none related ID to current record
relatedInfo string true none record entry of a table specified by recordType

User

{
  "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b",
  "tenant": "fpg-staging",
  "permissionLevel": "ADMIN",
  "keys": [
    {
      "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
      "publicKey": "blah-blah-blah",
      "secret": "blah blah blah blah",
      "description": "Nice keys"
    }
  ]
}

Properties

Name Type Required Restrictions Description
name number(integer) true none Record ID
createdTime string true none Time that the user was created in our system
permissionLevel string true FPGADMIN, ADMIN, TRADER, ACCOUNTANT Level of API permissions
keys string true none API Key owned by user

Key

{
  "name": "users/21c482ec-d87b-4f5d-9b85-3aa6228f018b/keys/8e18b0fd-0e35-4d73-b86a-7b090dd0294b",
  "publicKey": "3da93a46-64b0-453a-9755-3e911f889bf3",
  "secret": "5c66af0f-66cd-4597-b975-91762c0de5f2",
  "description": "Nice keys"
}

Properties

Name Type Required Restrictions Description
name number(integer) true none Record ID
publicKey string true none Public key
secret string true none Secret key
description string false none Description for key

Order

Submitting Order json { "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a", "userName": "users/fizz", "createdTime": "2019-05-14T19:57:38.123Z", "status": "FPGOS_SUBMITTING", "base": "BTC", "quote": "USD", "size": "6", "price": "5000", "algo": "ACTIVE", "orderType": "BUY", "exchangeNames": [ "KRAKEN", "GEMINI" ], "expectedStartTime": "2019-05-14T19:57:38.123Z", "expectedEndTime": "2019-05-14T19:57:38.123Z", "executionStartTime": "2019-05-14T19:57:38.123Z", }

Running Order json { "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a", "userName": "users/fizz", "createdTime": "2019-05-14T19:57:38.123Z", "status": "FPGOS_RUNNING", "base": "BTC", "quote": "USD", "size": "6", "price": "5000", "algo": "ACTIVE", "orderType": "BUY", "exchangeNames": [ "KRAKEN", "GEMINI" ], "executionAveragePrice": "4150.5", "executionCost": "15000", "executionSize": "3", "executionFee": "20", "expectedStartTime": "2019-05-14T19:57:38.123Z", "expectedEndTime": "2019-05-14T19:57:38.123Z", "executionStartTime": "2019-05-14T19:57:38.123Z", "executionEndTime": "2019-05-14T19:57:38.123Z" } An "Order" is placed by the client and fufilled by FPG. These Orders are not submitted directly to the exchanges: rather, FPG uses the given algorithm to generate a series of "Suborders", which are then submitted to the exchanges. When the Suborders are fufilled by the exchanges, FPG uses that data to update the Order associated with that Suborder; when all Suborders associated with a given Order are completely filled by the exchange, the given Order will be considered "Completed."

Note on Order status: An Order is "Submitting" from when FPG recieves the request until the time that all associated suborders have been created. It is then "Running" either until all of the Suborders are completed, in which it is then "Complete"; until FPG is unable to fill an it for any reason, in which case it is "Failed"; or until a request is recieved to cancel it, in which case it is "PendingCancel" until all suborders have been cancelled: then it is "Cancelled".

Properties

Name Type Required Restrictions Description
name string false Must begin with "orders/" Name of the order
userName string false Must begin with "users/" Name of user submitting the order
createdTime string false Must be greater than 0 Time that the order started on our system
status string false SUBMITTING, RUNNING, COMPLETE, PENDING_CANCEL, CANCELLED, FAILED Status of the order
base string true Exchange dependent Base currency
quote string true Exchange dependent Quote currency
size string(float) true Must be greater than 0 Requested size of the order
price string(float) false Must be greater than 0 Price limit of an order
algo string false DMA, DMA_2, ACTIVE, PASSIVE, TWAP, VWAP Algorithm used to generate and execute Suborders
orderType string true BUY, SELL Order type
exchangeNames List[string] true Binance, Coinbase Pro, Kraken, Gemini Names of exchanges to route orders
executionAveragePrice string(float) false none Average price (in quote) of trades constituting order
executionCost string(float) false none Quantity of quote currency traded
executionSize string(float) false none Quantity of base currency traded
executionFee string(float) false none Quantity of currency (in quote) taken by exchange as a fee
expectedStartTime string(date-time) false Must be greater than current time Time execution expected to start
expectedEndTime string(date-time) false Must be greater than current time Time execution expected to end
executionStartTime string(date-time) false Must be greater than current time Actual execution start time
executionEndTime string(date-time) false Must be greater than current time Actual execution end time

SubOrder

Scheduled Suborder ```json { "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/ae6a5449-ff00-486a-835a-702eee9cba37", "createdTime": "2019-05-14T19:57:38.123Z", "status": "FPGEOS_SCHEDULED", "base": "BTC", "quote": "USD", "algo": "ACTIVE", "orderType": "BUY", "exchangeName": "KRAKEN", "expectedSize": "5", "expectedPrice": "5000", "expectedStartTime": "2019-05-14T19:57:38.123Z", "expectedEndTime": "2019-05-14T19:57:38.123Z", }


> Complete Suborder
```json
{
  "name": "orders/af0a83a7-4a39-4f80-a607-4b50c3046e5a/suborders/ae6a5449-ff00-486a-835a-702eee9cba37",
  "createdTime": "2019-05-14T19:57:38.123Z",
  "status": "FPGEOS_COMPLETE",
  "base": "BTC",
  "quote": "USD",
  "algo": "ACTIVE",
  "orderType": "BUY",
  "exchangeName": "KRAKEN",
  "expectedSize": "5",
  "expectedPrice": "5000",
  "executionSize": "5",
  "executionAveragePrice": "4879.89",
  "executionFee": "20",
  "expectedStartTime": "2019-05-14T19:57:38.123Z",
  "expectedEndTime": "2019-05-14T19:57:38.123Z",
  "executionStartTime": "2019-05-14T19:57:38.123Z",
  "executionEndTime": "2019-05-14T19:57:38.123Z",
  "exchangeOrderId": "orderID123"
}

Properties

Name Type Required Restrictions Description
name string true Must be of form "orders/{order_id}/suborders/{suborder_id} Name of the suborder
createdTime string(date-time) false Must be greater than 0 Time that the order started on our system
status string false SCHEDULED, SUBMITTING, RUNNING, COMPLETE, PENDING_CANCEL, CANCELLED, FAILED Status of the suborder
base string false none Currency used by the parent order
quote string false none Currency used by the parent order
algo string false DMA, DMA_2, ACTIVE, PASSIVE, TWAP, VWAP Algorithm used to generate and execute the suborder
orderType string false BUY, SELL The order type on the exchange
exchangeName string false One of exchanges specified in parent order Exchange suborder is executed on
executionAveragePrice string(float) false none Average price (in quote) of trades constituting order
executionSize string(float) false none Quantity of base currency traded
executionFee string(float) false none Quantity of currency (in quote) taken by exchange as a fee
expectedStartTime string(date-time) false Must be greater than current time Time execution expected to start
expectedEndTime string(date-time) false Must be greater than current time Time execution expected to end
executionStartTime string(date-time) false Must be greater than current time Actual execution start time
executionEndTime string(date-time) false Must be greater than current time Actual execution end time
exchangeOrderId string false none Name asigned to suborder when submitted to exchange

Error

{
  "message": "Order 'orders/bar' does not exist."
}

An error returned from the server. Note that a Status Code field is intentionally omitted because there's already one included in either the gRPC or HTTP response.

Properties

Name Type Required Restrictions Description
message string false none A human-readable error message

Algorithms

FPG's Algorithms allow the users to adjust familiar benchmark algorithms to suit their needs. Alternatively, you can use our DMA system to make the trades yourself.

Algorithms can be split into three different categories: schedule-driven, evaluative, and opportunitistic.

Schedule-driven includes TWAP and VWAP.

Evaluative includes Passive.

Opportunistic includes Active.

Note that we recommend DMA_2 for high-performance single-exchange trading. This will route directly to the exchange.

TWAP

The algorithm follows the Time-Weighted Average Price benchmark. Trade n coin over t time, starting from start_date and ending at end_date. The forecasted TWAP price is the default if a price parameter is not overriden by the user.

Parameters

Name Type Required Default Description
price string(float) false none Price limit of an order
size string(float) true none Requested size of the order
expectedStartTime string(date-time) false Must be greater than current time Time expected to start executing
expectedEndTime string(date-time) false Must be greater than current time Time expected to end execution
exchangeNames List[string] true Binance, Coinbase Pro, Kraken, Gemini Names of exchanges to route orders
base string true Exchange dependent Base currency
quote string true Exchange dependent Quote currency
period int No 10 Number of periods that splits an Order

VWAP

The algorithm follows the Volume-Weighted Average Price benchmark. Trade n coin over t time, starting from start_date and ending at end_date with period P. The forecasted VWAP price is the defeault given the period is the default if a price parameter is not overriden by the user.

Parameters

Parameter Type Required Default Description
price string(float) false none Price limit of an order
size string(float) true none Requested size of the order
expectedStartTime string(date-time) false Must be greater than current time Time expected to start executing
expectedEndTime string(date-time) false Must be greater than current time Time expected to end execution
exchangeNames List[string] true Binance, Coinbase Pro, Kraken, Gemini Names of exchanges to route orders
base string true Exchange dependent Base currency
quote string true Exchange dependent Quote currency
period int No 10 Number of periods that splits an Order

Passive

The algorithm places only limit orders. The Suborders will track the trading pair's forecasted price wihtout incurring taker fees. This is most useful when volatility is not a concern over a long period of time.

Parameters

Parameter Type Required Default Description
price string(float) false none Price limit of an order
size string(float) true none Requested size of the order
expectedStartTime string(date-time) false Must be greater than current time Time expected to start executing
expectedEndTime string(date-time) false Must be greater than current time Time expected to end execution
exchangeNames List[string] true Binance, Coinbase Pro, Kraken, Gemini Names of exchanges to route orders
base string true Exchange dependent Base currency
quote string true Exchange dependent Quote currency

Active

The algorithm will aggressively trade and will cross the orderbooks to fulfill the order in the fastest time possible. If a price is given, the orders will execute until it hits the target price. If a time is given, the order will increase in aggressiveness as it approaches expiration. A future release will offload the position to an OTC desk if the order reaches a specific price or time.

Parameters

Parameter Type Required Default Description
price string(float) false none Price limit of an order
size string(float) true none Requested size of the order
expectedStartTime string(date-time) false Must be greater than current time Time expected to start executing
expectedEndTime string(date-time) No none Order will increase price linearly by aggression*(execution_size)/(expectedEndTime-expectedStartTime).
exchangeNames List[string] true Binance, Coinbase Pro, Kraken, Gemini Names of exchanges to route orders
base string true Exchange dependent Base currency
quote string true Exchange dependent Quote currency
otc bool No N/A If the order is incomplete after expectedEndTime, the remainder will be filled by OTC desks

Errors

The FPG API uses the following error codes:

Error Code Meaning
400 Bad Request -- Request is invalid.
401 Unauthorized -- API key is invalid.
403 Forbidden -- The endpoint requested is hidden for administrators only.
404 Not Found -- The specified endpoint could not be found.
429 Too Many Requests -- You're buying too much bitcoin. Take it easy.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.