Full ExampleΒΆ

#!/usr/bin/python

import hashlib
import hmac
import json
import logging
import pprint
import requests
import time
import urllib


class BtronClient(object):

    def __init__(self):
        self.base_url = 'https://www.btron.com/v2.0/api'
        self.session = requests.Session()

    def _request(self, method, path, query=None, data=None, headers=None):
        if path.startswith('/fund'):
            url = 'https://www.btron.com/api' + path
        else:
            url = self.base_url + path

        if query:
            url += '?' + query

        try:
            if method == 'POST':
                if data:
                    headers = headers or {}
                    headers.update({'Content-Type': 'application/json'})
                resp = self.session.post(url, data=data, headers=headers)
            elif method == 'GET':
                resp = self.session.get(url, headers=headers)

            ret = resp.json()
            if ret['code'] == 'OK':
                return ret['payload']

            logging.error(
                'API call failed, server returns "%s" (code %s)',
                ret['msg'], ret['code']
            )
            raise RuntimeError("Server reply %s" % resp)
        except requests.exceptions.RequestException:
            logging.exceptions('Something wrong happened.')
            raise

    def get_products(self):
        return self._request('GET', '/trade/products/')['products']

    def get_exchanges(self):
        return self._request('GET', '/trade/exchanges/')['exchanges']

    def get_tickers(self, products, detailed=False):
        params = {
            'products': ','.join(products),
            'detailed': str(detailed)
        }
        query = urllib.urlencode(params)
        return self._request('GET', '/trade/tickers', query)['tickers']

    def get_recent_trades(self, product, limit=20, since=0, marker=0):
        params = {
            'product': product,
            'limit': limit
        }
        if since:
            params['since'] = since
        if marker:
            params['marker'] = marker

        query = urllib.urlencode(params)
        return self._request('GET', '/trade/trades/', query)['trades']

    def get_depth(self, product):
        query = urllib.urlencode({'product': product})
        return self._request('GET', '/trade/depth/', query)['depth']


class BtronAuthedClient(BtronClient):
    ORDER_STATUS_OPEN = 'OPEN'
    ORDER_STATUS_EXECUTED = 'EXECUTED'
    ORDER_STATUS_CANCELLED = 'CANCELLED'

    def __init__(self, api_key, api_secret):
        super(BtronAuthedClient, self).__init__()
        self.api_key = api_key
        self.api_secret = api_secret

    def _build_signature(self, nonce, method, path, query=None, data=None):
        if path.startswith('/fund'):
            path = '/api' + path
        else:
            path = '/v2.0/api' + path

        message = ''.join([
            method,
            path,
            ('?' + query) if query else '',
            nonce,
            data if data else ''
        ])

        return hmac.new(
            self.api_secret.encode(),
            message.encode(),
            digestmod=hashlib.sha384
        ).hexdigest()

    @staticmethod
    def get_nonce():
        return str(int(time.time() * 1000))

    def _authed_request(self, method, path, query=None, data=None, headers=None):
        nonce = self.get_nonce()
        headers = headers or {}
        if data:
            data = json.dumps(data)

        signature = self._build_signature(nonce, method, path, query, data)
        headers.update({
            'X-BTRON-APIKEY': self.api_key,
            'X-BTRON-NONCE': nonce,
            'X-BTRON-SIGN': signature
        })

        return super(BtronAuthedClient, self)._request(
            method, path, query, data, headers
        )

    def get_fund_details(self):
        return self._authed_request('GET', '/fund/user_funds/overview/')

    def get_orders(
            self, status=None, product=None, exchange=None,
            limit=None, marker=None
    ):
        params = {'status': status or self.ORDER_STATUS_OPEN}
        if product:
            params.update({'product': product})
        if exchange:
            params.update({'exchange': exchange})
        if limit:
            params.update({'limit': limit})
        if marker:
            params.update({'marker': marker})
        query = urllib.urlencode(params)

        return self._authed_request('GET', '/trade/orders/', query)

    def cancel_orders(self, orders):
        data = {'orders': orders}

        return self._authed_request('POST', '/trade/cancel/', data=data)

    def buy_limited(self, product, exchange, price, volume):
        data = {
            'product': product,
            'exchange': exchange,
            'price': price,
            'volume': volume
        }

        return self._authed_request('POST', '/trade/buy_limited/', data=data)

    def sell_limited(self, product, exchange, price, volume):
        data = {
            'product': product,
            'exchange': exchange,
            'price': price,
            'volume': volume
        }

        return self._authed_request('POST', '/trade/sell_limited/', data=data)


    def buy_market(self, product, exchange, amount):
        data = {
            'product': product,
            'exchange': exchange,
            'amount': amount
        }

        return self._authed_request('POST', '/trade/buy_market/', data=data)

    def sell_market(self, product, exchange, volume):
        data = {
            'product': product,
            'exchange': exchange,
            'volume': volume
        }

        return self._authed_request('POST', '/trade/sell_market', data=data)


