Upbit API使用详解:快速入门指南与教程

Upbit API 使用教程详解

1. 概述

Upbit 作为韩国领先的数字资产交易平台,为全球开发者提供了功能全面的应用程序编程接口(API),以便于程序化交易的执行、深入的市场数据分析以及与其他系统的集成。 通过 Upbit API,开发者可以构建自动化交易策略、实时监控市场动态、管理账户信息,并执行多种交易操作。

本文档旨在提供 Upbit API 的详尽指南,涵盖从 API 密钥的申请、身份验证流程、各种 API 端点的使用方法,到常见问题的解决方案。 无论您是初学者还是经验丰富的开发者,本指南都将帮助您快速理解和高效利用 Upbit API,从而实现您的交易目标。

Upbit API 具有 RESTful 架构风格,使用 JSON 格式进行数据交换,易于理解和实现。 API 提供了对市场行情、交易订单、账户余额等核心数据的访问权限,并支持 WebSocket 协议进行实时数据推送。 本文将详细介绍这些关键特性,并提供相应的代码示例,助力开发者快速上手并构建可靠的应用程序。

2. 准备工作

为了顺利地使用 Upbit API,在开始编程之前,必须完成一系列必要的准备步骤,这些步骤直接关系到后续开发的效率和安全性:

  • 注册 Upbit 账号并完成 KYC 认证:

    访问 Upbit 官方网站,按照指示注册一个新的账户。注册完成后,务必完成 KYC(Know Your Customer)身份验证流程。KYC 认证是交易所为了遵守监管要求、防止洗钱等非法活动而采取的措施,通常需要提供身份证明、地址证明等信息。只有通过 KYC 认证的账户才能正常使用 API 进行交易或数据查询。

  • 创建并配置 API 密钥:

    成功登录您的 Upbit 账户后,导航至 API 管理页面。在此页面,您可以创建新的 API 密钥。创建 API 密钥时,请务必仔细配置权限。Upbit 允许您为每个 API 密钥设置不同的权限,例如:

    • 只读权限: 仅允许获取账户信息、市场数据等,禁止进行任何交易操作。
    • 交易权限: 允许进行买入、卖出等交易操作。
    • 提现权限: 允许将数字货币提现到外部地址(通常不建议开启)。

    为了最大程度地保障您的资金安全,强烈建议遵循最小权限原则,即仅授予 API 密钥完成特定任务所需的最小权限。例如,如果您只需要获取市场数据,则只授予只读权限。同时,务必妥善保管您的 API 密钥,不要将其泄露给任何人,也不要将其存储在不安全的地方。

  • 安装必要的开发环境和依赖库:

    根据您选择的编程语言,配置相应的开发环境。不同的编程语言需要不同的开发工具包和库来与 Upbit API 进行交互。例如:

    • Python: 推荐使用 requests 库发送 HTTP 请求,并使用 库处理 JSON 格式的 API 响应。您可以使用 pip install requests pip install 命令安装这些库。
    • JavaScript (Node.js): 可以使用 axios node-fetch 库发送 HTTP 请求。使用 npm install axios npm install node-fetch 命令进行安装。
    • Java: 可以使用 Apache HttpClient 或 OkHttp 库发送 HTTP 请求。

    确保您的开发环境已正确配置,并且所需的库已成功安装,这将为后续的 API 调用奠定基础。

3. API 认证

Upbit API 采用 JWT (JSON Web Token) 进行身份验证,确保请求的安全性与合法性。 为了访问受保护的 Upbit API 资源,每次向 API 端点发送请求时,都必须在 HTTP 请求头的 Authorization 字段中携带符合规范的 JWT。

