NAV Navbar
python shell

Introduction

Welcome to the FPG REST API. This API provides access to:

Real-Time Cryptocurrency Market Data

Order Management and Execution Engine

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

Base URLs

Sandbox API

https://sandbox.api.floating.group

Authentication

The FPG REST API uses symmetric key encryption to securely send and recieve data. Your API keys will be delivered to you upon registration. In the event that your credentials are lost and/or potentially compromised, FPG will provide you with a new set of keys.

Example Authentication Framework

  # Requires python-requests. Install with pip:
  #
  #   pip install requests
  #
  # or, with easy-install:
  #
  #   easy_install requests

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

  # Create custom authentication for Exchange
  class FPGExchangeAuth(AuthBase):
      def __init__(self, api_key, secret_key):
          self.api_key = api_key
          self.secret_key = secret_key

      def __call__(self, request):
          timestamp = str(time.time())
          message = timestamp + request.method + request.path_url + (request.body or '')
          hmac_key = base64.b64decode(self.secret_key)
          signature = hmac.new(hmac_key, message, hashlib.sha256)
          signature_b64 = signature.digest().encode('base64').rstrip('\n')

          request.headers.update({
              'FPG-ACCESS-SIGN': signature_b64,
              'FPG-ACCESS-TIMESTAMP': timestamp,
              'FPG-ACCESS-KEY': self.api_key,
              'Content-Type': 'application/json'
          })
          return request

  base_url = 'https://sandbox.api.floating.group/'
  auth = FPGExchangeAuth(API_KEY, API_SECRET)
  ...

Creating a request

All requests must contain the following headers:

GET and POST requests

GET and POST requests both follow the HMAC authentication scheme detailed above.

Our API follows standard convention, where GET requests are used to "fetch" data and POST requests are used to "submit" data.

GET Example

Payload to deliver to /fetch_order_info

{"order_id": "011dfbf1-512a-41c2-9aa2-6cea8810048b"}

Handling the request

  # Continued from the above code. 
  ...
  r = requests.get(base_url + 'fetch_order_info', params=payload, auth=auth)
  print(r.json())

JSON Response

{
    "data": {
        "_id": "011dfbf1-512a-41c2-9aa2-6cea8810048b",
        "created_time": 1551541488132,
        "base": "BTC",
        "quote": "USDT",
        "price": 3862.45,
        "size": 100,
        "order_type": "BUY",
        "algo": "ACTIVE",
        "exchanges": [
            "binance",
            "huobi",
            "okex"
        ],
        "expected_end_time": 1551545088132,
        "status": "RUNNING"
    },
    "succeeded": true
}

POST Example

Payload to deliver to /submit_order

{
      "base": "ETH",
      "quote": "USD",
      "price": 135.04,
      "size": 8000,
      "order_type": "SELL",
      "algo": "VWAP",
      "created_time": 1551397488145,
      "exchange_names": [
          "kraken",
          "gdax"
      ],
      "extras":{
        "time_to_live": 30
      }
}

Handling the request

  # Continued from the above code. 
  ...
  # Place an order via SOR using an VWAP ordertype that has 95% confidence delivery within 50 seconds. 
  r = requests.post(base_url + 'submit_order', json=order, auth=auth)
  print(r.json())

JSON Response

{
  "data":
  {
    "price": 105.55, 
    "status": "success", 
    "timestamp": 1549088581.0, 
    "trade_info": [
          {
            "base_quote": "ETH/BTC",
            "order_size": 0.5,
            "order_side": "buy",
            "algo": "active",
            "parameters": {},
            "exchanges": []
          },
          {
            "action": "buy", 
            "amount": "0.01", 
            "ebq": "ETH/BTC", 
            "order_price": 105.52,
            "venue":"binance"
          },
          ...
    ]
  },
  "succeeded" : true
}

Public Endpoints

Test

import requests, json

base_url = "https://sandbox.api.floating.group"
r = requests.get(base_url + "/test")
print(r.json())
curl "https://sandbox.api.floating.group/test"

Sample Payload

  {
  }

Returned JSON structure:

{
  "data":
      {
        "message":"Echo Server Response."
      },
  "succeeded": true


}

Echo to server to check the connection.

HTTP Request

GET /test

Query Parameters

Parameter Type Description

Fetch Exchanges

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

Sample Payload

  {
  }

