Make a Request

How to Construct an HTTP Request

Once the signature is calculated the user can make a request to the endpoint of interest by sending:

  1. the HTTP method (POST, GET, etc)
  2. the full end point (this is the base URL and the path)
  3. the message header
  4. the message body

How information is sent varies slightly between REST V3 and V4 in terms of whether data is sent in the header or the body.

REST V3REST V4
HEADERAPI Key
API Signature
API Key
API Signature
Tonce
BODYTonce Unix time-

Example Request Method

Here is an example of how to send the request.

requests.request(method, base_url + "/" + path, headers = headers, data = body_str)

Full REST Examples

These full examples bring all the methods together to demonstrate how to generate the API signature and send it along with the other important data.

The responses associated to these (and all end point requests) are documented in the relevant sections later in the document.

import time
import json
import base64
import hashlib
import hmac
import requests
import pprint
base_url = "https://trade-hk.oslsandbox.com"
key = "<key>"
secret = "<secret>"

def gen_sig_helper(secret, data):
  secret_bytes = base64.b64decode(secret.encode("utf8"))
  return base64.b64encode(hmac.new(secret_bytes, data.encode("utf8"), digestmod = hashlib.sha512).digest()).decode("utf8")

def v3_gen_sig(secret, path, body_str = None):
  data = path
  if body_str != None:
    data = data + chr(0) + body_str
  return gen_sig_helper(secret, data)

def v3_mk_request(method, path, body = {}, realrun = True):
  print("=> " + method + ' ' + path)
  tonce = int(time.time() * 1000 * 1000)
  body["tonce"] = tonce
  body_str = json.dumps(body)
  headers = {
    "Rest-Key": key,
    "Rest-Sign": v3_gen_sig(secret, path, body_str),
    "Content-Type": "application/json"
  }
  print("=> " + v3_gen_sig(secret, path, body_str))
  print("=> " + str(tonce))
  print("=> " + body_str)
  
  if realrun:
    response = requests.request(method, base_url + "/" + path, headers = headers, data = body_str)
    response_json = response.json()
    pprint.pprint(response_json)
    response.raise_for_status()
    return response_json
  else:
    print("=> Not sending messages to API server...")
    return 0
  
def request_acc():
return v3_mk_request("POST", "api/3/account")

request_acc()
import time
import json
import base64
import hashlib
import hmac
import requests
import pprint
base_url = "https://trade-hk.oslsandbox.com"
key = "<key>"
secret = "<secret>"

def gen_sig_helper(secret, data):
  secret_bytes = base64.b64decode(secret.encode("utf8"))
  return base64.b64encode(hmac.new(secret_bytes, data.encode("utf8"), digestmod = hashlib.sha512).digest()).decode("utf8")

def v3_gen_sig(secret, path, body_str = None):
  data = path
  if body_str != None:
    data = data + chr(0) + body_str    
  return gen_sig_helper(secret, data)

def v3_mk_request(method, path, body = {}, realrun = True):
  print("=> " + method + ' ' + path)
  tonce = int(time.time() * 1000 * 1000)
  body["tonce"] = tonce
  body_str = json.dumps(body)
  headers = {
    "Rest-Key": key,
    "Rest-Sign": v3_gen_sig(secret, path, body_str),
    "Content-Type": "application/json"
  }
  print("=> " + v3_gen_sig(secret, path, body_str))
  print("=> " + str(tonce))
  print("=> " + body_str)
  
  if realrun:
    response = requests.request(method, base_url + "/" + path, headers = headers, data = body_str)
    response_json = response.json()
    pprint.pprint(response_json)
    response.raise_for_status()
    return response_json
  else:
    print("=> Not sending messages to API server...")
    return 0
 

def request_token():
      return v3_mk_request("POST", "api/3/bcg/rest/auth/token")
  
request_token()
import time
import json
import base64
import hashlib
import hmac
import requests
import pprint

base_url = 'https://trade-hk.oslsandbox.com'
key = '<key>'
secret = '<secret>'

def gen_sig_helper(secret, data):
  secret_bytes = base64.b64decode(secret.encode('utf8'))
  return base64.b64encode(hmac.new(secret_bytes, data.encode('utf8'), digestmod = hashlib.sha512).digest()).decode('utf8')

def v4_gen_sig(secret, method, path, expires, body_str = None):
  data = method + path + str(expires)
  if body_str != None:
    data = data + body_str
  return gen_sig_helper(secret, data)

def v4_mk_request(method, path, body = None):
  print('=> ' + method + ' ' + path)
  tonce = int(time.time()) + 10
  body_str = None
  if body:
    body_str = json.dumps(body)
  headers = {
    'api-key': key,
    'api-signature': v4_gen_sig(secret, method, path, tonce, body_str),
    'api-expires': str(tonce),
  }
  if body:
    headers['Content-Type'] = 'application/json'

  response = requests.request(method, base_url + path, headers = headers, data = body_str)
  response_json = response.json()
  pprint.pprint(response_json)
  response.raise_for_status()
  return response_json

def v3_gen_sig(secret, path, body_str = None):
  data = path
  if body_str != None:
    data = data + chr(0) + body_str
  return gen_sig_helper(secret, data)