JWT 的生成过程涉及多个步骤,包括构建 Payload、使用 Secret Key 进行签名以及最终生成 JWT 字符串。 下面详细阐述每个步骤:

  1. 构建 Payload: Payload 是 JWT 的核心组成部分,其中包含了声明(claims),这些声明是关于实体(通常是用户)和其他数据的陈述。 对于 Upbit API 认证,Payload 必须包含以下两个关键字段:
    • access_key : 此字段对应于 Upbit API 密钥对中的访问密钥(Access Key),用于标识请求的来源。 务必妥善保管您的 Access Key,避免泄露。
    • nonce : nonce 是一个随机生成的唯一字符串,旨在防止重放攻击(Replay Attack)。 每次生成 JWT 时,都必须使用一个新的 nonce 值。 建议使用 UUID (Universally Unique Identifier) 等算法生成高随机性的字符串。
    Payload 通常表示为一个 JSON 对象。
  2. 使用 Secret Key 对 Payload 进行签名: 为了确保 JWT 的完整性和真实性,需要使用 Upbit API 密钥对中的安全密钥(Secret Key)对 Payload 进行签名。 签名过程使用 HMAC SHA512 算法,该算法结合了哈希函数 SHA512 和密钥,生成一个唯一的签名。 安全性依赖于 Secret Key 的保密性,请务必妥善保管,切勿泄露。
  3. 生成 JWT: JWT 的最终生成过程包括以下步骤:对 Payload 进行 Base64 编码(Base64url 编码,一种 URL 安全的 Base64 变体)。然后,使用 Secret Key 对 Payload 进行 HMAC SHA512 签名,并将签名结果也进行 Base64url 编码。 将编码后的 Payload、签名以及 JWT 头部(指定算法类型,例如 {"alg": "HS256", "typ": "JWT"} 并进行 Base64url 编码)用句点( . )连接起来,形成最终的 JWT 字符串。 JWT 字符串的结构如下: [Header].[Payload].[Signature]

以下 Python 代码示例演示了如何使用 jwt 库生成 JWT。 请注意,该示例使用了 HS256 算法,而非 HMAC SHA512 算法,Upbit 可能需要其他算法,请根据Upbit官方文档进行调整:

import jwt
import uuid
import hashlib
import hmac
import base64

access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"

payload = {
    'access_key': access_key,
    'nonce': str(uuid.uuid4()),
}

# HS256 算法示例 (如果 Upbit 使用 HS256)
jwt_token_hs256 = jwt.encode(payload, secret_key, algorithm='HS256')
print("HS256 JWT Token:", jwt_token_hs256)

# HMAC SHA512 算法示例 (需要手动实现,如果 Upbit 使用 HMAC SHA512)
def generate_jwt_hmac_sha512(payload, secret_key):
    header = {'alg': 'HS512', 'typ': 'JWT'}
    header_ = .dumps(header, separators=(',', ':')) # Remove whitespace
    payload_ = .dumps(payload, separators=(',', ':')) # Remove whitespace

    header_b64 = base64.urlsafe_b64encode(header_.encode('utf-8')).rstrip(b'=').decode('utf-8')
    payload_b64 = base64.urlsafe_b64encode(payload_.encode('utf-8')).rstrip(b'=').decode('utf-8')

    message = header_b64 + '.' + payload_b64
    signature = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha512).digest()
    signature_b64 = base64.urlsafe_b64encode(signature).rstrip(b'=').decode('utf-8')

    return message + '.' + signature_b64


# 替换为你实际使用的库和方法 (如果 Upbit 使用 HMAC SHA512)
# jwt_token = generate_jwt_hmac_sha512(payload, secret_key) #假设 generate_jwt_hmac_sha512 是你实现的HMAC SHA512的jwt生成方法。
# print("HMAC SHA512 JWT Token:", jwt_token)

重要提示:

  • 请务必将示例代码中的 YOUR_ACCESS_KEY YOUR_SECRET_KEY 替换为您从 Upbit 平台获得的真实 API 密钥。
  • 示例代码中包含 HS256 算法和 HMAC SHA512 算法的示例。 请查阅 Upbit 官方 API 文档,确认 Upbit 实际使用的签名算法,并相应地调整代码。 如果 Upbit 使用 HMAC SHA512, 则需要手动实现相应的签名逻辑(如上面的代码所示)或者查找并使用支持 HMAC SHA512 的 JWT 库。
  • 实际部署时,请使用更安全的密钥管理方案来存储和管理您的 API 密钥,例如使用环境变量或专门的密钥管理服务。 避免将密钥硬编码在代码中,以防止泄露。
  • 请仔细阅读并遵守 Upbit API 的使用条款和限制,合理使用 API 资源,避免对平台造成不必要的负担。
  • nonce 的目的是防止重放攻击,每次调用API都必须生成新的nonce。

