Upbit API 自动化交易指南:新手也能轻松上手!

Upbit API 调用教程

简介

Upbit 是韩国领先的加密货币交易所之一,由 Dunamu 公司运营,并与美国交易所 Bittrex 合作,提供多元化的数字资产交易服务。其强大的 API 接口为开发者提供了高度的灵活性,可以构建自动化的交易系统、实时监控市场动态,并高效管理其 Upbit 账户。本文将深入探讨如何利用 Upbit API 实现常见的交易操作,包括安全可靠的身份验证机制、全面而精细的市场数据获取、快速准确的下单流程以及灵活高效的撤单功能。

Upbit API 采用 RESTful 架构,易于理解和使用。开发者可以使用各种编程语言(如 Python、Java、Node.js 等)通过 HTTP 请求与 API 交互。在使用 API 之前,需要进行身份验证,以确保账户安全。Upbit 使用 API 密钥对进行身份验证,用户需要在 Upbit 网站上创建 API 密钥,并妥善保管。 API 密钥包含访问密钥(Access Key)和安全密钥(Secret Key),分别用于标识用户身份和进行请求签名。

Upbit API 提供了丰富的市场数据接口,包括实时行情、历史 K 线数据、交易量、订单簿深度等。这些数据对于量化交易策略的制定和市场分析至关重要。开发者可以根据自己的需求选择不同的 API 接口,获取所需的市场数据。例如,可以使用 /ticker 接口获取最新的价格信息,使用 /candles 接口获取历史 K 线数据,使用 /orderbook 接口获取订单簿深度。

Upbit API 允许开发者进行各种类型的交易操作,包括市价单、限价单、止损单等。开发者可以使用 /orders 接口下单,需要指定交易的币种、交易类型、价格、数量等参数。为了确保交易的安全性,所有交易请求都需要进行签名验证。签名算法采用 HMAC-SHA512 算法,使用安全密钥对请求参数进行加密签名,并将签名添加到请求头中。

在交易过程中,开发者可能需要撤销未成交的订单。Upbit API 提供了 /order 接口用于撤单。开发者需要指定要撤销的订单 ID,并通过 API 发送撤单请求。API 会验证订单状态,如果订单尚未成交,则会取消订单。成功撤单后,相应的资金将返还到用户的账户。

前期准备

在使用 Upbit API 之前,你需要完成以下准备工作,这将确保你能够安全、高效地与 Upbit 的交易平台进行交互。

  1. Upbit 账户 : 确保你已经注册并拥有一个经过验证的 Upbit 账户。验证过程可能包括身份验证(KYC),以符合监管要求。只有拥有有效账户,才能使用 API 进行交易和数据查询。
  2. API 密钥 : 在 Upbit 官方网站的 API 管理页面生成你的 API 密钥对,包括 Access Key(访问密钥)和 Secret Key(私密密钥)。 Access Key 用于标识你的应用程序,Secret Key 用于验证你的请求。 务必极其谨慎地保管你的 Secret Key ,切勿将其存储在公共版本控制系统、客户端代码或任何不安全的位置。 建议使用环境变量或安全的密钥管理系统来存储 Secret Key。 泄露 Secret Key 将可能导致资产损失或账户被盗用。 可以考虑定期更换 API 密钥,以增强安全性。
  3. 编程环境 : 选择一种你精通的编程语言,例如 Python、JavaScript、Java、Go 或 C# 等,并搭建相应的开发环境。 每种语言都有其优势和劣势,选择最适合你项目需求的语言。 确保你的开发环境配置正确,包括安装必要的编译器、解释器和工具。
  4. 相关库 : 安装必要的库,以便发送 HTTP 请求并处理 JSON 格式的数据。 例如:
    • Python : 使用 requests 库发送 HTTP 请求, 库处理 JSON 数据。 可以使用 pip install requests pip install 安装这些库。 还可以考虑使用 ccxt 库,它是一个用于连接到多个加密货币交易所的统一 API。
    • JavaScript : 使用 axios node-fetch 库发送 HTTP 请求。
    • Java : 使用 HttpClient OkHttp 库发送 HTTP 请求, Gson Jackson 库处理 JSON 数据。
    了解这些库的基本用法,包括如何发送 GET 和 POST 请求,以及如何处理响应数据。 建议阅读官方文档和示例代码,以便更好地掌握这些库的使用方法。

