入门指引


欢迎使用OKTop开发者文档。此文档目前为V3 Beta版,会继续更新,请大家及时关注。

此文档为用户提供了一整套简单而又强大的开发工具,旨在帮助用户快速、高效地将OKTop交易功能整合到自己的应用当中。
OKTop接口是提供服务的基础,API分为账户、交易和行情三类。开发者在OKTop网站创建账号后,可以根据自身需求建立不同权限的API,并利用API进行自动交易或者提现。
账户和交易API需要身份验证,提供下单、撤单,查询订单和帐户信息等功能。行情API提供市场的行情数据,所有行情接口都是公开的。

接口调用方式说明

OKTop为用户提供两种调用接口的方式,开发者可根据自己的使用场景和偏好选择适合自己的方式来查询行情、进行交易或提现。目前只开放REST接口,Websocket接口将会随后提供。

REST API

REST,即Representational State Transfer的缩写,是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,正得到越来越多网站的采用。其优点如下:

  • 在RESTful架构中,每一个URL代表一种资源;
  • 客户端和服务器之间,传递这种资源的某种表现层;
  • 客户端通过四个HTTP指令,对服务器端资源进行操作,实现“表现层状态转化”。 建议开发者使用REST API进行币币交易或者资产提现等操作。
WebSocket API

WebSocket是HTML5一种新的协议(Protocol)。它实现了客户端与服务器全双工通信,使得数据可以快速地双向传播。通过一次简单的握手就可以建立客户端和服务器连接,服务器根据业务规则可以主动推送信息给客户端。其优点如下:

  • 客户端和服务器进行数据传输时,请求头信息比较小,大概2个字节;
  • 客户端和服务器皆可以主动地发送数据给对方;
  • 不需要多次创建TCP请求和销毁,节约宽带和服务器的资源。

联系我们

如需帮助请添加微信号:jj18515532533 备注:API+OKTop,拉你进API问题交流群

API概述

市场概况和基础信息

撮合引擎

本章节主要为撮合引擎的细节分以下三个方面:

  • 成交价
  • 订单生命周期
  • 币币交易限价规则

成交价

OKTop撮合系统撮合订单的优先级按照价格优于时间的优先级来撮合,优先撮合价格更有优势的订单。当价格一致时按照下单时间顺序撮合,先下单的先撮合。

比如深度列表中目前有3笔挂单等待成交,分别为1: 9900USDT买1BTC,2: 10100USDT买2BTC,3: 9900USDT买1.5BTC。他们是按时间顺序1-2-3进入撮合系统的,根据价格优先,系统优先撮合订单2,根据时间优先,1跟3优先撮合1。所以系统撮合顺序是2-1-3。

订单撮合时成交价将按maker挂单价格成交,而非taker吃单价格。

例如:A用户在10000USDT挂了1BTC的买单,然后B用户以8000USDT的价格下了1BTC的卖单,因为A用户的订单先进入撮合系统挂在深度列表上,所以以A的价格为准,最终这笔订单最终以10000USDT成交。

订单生命周期

订单进入撮合引擎后是"未成交"状态;

如果一个订单被撮合而全部成交,那么它会变成"已成交"状态;

一个订单被撮合可能出现部分成交,那么他的状态会变成"部分成交"状态,并且继续留在撮合队列中进行撮合;

一个留在撮合队伍中等待撮合的订单被撤销,那么他的状态会变成"已撤销"状态;

发起撤消到完成撤消的过程中有一个过程状态"撤单中";

被撤消或者全部成交的订单将被从撮合队列中剔除。

币币交易限价规则

为了防止用户下错大单造成市场异常波动和个人资金损失,OKTop币币交易设置了FOK限价规则:如果用户在币币交易所下的市价单/限价单可以与当前买卖盘内订单直接成交,那么系统会判断成交深度对应的价格与同方向盘口价的偏差是否超出30%。如果超过,则此订单将被系统立即全数撤销,否则此订单正常进行撮合。

例如:某用户在XRP/BTC交易区下了100BTC的市价买单(此时卖一价为0.00012),系统判断订单完成成交后最新成交价为0.0002。此时,(0.0002-0.00012)/0.00012=66.7%>30%,用户的这笔市价买单将被立即撤销,不会和买卖盘内订单进行撮合。

费用

本章节主要为费用的细节分以下两个方面:

  • 交易费用
  • 充/提币费用

交易费用

详情请参考OKTop官网费率说明。

充/提币费用

OKTop不收取任何充币/提币费用,但是提币到数字货币地址的过程中产生的矿工手续费需要用户自己承担。

服务器

OKTop的数据库和服务器运行在香港。为了最大限度地减少API访问延迟,建议您使用与香港通讯通畅的服务器。

请求

本章节主要为请求的细节分以下三个方面:

  • 介绍
  • 错误
  • 成功

介绍

REST API提供账户管理、行情查询和交易功能。

REST API终端URL https://www.ok.top/

所有请求基于Https协议,请求头信息中contentType需要统一设置为:’application/json’

错误

除非特殊说明,错误请求都通过HTTP 4xx或者状态码进行返回,返回内容还将包含错误原因、参数信息。您的HTTP库应配置为非2xx请求提供消息主体,以便您可以从主体读取消息字段。

常见错误码
400 Bad Request — Invalid request fotmat
401 Unauthorized — Invalid API Key
403 Forbidden — You do not have access to the requested resou-rce
404 Not Found
500 Intermal Server Error — We had a problem with our server

成功

HTTP状态码200表示成功响应,并可能包含内容。如果响应含有内容,则将显示在相应的返回内容里面。

分页

OKTop为所有返回数据集的REST请求使用分页。分页允许在结果的当前页面之前和之后获取结果,并且非常适合于实时数据。像/ trades,/ fill,/ orders这样默认返回最新内容的请求。根据当前的返回结果,后续请求可以在他的基础之上指定请求数据的方向,可以请求在这之前的,也可以请求在这之后的数据。

before和after可通过响应头OK-BEFORE和OK-AFTER使用。在请求初始请求页面之后,请求应使用这些值。

Before 游标指向的是返回结果页的第一条内容,After游标指向的是返回结果页的最后一条内容。(页面内容是按照最新的排在最上面的顺序)

如果你希望请求当前返回结果页最后的新数据,需要用before参数。你的第一个请求可以省略这个参数来获得默认的第一页。

返回结果将会包含一个OK-BEFORE头这里会包含当前返回结果页里面最新的一条的数据的ID。

返回结果将会包含一个OK-AFTER头这里会包含当前返回结果页里面最后的一条的数据的ID。

举例如果你请求返回的结果每一条内容的id 是 111,112,113,114,115,116,117,118,119,120

那么在返回结果里面这些内容的排列顺序是120,119,118,117,116,115,114,113,112,111

这时OK-BEFORE记录的ID是120,OK-AFTER记录的ID是111,如果你想访问更新的数据,如120以后的数据那么你需要使用before参数,如:orders?before=120&limit=5,则返回的是120以后的5条数据,且排列顺序为:125,124,123,122,121

参数
参数名 描述
before 请求此页码之后(更新)的分页(一列数:1,2,3,4,5.before 4只有5,after 4有1,2,3)
after 请求此页码之前(更旧)的分页
limit 分页返回的结果集数量,默认为100,最大为100
例子

GET /orders?before=2&limit=30

标准规范

本章节主要为标准规范的细节分以下三个方面:

  • 时间戳
  • 数字
  • ID

时间戳

除非另外指定,API中的所有时间戳均以毫秒为单位返回,符合ISO 8601标准。请确保您可以解析ISO 8601格式。

例子

2014-11-06T10:34:47.123456Z

数字

为了保持跨平台时精度的完整性,十进制数字作为字符串返回。建议您在发起请求时也将数字转换为字符串以避免截断和精度错误。

整数(如交易编号和顺序)不加引号。

ID

除非另有说明,大多数标识符是UUID。当提出一个需要UUID的请求时,以下两个形式(有和没有破折号)都被接受。