def build_products_map(products):
    ret = {}
    for product in products:
        product_name = product['product']
        product_uuid = product['product_uuid']
        for exchange in product['exchanges']:
            exchange_name = exchange['name']
            exchange_uuid = exchange['uuid']
            full_product_name = '%s:%s' % (exchange_name, product_name)
            ret[full_product_name] = (product_uuid, exchange_uuid)
    return ret


# #### 8< ######## Example codes below ####################### >8 #########

####################
# PUBLIC ENDPOINTS #
####################

public_client = BtronClient()

# Get Products
products = public_client.get_products()

# Cache products info for later usage
PRODUCTS_MAP = build_products_map(products)

# Show all the supported products
print "\nShowing all supported products..."
pprint.pprint(PRODUCTS_MAP.keys())

# Get tickers of the some products
print "\nTickers of 5 products..."
products_to_get = PRODUCTS_MAP.keys()[:5]
pprint.pprint(public_client.get_tickers(products_to_get, detailed=True))

# Get recent trades of the first supported product
product = PRODUCTS_MAP.keys()[0]
print "\nShowing recent trades of %s..." % product
pprint.pprint(public_client.get_recent_trades(product))

# Get full orderbook of Q/USDT
print "\nShowing orderbook of btron:Q/USDT..."
depths = public_client.get_depth('btron:Q/USDT')
pprint.pprint(depths['buys'])
pprint.pprint(depths['sells'])

###########################
# AUTHENTICATED ENDPOINTS #
###########################

API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'
authed_client = BtronAuthedClient(API_KEY, API_SECRET)

# Get fund details
fund_details = authed_client.get_fund_details()
pprint.pprint(fund_details)

# Get btron:Q/USDT's product_uuid and exchange_uuid
q_usdt, btron = PRODUCTS_MAP.get('btron:Q/USDT')

# Place a buy limited order for btron:Q/USDT, price 0.005, volume 1000
buy_limited_order = authed_client.buy_limited(q_usdt, btron, '0.005', '1000')
pprint.pprint(buy_limited_order)

# Place a sell limited order for btron:Q/USDT, price 0.008, volume 1000
sell_limited_order = authed_client.sell_limited(q_usdt, btron, '0.008', '1000')
pprint.pprint(sell_limited_order)

# Cancel the orders just placed
cancel_ret = authed_client.cancel_orders(
    [buy_limited_order['uuid'], sell_limited_order['uuid']]
)
pprint.pprint(cancel_ret)

# Place a buy market order for btron:Q/USDT, order amount 200 USDT
buy_market_order = authed_client.buy_market(q_usdt, btron, '200')
pprint.pprint(buy_market_order)

# Place a sell market order for btron:Q/USDT, order volume 1000 Q
sell_market_order = authed_client.sell_market(q_usdt, btron, '1000')
pprint.pprint(sell_market_order)

# Get all OPEN orders of btron:Q/USDT
open_orders_info = authed_client.get_orders(
    status=authed_client.ORDER_STATUS_OPEN,
    product=q_usdt,
    exchange=btron
)
open_orders = open_orders_info['orders']
pprint.pprint(open_orders)

# Get next page if there is more info
if open_orders_info['more']:
    next_page = authed_client.get_orders(
        status=authed_client.ORDER_STATUS_OPEN,
        product=q_usdt,
        exchange=btron,
        marker=open_orders[-1]['id']
    )
    pprint.pprint(next_page)

# Get all CANCELLED orders of btron:Q/USDT
cancel_orders_info = authed_client.get_orders(
    status=authed_client.ORDER_STATUS_CANCELLED,
    product=q_usdt,
    exchange=btron
)
pprint.pprint(cancel_orders_info)

# Get all EXECUTED orders on binance
btc_usdt, binance = PRODUCTS_MAP.get('binance:BTC/USDT')
executed_orders = authed_client.get_orders(
    srtatus=authed_client.ORDER_STATUS_EXECUTED,
    exchange=binance
)
pprint.pprint(executed_orders)