JSON response

  {
    "data":
      [
        "binance",
        "kraken",
        ...
        "bitmex"
      ],
    "succeeded": true
  }

Fetches the exchanges that are available in the FPG data feed.

HTTP Request

GET /fetch_exchanges

Query Parameters

Parameter Type Description

Fetch Markets

  r = requests.get(base_url + 'fetch_markets', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "exchange_name" : "binance"
  }

JSON response

  {
    "data":
      [
        "BTC/USDT",
        "ETH/USDT",
        ...
        "XRP/USDT"
      ],
    "succeeded": true
  }

Fetches a list of the available currency pairs (markets) for the specified exchange.

HTTP Request

GET /fetch_markets

Query Parameters

Parameter Type Description
exchange_name string Target exchange. Should match an exchange from fetch_exchanges.

Market Data

Fetch Mid-Price

  r = requests.get(base_url + 'fetch_mid_price', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "base_quote":"BTC/USD"
  }

JSON Response

  {
    "data":
      {
        "ask": 3393.4,
        "bid": 3393.3,
        "mid": 3393.35,
        "status": "success",
        "timestamp": 1548804200.0
      },
    "succeeded": true
}

Fetches the highest bid, lowest ask, and mid-price for specified exchange and currency pair.

HTTP Request

GET /fetch_price

Query Parameters

Parameter Type Description
base_quote string Target currency pair.
exchange_name string Target exchange. Should match an exchange from fetch_exchanges.

Fetch L2 Order Book

  r = requests.get(base_url + 'fetch_l2_order_book', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "base_quote" : "BTC/USD"
  }

JSON response

  {
    "data":
      {
        "asks": [
          [
            3417.1, 
            0.635
          ], 
          ...
        ], 
        "bids": [
          [
            3417.0, 
            8.282
          ], 
          ...
        ], 
        },
      "succeeded" : true
    }

Fetches the L2 order book for a particular currency pair.

The return will be a dictionary of asks/bids. The structure of this will be a {'asks':[[],[],[],...],'bids':[[],[],...]}, with the value on these being a two dimensional list of (price,volume) in the second.

HTTP Request

GET /fetch_l2_order_book

Query Parameters

Parameter Type Description
base_quote string The base_quote to fetch the orderbook for.
exchange List[ string ] (optional) The exchanges to consolidate across. It will default to all valid exchanges if not set.

Account and Order Management

Fetch Balance

  r = requests.get(base_url + 'fetch_balance',  params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "currency" : ["BTC","USD"]
  }

JSON Response

  {

    "data":
      {
      "BTC": 0.0, 
      "USD": 103.64
      },
    "succeeded": true
  }

Fetches the currency balances in the FPG systems for a given user. If the user_id is not given, the API keys are used to identify the account. If the currency pairs are not given, it will return the values for all non-zero holdings.

It returns a dictionary of {'coin':___}. This is a dictionary of the coin : volume.

HTTP Request

GET /fetch_balance

Query Parameters

Parameter Type Description
user_id string (optional) The ID of the user to be fetched for.
currency string (optional) The currency pair to pull orders for.

Fetch Open FPG Orders

  r = requests.get(base_url + 'fetch_open_orders', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
  }

JSON Response

  {
    "data":
    {
      "fpg": [
          {
            "action": "sell", 
            "amount": 100, 
            "created_time": 15203900493.0, 
            "ebq": "XMR/BTC", 
            "fill_amount": 30.0, 
            "fill_price": 129, 
            "order_price": 130, 
            "info":
                {
                "base_quote": "XMR/BTC",
                "order_size": 200,
                "order_side": "sell",
                "algo": "active",
                "parameters": {},
                "exchanges": []
                }
          },
          ... 
        ] 
      },
    "succeeded": true
  }

This method returns the current pending transactions. Note this will track the aggregate set of all transactions you passed in for a single trade_id.

It returns a dictionary of {"user_id": [ ...]}. Where the list is a list of trade details containing:

HTTP Request

GET /fetch_open_orders

Query Parameters

Parameter Type Description
base_quotes List[string] (optional) The currencies to fetch the balances for.
user_id string (optional) The user ID to be fetched.

Fetch Closed FPG Orders

  r = requests.get(base_url + 'fetch_closed_orders', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "user_id" : "A"
  }