132fb6ae-456b-4654-b4e0-d681ac05cea1或者132fb6ae456b4654b4e0d681ac05cea1

接口类型

本章节主要为接口类型的细节分以下两个方面:

  • 公共接口
  • 私有接口

公共接口

公共接口可用于获取配置信息和行情数据。公共请求无需认证即可调用。

私有接口

私有接口可用于订单管理和账户管理。每个私有请求必须使用规范的验证形式进行签名。

私有接口需要使用您的API key进行验证。您可以在这里生成API key。

访问限制

本章节主要为访问限制的细节分以下方面:

  • REST API

当访问超过频率限制时,将返回429状态:请求太频繁。

REST API

通过APIKEY限制公共接口和私有接口的调用,如果用户访问的是公共接口无APIKEY则通过IP地址进行限速。

限速规则:一般接口限速6次/秒。其中币币API包含accounts的接口,所有接口的总访问频率不能超过10次/秒;币币API包含orders的接口,所有接口的总访问频率不能超过10次/秒。

验证

本章节主要为验证的细节分以下五个方面:

  • 生成API Key
  • 发起请求
  • 签名
  • 时间戳
  • 获取服务器时间

生成API Key

在对任何请求进行签名之前,您必须通过OKTop网站创建一个API Key。创建API Key后,您将获得3个必须记住的信息:

API Key
Secret
Passphrase
API Key和Secret将由OKTop随机生成和提供,Passphrase将由您提供以确保API访问的安全性。OKTop将存储Passphrase加密后的哈希值进行验证,但如果您忘记Passphrase,则无法恢复,请您通过OKTop网站重新生成新的API Key。

发起请求

所有REST请求头都必须包含以下内容:

OK-ACCESS-KEY字符串类型的API Key。

OK-ACCESS-SIGN使用base64编码签名(请参阅签名)。

OK-ACCESS-TIMESTAMP发起请求的时间戳。

OK-ACCESS-PASSPHRASE您在创建API密钥时指定的Passphrase。

所有请求都应该含有application/json类型内容,并且是有效的JSON。

签名

OK-ACCESS-SIGN的请求头是对timestamp + method + requestPath + body字符串(+表示字符串连接)使用HMAC SHA256方法加密,通过BASE64编码输出而得到的。

其中,timestamp的值与OK-ACCESS-TIMESTAMP请求头相同。

method是请求方法,字母全部大写。

requestPath是请求接口路径。

body是指请求主体的字符串,如果请求没有主体(通常为GET请求)则body可省略。

public enum ContentTypeEnum {

    APPLICATION_JSON("application/json"),
    APPLICATION_JSON_UTF8("application/json; charset=UTF-8"),
    // The server does not support types
    APPLICATION_FORM("application/x-www-form-urlencoded; charset=UTF-8"),;


    private String contentType;

    ContentTypeEnum(String contentType) {
        this.contentType = contentType;
    }

    public String contentType() {
        return contentType;
    }
}


public enum HttpHeadersEnum {

    OK_ACCESS_KEY("OK-ACCESS-KEY"),
    OK_ACCESS_SIGN("OK-ACCESS-SIGN"),
    OK_ACCESS_TIMESTAMP("OK-ACCESS-TIMESTAMP"),
    OK_ACCESS_PASSPHRASE("OK-ACCESS-PASSPHRASE"),

    OK_BEFORE("OK-BEFORE"),
    OK_AFTER("OK-AFTER"),
    OK_LIMIT("OK-LIMIT"),;

    private String header;

    HttpHeadersEnum(String header) {
        this.header = header;
    }

    public String header() {
        return header;
    }
}

import com.okcoin.commons.OKTop.open.api.config.APIConfiguration;
import com.okcoin.commons.OKTop.open.api.constant.APIConstants;
import com.okcoin.commons.OKTop.open.api.enums.ContentTypeEnum;
import com.okcoin.commons.OKTop.open.api.enums.HttpHeadersEnum;
import com.okcoin.commons.OKTop.open.api.exception.APIException;
import com.okcoin.commons.OKTop.open.api.utils.DateUtils;
import com.okcoin.commons.OKTop.open.api.utils.HmacSHA256Base64Utils;
import okhttp3.*;
import okio.Buffer;

public class APIHttpClient {

    private APIConfiguration config;
    private APICredentials credentials;

    public APIHttpClient(APIConfiguration config, APICredentials credentials) {
        this.config = config;
        this.credentials = credentials;
    }

    public OkHttpClient client() {
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        clientBuilder.connectTimeout(this.config.getConnectTimeout(), TimeUnit.SECONDS);
        clientBuilder.readTimeout(this.config.getReadTimeout(), TimeUnit.SECONDS);
        clientBuilder.writeTimeout(this.config.getWriteTimeout(), TimeUnit.SECONDS);
        clientBuilder.retryOnConnectionFailure(this.config.isRetryOnConnectionFailure());
        clientBuilder.addInterceptor((Interceptor.Chain chain) -> {
            Request.Builder requestBuilder = chain.request().newBuilder();
            String timestamp = DateUtils.getUnixTime();
            requestBuilder.headers(headers(chain.request(), timestamp));
            Request request = requestBuilder.build();
            if (this.config.isPrint()) {
                printRequest(request, timestamp);
            }
            return chain.proceed(request);
        });
        return clientBuilder.build();
    }

    private Headers headers(Request request, String timestamp) {
        Headers.Builder builder = new Headers.Builder();
        builder.add(APIConstants.ACCEPT, ContentTypeEnum.APPLICATION_JSON.contentType());
        builder.add(APIConstants.CONTENT_TYPE, ContentTypeEnum.APPLICATION_JSON_UTF8.contentType());
        builder.add(APIConstants.COOKIE, getCookie());
        if (StringUtils.isNotEmpty(this.credentials.getSecretKey())) {
            builder.add(HttpHeadersEnum.OK_ACCESS_KEY.header(), this.credentials.getApiKey());
            builder.add(HttpHeadersEnum.OK_ACCESS_SIGN.header(), sign(request, timestamp));
            builder.add(HttpHeadersEnum.OK_ACCESS_TIMESTAMP.header(), timestamp);
            builder.add(HttpHeadersEnum.OK_ACCESS_PASSPHRASE.header(), this.credentials.getPassphrase());
        }
        return builder.build();
    }

    private String getCookie() {
        StringBuilder cookie = new StringBuilder();
        cookie.append(APIConstants.LOCALE).append(this.config.getI18n().i18n());
        return cookie.toString();
    }

    private String sign(Request request, String timestamp) {
        String sign;
        try {
            sign = HmacSHA256Base64Utils.sign(timestamp, method(request), requestPath(request),
                    queryString(request), body(request), this.credentials.getSecretKey());
        } catch (IOException e) {
            throw new APIException("Request get body io exception.", e);
        } catch (CloneNotSupportedException e) {
            throw new APIException("Hmac SHA256 Base64 Signature clone not supported exception.", e);
        } catch (InvalidKeyException e) {
            throw new APIException("Hmac SHA256 Base64 Signature invalid key exception.", e);
        }
        return sign;
    }

    private String url(Request request) {
        return request.url().toString();
    }

    private String method(Request request) {
        return request.method().toUpperCase();
    }

    private String requestPath(Request request) {
        String url = url(request);
        url = url.replace(this.config.getEndpoint(), APIConstants.EMPTY);
        String requestPath = url;
        if (requestPath.contains(APIConstants.QUESTION)) {
            requestPath = requestPath.substring(0, url.lastIndexOf(APIConstants.QUESTION));
        }
        if(this.config.getEndpoint().endsWith(APIConstants.SLASH)){
            requestPath = APIConstants.SLASH + requestPath;
        }
        return requestPath;
    }

    private String queryString(Request request) {
        String url = url(request);
        String queryString = APIConstants.EMPTY;
        if (url.contains(APIConstants.QUESTION)) {
            queryString = url.substring(url.lastIndexOf(APIConstants.QUESTION) + 1);
        }
        return queryString;
    }

