Upbit API接口使用教程详解
1. 概述
Upbit是韩国顶级的数字资产交易所之一,以其高流动性和多样化的交易对而闻名。为了满足机构投资者和量化交易团队的需求,Upbit提供了全面的API接口,赋予开发者通过编程方式深度接入交易所的能力。这些API接口涵盖了市场数据的实时获取、交易下单和撤单、账户余额查询、以及其他关键的账户管理功能。
通过Upbit API,用户可以自动化交易策略的执行,构建量化交易系统,或者开发定制化的交易工具。本文将深入探讨Upbit API的使用方法,从环境搭建到身份验证,再到常用API的调用,以及常见问题的解决,力求为开发者提供一份详尽的指南。我们将着重讲解如何使用API密钥进行安全认证,如何解析API返回的JSON数据,以及如何处理API调用过程中可能遇到的错误和限制。
还将讨论如何利用Upbit API获取实时市场数据,例如最新成交价、订单簿信息和历史交易数据,这些数据对于技术分析和算法交易至关重要。对于交易功能,我们将详细说明如何通过API提交市价单、限价单等不同类型的订单,以及如何监控订单状态并进行撤单操作。我们还会介绍如何使用API查询账户余额和交易历史,以便进行资金管理和绩效分析。
2. 环境配置
在使用Upbit API之前,务必完成必要的环境配置,这对于后续的API调用至关重要。环境配置主要包括以下几个方面:确保你已安装最新版本的Python解释器(建议使用Python 3.7及以上版本),因为Upbit API的Python SDK需要较新的Python环境支持。为了隔离不同项目的依赖关系,强烈推荐使用虚拟环境。你可以使用
venv
或
conda
等工具创建和管理虚拟环境。激活虚拟环境后,使用pip安装Upbit API的Python SDK,命令是
pip install pyupbit
。安装过程中,请确保你的网络连接稳定,以便顺利下载和安装依赖包。如果你在使用过程中遇到任何安装问题,可以查阅官方文档或在相关的开发者社区寻求帮助。成功安装SDK后,你需要准备你的Upbit API密钥。这包括一个访问密钥(Access Key)和一个安全密钥(Secret Key)。你可以在Upbit的开放API管理页面创建和管理你的API密钥。请务必妥善保管你的密钥,不要泄露给他人,也不要将密钥硬编码到你的代码中。推荐使用环境变量或配置文件来存储密钥,并在程序运行时动态加载。考虑到API调用可能涉及网络请求,建议安装
requests
库,尽管
pyupbit
通常会自带此依赖,但显式安装可以确保其存在并避免潜在问题,安装命令为
pip install requests
。 为了提升代码的可读性和可维护性,建议配置代码编辑器或IDE,并安装Python代码风格检查工具,例如
flake8
或
pylint
。这些工具可以帮助你发现代码中的潜在问题,并强制执行一致的代码风格。 完成以上环境配置后,你就可以开始使用Upbit API进行开发了。
2.1 安装必要的库
推荐使用Python进行开发,因为它拥有丰富的加密货币开发库和工具。为了实现安全、高效的交易和数据处理,需要安装以下关键库:
-
requests
: 用于发送HTTP请求。该库简化了与外部API(例如交易所API、区块链浏览器API)的交互,允许开发者获取实时市场数据、提交交易以及查询账户信息。通过
requests
库,可以方便地模拟浏览器行为,发送GET、POST等多种类型的HTTP请求。 -
uuid
: 用于生成唯一ID(Universally Unique Identifier)。在加密货币应用中,唯一ID对于标识交易、用户会话、以及其他需要唯一性的数据至关重要。
uuid
库提供了多种生成UUID的算法,确保生成的ID在全球范围内具有唯一性,避免冲突。 -
jwt
: 用于生成和验证JSON Web Tokens (JWT)。JWT是一种轻量级的、自包含的令牌格式,常用于身份验证和授权。在加密货币应用中,可以使用JWT来安全地传递用户信息,验证用户身份,并控制对API资源的访问。
jwt
库提供了生成、编码、解码和验证JWT的功能,支持各种签名算法,例如HMAC、RSA等。 -
hashlib
: 用于哈希算法。哈希算法是一种单向加密算法,可以将任意长度的数据转换为固定长度的哈希值。在加密货币领域,哈希算法被广泛用于生成数字签名、验证数据完整性、以及构建区块链等。
hashlib
库提供了多种常用的哈希算法,例如SHA-256、SHA-3、MD5等,开发者可以根据安全需求选择合适的算法。
可以使用pip(Python的包管理工具)安装这些库。pip允许开发者轻松地从Python Package Index (PyPI) 下载和安装第三方库。强烈建议使用虚拟环境,以隔离项目依赖,避免版本冲突。
命令行安装示例如下:
pip install requests pyjwt hashlib uuid
建议在安装前更新pip到最新版本,以确保安装过程顺利:
pip install --upgrade pip
2.2 获取API密钥
为了安全地与Upbit交易所的API进行交互,您需要一组API密钥进行身份验证。 Upbit API密钥允许您以编程方式访问您的账户并执行各种操作,例如下单、查询余额和获取市场数据。 这些密钥至关重要,请务必安全存储并谨慎使用。
获取API密钥的过程需要在您的Upbit账户中完成。 登录您的Upbit账户后,您可以在“我的页面”或类似的账户设置区域找到“API密钥管理”选项。 按照Upbit的指示创建新的API密钥。 系统会生成两部分关键信息:
- Access Key (访问密钥) : 类似于您的用户名,用于唯一标识您的Upbit账户。 在每个API请求中都需要包含此密钥,以便Upbit服务器识别您的身份。 您可以将其视为公开标识符。
- Secret Key (私密密钥) : 类似于您的密码,用于对API请求进行加密签名。 这个密钥极其敏感,绝对不能泄露给任何人。 私密密钥用于生成HMAC (Hash-based Message Authentication Code)签名,从而验证请求的真实性和完整性。 泄露私密密钥可能导致您的账户被盗用。 请务必将其安全地存储在您的服务器端,并避免在客户端代码或任何不安全的环境中使用。
请务必妥善保管您的Access Key和Secret Key。 建议将Secret Key加密存储,并限制对密钥的访问权限。 如果您怀疑密钥已被泄露,请立即在Upbit账户中撤销该密钥并生成新的密钥对。
务必保护好您的Secret Key,不要泄露给他人。
2.3 设置环境变量 (可选)
为了更安全、更便捷地管理您的 Upbit API 密钥(包括访问密钥 Access Key 和安全密钥 Secret Key),强烈建议将其设置为操作系统级别的环境变量,而不是直接硬编码在您的脚本或应用程序中。
使用环境变量的好处包括:
- 安全性增强: 避免将敏感密钥暴露在代码仓库中,降低泄露风险。
- 配置灵活性: 无需修改代码即可轻松更换 API 密钥,方便在不同环境(例如开发、测试、生产)间切换。
- 简化管理: 集中管理密钥,方便更新和维护。
以下展示如何在 Linux 或 macOS 系统中使用 Bash Shell 设置环境变量:
export UPBIT_ACCESS_KEY="your_access_key"
export UPBIT_SECRET_KEY="your_secret_key"
请务必将
your_access_key
和
your_secret_key
替换为您实际的 Upbit API 密钥。
执行以上命令后,这些环境变量只在当前 Shell 会话中有效。 为了使它们永久生效,您可以将这些命令添加到您的 Shell 配置文件(例如
~/.bashrc
,
~/.zshrc
或
~/.profile
)。 添加完成后,请运行
source ~/.bashrc
(或者相应的配置文件) 使其生效。
在您的 Python 代码中,您可以使用
os.environ.get()
方法来安全地访问这些环境变量:
import os
access_key = os.environ.get("UPBIT_ACCESS_KEY")
secret_key = os.environ.get("UPBIT_SECRET_KEY")
if access_key and secret_key:
print("Upbit Access Key:", access_key)
print("Upbit Secret Key:", secret_key)
else:
print("请设置 UPBIT_ACCESS_KEY 和 UPBIT_SECRET_KEY 环境变量。")
这段代码首先导入
os
模块,然后尝试从环境变量中获取
UPBIT_ACCESS_KEY
和
UPBIT_SECRET_KEY
的值。 如果环境变量存在,则将其赋值给
access_key
和
secret_key
变量,并打印出来。 否则,将提示用户设置环境变量。
通过这种方式,您的 API 密钥不会直接出现在代码中,从而提高了应用程序的安全性。
3. 身份验证
Upbit API 采用 JSON Web Token (JWT) 机制进行身份验证,确保请求的安全性。要访问 Upbit API,您必须先使用您的 Access Key 和 Secret Key 生成一个合法的 JWT,并在每个请求的 HTTP 头部中包含该 JWT。
JWT 的本质是一个经过编码的 JSON 对象,包含了声明(claims),这些声明描述了客户端的身份和权限。服务器通过验证 JWT 的签名来确认请求的合法性。
以下是使用 Python 生成 JWT 的代码示例,展示了如何利用 Access Key 和 Secret Key 创建一个有效的 JWT:
import jwt import uuid import hashlib from urllib.parse import urlencode import os import requests access_key = os.environ.get("UPBIT_ACCESS_KEY") secret_key = os.environ.get("UPBIT_SECRET_KEY") def generate_jwt(access_key, secret_key): """ 生成 Upbit API 的 JWT。 Args: access_key: Upbit Access Key. secret_key: Upbit Secret Key. Returns: 生成的 JWT 字符串. """ payload = { 'access_key': access_key, 'nonce': str(uuid.uuid4()) # 保证每次请求的唯一性,防止重放攻击 } jwt_token = jwt.encode(payload, secret_key, algorithm="HS256") # 使用 HMAC-SHA256 算法进行签名 return jwt_token
上述代码首先从环境变量中获取 Upbit 的 Access Key 和 Secret Key。
generate_jwt
函数使用这些密钥创建一个包含 'access_key' 和 'nonce' 的 payload。'nonce' 是一个唯一标识符(UUID),用于防止重放攻击,确保每个请求都是唯一的。
然后,使用
jwt.encode
函数,采用 HMAC-SHA256 算法 (
HS256
) 对 payload 进行签名,生成 JWT。HMAC-SHA256 是一种常用的加密哈希函数,用于验证数据的完整性和真实性。
jwt_token = generate_jwt(access_key, secret_key)
生成的
jwt_token
必须放置在 HTTP 请求头的
Authorization
字段中。正确的格式为
Bearer
。例如:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJaccess_keyIjoiYXBpS2V5Iiwibm9uY2UiOiJhZDQxYzVmYy04NzRiLTQ2ZjgtYjNhZi1lOGU4MzM5ZjNjNmUifQ.WmpJqHRQIyKdWwUaJVIq1swcVX9EQiQyfQ_GZ0Zg0
请务必将
替换为您实际生成的 JWT 字符串。服务器会解析这个 JWT,验证您的身份,并根据您的权限处理您的请求。如果JWT无效或过期,服务器将拒绝您的请求并返回错误。
4. 常用API接口调用
以下将详细介绍一些常用的Upbit API接口,包括其功能、请求方法、参数以及返回数据格式,并提供具体的调用方法示例,帮助开发者更好地理解和使用Upbit API。
4.1 行情数据接口
行情数据接口用于获取Upbit交易所的实时和历史交易数据,是进行量化交易和市场分析的基础。
4.1.1 获取所有市场代码 (
GET /market/all
)
该接口用于获取Upbit支持的所有市场代码列表,包括市场名称、韩元市场代码、比特币市场代码等。开发者可以通过该接口了解Upbit支持的交易对。
请求方法:
GET
请求URL:
https://api.upbit.com/v1/market/all
请求参数:
-
is_details
(可选): 是否返回详细信息,例如市场警告信息。默认为false
。
返回数据格式: JSON数组,包含每个市场代码的详细信息。
4.1.2 获取蜡烛线数据 (
GET /candles/{candle_type}
)
该接口用于获取指定市场代码的蜡烛线数据,例如分钟蜡烛、日蜡烛、周蜡烛、月蜡烛。蜡烛线数据是技术分析的重要工具。
请求方法:
GET
请求URL:
https://api.upbit.com/v1/candles/{candle_type}
请求参数:
-
market
(必选): 市场代码,例如KRW-BTC
。 -
to
(可选): 返回数据时间的最晚时间点 (exclusive)。 格式为YYYY-MM-DDThh:mm:ssZ
或YYYY-MM-DD hh:mm:ss
。 -
count
(可选): 返回数据的数量。最大数量为 200。
返回数据格式: JSON数组,包含每个蜡烛线的开盘价、收盘价、最高价、最低价、交易量等信息。
candle_type 可选值:
- minutes/{unit} : 分钟蜡烛,unit 可选值为 1, 3, 5, 15, 30, 60, 240
- days : 日蜡烛
- weeks : 周蜡烛
- months : 月蜡烛
4.1.3 获取最新成交价 (
GET /ticker
)
该接口用于获取指定市场代码的最新成交价信息。
请求方法:
GET
请求URL:
https://api.upbit.com/v1/ticker
请求参数:
-
markets
(必选): 以逗号分隔的市场代码列表,例如KRW-BTC,KRW-ETH
。
返回数据格式: JSON数组,包含每个市场代码的最新成交价、成交量等信息。
4.2 交易接口
交易接口用于进行下单、取消订单、查询订单等操作,需要进行身份验证。
4.2.1 下单 (
POST /orders
)
该接口用于提交新的订单。
请求方法:
POST
请求URL:
https://api.upbit.com/v1/orders
请求参数:
-
market
(必选): 市场代码,例如KRW-BTC
。 -
side
(必选): 买卖类型,可选值为bid
(买入) 或ask
(卖出)。 -
volume
(可选): 下单量,市价卖出时必须填写。 -
price
(可选): 指定价格,市价买入时必须填写。 -
ord_type
(必选): 订单类型,可选值为limit
(限价单),price
(市价买入),market
(市价卖出)。 -
identifier
(可选): 用户自定义的订单标识符,用于区分不同的订单。
返回数据格式: JSON对象,包含订单的UUID、市场代码、订单类型等信息。
4.2.2 取消订单 (
DELETE /order
)
该接口用于取消尚未成交的订单。
请求方法:
DELETE
请求URL:
https://api.upbit.com/v1/order
请求参数:
-
uuid
(必选): 订单的UUID。 -
identifier
(可选): 用户自定义的订单标识符。
返回数据格式: JSON对象,包含订单的UUID、状态等信息。
4.3 身份验证
使用交易接口需要进行身份验证,Upbit使用JWT (JSON Web Token) 进行身份验证。开发者需要先申请API密钥 (Access Key 和 Secret Key),然后使用密钥生成JWT,并在请求头中携带JWT。
4.1 行情API:获取市场行情
4.1.1 获取所有市场代码 (
markets
)
该接口用于检索Upbit交易所支持的所有交易对的详细信息,包括市场代码、市场名称、以及是否支持交易等属性。通过此接口,可以获取当前Upbit平台上所有可交易的数字货币对和相关市场信息。
def get_markets():
获取所有市场代码。
"""
获取Upbit支持的所有市场代码列表及其详细信息。
该函数向Upbit API发送请求,获取所有可交易市场的信息。
Returns:
list: 包含市场代码和其他详细信息的列表。列表中的每个元素都代表一个市场,并包含诸如市场代码(market)、英文名称(english_name)、中文名称(korean_name)、是否支持交易(market_warning)等字段。
Raises:
requests.exceptions.HTTPError: 如果API请求返回非200状态码,则抛出异常。
"""
import requests
import
url = "https://api.upbit.com/v1/market/all"
headers = {"Accept": "application/"} # 显式指定接受JSON格式数据
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # 抛出 HTTPError 异常,如果响应状态码不是 200
markets = response.() # 将 JSON 响应转换为 Python 对象(列表)
return markets
except requests.exceptions.RequestException as e:
print(f"请求发生错误: {e}")
return None # 或者抛出异常,根据实际需求处理错误
markets = get_markets()
print(markets)
上述代码片段展示了如何调用
get_markets()
函数并打印返回的市场信息。返回的数据是一个JSON数组,每个元素代表一个市场,包含诸如
market
(市场代码),
korean_name
(韩文名称),
english_name
(英文名称), 和
market_warning
(市场警告级别) 等字段。
market_warning
字段可能包含
NONE
(无警告),
CAUTION
(注意), 或
DANGER
(危险) 等值,用于指示该市场的风险级别。
4.1.2 获取K线数据 (Candles)
该接口用于获取指定交易对的历史K线(烛台图)数据,是分析加密货币价格走势的重要工具。
def get_candles(market, candle_type, count=200, to=None):
获取指定交易对和时间周期的K线数据。
Args:
market: 市场代码,指定交易对。例如,"KRW-BTC" 代表韩元-比特币交易对。 完整的市场代码列表请参考Upbit官方API文档。
candle_type: K线类型,指定K线的时间周期。 可选值包括:
minute1: 1分钟K线。
minute5: 5分钟K线。
minute15: 15分钟K线。
minute30: 30分钟K线。
minute60: 60分钟(1小时)K线。
minute240: 240分钟(4小时)K线。
day: 日K线。
week: 周K线。
month: 月K线。
count: 返回数据条数,即K线数量。 默认为 200。 Upbit API 可能对该参数有最大值限制,超过限制将返回错误。
to: 可选参数,指定返回的K线数据的结束时间(最新K线的时间)。 格式应符合ISO 8601标准,例如 "2023-10-27T10:00:00Z"。 如果不指定,则返回最新的K线数据。
Returns:
一个包含K线数据的列表。 每个K线数据通常包含以下字段:
"market": 市场代码。
"candle_date_time_utc": K线时间(UTC)。
"candle_date_time_kst": K线时间(韩国标准时间)。
"opening_price": 开盘价。
"high_price": 最高价。
"low_price": 最低价。
"trade_price": 收盘价。
"timestamp": 时间戳。
"candle_acc_trade_price": 累积交易价格。
"candle_acc_trade_volume": 累积交易量。
"unit": 单位 (分钟K线为分钟数, 日/周/月K线为null)
Raises:
requests.exceptions.HTTPError: 如果API请求返回错误状态码。
示例代码:
import requests
import
def get_candles(market, candle_type, count=200, to=None):
"""
获取K线数据。
"""
url = f"https://api.upbit.com/v1/candles/{candle_type}?market={market}&count={count}"
if to:
url += f"&to={to}"
headers = {"Accept": "application/"} # 明确指定接受JSON格式数据
response = requests.get(url, headers=headers)
response.raise_for_status() # 抛出HTTPError异常,如果请求失败
return response.() # 使用response.()解析JSON响应
# 获取KRW-BTC的1分钟K线数据
candles = get_candles("KRW-BTC", "minute1")
print(.dumps(candles, indent=4)) # 使用.dumps格式化输出,提高可读性
上述代码展示了如何调用
get_candles
函数获取KRW-BTC交易对的1分钟K线数据,并将结果打印到控制台。
.dumps
函数用于将Python对象转换为JSON字符串,并使用
indent=4
参数进行格式化,使其更易于阅读。 务必安装 `requests` 库: `pip install requests` 。 注意Upbit API的频率限制,避免频繁请求导致IP被封禁。建议阅读Upbit官方API文档,了解更详细的参数说明和使用限制。
4.2 交易API:下单、查询订单等
4.2.1 下单 (orders)
该接口用于提交交易订单,允许用户在指定市场上执行买入或卖出操作。通过此接口,可以创建限价单或市价单,满足不同的交易需求。
def place_order(market, side, volume, price, order_type):
提交交易订单。
Args:
market: 市场代码 (例如: KRW-BTC),指定交易的市场,必须是交易所支持的有效市场代码.
side: 订单类型 (bid: 买, ask: 卖),指明是买入订单还是卖出订单. "bid" 表示买入,"ask" 表示卖出。
volume: 数量,要买入或卖出的资产数量,以市场规定的最小交易单位为准。
price: 价格,对于限价单,这是期望的买入或卖出价格;对于市价买单,可以设置为None或者适当的值(交易所可能忽略此参数);对于市价卖单,此参数将被忽略.
order_type: 订单类型 (limit: 限价单, price: 市价买单, market: 市价卖单),"limit" 代表限价单,"price" 代表市价买单,"market" 代表市价卖单. 不同交易所对市价单的参数可能有不同要求。
Returns:
订单信息,返回包含订单详细信息的 JSON 对象,例如订单 UUID、订单状态、已成交数量等。
"""
query = {
'market': market,
'side': side,
'volume': volume,
'price': price,
'ord_type': order_type
}
query_string = urlencode(query).encode()
m = hashlib.sha512()
m.update(query_string)
query_hash = m.hexdigest()
payload = {
'access_key': access_key,
'nonce': str(uuid.uuid4()),
'query_hash': query_hash,
'query_hash_alg': 'SHA512',
}
jwt_token = jwt.encode(payload, secret_key, algorithm='HS256')
authorize_token = 'Bearer {}'.format(jwt_token)
headers = {"Authorization": authorize_token}
res = requests.post("https://api.upbit.com/v1/orders", params=query, headers=headers)
res.raise_for_status()
return res.()
注意: 下单需要进行更复杂的签名认证,需要使用 hashlib
计算query的SHA512哈希值,并在JWT的payload中包含 query_hash
和 query_hash_alg
字段。
4.2.2 查询订单 (order)
该接口用于查询指定订单的详细信息。通过提供订单的唯一UUID或订单标识符,可以检索到关于该订单的各种属性,例如订单状态、交易对、订单类型、下单时间、成交数量、成交价格等。
def get_order(uuid=None, identifier=None):
查询订单信息。
Args:
uuid (str, optional): 订单的UUID(通用唯一识别码)。这是一个32位的十六进制字符串,用于唯一标识一个订单。Defaults to None.
identifier (str, optional): 订单标识符。这是一个由交易所分配的,用于标识订单的字符串。与UUID类似,但格式可能不同。Defaults to None.
Returns:
dict: 订单信息的字典。包含订单的详细属性,例如:
- uuid: 订单UUID。
- identifier: 订单标识符。
- market: 交易市场(例如:BTC-KRW)。
- side: 订单类型(buy: 买单, sell: 卖单)。
- ord_type: 订单模式(limit: 限价单, price: 市价单, market: 市价单)。
- price: 订单价格。
- avg_price: 平均成交价格。
- state: 订单状态 (wait: 等待成交, watch: 预备成交, done: 全部成交, cancel: 订单取消)。
- volume: 订单数量。
- remaining_volume: 剩余未成交数量。
- reserved_fee: 预留手续费。
- remaining_fee: 剩余手续费。
- paid_fee: 已支付手续费。
- locked: 锁定数量。
- executed_volume: 已成交数量。
- trades_count: 交易次数。
- created_at: 订单创建时间。
- trades: 成交历史记录列表。
Raises:
ValueError: 如果未提供uuid或identifier,则引发ValueError异常,提示用户必须提供至少一个参数。
if uuid is None and identifier is None:
raise ValueError("必须提供 uuid 或 identifier。")
query = {}
if uuid:
query['uuid'] = uuid
if identifier:
query['identifier'] = identifier
query_string = urlencode(query)
payload = {
'access_key': access_key,
'nonce': str(uuid.uuid4()),
}
jwt_token = jwt.encode(payload, secret_key, algorithm='HS256')
authorize_token = 'Bearer {}'.format(jwt_token)
headers = {"Authorization": authorize_token}
res = requests.get(f"https://api.upbit.com/v1/order?{query_string}", headers=headers)
res.raise_for_status()
return res.()
4.2.3 取消订单 (order)
该接口允许用户取消尚未完全成交的订单。通过提供订单的唯一标识符,系统将尝试从交易系统中移除该订单。
def cancel_order(uuid=None, identifier=None):
取消订单函数,用于向交易所发送取消指定订单的请求。
Args:
uuid: 订单的 UUID (Universally Unique Identifier)。这是一个标准的 128 位标识符,用于唯一标识一个订单。如果提供了 UUID,系统将优先使用它来查找要取消的订单。
identifier: 订单标识符。这是交易所分配给订单的自定义标识符,例如订单号。如果未提供 UUID,则可以使用订单标识符来取消订单。
Returns:
取消结果。返回来自交易所的响应,其中包含取消操作是否成功的指示,以及任何相关的错误信息。响应通常包含 HTTP 状态码和 JSON 格式的数据。
Raises:
ValueError: 如果既没有提供 uuid 也没有提供 identifier,则会引发 ValueError 异常,提示用户必须提供至少一个参数来标识要取消的订单。
"""
if uuid is None and identifier is None:
raise ValueError("必须提供 uuid 或 identifier。")
query = {}
if uuid:
query['uuid'] = uuid # 使用 UUID 作为查询参数
if identifier:
query['identifier'] = identifier # 使用订单标识符作为查询参数
payload = {
'access_key': access_key, # 用户的 API 访问密钥,用于身份验证。
'nonce': str(uuid.uuid4()), # 一个随机数,用于防止重放攻击。每次请求都应生成一个新的 UUID。
}
jwt_token = jwt.encode(payload, secret_key, algorithm='HS256') # 使用用户的密钥和指定的算法 (HS256) 创建 JSON Web Token (JWT)。JWT 用于安全地将用户身份验证信息传递给服务器。
authorize_token = 'Bearer {}'.format(jwt_token) # 构建授权令牌,将其添加到 HTTP 请求头中。'Bearer' 是一种授权方案,指示使用 JWT 进行身份验证。
headers = {"Authorization": authorize_token} # 创建 HTTP 请求头,其中包含授权令牌。
res = requests.delete("https://api.upbit.com/v1/order", params=query, headers=headers) # 发送 HTTP DELETE 请求到交易所的 API 端点,以取消订单。params 参数包含订单标识符,headers 参数包含授权令牌。
res.raise_for_status() # 如果 HTTP 响应状态码指示错误(例如 400、401、500),则引发 HTTPError 异常。这有助于快速检测 API 请求中的问题。
return res.() # 返回 API 响应的内容,通常是 JSON 格式的数据,指示取消操作的结果。
4.3 账户API:查询账户信息
4.3.1 查询账户信息 (
accounts
)
该接口用于查询您在Upbit交易所的账户余额及相关信息,例如可用资金、已锁定资金以及账户中持有的各种加密货币数量。
函数定义:
def get_accounts():
"""
查询Upbit账户信息。
该函数通过调用Upbit API的`accounts`端点,获取当前账户的详细信息,
包括账户中各种加密货币的余额、锁定金额等。
Returns:
list: 包含账户信息的列表,每个元素代表一个币种的账户信息。
列表中的每个元素是一个字典,包含以下键值对:
- `currency`: 币种代码 (例如: "KRW", "BTC", "ETH")
- `balance`: 可用余额 (字符串类型)
- `locked`: 锁定余额 (字符串类型,例如挂单冻结的金额)
- `avg_buy_price`: 平均买入价格 (字符串类型)
- `avg_buy_price_modified`: 平均买入价格是否修正 (布尔类型)
- `unit_currency`: 计价货币 (字符串类型,例如: "KRW")
Raises:
requests.exceptions.HTTPError: 如果API请求返回错误状态码。
"""
import uuid
import jwt
import requests
access_key = "YOUR_ACCESS_KEY" # 替换为你的Access Key
secret_key = "YOUR_SECRET_KEY" # 替换为你的Secret Key
payload = {
'access_key': access_key,
'nonce': str(uuid.uuid4()), # 唯一字符串,用于防止重放攻击
}
jwt_token = jwt.encode(payload, secret_key, algorithm='HS256') # 使用HS256算法对payload进行签名
authorize_token = 'Bearer {}'.format(jwt_token) # 构建Authorization头部信息
headers = {"Authorization": authorize_token} # 设置请求头部
res = requests.get("https://api.upbit.com/v1/accounts", headers=headers) # 发送GET请求到Upbit API
res.raise_for_status() # 检查响应状态码,如果不是200,则抛出HTTPError异常
return res.() # 将响应内容解析为JSON格式并返回
使用示例:
accounts = get_accounts()
print(accounts)
示例输出:
[
{
"currency": "KRW",
"balance": "100000.0",
"locked": "0.0",
"avg_buy_price": "0",
"avg_buy_price_modified": false,
"unit_currency": "KRW"
},
{
"currency": "BTC",
"balance": "0.005",
"locked": "0.001",
"avg_buy_price": "60000000",
"avg_buy_price_modified": false,
"unit_currency": "KRW"
},
{
"currency": "ETH",
"balance": "0.1",
"locked": "0.0",
"avg_buy_price": "3000000",
"avg_buy_price_modified": false,
"unit_currency": "KRW"
}
]
注意事项:
-
请务必将
YOUR_ACCESS_KEY
和YOUR_SECRET_KEY
替换为您自己的Upbit API密钥。 -
Upbit API 使用 JWT (JSON Web Token) 进行身份验证。你需要使用你的Access Key和Secret Key生成JWT Token,并将其包含在请求头部的
Authorization
字段中。 -
nonce
参数是一个唯一字符串,用于防止重放攻击。每次请求都需要生成一个新的nonce
。uuid.uuid4()
函数可以生成一个随机的UUID。 - 为了安全起见,请妥善保管您的Access Key和Secret Key,不要将其泄露给他人。
-
res.raise_for_status()
会检查HTTP响应状态码。如果状态码表示错误(例如 400, 401, 500),它会抛出一个HTTPError
异常。这可以帮助您快速发现API请求中的问题。 - 返回的余额和锁定金额都是字符串类型。如果需要进行数值计算,请将其转换为浮点数。
-
avg_buy_price
表示平均购买价格,用于计算盈亏。
5. 常见问题处理
-
401 Unauthorized (未授权)
: 身份验证失败,表明您提供的凭据不正确。这通常发生在以下几种情况:
- Access Key和Secret Key错误 : 请仔细核对您的Access Key和Secret Key是否与Upbit账户中生成的一致。注意区分大小写,避免复制时引入空格或其他不可见字符。
- JWT生成错误 : JSON Web Token (JWT)的生成过程涉及对请求参数进行签名。如果签名算法、Payload内容或密钥使用不当,将导致JWT无效,从而无法通过身份验证。请检查您的JWT生成代码,确保其符合Upbit API文档的要求。
- Token过期 : JWT通常具有过期时间。如果您的Token已过期,需要重新生成。
-
429 Too Many Requests (请求过多)
: 您发送的请求频率超过了Upbit API的限制。Upbit为了保护服务器的稳定性和防止滥用,对API的调用频率进行了限制。
- 频率限制 : Upbit API针对不同的接口设置了不同的频率限制。请参考Upbit API文档,了解各个接口的限制情况。
-
解决方案
: 您可以通过以下方式来解决此问题:
- 降低请求频率 : 减少在单位时间内发送的请求数量。
- 使用延迟 : 在发送请求之间添加适当的延迟,以避免触发频率限制。
- 批量处理 : 将多个请求合并为一个请求进行发送,减少请求的总数量。
- 使用WebSocket API : 对于实时数据,可以考虑使用Upbit的WebSocket API,该API允许您订阅数据流,而无需频繁地发送请求。
-
500 Internal Server Error (服务器内部错误)
: Upbit服务器遇到了内部错误,导致请求无法完成。
- 原因 : 此错误通常与您的代码或请求无关,而是Upbit服务器本身的问题。
- 解决方案 : 您可以稍后重试该请求。如果问题持续存在,请联系Upbit技术支持。
-
API Key Permission Error (API密钥权限错误)
: 您的API Key没有访问您尝试调用的API的权限。Upbit允许您为API Key设置不同的权限,以控制其可以访问的资源。
- 权限设置 : 登录Upbit账户,进入API Key管理页面,检查您的API Key是否具有访问相应API的权限。
- 交易权限 : 如果您需要使用交易相关的API,请确保您的API Key已启用交易权限,并已完成相应的安全认证。
- 只读权限 : 某些API Key可能只具有只读权限,只能用于获取数据,而不能进行交易操作。
6. 错误处理
在实际应用中,健全的错误处理机制至关重要,能够提升程序的稳定性和可靠性。使用
try...except
语句是捕获和处理异常的标准方法。针对HTTP请求,应特别关注
requests.exceptions.HTTPError
异常,它表示HTTP请求返回了错误状态码(例如404 Not Found, 500 Internal Server Error)。捕获此异常后,可以根据
response.status_code
属性来确定具体的错误类型,并采取相应的应对措施,例如:
- 400 Bad Request: 客户端请求错误,检查请求参数或请求格式。
- 401 Unauthorized: 未经授权的访问,需要提供身份验证信息。
- 403 Forbidden: 服务器拒绝请求,客户端可能没有权限访问该资源。
- 404 Not Found: 请求的资源不存在,检查URL是否正确。
- 500 Internal Server Error: 服务器内部错误,通常需要服务器端进行修复。
- 503 Service Unavailable: 服务器暂时不可用,稍后重试。
除了
requests.exceptions.HTTPError
,还应该考虑处理其他可能的异常,例如:
- requests.exceptions.ConnectionError: 网络连接错误,例如服务器无响应或连接超时。
- requests.exceptions.Timeout: 请求超时,可以尝试增加超时时间或检查网络状况。
- requests.exceptions.RequestException: 所有requests库抛出的异常的基类,可以用于捕获所有与请求相关的异常。
示例代码:
import requests
import logging
# 配置日志记录
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')
def fetch_data(url):
try:
response = requests.get(url, timeout=10) # 设置超时时间
response.raise_for_status() # 检查HTTP状态码,如果不是200则抛出HTTPError
return response.()
except requests.exceptions.HTTPError as errh:
logging.error(f"HTTP Error: {errh}")
return None
except requests.exceptions.ConnectionError as errc:
logging.error(f"Connection Error: {errc}")
return None
except requests.exceptions.Timeout as errt:
logging.error(f"Timeout Error: {errt}")
return None
except requests.exceptions.RequestException as err:
logging.error(f"Request Error: {err}")
return None
except Exception as e:
logging.exception("An unexpected error occurred:") # 记录更详细的错误信息
return None
# 使用示例
data = fetch_data("https://api.example.com/data")
if data:
print(data)
同时,添加详细的日志记录功能也至关重要。通过记录请求的URL、状态码、请求头、响应内容以及发生的异常信息,可以帮助开发人员快速定位和解决问题。使用Python的
logging
模块可以方便地实现日志记录功能。根据不同的错误级别(例如DEBUG, INFO, WARNING, ERROR, CRITICAL)记录不同严重程度的错误信息,并可以将日志信息输出到控制台、文件或其他日志服务器。良好的错误处理和日志记录机制能够显著提高程序的健壮性和可维护性。