4. 常用 API 接口

Upbit API 提供了一系列功能强大的接口,方便开发者获取市场数据、管理账户以及执行交易操作。这些接口涵盖了广泛的功能,从实时行情查询到复杂的订单管理,能够满足不同用户的需求。以下详细介绍几个常用的 API 接口,并提供基本的使用说明和注意事项。

  • 行情查询 API (Market API):

    用于查询Upbit交易所的各种交易对的实时行情数据、历史K线数据、以及市场深度信息。

    • 获取所有交易对信息 (GET /markets): 返回Upbit支持的所有交易对的列表,包括市场代码、韩元市场代码、英文名称和韩文名称等信息。
    • 获取单个交易对的最新成交价 (GET /ticker): 获取指定交易对的最新成交价、涨跌幅等信息,是实时监控市场价格变动的关键接口。
    • 获取K线数据 (GET /candles): 获取指定交易对的历史K线数据,包括分钟K线、日K线、周K线和月K线。开发者可以根据这些数据进行技术分析和趋势预测。可以自定义K线类型 (minute1, minute5, minute15, minute30, minute60, day, week, month) 和数量。
    • 获取当前深度 (Orderbook) (GET /orderbook): 返回指定交易对的当前买单和卖单的挂单信息,可以帮助开发者了解市场的供需情况和流动性。

行情查询:

  • GET /v1/ticker : 获取指定交易对或市场的最新行情信息。此接口返回的数据通常包括当前价格、最高价、最低价、成交量等关键指标,为用户提供快速的市场概览。
  • GET /v1/candles/minutes/{unit} : 查询指定市场的分钟级别 K 线数据。 unit 参数定义了 K 线的周期,允许用户选择不同时间粒度的数据分析。支持的 unit 值包括 1, 3, 5, 15, 30, 60 和 240 分钟,分别对应 1 分钟、3 分钟、5 分钟、15 分钟、30 分钟、1 小时和 4 小时 K 线。这种灵活性满足了不同交易策略的需求,从短线高频交易到中长线趋势分析。
  • GET /v1/candles/days : 检索指定市场的每日 K 线数据。该接口提供每日开盘价、收盘价、最高价、最低价以及成交量等信息,适用于分析日线级别的市场趋势和波动。
  • GET /v1/candles/weeks : 获取指定市场的每周 K 线数据。周 K 线能够有效过滤短期市场噪音,帮助交易者识别中长期趋势,并进行更稳健的投资决策。
  • GET /v1/candles/months : 查询指定市场的每月 K 线数据。月 K 线提供最长期的市场视角,适用于长期投资者评估资产表现和进行战略性资产配置。

账户管理:

  • GET /v1/accounts : 查询所有账户信息。

    该接口用于获取用户在交易所拥有的所有账户的详细信息。返回数据通常包括账户ID、币种类型、可用余额、冻结余额等关键信息。用户可以通过此接口全面了解其资产状况。

    请求示例: GET /v1/accounts

    响应示例:

    
    [
        {
            "account_id": "12345",
            "currency": "BTC",
            "available": "1.5",
            "frozen": "0.2"
        },
        {
            "account_id": "67890",
            "currency": "USDT",
            "available": "1000",
            "frozen": "50"
        }
    ]
            
  • GET /v1/orders/chance : 查询指定市场下单可能的最大数量/金额。

    该接口允许用户在下单前预估指定交易对(例如 BTC/USDT)在当前市场条件下可下单的最大数量或金额。这有助于用户避免因余额不足或超出市场限额而导致下单失败。

    参数说明:

    • market : 交易市场,例如 "BTC/USDT"。
    • side : 交易方向,"buy" (买入) 或 "sell" (卖出)。
    • price (可选): 委托价格。 如果不提供,则返回市价单的最大下单数量/金额。

    请求示例: GET /v1/orders/chance?market=BTC/USDT&side=buy

    响应示例:

    
    {
        "market": "BTC/USDT",
        "side": "buy",
        "max_size": "0.1",
        "max_funds": "5000"
    }
            

    字段解释:

    • max_size : 最大可买入/卖出的数量 (针对限价单和市价单)。
    • max_funds : 最大可用于买入的金额 (仅针对市价买单)。