    private String body(Request request) throws IOException {
        RequestBody requestBody = request.body();
        String body = APIConstants.EMPTY;
        if (requestBody != null) {
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            body = buffer.readString(APIConstants.UTF_8);
        }
        return body;
    }
}



import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;

import java.util.List;

interface FuturesMarketAPI {

    @GET("/api/futures/v3/products/{product_id}/candles")
    Call<JSONArray> getProductCandles(@Path("product_id") String productId, @Query("start") String start, @Query("end") String end, @Query("granularity") String granularity);

}

import com.alibaba.fastjson.JSONArray;
import com.okcoin.commons.OKTop.open.api.bean.futures.result.*;
import com.okcoin.commons.OKTop.open.api.client.APIClient;
import com.okcoin.commons.OKTop.open.api.config.APIConfiguration;
import com.okcoin.commons.OKTop.open.api.service.futures.FuturesMarketAPIService;



public class FuturesMarketAPIServiceImpl implements FuturesMarketAPIService {

    private APIClient client;
    private FuturesMarketAPI api;

    public FuturesMarketAPIServiceImpl(APIConfiguration config) {
        this.client = new APIClient(config);
        this.api = client.createService(FuturesMarketAPI.class);
    }

    @Override
    public JSONArray getProductCandles(String productId, long start, long end, long granularity) {
        return this.client.executeSync(this.api.getProductCandles(productId, String.valueOf(start), String.valueOf(end), String.valueOf(granularity)));
    }

}

import okhttp3.Headers;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

public class APIClient {

    /**
     * Synchronous send request
     */
    public <T> T executeSync(Call<T> call) {
        try {
            Response<T> response = call.execute();
            if (this.config.isPrint()) {
                printResponse(response);
            }
            int status = response.code();
            String message = new StringBuilder().append(response.code()).append(" / ").append(response.message()).toString();
            if (response.isSuccessful()) {
                return response.body();
            } else if (APIConstants.resultStatusArray.contains(status)) {
                HttpResult result = JSON.parseObject(new String(response.errorBody().bytes()), HttpResult.class);
                result.setStatusCode(status);
                throw new APIException(result.message());
            } else {
                throw new APIException(message);
            }
        } catch (IOException e) {
            throw new APIException("APIClient executeSync exception.", e);
        }
    }

}

public class FuturesAPIBaseTests extends BaseTests {

    public APIConfiguration config() {
        APIConfiguration config = new APIConfiguration();

        config.setEndpoint("https://www.ok.top/");
        config.setApiKey("");
        config.setSecretKey("");

        config.setPassphrase("");
        config.setPrint(true);
        config.setI18n(I18nEnum.ENGLISH);

        return config;
    }

    String productId = "BTC-USD-180928";
}



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.okcoin.commons.OKTop.open.api.bean.futures.result.*;
import com.okcoin.commons.OKTop.open.api.service.futures.FuturesMarketAPIService;
import com.okcoin.commons.OKTop.open.api.service.futures.impl.FuturesMarketAPIServiceImpl;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class FuturesMarketAPITests extends FuturesAPIBaseTests {

    private FuturesMarketAPIService marketAPIService;

    @Before
    public void before() {
        config = config();
        marketAPIService = new FuturesMarketAPIServiceImpl(config);
    }

    @Test
    public void testGetProductCandles() {
        long start = System.currentTimeMillis();
        long end = System.currentTimeMillis() + 2000L;
        JSONArray array = marketAPIService.getProductCandles(productId, 1530323640000L, 0, 180L);
        toResultString(LOG, "Product-Candles", array);
    }


}
package oktop

import (
    "bytes"
    "errors"
    "fmt"
    "io/ioutil"
    "net/http"
    "strconv"
    "strings"
    "time"
)

type Client struct {
    Config     Config
    HttpClient *http.Client
}

type ApiMessage struct {
    Message string `json:"message"`
}

/*
 Get a http client
*/
func NewClient(config Config) *Client {
    var client Client
    client.Config = config
    timeout := config.TimeoutSecond
    if timeout <= 0 {
        timeout = 30
    }
    client.HttpClient = &http.Client{
        Timeout: time.Duration(timeout) * time.Second,
    }
    return &client
}

/*
 Send a http request to remote server and get a response data
*/
func (client *Client) Request(method string, requestPath string,
    params, result interface{}) (response *http.Response, err error) {
    config := client.Config
    // uri
    endpoint := config.Endpoint
    if strings.HasSuffix(config.Endpoint, "/") {
        endpoint = config.Endpoint[0:len(config.Endpoint)-1]
    }
    url := endpoint + requestPath

    // get json and bin styles request body
    var jsonBody string
    var binBody = bytes.NewReader(make([]byte, 0))
    if params != nil {
        jsonBody, binBody, err = ParseRequestParams(params)
        if err != nil {
            return response, err
        }
    }

    // get a http request
    request, err := http.NewRequest(method, url, binBody)
    if err != nil {
        return response, err
    }

    // Sign and set request headers
    timestamp := IsoTime()
    preHash := PreHashString(timestamp, method, requestPath, jsonBody)
    sign, err := HmacSha256Base64Signer(preHash, config.SecretKey)
    if err != nil {
        return response, err
    }
    Headers(request, config, timestamp, sign)

    if config.IsPrint {
        printRequest(config, request, jsonBody, preHash)
    }

    // send a request to remote server, and get a response
    response, err = client.HttpClient.Do(request)
    if err != nil {
        return response, err
    }
    defer response.Body.Close()

    // get a response results and parse
    status := response.StatusCode
    message := response.Status
    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return response, err
    }

    if config.IsPrint {
        printResponse(status, message, body)
    }

    response.Header.Add(ResultJsonString, string(body))

    if status >= 200 && status < 300 {
        if body != nil && result != nil {
            err := JsonBytes2Struct(body, result)
            if err != nil {
                return response, err
            }
        }
        return response, nil
    } else if status == 400 || status == 401 || status == 500 {
        if body != nil {
            var apiMessage ApiMessage
            err := JsonBytes2Struct(body, &apiMessage)
            if err != nil {
                return response, err
            }
            message = strconv.Itoa(status) + " " + apiMessage.Message
        }
        return response, errors.New(message)
    } else {
        return response, errors.New(message)
    }
    return response, nil
}

type Config struct {
    // Rest api endpoint url. eg: http://www.ok.top/
    Endpoint string
    // The user's api key provided by OKTop.
    ApiKey string
    // The user's secret key provided by OKTop. The secret key used to sign your request data.
    SecretKey string
    // The Passphrase will be provided by you to further secure your API access.
    Passphrase string
    // Http request timeout.
    TimeoutSecond int
    // Whether to print API information
    IsPrint bool
    // Internationalization @see file: constants.go
    I18n string
}

func (client *Client) GetFuturesProductCandles(productId string, start, end, granularity int64) ([][] float64, error) {
    var candles [][] float64
    params := NewParams()
    params["start"] = Int642String(start)
    params["end"] = Int642String(end)
    params["granularity"] = Int642String(granularity)
    requestPath := BuildParams(FuturesPathPrefix+"products/"+productId+"/candles", params)
    _, err := client.Request(GET, requestPath, nil, &candles)
    return candles, err
}


func NewTestClient() *Client {
    // Set OKTop API's config
    var config Config
    config.Endpoint = "https://www.ok.top/"
    config.ApiKey = ""
    config.SecretKey = ""
    config.Passphrase = ""
    config.TimeoutSecond = 45
    config.IsPrint = false
    config.I18n = ENGLISH

    client := NewClient(config)
    return client
}



import "testing"

const (
    productId = "BTC-USD-180928"
    currency  = "BTC"
)