JSON Response

  {
    "data":
    {
      "fpg": [
          {
            "action": "sell", 
            "amount": 100, 
            "date_created": 15203900493, 
            "date_finished": 15203900493, 
            "ebq": "XMR/BTC", 
            "fill_price": 129, 
            "order_price": 130, 
            "trade_id": 20,
            "trade_details":
                {
                "base_quote": "XMR/BTC",
                "order_size": 200,
                "order_side": "sell",
                "algo": "active",
                "parameters": {},
                "exchanges": []
                }
          }, 
          ... 
        ] 
      },
    "succeeded": true
  }

Fetches the most recent closed transactions.

It returns a dictionary of {"user_id": [ ...]}. Where the list is a list of trade details containing:

HTTP Request

GET /fetch_closed_orders

Query Parameters

Parameter Type Description
user_id string (optional) The user ID to be fetched.
date_start timestamp (optional) UNIX timestamp (i.e. 15203900495)
date_end timestamp (optional) UNIX timestamp (i.e. 15203900495)

Fetch Deposit Address

  r = requests.get(base_url + 'fetch_deposit_address', json=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "currency": "XMR"
  }

JSON Response

  {
    "data":
    {
      "wallet_address":
        {
          "BTC" : "sample_btc_address",
          "ETH" : "sample_eth_address",
          "LTC" : "sample_ltc_address"
        }
    },
    "succeeded": true
  }

This method returns the address for users to deposit to.

It returns a dictionary of {"wallet_address":....}. This is a json of the wallet addresses to send the various amounts to.

HTTP Request

GET /fetch_deposit_address

Query Parameters

Parameter Type Description
currency float Currency code to be sent.
amount float (optional) Amount to be sent - This is for optimal routing.

Fetch Statistics

  r = requests.get(base_url + 'fetch_statistics', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "user_id" : "test_user_id",
    "base_quote" : "ALL"
  }