交易下单:

  • 下单接口:

    使用 POST /v1/orders 接口可以提交新的交易订单。通过此接口,您可以指定交易对、订单类型(如市价单、限价单)、交易方向(买入或卖出)和订单数量等参数,从而在市场上创建您的交易意向。请务必仔细核对订单参数,确保符合您的交易策略。

    请求示例:

    POST /v1/orders
    {
      "symbol": "BTCUSDT",
      "side": "BUY",
      "type": "LIMIT",
      "quantity": 0.1,
      "price": 30000
    }
            
  • 订单查询接口:

    使用 GET /v1/order 接口可以查询特定订单的详细信息。您需要提供订单ID作为参数来检索该订单的状态、成交数量、成交均价等信息。此接口对于监控订单执行情况和分析交易结果至关重要。

    请求示例:

    GET /v1/order?orderId=123456789
            
  • 订单取消接口:

    使用 DELETE /v1/order 接口可以取消尚未完全成交的订单。同样,您需要提供订单ID作为参数来指定要取消的订单。请注意,部分已成交的订单可能无法取消,具体取决于交易所的规则。

    请求示例:

    DELETE /v1/order?orderId=123456789
            

5. 代码示例

以下是一个使用 Python 调用 Upbit API 查询账户信息的示例代码。该示例展示了如何生成JWT(JSON Web Token)进行身份验证,并使用该Token来访问Upbit的 /v1/accounts API端点,以获取账户信息。

import requests
import jwt
import uuid

access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"

payload = {
    'access_key': access_key,
    'nonce': str(uuid.uuid4()),
}

jwt_token = jwt.encode(payload, secret_key, algorithm='HS256')
authorize_token = f'Bearer {jwt_token}'

headers = {"Authorization": authorize_token}

res = requests.get('https://api.upbit.com/v1/accounts', headers=headers)

print(res.())

该代码段使用 requests 库发送HTTP请求, jwt 库生成JWT, uuid 库生成唯一nonce值。 access_key secret_key 是您的Upbit API密钥,用于身份验证。 nonce 是一个一次性使用的随机字符串,用于防止重放攻击。

定义 access_key secret_key 变量,替换为你的实际Upbit API密钥。 然后,创建一个包含 access_key nonce 的payload字典。 nonce 使用 uuid.uuid4() 生成,保证每次请求的唯一性。 接下来,使用 jwt.encode() 方法,使用 secret_key HS256 算法对payload进行签名,生成JWT。然后,将JWT放入 Authorization 请求头中,格式为 Bearer {jwt_token} 。使用 requests.get() 方法向Upbit API的 /v1/accounts 端点发送GET请求,并将包含授权信息的header传入。服务器返回的JSON格式的响应包含了你的账户信息,通过 res.() 方法解析并打印。

在实际使用中,务必将 YOUR_ACCESS_KEY YOUR_SECRET_KEY 替换为你在Upbit交易所申请到的真实 API 密钥。请注意保护你的API密钥,避免泄露,防止他人未经授权访问你的账户。请仔细阅读Upbit API的官方文档,了解各个API端点的使用方法和频率限制,避免触发限流。

6. 错误处理

在使用 Upbit API 进行交易或数据查询时,开发者可能会遇到各种错误情况。Upbit API 使用标准的 HTTP 状态码来清晰地指示错误类型,这有助于开发者快速定位并解决问题。理解这些状态码及其含义是构建健壮应用程序的关键。

  • 400 Bad Request : 此状态码表明请求包含无效的参数或格式错误。例如,传递了超出范围的数值、提供了错误的日期格式,或者缺少必需的参数。开发者应仔细检查请求参数,并对照 Upbit API 文档进行验证,确保参数类型、格式和范围均符合要求。
  • 401 Unauthorized : 401 错误表示未经授权的访问尝试。通常,这意味着提供的 API 密钥不正确或缺失,或者用于身份验证的 JWT (JSON Web Token) 已过期或无效。请务必检查 API 密钥是否已正确配置,并且 JWT 是否根据 Upbit 的身份验证流程正确生成和签名。同时,确保您的 API 密钥拥有执行请求操作所需的权限。
  • 429 Too Many Requests : 此状态码表明客户端在短时间内发送了过多的请求,超过了 Upbit API 的速率限制。为了保证服务的稳定性和公平性,Upbit 对 API 请求频率进行了限制。开发者应该采取措施来降低请求频率,例如使用缓存机制、批量处理请求,或者实现指数退避算法。
  • 500 Internal Server Error : 500 错误通常指示 Upbit 服务器端发生内部错误。这可能与客户端请求无关,而是 Upbit 平台自身的问题。如果遇到此错误,建议稍后重试该请求。如果错误持续发生,请联系 Upbit 技术支持以获取帮助。