func TestGetFuturesProductCandles(t *testing.T) {
    start := int64(0)
    end := int64(0)
    candles, err := NewTestClient().GetFuturesProductCandles(productId, start, end, 180)
    if err != nil {
        t.Error(err)
    }
    FmtPrintln(GUnitTest+"Futures product candles: ", candles)
}
string OKTopAPI::GetSign(string timestamp, string method, string requestPath, string body) {
    string sign;
    unsigned char * mac = NULL;
    unsigned int mac_length = 0;
    string data = timestamp + method + requestPath + body;
    string key = m_config.SecretKey;
    int ret = HmacEncode("sha256", key.c_str(), key.length(), data.c_str(), data.length(), mac, mac_length);
    sign = base64_encode(mac, mac_length);
    return sign;
}

string OKTopAPI::Request(const string &method, const string &requestPath, const string &params) {
    /************************** set request method ***************************/
    http_request request;
    request.set_method(method);
    /************************** set request uri ***************************/
    uri_builder builder;
    builder.append_path(requestPath);
    request.set_request_uri(builder.to_uri());

    /************************** set request headers ***************************/
    char * timestamp = new char[32];
    timestamp = GetTimestamp(timestamp, 32);
    string sign = GetSign(timestamp, method, builder.to_string(), params);
    request.headers().clear();
    request.headers().add(U("OK-ACCESS-KEY"), m_config.ApiKey);
    request.headers().add(U("OK-ACCESS-SIGN"), sign);
    request.headers().add(U("OK-ACCESS-TIMESTAMP"), timestamp);
    request.headers().add(U("OK-ACCESS-PASSPHRASE"), m_config.Passphrase);
    request.headers().add(U("Accept"), U("application/json"));
    request.headers().set_content_type(U("application/json; charset=UTF-8"));
    request.headers().add(U("Cookie"),U("locale="+m_config.I18n));

    /************************** set request body ***************************/
    request.set_body(params,"application/json; charset=UTF-8");

    /************************** get response ***************************/
    http_response response;
    string str;
    http_client client(m_config.Endpoint);
    response = client.request(request).get();
    str = response.extract_string(true).get();

    delete []timestamp;
    return str;
}


string GetSpotOrdersExample() {
    OKTopAPI oktopapi;
    /************************** set config **********************/
    struct Config config;
    config.Endpoint = "https://www.ok.top";
    config.SecretKey = "";
    config.ApiKey = "";
    config.Passphrase = "";
    okapi.SetConfig(config);

    /************************** set parameters **********************/
    string method(GET);
    map<string,string> m;
    m.insert(make_pair("productId", "BTC-USD"));
    m.insert(make_pair("status", "all"));

    /************************** request and response **********************/
    string request_path = BuildParams("/api/spot/v3/orders", m);
    return OKTopapi.Request(method, request_path);
}

string AddSpotOrderExample() {
    OKTopAPI oktopapi;
    /************************** set config **********************/
    struct Config config;
    config.Endpoint = "https://www.ok.top";
    config.SecretKey = "";
    config.ApiKey = "";
    config.Passphrase = "";
    okapi.SetConfig(config);

    /************************** set parameters **********************/
    value obj;
    obj["size"] = value::number(1);
    obj["price"] = value::number(8);
    obj["side"] = value::string("buy");
    obj["product_id"] = value::string("BTC-USD");

    /************************** request and response **********************/
    string params = obj.serialize();
    return OKTopapi.Request(POST, "/api/spot/v3/orders", params);
}
}
import hmac
import base64
import requests
import json

CONTENT_TYPE = 'Content-Type'
OK_ACCESS_KEY = 'OK-ACCESS-KEY'
OK_ACCESS_SIGN = 'OK-ACCESS-SIGN'
OK_ACCESS_TIMESTAMP = 'OK-ACCESS-TIMESTAMP'
OK_ACCESS_PASSPHRASE = 'OK-ACCESS-PASSPHRASE'
APPLICATION_JSON = 'application/json'


# signature
def signature(timestamp, method, request_path, body, secret_key):
    if str(body) == '{}' or str(body) == 'None':
        body = ''
    message = str(timestamp) + str.upper(method) + request_path + str(body)
    mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
    d = mac.digest()
    return base64.b64encode(d)


# set request header
def get_header(api_key, sign, timestamp, passphrase):
    header = dict()
    header[CONTENT_TYPE] = APPLICATION_JSON
    header[OK_ACCESS_KEY] = api_key
    header[OK_ACCESS_SIGN] = sign
    header[OK_ACCESS_TIMESTAMP] = str(timestamp)
    header[OK_ACCESS_PASSPHRASE] = passphrase
    return header


def parse_params_to_str(params):
    url = '?'
    for key, value in params.items():
        url = url + str(key) + '=' + str(value) + '&'

    return url[0:-1]


# request example
# set the request url
base_url = 'https://www.ok.top'
request_path = '/api/account/v3/currencies'
# set request header
header = get_header('your_api_key', signature('timestamp', 'GET', request_path, 'your_secret_key'), 'timestamp', 'your_passphrase')
# do request
response = requests.get(base_url + request_path, headers=header)
# json
print(response.json())

# [{
#     "id": "BTC",
#     "name": “Bitcoin”,
#      "deposit": "1",
#      "withdraw": “1”,
#       “withdraw_min”:”0.000001btc”
# }, {
#     "id": "ETH",
#     "name": “Ethereum”,
#     "deposit": "1",
#      "withdraw": “1”,
#      “withdraw_min”:”0.0001eth”
#     }
#  …
# ]


########################################################
# take order
base_url = 'https://www.ok.top'
request_path = '/api/spot/v3/orders'

# request params
params = {'type': 'market', 'side': 'buy', 'product_id': 'usdt_okb', 'size': '10', 'client_oid': '',
                  'price': '10', 'funds': ''}

# request path
request_path = request_path + parse_params_to_str(params)
url = base_url + request_path

# request header and body
header = get_header('your_api_key', signature('timestamp', 'POST', request_path, 'your_secret_key'), 'timestamp', 'your_passphrase')
body = json.dumps(params)

# do request
response = requests.post(url, data=body, headers=header)

#########################################################
# get order info
base_url = 'https://www.ok.top'
request_path = '/api/spot/v3/orders'

params = {'status':'all', 'product_id': 'okb_usdt'}

# request path
request_path = request_path + parse_params_to_str(params)
url = base_url + request_path

# request header and body
header = get_header('your_api_key', signature('timestamp', 'GET', request_path, 'your_secret_key'), 'timestamp', 'your_passphrase')

# do request
response = requests.get(url, headers=header)

时间戳

OK-ACCESS-TIMESTAMP请求头必须是UTC时区Unix时间戳的十进制秒数格式或ISO8601标准的时间格式。

时间戳和服务器时间相差30秒以上的请求将被系统视为过期并拒绝。如果您认为服务器和API服务器之间存在较大的时间偏差,那么我们建议您使用获取服务器时间的接口来查询API服务器时间。

获取服务时间

获取API服务器的时间。此接口为公共接口,不需要身份验证。

HTTP请求

GET/api/general/v3/time

返回参数
参数名 描述
iso ISO8601标准的时间格式
epoch UTC时区Unix时间戳的十进制秒数格式
[{

"iso": "2015-01-07T23:47:25.201Z",

"epoch": 1420674445.201

}]

钱包API

钱包主账户与交易账户/子账户之间的资金划转,获取充值地址,提现等功能。

获取币种列表

获取平台所有币种列表。并非所有币种都可被用于交易。在ISO 4217标准中未被定义的币种代码可能使用的是自定义代码。

HTTP请求

GET/api/account/v3/currencies

返回值
参数名 描述
id 币种代码
name 币种名称
deposit 是否可充值,0表示不可充值,1表示可以充值
withdraw 是否可提币,0表示不可提币,1表示可以提币
min_withdraw_limit 币种最小提币量
[{
    "id": "BTC",
    "name": “Bitcoin”,
     "deposit": "1",
     "withdraw": “1”,
      “min_withdraw_limit”:”0.000001btc”
}, {
    "id": "ETH",
    "name": “Ethereum”,
    "deposit": "1",
     "withdraw": “1”,
     “min_withdraw_limit”:”0.0001eth”
    }
 …
]