JSON Response

  {
    "data":
    {
      "BTC/USD":
        {"1d":
          {"buy":
            {"base": 10392,
             "quote":2.3}
          ,"sell":
            {"base": 3000,
             "quote":0.5}
        ,"30d":
            {"buy":
            {"base": 340302,
             "quote": 40.2}
          ,"sell":
            {"base": 20394,
             "quote": 15.5}
         },
      "ETH/USD":
        {"1d":
          {"buy":
            {"base": 10392,
             "quote":2.3}
          ,"sell":
            {"base": 3000,
             "quote":0.5}
        ,"30d":
            {"buy":
            {"base": 340302,
             "quote": 40.2}
          ,"sell":
            {"base": 20394,
             "quote": 15.5}
         }

    },
    "succeeded": true
  }

This method returns the statistics of how much has been bought/sold of a currency pair over the past month. If user_id is not given, the public key/private key pair is used to identify the account instead. It also checks that the keys have access to the subuser. The amounts are given in the base/quote (i.e. BTC/USD), where BTC is the base and USD is the quote, respectively.

HTTP Request

GET /fetch_statistics

Query Parameters

Parameter Type Description
base_quote string Currency to fetch statistics for. If 'ALL' is passed, this will return a dictionary for all currencies.

Execution Engine

Submit Order

  r = requests.post(base_url + 'submit_order', json=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "base_quote": "ETH/BTC",
    "size": 0.05,
    "order_type": "sell",
    "algo": "TWAP",
    "parameters":
      {
        "time_slices" : 100
      }
  }

JSON Response

  {
    "data":
    {
      "mode":"sandbox",
      "order_id":"sample_fpg_order_id",
    },
    "succeeded": true
  }

This method submits a client order into the FPG system. See the section below on Algorithms for types of orders.

It returns the order_id which you can use to track the progress of the order.

HTTP Request

POST /submit_order

Query Parameters

Parameter Type Description
base_quote string The base quote to trade.
size float The size of the trade (in quote).
order_type string The side of the transaction. Either "sell" or "buy"
algo string The algorithm of choice. See Algorithms
extras dictionary The parameters specified for the algorithm.

Fetch Order Info

  r = requests.get(base_url + 'fetch_order_info', params=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "order_id" : "sample_fpg_order_id"
  }

JSON Response

  {
    "data":
    {
      "action": "sell", 
      "amount": 100, 
      "date_created": 15203900493, 
      "ebq": "XMR/BTC", 
      "fill_amount": 30.0, 
      "fill_price": 129, 
      "order_price": 130, 
      "trade_id": 20,
      "trade_details":
          {
          "base_quote": "XMR/BTC",
          "order_size": 200,
          "order_side": "sell",
          "algo": "active",
          "parameters": {},
          "exchanges": []
          }
    },
    "succeeded": true
  }

This fetches information about the status of an order.

This returns the same information as the fetch_open_orders method.

HTTP Request

GET /fetch_order_info

Query Parameters

Parameter Type Description
order_id string The order id to fetch.

Cancel Order

  r = requests.get(base_url + 'cancel_order', params=payload,  auth=auth)
  print(r.json())

Sample Payload

  {
    "order_id" : "sample_fpg_order_id"
  }

JSON Response

  {
    "data": 
      {
      },
    "succeeded": true
  }

This method cancels an ongoing order. This will cease execution on all exchanges. There may be a latency between casting this and the most recent order, so you should call fetch_last_orders after calling this to find the final status of the orders.

It returns a success or fail.

HTTP Request

POST /cancel_order

Query Parameters

Parameter Type Description
order_id string The FPG order ID.

Cancel All Orders

  r = requests.post(base_url + 'cancel_all_orders', json=payload, auth=auth)
  print(r.json())

Sample Payload

  {
    "verification" : "GONUCLEAR"
  }

JSON Response

  {
    "data":
    {
    },
    "succeeded": true
  }

This cancels all open orders. This will freeze all account balances and cease execution on all accounts. Verification string must equal "GONUCLEAR".

HTTP Request

POST /cancel_all_orders

Query Parameters

Parameter Type Description
verification string Verification string. this must equal GONUCLEAR to be valid.

Algorithms

The FPG API Algorithm allows the users to adjust the familiar benchmark algorithms to suit their needs. Alternatively, the user can trust us, and we will use an algorithm tailored for crypto. Lastly, 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.

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. You can give us a price, or you can let us do it for you.

Parameters

Parameter Type Required Default Description
size float Yes N/A How many coins to buy or sell through TWAP
start_date float No current time the time when TWAP should start in UNIX milliseconds
end_date float Yes current time the time when TWAP should end in UNIX milliseconds. If end_date is defined but start_date is not defined, TWAP will start at current date and end at end_date.
exchange_names List[str] Yes [coinbase, kraken, gemini] Across how many exchanges do you want your TWAP
price float No N/A If a price is given, the orders will all be at price. Fulfillment will not be adjusted over time.
base str Yes N/A Base currency symbol.
quote str Yes N/A Quote currency symbol.
period int No 100 The TWAP will be done in sizes of size/period at a given or FPG-discovered price.
fee bool No False Whether the algorithm should avoid trading fees. This also implies that the order is a maker order and cannot cross the orderbook.

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 expected volume will be predicted by FPG, unless an array of volumes are given.

Parameters

Parameter Type Required Default Description
size float Yes N/A How many coins to buy or sell through VWAP
start_date float No current time the time when VWAP should start in UNIX milliseconds
end_date float Yes current time the time when VWAP should end in UNIX milliseconds. If end_date is defined but start_date is not defined, VWAP will start at current date and end at end_date.
exchange_names List[str] Yes [coinbase, kraken, gemini] Across how many exchanges do you want your VWAP
base str Yes N/A The base currency to trade.
quote str Yes N/A The quote currency to trade.
period int No 100 The number of periods to divide trade size by.
fee bool No False Whether the algorithm should avoid trading fees. This also implies that the order is a maker order and cannot cross the orderbook.

Passive

This is FPG's passive order type. This order will typically be filled a little more slowly, putting orders on top of the orderbook. This will track the trading pair's price without being affected by trading fees. This is useful for gathering a position when volatility is not a concern.

Parameters

Parameter Type Default Description
size float Yes N/A
start_date float Yes current time
end_date float No None
exchange_names List[str] Yes [coinbase, kraken, gemini]
base str Yes N/A
quote str Yes N/A

Active

This is FPG's active order type. This order will aggressively trade and will cross the orderbooks to fulfill the order in the fastest time possible. If a price is specified, the order will execute until it hits the target price. If a time is given, the order will increase in aggressiveness as it approaches expiration. It can offload the position to an OTC desk if the order reaches a specific price.

Parameters

Parameter Type Default Description
size float Yes N/A
start_date float Yes current time
end_date float No None
exchange_names List[str] Yes [coinbase, kraken, gemini]
base str Yes N/A
quote str Yes N/A
otc str No N/A

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.