处理错误时,不仅要关注 HTTP 状态码,还应仔细分析 Upbit API 返回的错误信息。错误信息通常包含有关错误的更详细描述,有助于开发者更好地理解问题所在。可以使用 try-except 语句来捕获可能发生的异常,并根据不同的错误类型采取相应的处理措施,例如重试请求、记录错误日志或向用户显示错误信息。

以下代码示例展示了如何使用 Python 的 requests 库处理 429 Too Many Requests 错误,并实现一个简单的重试机制:

import requests
import jwt
import uuid
import time

access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"

payload = {
    'access_key': access_key,
    'nonce': str(uuid.uuid4()),
}

jwt_token = jwt.encode(payload, secret_key, algorithm='HS256')
authorize_token = f'Bearer {jwt_token}'

headers = {"Authorization": authorize_token}

max_retries = 3
retry_delay = 10  # seconds

for attempt in range(max_retries):
    try:
        res = requests.get('https://api.upbit.com/v1/accounts', headers=headers)
        res.raise_for_status()  # Raise HTTPError for bad responses (4xx or 5xx)
        print(res.())
        break  # If successful, exit the loop

    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 429:
            print(f"Too many requests. Waiting {retry_delay} seconds... (Attempt {attempt + 1}/{max_retries})")
            time.sleep(retry_delay)
            retry_delay *= 2  # Exponential backoff: double the delay for the next retry
        else:
            print(f"An error occurred: {e}")
            break  # No point in retrying for non-429 errors

    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        break  # No point in retrying for unexpected errors
else:
    print("Max retries reached. Request failed.")

上述代码示例中,我们首先定义了最大重试次数 ( max_retries ) 和初始重试延迟 ( retry_delay )。然后,我们使用一个循环来尝试发送 API 请求。如果遇到 429 Too Many Requests 错误,我们会等待一段时间,然后重试该请求。为了避免过度请求,我们使用指数退避算法来逐渐增加重试延迟。如果达到最大重试次数后请求仍然失败,我们会放弃并输出错误信息。

7. WebSocket API

除了 REST API,Upbit 还提供 WebSocket API,用于实时订阅市场行情、交易信息、订单簿快照和成交历史等高频数据。WebSocket API 允许开发者建立持久连接,从而避免了频繁轮询 REST API 带来的延迟和资源消耗。 WebSocket API 使用 JSON 格式进行数据传输,便于解析和处理。

WebSocket API 支持多种数据类型订阅,包括:

  • Ticker (行情): 提供最近成交价、涨跌幅、交易量等信息。
  • Trade (成交): 提供每笔成交的详细信息,如成交价、成交量、成交时间等。
  • Orderbook (订单簿): 提供当前市场上的买单和卖单信息,反映市场深度。
  • Orderbook Snapshot (订单簿快照): 提供订单簿的完整快照信息。

以下是一个使用 Python 和 websocket-client 库订阅 Upbit WebSocket API 的示例代码:

import websocket
import 

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws, close_status_code, close_msg):
    print("### 连接已关闭 ###")
    print("关闭状态码:", close_status_code)
    print("关闭信息:", close_msg)

def on_open(ws):
    print("### 连接已建立 ###")
    # 发送订阅请求,订阅 KRW-BTC 和 KRW-ETH 的行情数据
    ws.send(.dumps([
        {"ticket": "unique_ticket"}, # 用于标识连接的唯一票据
        {"type": "ticker", "codes": ["KRW-BTC", "KRW-ETH"]}
    ]))