钱包账户信息

获取钱包账户资产列表,查询各币种的余额、冻结和可用等信息。

HTTP请求

GET/api/account/v3/wallet

返回参数
参数名 描述
currency 币种
balance 余额
holds 冻结(不可用)
available 可用于提现或资金划转的数量
[
{

 "currency": "ETH",

 "balance": “5”,

 "holds": “3.2",

 "available": “1.8”
 }, {
 "currency": "BTC",

 "balance": “2”,

 "holds": "1",

 "available": “1”

 }
…
]

单一币种账户信息

获取钱包账户单个币种的余额、冻结和可用等信息。

HTTP请求

GET/api/account/v3/wallet/<currency>

返回参数
参数名 描述
balance 余额
holds 冻结(不可用)
available 可用于提现或资金划转的数量
{

 "balance": “5”,

 "holds": “3.2",

 "available": “1.8”

 }

资金划转

OKTop站内在钱包账户、交易账户和子账户之间进行资金划转。

HTTP请求

POST/api/account/v3/transfer

查询参数
参数名 描述
currency 币种
amount 划转数量
from 转出账户(0:子账户 1:币币 6:钱包)
to 转入账户(0:子账户 1:币币 6:钱包)
sub_account [非必填]子账号登录名
product_id [非必填]杠杆币对ID,仅限已开通杠杆的币对
返回参数
参数名 描述
transfer_id 划转ID
currency 划转币种
from 转出账户
amount 划转量
to 转入账户
result 划转结果。若是划转失败,将给出错误码提示
解释说明

from或to指定为0时,sub_account为必填项。

{
    “transfer_id": “754147”,
    “currency”:“ETC”
    “from": "6",
    “amount": “0.1",
    “to”: "1",
    “result": true
}

提币

提币到OKCoin国际站账户,OKTop账户或数字货币地址。

HTTP请求

POST/api/account/v3/withdrawals

查询参数
参数名 描述
currency 币种
amount 数量
destination 提币到(2:OKCoin国际 3:OKEX 4:数字货币地址)
withdraw_address 认证过的数字货币地址、邮箱或手机号
trade_pwd 交易密码
fee 网络手续费≥0.提币到OKCoin国际或OKTop免手续费,请设置为0.提币到数字货币地址所需网络手续费可通过提币手续费接口查询
返回参数
参数名 描述
currency 提币币种
amount 提币数量
withdraw_id 提币申请ID
result 提币申请结果。若是提现申请失败,将给出错误码提示
{
    “currency”:”ETC”,
    “amount”:”1”
    "withdraw_id": "593533d2-ff31-46e0-b22e-ca754147a96a",
    "result": true

}

提币手续费

查询提现到数字货币地址时,建议网络手续费信息。手续费越高,网络确认越快。

HTTP请求

GET/api/account/v3/withdrawals/fee

查询参数
参数名 描述
currency [非必填]币种,不填则返回所有
返回参数
参数名 描述
currency 币种
min 最小提币手续费数量
max 最大提币手续费数量
{

"currency": "BTC",

"min": 0.002,

"max": 0.005,

}

查询最近所有币种的提币记录

查询最近所有币种的提币记录。

HTTP请求

GET/api/account/v3/withdrawals/history

查询参数
返回参数
参数名 描述
currency 币种
amount 数量
created_at 提币申请时间
from 提币地址(如果收币地址是OKTop平台地址,则此处将显示用户账户)
to 收币地址
tag 部分币种提币需要标签,若不需要则不返回此字段
payment_id 部分币种提币需要此字段,若不需要则不返回此字段
txid 提币哈希记录(内部转账将不返回此字段)
fee 提币手续费
解释说明

此处的from显示的是用户OKTop账户,并不等于区块链上实际的发币地址,如果提币到OKTop则to也显示为OKTop账户,此时将不返回txid 返回所有币种最近100条提币记录,若想查询更多请分币对查询。 注意此处显示的最新提币记录可能还没有在区块上打包成功,若此处有提币记录而实际未到账,请耐心等待


[
{
   "currency": "ETH",
    "amount": “20”,
     “created_at”: "2018-04-18 11:00:23"
     “from”:”0x6cc5f688a315f3dc28a7781717a9a798a59fda7b",
    “to": “0x9edfe04c866d636526828e523a60501a37daf8f6",
        “txid":“0xf1fb12a03c483f475fc33abcb5bf42a765c7131e2f955025aec706be3f616da4”,
     “fee”: “0.00042eth”,
  },
{
   "currency": "XRP",
    "amount": “200”,
     “created_at”: "2018-04-18 11:00:23"
     “from”:”rUzWJkXyEtT8ekSSxkBYPqCvHpngcy6Fks",
    “to": “r4hYwnBsNH764iTfhRSopu4M3Ct5gMkCGD",
     “tag”:”100061235”   “txid":“6B18A0E7078B5C850E640140A7F15A21A14D47C6DE4EAC7DF60BD7EC26918877”,
     “fee”: “0.0001xrp”,
  },

]

查询单个币种提币记录

查询单个币种的最近成交记录。

HTTP请求

GET/api/account/v3/withdrawals/history/<currency>

返回参数
参数名 描述
amount 数量
created_at 提币申请时间
from 提币地址(如果收币地址是OKTop平台地址,则此处将显示用户账户)
to 收币地址
tag 部分币种提币需要标签,若不需要则不返回此字段
payment_id 部分币种提币需要此字段,若不需要则不返回此字段
txid 提币哈希记录(内部转账将不返回此字段)
fee 提币手续费
解释说明

此处的from显示的是用户OKTop账户,并不等于区块链上实际的发币地址,如果提币到OKTop则to也显示为OKTop账户,此时将不返回txid 返回所有币种最近100条提币记录,若想查询更多请分币对查询。 注意此处显示的最新提币记录可能还没有在区块上打包成功,若此处有提币记录而实际未到账,请耐心等待

[
{
    "amount": “20”,
     “created_at”: "2018-04-18 11:00:23"
     “from”:”0x6cc5f688a315f3dc28a7781717a9a798a59fda7b",
    “to": “0x9edfe04c866d636526828e523a60501a37daf8f6",
        “txid":“0xf1fb12a03c483f475fc33abcb5bf42a765c7131e2f955025aec706be3f616da4”,
     “fee”: “0.00042eth”,
  },
]

账单流水查询

查询钱包账户账单流水。流水会分页,并且按时间倒序排序和储存,最新的排在最前面。请参阅分页部分以获取第一页之后的其他记录。

HTTP请求

GET/api/account/v3/ledger

查询参数
参数名 描述
currency [非必填]币种
type [非必填]1:充值2:提现13:撤销提现18:转入合约账户19:合约账户转出20:转入子账户21:子账户转出28:领取29:转入指数交易区30:指数交易区转出 31:转入点对点账户32:点对点账户转出 33:转入币币杠杆账户 34:币币杠杆账户转出 37:转入币币账户 38:币币账户转出
before 请求此页码之后(更新)的分页
after 请求此页码之前(更旧)的分页
limit 分页返回的结果集数量,默认为100,最大为100
返回参数
参数名 描述
ledger_id 账单ID
currency 币种
balance 余额
amount 变动数量
type 账单类型
fee 手续费
created_at 账单创建时间
[{

"ledger_id": "593533d2-ff31-46e0-b22e-ca754147a96a",

"currency": "BTC",

"balance": 200,

"amount": 2,

"fee": 0,

"typename": "withdraw",

"created_at": "2018-04-18 11:00:23"

}]

获取充值地址

获取各个币种的充值地址,包括曾使用过的老地址。

HTTP请求

GET/api/account/v3/deposit/address

查询参数
参数 描述
currency [必填]币种
返回参数
参数名 描述
address 充值地址
tag 充值tag(当该币种不需要tag的时候不会返回此字段)
payment_id 充值payment_id(单该币种不需要payment_id时不会返回此字段)
解释说明