def v3_mk_request(method, path, body = {}):
  print('=> ' + method + ' ' + path)
  tonce = int(time.time() * 1000 * 1000)
  body['tonce'] = tonce
  body_str = json.dumps(body)
  headers = {
    'Rest-Key': key,
    'Rest-Sign': v3_gen_sig(secret, path, body_str),
    'Content-Type': 'application/json'
  }
  response = requests.request(method, base_url + '/' + path, headers = headers, data = body_str)
  response_json = response.json()
  pprint.pprint(response_json)
  response.raise_for_status()
  return response_json

order_id_v4 = v4_mk_request('POST', '/api/v4/order', {
  'ordType': 'Limit',
  'symbol': 'BTCUSD',
  'orderQty': '0.01',
  'price': '39000',
  'side': 'Buy'
})['orderID']
v4_mk_request('GET', '/api/v4/order?orderID=' + order_id_v4)
v4_mk_request('DELETE', '/api/v4/order', {'orderID': [order_id_v4]})

order_id_v3 = v3_mk_request('POST', 'api/3/order/new', {
  'order': {
    'orderType': 'LIMIT',
    'tradedCurrency': 'BTC',
    'settlementCurrency': 'USD',
    'buyTradedCurrency': True,
    'tradedCurrencyAmount': '0.01',
    'limitPriceInSettlementCurrency': '39000'
  }
})['orderId']
v3_mk_request('POST', 'api/3/order/info', {'orderId': order_id_v3})
v3_mk_request('POST', 'api/3/order/cancel', {'orderIds': [order_id_v3]})
const https = require('https');
const crypto = require('crypto');

const host = 'trade-hk.oslsandbox.com';
const key = '<key>';
const secret = '<secret>';

function response_as_json(resolve, reject) {
  return function(res) {
    let str = '';
    res.on('data', function (chunk) { str += chunk; });
    res.on('end', function (arg) {
      console.log(JSON.parse(str));
      ((res.statusCode >= 200 && res.statusCode < 300) ? resolve : reject)(str ? JSON.parse(str) : '');
    });
  }
}

function gen_sig_helper(secret, data) {
  const secret_bytes = Buffer.from(secret, 'base64');
  return crypto.createHmac('sha512', secret_bytes).update(data).digest('base64');
}

function v4_gen_sig(secret, method, path, expires, body_str) {
  let data = method + path + expires;
  if (body_str) {
    data = data + body_str;
  }
  return gen_sig_helper(secret, data);
}

function v4_mk_request(method, path, body) {
  console.log(`=> ${method} ${path}`);
  return new Promise((resolve, reject) => {
    const tonce = Math.floor(Date.now() / 1000) + 10;
    const body_str = JSON.stringify(body);
    const headers = {
      'api-key': key,
      'api-signature': v4_gen_sig(secret, method, path, tonce, body_str),
      'api-expires': tonce,
      'Content-Type': 'application/json'
    }
    if (body) {
      headers['Content-Length'] = Buffer.byteLength(body_str);
    }
    const opt = { host, method, path, headers };
    const req = https.request(opt, response_as_json(resolve, reject));
    if (body) {
      req.write(body_str);
    }
    req.end();
  });
}

function v3_gen_sig(secret, path, body_str) {
  let data = path;
  if (body_str) {
    data = data + '\0' + body_str;
  }
  return gen_sig_helper(secret, data);
}

function v3_mk_request(method, path, body) {
  console.log(`=> ${method} ${path}`);
  return new Promise((resolve, reject) => {
    const tonce = Math.floor(Date.now() * 1000);
    body['tonce'] = tonce;
    const body_str = JSON.stringify(body);
    const headers = {
      'Rest-Key': key,
      'Rest-Sign': v3_gen_sig(secret, path, body_str),
      'Content-Type': 'application/json'
    }
    const opt = { host, method, path: '/' + path, headers };
    const req = https.request(opt, response_as_json(resolve, reject));
    req.write(body_str);
    req.end();
  });
}

async function run() {
  const order_id_v4 = (await v4_mk_request('POST', '/api/v4/order', {
    'ordType': 'Limit',
    'symbol': 'BTCUSD',
    'orderQty': '0.01',
    'price': '39000',
    'side': 'Buy'
  }))['orderID'];
  await v4_mk_request('GET', '/api/v4/order?orderID=' + order_id_v4);
  await v4_mk_request('DELETE', '/api/v4/order', {'orderID': [order_id_v4]});

  const order_id_v3 = (await v3_mk_request('POST', 'api/3/order/new', {
    'order': {
      'orderType': 'LIMIT',
      'tradedCurrency': 'BTC',
      'settlementCurrency': 'USD',
      'buyTradedCurrency': true,
      'tradedCurrencyAmount': '0.01',
      'limitPriceInSettlementCurrency': '39000'
    }
  }))['orderId'];
  await v3_mk_request('POST', 'api/3/order/info', {'orderId': order_id_v3});
  await v3_mk_request('POST', 'api/3/order/cancel', {'orderIds': [order_id_v3]});
}

run();