if __name__ == "__main__":
    websocket.enableTrace(True) # 开启调试信息,方便排查问题
    ws = websocket.WebSocketApp("wss://api.upbit.com/websocket/v1",
                              on_open = on_open,
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)

    ws.run_forever()

该代码首先导入必要的库: websocket 用于建立 WebSocket 连接, 用于处理 JSON 格式的数据。然后,定义了四个回调函数: on_open 在连接建立时被调用, on_message 在收到消息时被调用, on_error 在发生错误时被调用, on_close 在连接关闭时被调用。

on_open 函数发送一个 JSON 格式的订阅请求到 Upbit WebSocket API。请求中包含一个 ticket 字段,用于唯一标识连接,以及一个 type 字段,指定要订阅的数据类型为 ticker codes 字段指定要订阅的交易对为 KRW-BTC KRW-ETH 。开发者可以根据自己的需求修改 codes 字段来订阅其他交易对的数据,例如 ["KRW-XRP", "KRW-ADA"] type 可以修改为 trade , orderbook 等从而订阅成交数据和订单簿数据。

ws.run_forever() 方法会一直运行,直到连接被关闭。在收到行情数据后, on_message 函数会在控制台打印出来。开发者可以根据自己的需求修改 on_message 函数来处理收到的数据,例如将其保存到数据库或用于实时交易策略。

请注意, ticket 字段的值应该是唯一的,每次建立新的 WebSocket 连接时都应该生成一个新的 ticket 。建议使用 UUID 或其他方式生成唯一标识符。

为了提高代码的可读性和可维护性,建议将订阅请求的 JSON 数据定义为常量,并使用更具描述性的变量名。同时,可以添加错误处理机制,例如在连接失败时进行重试,或在收到无效数据时进行日志记录。

8. 注意事项

  • 资金安全: 在使用 Upbit API 进行交易时,务必将资金安全放在首位。强力推荐的做法是,为数据查询等非交易操作配置仅具有只读权限的API密钥,从根本上避免潜在的资金损失风险。进行任何交易操作前,务必仔细、反复核对交易参数,包括交易币种、数量、价格等关键信息,确保准确无误,防止因人为疏忽导致的误操作,造成不必要的经济损失。同时,建议开启Upbit平台提供的双重验证(2FA)功能,为账户安全提供更高级别的保障。
  • 频率限制: Upbit API对请求频率设置了明确的限制,以保障服务器的稳定运行和公平访问。开发者应合理规划并严格控制API请求的频率,避免超出限制。可以通过实施缓存机制,减少重复请求,或者采用异步处理方式,将请求分散到不同的时间段内。超出频率限制可能会导致API调用失败,甚至账户被暂时禁用。Upbit官方文档会详细说明不同API接口的频率限制,开发者应仔细查阅并严格遵守。
  • 数据准确性: Upbit API提供的数据是进行市场分析和交易决策的重要参考,但务必认识到,这些数据仅供参考,可能存在一定的延迟或误差。开发者需要结合自身经验和判断,对数据的准确性进行评估,不能完全依赖API提供的数据做出决策。在进行高风险交易时,建议参考多个数据来源,进行交叉验证,以降低风险。Upbit不对因使用API数据造成的任何损失承担责任。
  • API 文档: 充分理解和正确使用Upbit API的前提是,全面、深入地阅读Upbit官方API文档。文档中详细描述了每个API接口的功能、参数、返回值、错误代码等信息。务必仔细阅读文档,了解API的详细用法和限制,避免因不熟悉API规则而导致的问题。Upbit官方文档是开发者使用API的权威指南,应作为首要参考资料。
  • 版本更新: Upbit API可能会不定期进行版本更新,以修复漏洞、改进性能或增加新功能。为了确保API的正常使用和兼容性,开发者需要密切关注Upbit官方发布的公告,及时更新代码。版本更新可能涉及API接口的变更,开发者应仔细阅读更新说明,了解变更内容,并相应地修改代码。未及时更新代码可能会导致API调用失败或出现其他未知问题。建议订阅Upbit官方公告,以便第一时间获取版本更新信息。
本文章为原创、翻译或编译,转载请注明来自 币课堂