IOTA充值地址不能重复使用!在向IOTA地址发起充值后,再次充值到此相同地址将不会被确认到账。

某些币充值到账,需要同时填写一个充值地址和一个tag/payment_id。如果未遵守正确的充值步骤,币会丢失!

[{
    "address":"dafdsafdsfe",
    “tag":"123",
}, {
    "address":"dafdsafdsfe",
    “payment_id”:”xyzddrrrsdfsdf"
}]

获取所有币种充值记录

获取所有币种的充值记录。

HTTP请求

GET/api/account/v3/deposit/history

返回参数
参数名 描述
currency 充币币种
amount 充值数量
to 此笔充值到账地址
txid 区块转账哈希记录
created_at 充值到账时间
[{
     "currency": "ETH",
     "amount": 2,
   “to”:”0x9edfe04c866d636526828e523a60501a37daf8f6",    “txid”:“0xf1fb12a03c483f475fc33abcb5bf42a765c7131e2f955025aec706be3f616da4”,
    "created_at": "2018-04-18 11:00:23"
}]

获取单个币种充值记录

获取单个币种的充值记录

HTTP

GET/api/account/v3/deposit/history/<currency>

返回参数
参数名 描述
amount 充值数量
to 此笔充值到账地址
txid 区块转账哈希记录
created_at 充值到账时间
[{
 "amount": 2,

 “to”:”[0x9edfe04c866d636526828e523a60501a37daf8f6](https://etherscan.io/address/0x9edfe04c866d636526828e523a60501a37daf8f6)", “txid”:“0xf1fb12a03c483f475fc33abcb5bf42a765c7131e2f955025aec706be3f616da4”,

 "created_at": "2018-04-18 11:00:23"
}]

币币API

币币交易的行情信息,账户信息,订单操作,订单查询,账单明细查询。

币币账户信息

获取币币账户资产列表,查询各币种的余额、冻结和可用等信息。

HTTP请求

GET/api/spot/v3/accounts

返回参数
参数名 描述
currency 币种
balance 余额
holds 冻结(不可用)
available 可用于交易或资金划转的数量
id 账户ID
解释说明

当你下市价单或限价单时,订单所需的资金将被冻结。这部分数量将不能被用于其他订单或者资金划转。资金将一直被冻结直至订单被成交或者取消。

[{
   "currency": “BTC”,
   “balance”: ”2.3”,    
    “holds”: “2”,
    "available": “0.3”,
    “id”:”344555”
}]

单一币种账户信息

获取币币账户单个币种的余额、冻结和可用等信息。

HTTP请求

GET/api/spot/v3/accounts/<currency>

返回参数
参数名 描述
currency 币种
balance 余额
holds 冻结(不可用)
available 可用于交易或资金划转的数量
id 账户id
[{

 "currency": “BTC”,

 “balance”: ”2.3”, 

 “holds”: “2”,

 "available": “0.3”,

 “id”:”344555”

}]

账单流水查询

列出账户资产流水。账户资产流水是指导致账户余额增加或减少的行为。流水会分页,并且按时间倒序排序和存储,最新的排在最前面。请参阅分页部分以获取第一页之后的其他记录。

HTTP请求

GET/api/spot/v3/accounts/<currency>/ledger

返回参数
参数名 描述
ledger_id 账单ID
balance 余额
currency 币种
amount 变动数量
type 流水来源
created_at 账单创建时间
details 如果类型是match或者fee,则会有该details字段将包含order,product信息
order_id 交易的ID
product_id 交易的币对

解释说明

流水来源类型 描述
transfer 资金转入/转出
match 交易产生的资金变动
fee 手续费
rebate 返佣
[
{
      “amount":"0.999",
      “balance":"6.539194",
      “create_at":"2018-06-20T02:31:00Z",
      “details":
             {“order_id”:7542,"product_id":"LTC-BTC"},
      “ledger_id": “912025447”,
      “type”:”match"
},
{
      “amount":"-1",
      “balance":"31.797831",
      “create_at":"2018-06-20T02:31:00Z",
      “details":
        {“order_id”:7542,"product_id":"LTC-BTC"},
      “ledger_id”:“912025427”,
      “type”:”match"},
       …
]

下单

OKTop币币交易提供限价单和市价单两种下单模式(更多下单模式将会在后期支持)。只有当您的账户有足够的资金才能下单。一旦下单,您的账户资金将在订单生命周期内被冻结。被冻结的资金以及数量取决于订单指定的类型和参数。

HTTP请求

POST/api/spot/v3/orders

通用参数
参数名 描述
client_oid [非必填]由您设置的订单ID来识别您的订单
type limit,market(默认是limit)
side buy or sell
product_id 币对名称
margin_trading 下单类型(1表示币币交易,2表示币币杠杆交易,默认为1)
限价单特殊参数
参数名 描述
price 价格
size 买入或卖出的数量
市价单特殊参数
参数名 描述
size 卖出数量,市价卖出时必填size,不填funds
funds 买入金额,市价买入是必填funds,不填size
返回参数
参数名 描述
order_id 订单ID
client_oid 由您设置的订单ID来识别您的订单
result 下单结果。若是下单失败,将给出错误码提示
解释说明

product_id

product_id必须是有效的币对。币对列表可通过/ products接口获取。

client_oid

可选字段client_oid是您的交易程序自行生成的UUID。您可以使用此字段在系统返回给你的信息中识别订单。 client_oid与服务器分配的订单ID不同。如果您使用client_oid在系统返回的信息中发现对应订单,同样需要记录order_id,因为它将用于未来的订单状态更新查询。消息返回之后,client_oid就没有任何作用了。

type

下单时,您可以指定订单类型。您指定的订单类型将决定是否需要其他订单参数以及撮合引擎如何执行您的订单。如果type没有指定,订单类型将默认为limit。限价单既是默认订单类型,也是基本订单类型。限价单需要指定price和size。size是买入或卖出交易货币的数量,price表示每个交易货币相对计价货币的价格。限价单会按指定价格或更好的价格成交。根据市场条件,卖单可以按照指定价格或者更高价格来成交,买单可以按照指定价格或更低价格成交。如果限价单不能立即成交,那么限价单将进入深度列表,直到被另一个新订单成交或被用户撤单。 市价单不同于限价单,因为它们不提供价格控制。市价单提供了一种不必指定价格,而以固定数量的货币进行买入或者卖出的方式。市价单下单后会立即撮合,而不会被挂入深度列表。市价单总是吃单方(taker)并按taker收取手续费用。(注:如果你计划买入卖出的数量巨大时,将会对价格产生巨大影响,此时不推荐使用市价单)

price

price表示买入或卖出的价格。价格必须是价格步长(quote_increment)的倍数。价格步长(quote_increment)是价格的最小增量,可通过product接口获取。

size

size表示买入或卖出交易货币的数量。数量必须大于base_min_size。base_increment是交易货币数量的最小增量。上述参数都可通过product接口获取。 举例:假设 btc/usdt 的base_min_size是10,base_increment是0.0001。那么不能交易9.9个btc,但是可以交易10.0001个btc

funds

funds表示被用于市价买入的计价货币的数量,市价买入时必填。例如,在BTC-USDT交易时,市价单指定5000 USDT表示将花费5000 USDT购买BTC。

holds

对于限价买单,系统将冻结计价货币的数量 = 限定价格 x 买入数量。对于限价卖单,系统将冻结你想卖出的交易货币的数量。对于市价买单,funds数量的计价货币将被冻结。对于市价卖单,size数量的交易货币将被冻结。如果您取消部分成交或未成交的订单,剩余资金将被解除冻结。

订单生命周期

HTTP请求将在订单被拒绝(资金不足,参数无效等)或下单成功(由匹配引擎接受)时作出响应。一个200响应表示该订单被接收并且进入撮合。进入撮合的订单可以部分或全部立即成交(取决于价格和市场条件)。部分成交的时候将把订单的剩余数量继续进行撮合。完全成交的订单将进入已成交状态。 监听行情数据的用户建议使用client_oid字段以便在接受到的信息中标识对应的数据。

响应

成功接受的订单将被分配一个订单ID。订单是否成功接受取决于撮合引擎是否接受。 未成交的订单不会过期,并将保持撮合状态,直到被成交或取消。

{
    "order_id": "234652",
    "client_oid": “23",
    "result": true
}

撤销指定订单

撤销之前下的未完成订单。

HTTP请求

DELETE /api/spot/v3/orders/<order_id>

查询参数
参数名 描述
product_id [必填]提供此参数则撤销指定币对的相应订单,如果不提供此参数则返回错误码
返回参数
参数名 描述
order_id 订单ID
client_oid 由您设置的订单ID来识别您的订单
result 撤单结果。若是撤单失败,将给出错误码提示
解释说明

这order_id是服务器分配的订单ID,而不是用户传的的client_oid。

如果订单无法取消(已经成交或已取消),那么返回的报错内容里将显示相应的原因。

{
"client_oid":"",
"order_id":1745,
"result":true
}

批量撤销订单

撤销指定的某一种或多种币对的所有未完成订单。

HTTP请求

DELETE/api/spot/v3/orders

查询参数
参数名 描述
product_id [必填]提供此参数则撤销指定一个或多个币对的订单,如果不提供此参数则返回错误码,此字段支持传多个值。此参数为[“btc_usdt”,“ltc_eth”]
返回参数
参数名 描述
order_id 订单ID
client_oid 由您设置的订单ID来识别您的订单
result 撤单结果。若是撤单失败,将给出错误码提示
解释说明

一次调用最多撤销50个订单。撤销的是最新的50个订单 无法保证一定会成功撤销,建议用户调用批量撤单接口后,再调用获取订单列表接口确认。

{
“btc_usdt”:{
"result":true,
"client_oid":"",
"order_id":["1747","1748"]
},
“ltc_eth”:{
"result":true,
"client_oid":"",
“order_id”:[“1758”,”1779","1880"]
}
}

获取订单列表

列出您当前所有的订单信息。这个请求支持分页,并且按时间倒序排序和存储,最新的排在最前面。请参阅分页部分以获取第一页之后的其他纪录。

HTTP请求

GET/api/spot/v3/orders

查询参数
参数名 描述
status [必填]仅列出相应状态的订单列表。(all:所有状态 open:未成交 part_filled:部分成交 canceling:撤销中 filled:已成交 canceled:已撤销)
product_id [必填]列出指定币对的订单
before 请求此页码之后(更新)的分页
after 请求此页码之后(更旧)的分页
limit 分页返回的结果集数量,默认为100,最大为100
返回参数
参数名 描述
order_id 订单ID
price 价格
size 交易货币数量
funds 买入金额,市价买入时返回
product_id 币对名称
side 订单方向
type 订单类型
created_at 订单创建时间
filled_size 已成交数量
executed_value 已成交金额
status 订单状态
解释说明

本接口只能查询最近两天的已成交和已撤销订单信息。

如果订单在其生命周期内没有任何成交,其记录可能被清除。这表示订单详细信息将不可用本接口来获取。

executed_value表示[已成交数量*成交均价]。

未成交的订单可能会根据市场情况在你发起请求和服务器响应之间改变状态。

[{
    "order_id": "125678",
    "price": "0.10000000",
    "size": "0.01000000",
    "product_id": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "created_at": "2016-12-08T20:02:28.53864Z",
    "filled_size": "0.00000000",
    "executed_value": "0.0000000000000000",
    "status": "open"
},{
    "order_id": "125600",
    "size": "1.00000000",
    "product_id": "BTC-USDT",
    "side": "sell",
    "type": "market",
    "created_at": "2016-12-08T20:09:05.508883Z",
    "filled_size": "1.00000000",
    "executed_value": "9.9750556620000000",
    "status": "filled"
},{
    "order_id": "125459",
    "price": "0.10000000",
    "size": “0.01000000",
    "product_id": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "created_at": "2016-12-08T20:02:28.53864Z",
    "filled_size": "0.00000000",
    "executed_value": "0.0000000000000000",
    "status": "open"
}]

获取所有未成交订单

列出您当前所有的订单信息。这个请求支持分页,并且按时间倒序排序和存储,最新的排在最前面。请参阅分页部分以获取第一页之后的其他纪录。

HTTP请求

GET/api/spot/v3/orders_pending

查询参数
参数名 描述
before 请求此页码之后(更新)的分页
after 请求此页码之前(更旧)的分页
limit 分页返回的结果集数量,默认为100,最大为100
返回参数
参数名 描述
order_id 订单ID
price 价格
size 交易货币数量
funds 买入金额,市价买入时返回
product_id 币对名称
side 订单方向
type 订单类型
created_at 订单创建时间
filled_size 已成交数量
executed_value 已成交金额
status 订单状态
解释说明

本接口只能查询所有未成交或者部分成交的订单

executed_value表示[已成交数量*成交均价]。

未成交的订单可能会根据市场情况在你发起请求和服务器响应之间改变状态。

[{
    "order_id": "125678",
    "price": "0.10000000",
    "size": "0.01000000",
    "product_id": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "created_at": "2016-12-08T20:02:28.53864Z",
    "filled_size": "0.00000000",
    "executed_value": "0.0000000000000000",
    "status": "open"
},{
    "order_id": "125600",
    "size": "1.00000000",
    "product_id": "BTC-USDT",
    "side": "sell",
    "type": "market",
    "created_at": "2016-12-08T20:09:05.508883Z",
    "filled_size": "0.80000000",
    "executed_value": "9.9750556620000000",
    "status": “part_filled”
},{
    "order_id": "125459",
    "price": "0.10000000",
    "size": “0.01000000",
    "product_id": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "created_at": "2016-12-08T20:02:28.53864Z",
    "filled_size": "0.00000000",
    "executed_value": "0.0000000000000000",
    "status": “open"
}]

获取订单信息

通过订单ID获取单个订单信息。

HTTP请求

GET/api/spot/v3/orders/<order_id>

查询参数
参数名 描述
product_id [必填]提供此参数则撤销指定币对的相应订单,如果不提供此参数则返回错误码
返回参数
参数名 描述
order_id 订单ID
price 价格
size 交易货币数量
funds 买入金额,市价买入时返回
product_id 币对名称
side 订单方向
type 订单类型
created_at 订单创建时间
filled_size 已成交数量
executed_value 已成交金额
status 订单状态
解释说明

本接口只能查询最近两天的已成交和已撤销订单信息。

如果订单在其生命周期内没有任何成交,其记录可能被清除,则响应可能因为没有相应的匹配而返回状态码404。

executed_value表示[已成交数量*成交均价]。

未成交的订单可能会根据市场情况在你发起请求和服务器响应之间改变状态。

{
    "order_id": "233456",
    "funds": “10000.0000",
    “price”:“8014.23”,
    “size”:“4”,
    "product_id": "BTC-USDT",
    "side": "buy",
    "type": “market",
    "created_at": "2016-12-08T20:09:05.508883Z",
    "filled_size": "0.1291771",
    "executed_value": "10000.0000",
    "status": "filled"
}

获取成交明细

获取最近的成交明细表。这个请求支持分页,并且按时间倒序排序和存储,最新的排在最前面。请参阅分页部分以获取第一页之后的其他记录。

HTTP请求

GET/api/spot/v3/fills

查询参数
参数名 描述
order_id 仅限此order_id的资金明细列表,默认返回所有
product_id 仅限此product_id的资金明细表,默认返回所有
before 请求此页码之后(更新)的分页
after 请求此页码之前(更旧)的分页
limit 分页返回的结果集数量,默认为100,最大为100
返回参数
参数名 描述
ledger_id 账单ID
product_id 币对名称
price 价格
size 数量
order_id 订单ID
created_at 订单创建时间
exec_type 流动性方向(T or M)
fee 手续费
side 订单方向(buy or sell)
解释说明

手续费

fee字段表示这条账单记录所收取的手续费。

流动性

exec_type字段表示该账单是maker还是taker产生的。M表示Maker,T表示Taker。

分页

返回账单列表的ledger_id按降序排列,从最大ledger_id到最小ledger_id。OK-BEFORE都会有这样的第一笔ledger_id,以便将来的请求使用OK-BEFORE参数将获取一个更大的ledger_id(新的账单)。

[{

 "ledger_id": “741234”,

 "product_id": "BTC-USDT",

 "price": "10.00",

 "size": "0.01",

 "order_id": "234566",

 "created_at": "2014-11-07T22:19:28.578544Z",

 "exec_type": "T",

 "fee": “0.00025",

 "side": "buy"

}]

获取币对信息

用于获取行情数据,这组公开接口提供了行情数据的快照,无需认证即可调用。

获取交易币对的列表,查询各币对的交易限制和价格步长等信息。

HTTP请求

GET/api/spot/v3/products

返回参数
参数名 描述
product_id 币对名称
base_currency 交易货币币种
quote_currency 计价货币币种
base_min_size 最小交易数量
base_increment 交易货币数量精度
quote_increment 交易价格精度
解释说明

base_min_size指下单数量的最小值。base_increment(交易数量步长)是指下单数量的最小增量。例如,当base_increment为0.000001,委托数量传入0.0000121将被系统按截尾法修正为0.000012。

quote_increment(价格步长)是指下单价格的最小增量,委托价格必须是quote_increment的倍数。例如,当quote_increment为0.0001,委托价格传入0.02231将被系统按截尾法修正为0.0223。

[{
"product_id": "BTC-USDT",

"base_currency": "BTC",

"quote_currency": "USDT",

"base_min_size": "0.001",

"base_increment": "0.00000001",

"quote_increment": "0.0001"
}]

获取深度数据

获取币对的深度列表。这个请求不支持分页,一个请求返回整个深度列表。

HTTP请求

GET/api/spot/v3/products/<product_id>/book

查询参数
参数名 描述
size 返回深度档位数量,最多返回200
depth 按价格合并深度,默认为quote_increment(价格步长)
返回参数
普通返回数据
参数名 描述
price 价格
size 数量
num_orders 组成此条深度的卖单数量
解释说明

按价格合并深度是指每个价格区间将仅返回一个数量,就像在该价格区间上只有一个订单。

{

    "bids": [
        [ price, size, num-orders ],
        [ "295.96", "4.39088265", 2 ],
        ...
    ],
    "asks": [
        [ price, size, num-orders ],
        [ "295.97", "25.23542881", 12 ],
        ...
    ]
}

获取全部ticker信息

获取平台全部币对的最新成交价、买一价、卖一价和24小时交易量的快照信息。

HTTP请求

GET/api/spot/v3/products/ticker

返回参数
参数名 描述
product_id 币对名称
last 最新成交价
best_ask 卖一价
best_bid 买一价
open_24h 24小时开盘价
high_24h 24小时最高价
low_24h 24小时最低价
base_volume_24h 24小时成交量,按交易货币统计
quote_volume_24h 24小时成交量,按交易货币统计
timestamp 系统时间戳
解释说明

最高价、最低价和成交量都是按最近24小时为维度统计的。

24小时开盘价取值来自24小时前那一分钟的K线的开盘价。即 2018年7月23日08:23:45,此时的涨跌幅依靠的是开盘价是2018年7月22日08:23:00时的价格。

[{

"product_id": "BTC-USDT",

"last": "333.99",

"best_ask": "333.98",

"best_bid": "333.99",

"high_24h": "0.193",

"low_24h": "333.98",

"base_volume_24h": "5957.11914015",

"quote_volume_24h": "5957.11914015",

"time": "2015-11-14T20:46:03.511254Z"

},{

"product_id": "LTC-USDT",

"last": "333.99",

"best_ask": "333.98",

"best_bid": "333.99",

"high_24h": "0.193",

"low_24h": "333.98",

"base_volume_24h": "5957.11914015",

"quote_volume_24h": "5957.11914015",

"time": "2015-11-14T20:46:03.511254Z"

}]

获取某个ticker信息

获取币对的最新成交价、买一价、卖一价和24小时交易量的快照信息。

HTTP请求

GET/api/spot/v3/products/product_id/ticker

返回参数
参数名 描述
product_id 币对名称
last 最新成交价
best_ask 卖一价
best_bid 买一价
open_24h 24小时开盘价
high_24h 24小时最高价
low_24h 24小时最低价
base_volume_24h 24小时成交量,按交易货币统计
quote_volume_24h 24小时成交量,按计价货币统计
timestamp 系统时间戳
解释说明

最高价、最低价和成交量都是按最近24小时为维度统计的。

24小时开盘价取值来自24小时前那一分钟的K线的开盘价。即 2018年7月23日08:23:45,此时的涨跌幅依靠的是开盘价是2018年7月22日08:23:00时的价格。

{
“product_id": "BTC-USDT",

"last": "333.99",

"best_ask": "333.98",

"best_bid": "333.99",

"high_24h": "0.193",

"low_24h": "333.98",

"base_volume_24h": "5957.11914015",

"quote_volume_24h": "5957.11914015",

"time": "2015-11-14T20:46:03.511254Z"
}

获取成交数据

获取币对最新的2000条成交列表。这个请求支持分页,并且按时间倒序排序和存储,最新的排在最前面。请参阅分页部分以获取第一页之后的其他纪录。

HTTP请求

GET/api/spot/v3/products/<product_id>/trades

查询参数
参数名 描述
before 请求此页码之后(更新)的分页
after 请求此页码之前(更旧)的分页
limit 分页返回的结果集数量,默认为100,最大为100
返回参数
参数名 描述
time 成交时间
trade_id 成交ID
price 成交价格
size 成交数量
side 成交方向

解释说明

成交方向side是指Taker订单的下单方向,Taker表示主动与深度列表中挂单进行成交。buy表示价格上涨,因为Taker是买单吃掉深度,所以价格将上行。相反,sell表示价格下跌。

trade_id是记录成交信息的递增ID,可能不完整。

[{

"time": "2014-11-07T22:19:28.578544Z",

"trade_id": "3245601",

"price": "10.00000000",

"size": "0.01000000",

"side": "buy"

}, {

"time": "2014-11-07T01:08:43.642366Z",

"trade_id": "3245602",

"price": "100.00000000",

"size": "0.01000000",

"side": "sell"

}]

获取K线数据

获取币对的K线数据。K线数据按请求的粒度分组返回。

HTTP请求

GET /api/spot/v3/products/<product_id>/candles

查询参数
参数名 描述
start 开始时间(ISO 8601标准)
end 结束时间(ISO 8601标准)
granularity 以秒来计量的时间粒度
返回参数
参数名 描述
time 开始时间
low 最低价格
high 最高价格
open 开盘价格
close 收盘价格
volume 交易量
解释说明

如果用户没有提供开始时间或结束时间中的任一字段,则两个字段都将被忽略。未提供开始时间和结束时间的请求,则系统按时间粒度返回最近的300个数据。

时间粒度granularity必须是[60 180 300 900 1800 3600 7200 14400 21600 43200 86400 604800]中的任一值,否则请求将被拒绝。这些值分别对应的是[1min 3min 5min 15min 30min 1hour 2hour 4hour 6hour 12hour 1day 1week]的时间段。

K线数据可能不完整。K线数据不应该轮询调用。

单次请求的最大数据量是300。如果您选择的开始/结束时间和时间粒度导致超过单次请求的最大数据量,您的请求将只会返回300个数据。如果您希望在更大的时间范围内获取足够精细的数据,则需要使用多个开始/结束范围进行多次请求。

[
 {
 "close":7071.1913,
 "high":7072.7999,
 "low":7061.7,
 "open":7067.9008,
 "time":"2018-08-05T10:00:00Z",
 "volume":68.4532745
 },
 ]

results matching ""

    No results matching ""