身份验证

Upbit API 使用 JWT (JSON Web Token) 进行身份验证。JWT 是一种开放标准 (RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为 JSON 对象传输。在 Upbit API 的上下文中,你需要使用你的 Access Key 和 Secret Key 生成 JWT,并在每次 API 请求中将其包含在 Authorization header 中。

Authorization header 的格式应为 Authorization: Bearer [JWT] ,其中 [JWT] 是你生成的 JWT 字符串。服务器会验证 JWT 的签名和内容,以确认请求的身份和权限。

以下是一个使用 Python 生成 JWT 的示例代码。此示例使用了 PyJWT 库,你需要先安装它: pip install pyjwt 。确保你的 Python 环境已经配置好。

import jwt
import uuid
import hashlib

access_key = "YOUR_ACCESS_KEY"  # 替换为你的 Access Key
secret_key = "YOUR_SECRET_KEY"  # 替换为你的 Secret Key

def generate_jwt():
    """生成 JWT"""
    payload = {
        'access_key': access_key,
        'nonce': str(uuid.uuid4()),
    }

    jwt_token = jwt.encode(payload, secret_key, 'HS256')
    return jwt_token

jwt_token = generate_jwt()
print(jwt_token)

这段代码首先导入必要的库: jwt 用于生成和编码 JWT, uuid 用于生成唯一的 nonce(一次性使用的随机数), hashlib 虽然在这个例子中没有直接使用,但在更复杂的应用场景中,可能会被用于对数据进行哈希处理,增加安全性。

access_key secret_key 变量需要替换为你从 Upbit 获取的真实密钥。 generate_jwt 函数创建了一个 payload 字典,其中包含了 access_key 和一个随机生成的 nonce nonce 的作用是防止重放攻击,确保每次请求的唯一性。

jwt.encode 函数使用 payload secret_key 'HS256' 算法生成 JWT。 HS256 是一种常用的 HMAC-SHA256 算法,用于对 JWT 进行签名。签名确保 JWT 的完整性和真实性,防止被篡改。

请务必替换 YOUR_ACCESS_KEY YOUR_SECRET_KEY 为你自己的 Access Key 和 Secret Key。保管好你的 Secret Key,不要泄露给他人,因为它相当于你的 API 访问密码。 建议将密钥存储在环境变量或安全配置管理工具中,避免硬编码在代码中。

获取行情数据

使用 Upbit API 获取加密货币市场的行情数据是一种便捷高效的方式。Upbit 提供了多个 API 端点,允许开发者和交易者获取包括实时价格、成交历史、订单簿以及不同时间周期的 K 线图等关键信息。以下详细介绍各个 API 端点及其功能:

  • Tickers (当前价): /v1/ticker - 获取指定市场的当前交易价格信息。该端点返回的数据包括最新的交易价格、24 小时内的最高价、最低价、成交量等关键指标,可以帮助用户快速了解市场动态。
  • Trades (成交历史): /v1/trades/ticks - 获取指定市场一段时间内的成交历史记录。该端点返回的数据包括成交时间、成交价格、成交量等详细信息,可以用于分析市场交易活跃度以及价格波动情况。用户可以通过调整参数,获取不同时间范围内的成交数据。
  • Orderbook (挂单簿): /v1/orderbook - 获取指定市场的挂单簿信息,展示买单和卖单的分布情况。订单簿数据对于了解市场的买卖力量对比、支撑位和阻力位等至关重要,是进行交易决策的重要参考依据。该端点返回的数据包括买单和卖单的价格、数量等信息。
  • Candles (K线数据): K 线图是技术分析中常用的工具,Upbit 提供了不同时间周期的 K 线数据 API 端点,方便用户进行技术分析:
    • /v1/candles/minutes/{unit} - 获取指定分钟周期的 K 线数据。 {unit} 可以是 1, 3, 5, 15, 30, 60, 240,分别代表 1 分钟、3 分钟、5 分钟、15 分钟、30 分钟、60 分钟和 240 分钟的 K 线周期。该端点返回的数据包括开盘价、收盘价、最高价、最低价以及成交量等。
    • /v1/candles/days - 获取日 K 线数据。该端点返回每日的开盘价、收盘价、最高价、最低价以及成交量等信息。
    • /v1/candles/weeks - 获取周 K 线数据。该端点返回每周的开盘价、收盘价、最高价、最低价以及成交量等信息。
    • /v1/candles/months - 获取月 K 线数据。该端点返回每月的开盘价、收盘价、最高价、最低价以及成交量等信息。

以下是一个使用 Python 获取 BTC-KRW 市场的当前价信息的示例代码。该示例演示了如何使用 requests 库向 Upbit API 发送请求,并解析返回的 JSON 数据:

import requests

url = "https://api.upbit.com/v1/ticker"

params = {"markets": "KRW-BTC"}

headers = {"Accept": "application/"}

response = requests.get(url, params=params, headers=headers)

if response.status_code == 200:

data = response.()

print(data)

else:

print(f"Error: {response.status_code} - {response.text}")

下单

使用 Upbit API 下单需要提供以下信息,这些信息对于确保交易顺利执行至关重要:

  • Market (市场代码): 这是指定交易对的唯一标识符,例如 "KRW-BTC" 代表韩元 (KRW) 交易比特币 (BTC)。 确保市场代码正确无误,否则订单将无法正确执行。不同的交易所可能使用不同的市场代码格式。
  • Side (买卖方向): 指示您是买入还是卖出加密货币。 "bid" 表示买入,通常称为做多;"ask" 表示卖出,也称为做空。根据您的交易策略和市场判断选择正确的方向。
  • Volume (数量): 您希望交易的加密货币数量,以指定货币单位表示。 对于 "KRW-BTC" 市场,数量将以 BTC 为单位。请注意,交易所通常有最小交易数量的限制,低于该限制的订单可能无法提交。
  • Price (价格): 您愿意买入或卖出的价格。 如果使用市价单,则交易所将以当前市场最佳价格执行订单,无需指定价格。对于限价单,价格是至关重要的,因为它决定了您的订单是否以及何时成交。
  • Ord_type (订单类型): 指定订单的执行方式,Upbit API 支持以下几种订单类型:
    • "limit" (限价单): 以指定的价格下单。 只有当市场价格达到或超过您指定的价格时,订单才会成交。 限价单允许您控制交易价格,但不能保证立即成交。
    • "price" (市价买单): 以当前市场最佳可用价格买入指定金额的加密货币。 您指定的是希望花费的总金额,而不是购买的加密货币数量。 实际购买的数量将取决于市场价格。
    • "market" (市价卖单): 以当前市场最佳可用价格卖出指定数量的加密货币。 您指定的是希望卖出的加密货币数量,而不是获得的金额。实际获得的金额将取决于市场价格。

以下是一个使用 Python 下限价买单的示例代码,展示了如何使用 Upbit API 提交订单:

import requests
import jwt
import uuid
import hashlib

access_key = "YOUR_ACCESS_KEY"  # 替换为你的 Access Key,请务必妥善保管你的 Access Key,不要泄露给他人。
secret_key = "YOUR_SECRET_KEY"  # 替换为你的 Secret Key,Secret Key 与 Access Key 一样重要,是访问 Upbit API 的凭证。

def generate_jwt(query):
    """生成 JSON Web Token (JWT) 用于身份验证。"""
    payload = {
        'access_key': access_key,
        'nonce': str(uuid.uuid4()), # nonce 是一个随机字符串,用于防止重放攻击
    }

    if query is not None:
        m = hashlib.sha512()
        m.update(query.encode('utf-8'))
        query_hash = m.hexdigest()
        payload['query_hash'] = query_hash
        payload['query_hash_alg'] = 'SHA512'

    jwt_token = jwt.encode(payload, secret_key, 'HS256') # 使用 HS256 算法对 JWT 进行签名
    return jwt_token

url = "https://api.upbit.com/v1/orders"
market = "KRW-BTC" # 交易市场,这里是韩元对比特币
side = "bid" # 买入方向
volume = "0.0001" # 购买数量
price = "1000000" # 购买价格
ord_type = "limit" # 订单类型为限价单

query = f"market={market}&side={side}&volume={volume}&price={price}&ord_type={ord_type}" # 构建查询字符串

jwt_token = generate_jwt(query) # 生成 JWT
authorization_token = f"Bearer {jwt_token}" # 构建 Authorization Header

headers = {
    "Accept": "application/", # 明确指定接受 JSON 格式的响应
    "Authorization": authorization_token # 设置授权头部
}

data = {
    "market": market,
    "side": side,
    "volume": volume,
    "price": price,
    "ord_type": ord_type
}

response = requests.post(url, headers=headers, data=data) # 发送 POST 请求提交订单

if response.status_code == 201: # 201 表示订单创建成功
    data = response.() # 解析 JSON 响应
    print(data) # 打印响应数据,通常包含订单 UUID 等信息
else:
    print(f"Error: {response.status_code} - {response.text}") # 打印错误信息,方便调试

请注意,您需要根据实际情况修改 market , side , volume , price ord_type 的值,并确保您的 Access Key 和 Secret Key 正确配置。在生产环境中使用 API 之前,建议先在 Upbit 提供的测试环境中进行测试,以避免意外损失。

撤单

在 Upbit 交易所,通过 API 撤销未成交的订单是交易策略的重要组成部分。撤单操作允许交易者根据市场变化调整其交易计划。使用 Upbit API 撤单,你需要提供目标订单的唯一标识符(UUID)。订单 UUID 是 Upbit 系统为每笔订单生成的唯一编码,用于精确定位需要撤销的订单。

你可以使用以下 API 端点发起撤单请求:

  • /v1/order - 撤销指定 UUID 的订单。此端点接受 DELETE 请求,通过提供订单 UUID 作为参数,即可取消该订单。

以下是一个使用 Python 编程语言,通过 Upbit API 撤销订单的示例代码,展示了如何构造和发送撤单请求:

import requests
import jwt
import uuid
import hashlib

access_key = "YOUR_ACCESS_KEY" # 替换为你的 Upbit Access Key
secret_key = "YOUR_SECRET_KEY" # 替换为你的 Upbit Secret Key

def generate_jwt(query):
"""生成 JWT (JSON Web Token) 用于 API 身份验证。"""
payload = {
'access_key': access_key,
'nonce': str(uuid.uuid4()), # UUID确保每次请求的唯一性,防止重放攻击。
}
if query is not None:
m = hashlib.sha512()
m.update(query.encode('utf-8'))
query_hash = m.hexdigest()
payload['query_hash'] = query_hash
payload['query_hash_alg'] = 'SHA512' # 指定用于生成 query_hash 的哈希算法。
jwt_token = jwt.encode(payload, secret_key, 'HS256') # 使用 HS256 算法对 payload 进行签名。
return jwt_token

url = "https://api.upbit.com/v1/order"
uuid_to_cancel = "YOUR_ORDER_UUID" # 替换为你要撤销的订单 UUID
# side = "ask" # or "bid", depends on the order,此参数并非必须,UUID已足够标识订单

query = f"uuid={uuid_to_cancel}" # 查询字符串,包含要撤销的订单 UUID。

jwt_token = generate_jwt(query)
authorization_token = f"Bearer {jwt_token}" # 构造 Authorization header,包含 JWT token。

headers = {
"Accept": "application/", # 明确告知服务器期望接收 JSON 格式的响应。
"Authorization": authorization_token # Authorization header 用于身份验证。 }

params = {
"uuid": uuid_to_cancel # 通过 params 传递 UUID,增强代码可读性 }

response = requests.delete(url, headers=headers, params=params) # 发送 DELETE 请求以撤销订单。

if response.status_code == 200:
data = response.() # 解析 JSON 响应。
print(data) # 打印响应数据,通常包含撤单成功的相关信息。
else:
print(f"Error: {response.status_code} - {response.text}") # 打印错误信息,包括 HTTP 状态码和错误消息。

在执行此代码前,请务必将 YOUR_ACCESS_KEY , YOUR_SECRET_KEY YOUR_ORDER_UUID 替换为你的 Upbit 账户凭据和需要撤销的订单的 UUID。订单的 UUID 可以通过查询订单列表 API 获得,也可以在下单成功后从返回信息中获取。另外,请确保你的 API 密钥已启用撤单权限。

错误处理

在使用 Upbit API 时,开发者可能会遇到各种预料之外的问题。为了方便开发者调试和优化程序,Upbit API 提供了详细的错误反馈机制。API 会返回标准的 HTTP 状态码,以及 JSON 格式的错误信息,包含具体的错误代码和描述。开发者可以根据这些信息来诊断和解决问题,例如检查请求参数、调整请求频率或处理身份验证问题。

  • 400 Bad Request(错误请求): 此状态码表明客户端发送的请求存在错误,通常是由于请求参数不符合 API 的要求。例如,缺少必要的参数、参数格式不正确或参数值超出允许范围。开发者应仔细检查请求的 URL、请求头和请求体,确保所有参数都符合 Upbit API 的规范。
  • 401 Unauthorized(未授权): 此状态码表示客户端未经过身份验证,或身份验证失败。通常是由于 API 密钥无效、过期或没有足够的权限访问所请求的资源。请仔细检查你的 API 密钥是否正确配置,包括访问密钥 (Access Key) 和安全密钥 (Secret Key),以及 JWT (JSON Web Token) 的生成方式。确保你的 API 密钥拥有执行该操作的权限。
  • 429 Too Many Requests(请求过多): 此状态码表示客户端在短时间内发送了过多的请求,超过了 Upbit API 的请求频率限制。为了保证系统的稳定性和公平性,Upbit API 对每个 IP 地址或每个 API 密钥的请求频率进行了限制。开发者需要实施请求频率控制策略,例如使用延迟、队列或令牌桶算法,以避免触发此错误。可以参考Upbit官方文档,查看具体的频率限制规则。
  • 500 Internal Server Error(内部服务器错误): 此状态码表示 Upbit 服务器在处理请求时遇到了内部错误。这通常是由于服务器端的故障或程序错误导致的,与客户端的请求无关。遇到这种情况,开发者可以稍后重试该请求。如果问题持续存在,建议联系 Upbit 的技术支持团队,提供相关的信息,例如请求的 URL、时间戳和错误信息,以便他们进行排查和解决。

在使用 Upbit API 进行真实交易前,强烈建议在模拟环境中进行全面的测试,以确保程序的正确性和稳定性,并避免因程序错误导致实际资金的损失。Upbit 提供了专门的测试网络 (Testnet),开发者可以在测试网上进行各种 API 操作的模拟,例如下单、撤单、查询账户余额等,而无需承担真实资金的风险。测试网的数据与真实环境是隔离的,开发者可以放心地进行各种实验和调试。在将程序部署到真实环境之前,务必在测试网上进行充分的验证。