现货交易指南
本指南将带您深入了解 BigONE 现货交易 API 的核心逻辑。我们不提供复杂的包装类,而是专注于 原始 HTTP 交互、JSON 载荷 和您构建稳定交易机器人所需的 业务逻辑。
准备工作
- 基础 URL:
https://api.big.one/api/v3 - 认证: 大多数 "Viewer" 端点(账户、订单)需要 Bearer Token (JWT)。详情请见 鉴权认证指南。
- 所需权限范围 (Scopes):
view account balance information(用于检查资金)create orders(用于下单和撤单)view order information(用于查询状态)
- Content-Type: 所有 POST 请求必须包含
Content-Type: application/json。
第一课:市场规则与精度
在下单之前,您 必须 了解目标交易对的交易规则。与标准金融市场不同,加密货币市场实行严格的小数精度限制和最小订单价值要求。
理解交易对配置
GET /asset_pairs 端点提供了交易规则。您应该在应用程序启动时调用一次并缓存结果。
关键配置字段:
- base_scale: 控制 数量 (Amount) 的小数精度。
- 示例:
BTC-USDT的base_scale为6。数量0.123456是有效的;0.1234567是无效的。
- 示例:
- quote_scale: 控制 价格 (Price) 的小数精度。
- 示例:
BTC-USDT的quote_scale为2。价格50000.12是有效的;50000.123是无效的。
- 示例:
- min_quote_value: 所需的最小订单价值(价格 × 数量)。
- 示例: 如果
min_quote_value为5.0,那么价值 $4.99 的买单将被拒绝并返回400 Bad Request。
- 示例: 如果
逻辑实现
- 获取配置。
- 识别目标交易对的精度。
- 验证: 检查
价格 * 数量 >= min_quote_value。 - 格式化: 将数字转换为具有精确精度的字符串。
import requests
BASE_URL = "https://api.big.one/api/v3"
# 1. 获取配置
response = requests.get(f"{BASE_URL}/asset_pairs")
pairs = response.json()
pair = next(p for p in pairs if p["name"] == "BTC-USDT")
# 2. 逻辑: 验证与格式化
def prepare_order(amount, price, pair_config):
# 检查最小价值
value = amount * price
min_val = float(pair_config['min_quote_value'])
if value < min_val:
raise ValueError(f"订单价值 {value} 低于最小值 {min_val}")
# 格式化为固定精度的字符串
safe_amount = f"{amount:.{pair_config['base_scale']}f}"
safe_price = f"{price:.{pair_config['quote_scale']}f}"
return safe_amount, safe_price
# 示例用法
try:
amt, prc = prepare_order(0.0001, 50000, pair) # 价值 = 5.0
print(f"Payload: amount='{amt}', price='{prc}'")
except ValueError as e:
print(f"验证错误: {e}")
第二课:资金与账户状态
在交易之前,请确认您有足够的 可用余额。
端点: GET /viewer/accounts
关键响应字段:
- balance: 可用于新交易或提现的金额。
- locked_balance: 当前被挂单占用的金额。
状态转换:
- 您有
100 USDT可用余额。 - 您放置了一个
50 USDT的限价买单。 - 新状态:
balance = 50,locked_balance = 50。 - 如果订单成交,
locked_balance变为0,您获得 BTC。 - 如果您撤单,
locked_balance回到balance。
# 下单前检查资金
accounts = requests.get(f"{BASE_URL}/viewer/accounts", headers=headers).json()
usdt_wallet = next((a for a in accounts if a['asset_symbol'] == 'USDT'), None)
if usdt_wallet and float(usdt_wallet['balance']) > 50.0:
print("资金充足。")
else:
print("资金不足。")
第三课:下单 (细节详解)
POST /viewer/orders 端点是您的主要工具。让我们看看控制订单执行 方式 的高级参数。
订单类型 (type)
- LIMIT: "我想以价格 X 或更好的价格买入。"(标准限价单)
- MARKET: "我想立即以任何价格买入。"(市价单/吃单)
- STOP_LIMIT: "如果价格触及触发价,下限价单。"
- STOP_MARKET: "如果价格触及触发价,下市价单。"
执行标志 (生效时间)
这些标志对于算法交易(如套利)至关重要,可以防止部分成交或卡单。
- immediate_or_cancel (IOC):
- 逻辑: "立即成交尽可能多的部分,并取消剩余部分。"
- 场景: 您看到 10 BTC 挂售。您想买下它们,但如果有人先买了 5 BTC,您不希望剩余的买单留在订单簿中。
- post_only:
- 逻辑: "我必须是 Maker(做市方)。如果我穿过价差(成为 Taker),请取消我。"
- 场景: 希望赚取返佣并避免吃单手续费的做市机器人。
示例:安全的“做市方”订单
此订单尝试在 $50,000 买入,但 保证 不会意外支付吃单手续费。
payload = {
"asset_pair_name": "BTC-USDT",
"side": "BID",
"type": "LIMIT",
"price": "50000.00",
"amount": "0.500000",
"post_only": True, # 对做市商至关重要
"client_order_id": "mm-bot-001"
}
response = requests.post(f"{BASE_URL}/viewer/orders", json=payload, headers=headers)
# 如果价格已经是 49900,此 API 调用将返回已取消的订单或错误。
第四课:管理生命周期
订单一旦下达,就是一个动态对象。您使用其 ID 与其交互。
1. 检查状态
端点: GET /viewer/orders/{id}
需要处理的状态值:
PENDING: 等待中。FILLED: 已成交。检查avg_deal_price以查看实际成交价格。CANCELLED: 由用户或系统取消。
2. 撤销订单
端点: POST /viewer/orders/{id}/cancel
请始终使用 POST 方法。
3. 批量撤单 (重置)
端点: POST /viewer/orders/cancel
当您的机器人重启或检测到市场异常时非常有用。
# 紧急按钮:撤销所有订单
requests.post(f"{BASE_URL}/viewer/orders/cancel",
json={"asset_pair_name": "BTC-USDT"},
headers=headers)
第五课:错误处理
不要只检查 HTTP 200。BigONE 会在 JSON 主体中返回有用的错误代码。
常见错误代码:
| 代码 | 信息 | 含义 | 建议操作 |
|---|---|---|---|
10014 | Insufficient funds | 可用余额过低。 | 检查 locked_balance 或充值。 |
40304 | Order forbidden | 市场可能处于维护中。 | 停止机器人并提醒人工。 |
54041 | Duplicate order | client_order_id 重复使用。 | 生成新的 ID。 |
50047 | Liquidity taken too much | post_only 订单将作为吃单执行。 | 调整价格并重试。 |
response = requests.post(f"{BASE_URL}/viewer/orders", json=payload, headers=headers)
if response.status_code != 200:
error = response.json()
code = error.get('code')
if code == 10014:
print("余额不足!")
elif code == 50047:
print("价格穿过价差,正在重试...")
else:
print(f"关键 API 错误: {error['message']}")
完整示例
以下是一个结合了上述所有课程的可运行脚本。它实现了一个安全的“做市方”买单,并带有状态监控。
import requests
import time
import jwt # pip install PyJWT
# --- 配置 ---
API_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
BASE_URL = "https://api.big.one/api/v3"
PAIR = "BTC-USDT"
# --- 认证辅助函数 ---
def get_headers():
token = jwt.encode({
"sub": API_KEY,
"nonce": int(time.time() * 1000000), # 微秒级 nonce
"iat": int(time.time()),
"exp": int(time.time()) + 60
}, SECRET_KEY, algorithm="HS256")
return {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
def run_bot():
print(f"--- 启动 {PAIR} 的现货机器人 ---")
# 1. 获取精度规则
print("1. 获取市场规则...")
pairs = requests.get(f"{BASE_URL}/asset_pairs").json()
pair_cfg = next(p for p in pairs if p["name"] == PAIR)
base_scale = pair_cfg['base_scale'] # 数量精度
quote_scale = pair_cfg['quote_scale'] # 价格精度
min_val = float(pair_cfg['min_quote_value'])
# 2. 定义目标
target_price = 40000.50 # 示例价格
target_amount = 0.002 # 示例数量
# 3. 验证与格式化
order_val = target_price * target_amount
if order_val < min_val:
print(f"错误: 订单价值 {order_val} < 最小值 {min_val}")
return
# 格式化为字符串对现货 API 至关重要
safe_price = f"{target_price:.{quote_scale}f}"
safe_amount = f"{target_amount:.{base_scale}f}"
print(f" 目标: 买入 {safe_amount} @ {safe_price} (价值: {order_val})")
# 4. 检查余额
print("2. 检查资金...")
accounts = requests.get(f"{BASE_URL}/viewer/accounts", headers=get_headers()).json()
# 查找计价资产 (USDT)
quote_asset = pair_cfg['quote_asset']['symbol']
wallet = next((a for a in accounts if a['asset_symbol'] == quote_asset), None)
available = float(wallet['balance']) if wallet else 0.0
if available < order_val:
print(f" 资金不足: 持有 {available}, 需要 {order_val}")
return
# 5. 下单 (Post-Only)
print("3. 正在下单...")
payload = {
"asset_pair_name": PAIR,
"side": "BID",
"type": "LIMIT",
"price": safe_price, # 字符串
"amount": safe_amount, # 字符串
"post_only": True,
"client_order_id": f"bot-{int(time.time())}"
}
res = requests.post(f"{BASE_URL}/viewer/orders", json=payload, headers=get_headers())
if res.status_code != 200:
print(" 下单失败:", res.json())
return
order_id = res.json()['id']
print(f" 订单 {order_id} 已下达。状态: {res.json()['state']}")
# 6. 监控状态
print("4. 监控中 (5秒)...")
time.sleep(5)
status = requests.get(f"{BASE_URL}/viewer/orders/{order_id}", headers=get_headers()).json()
print(f" 当前状态: {status['state']}, 已成交: {status['filled_amount']}")
# 7. 如果未成交则撤单
if status['state'] == "PENDING":
print(" 订单仍在挂单中。正在撤单...")
cancel = requests.post(f"{BASE_URL}/viewer/orders/{order_id}/cancel", headers=get_headers())
print(" Result:", cancel.json()['state'])
if __name__ == "__main__":
run_bot()
结论
您现在已经掌握了在 BigONE 上构建稳定现货交易应用程序的工具。通过遵守 市场精度规则 并正确处理 订单生命周期,您可以避免大多数常见的集成陷阱。
要点:
- 始终获取并缓存
asset_pair配置以处理精度 (base_scale,quote_scale)。 - 以 字符串 形式发送数值以防止浮点数错误。
- 在做市策略中使用
post_only以确保您始终作为流动性提供方。
下一步:
- 探索 WebSocket API 以接收实时订单更新,而不是通过轮询。
- 查看 API 参考 了解订单类型和错误代码的完整列表。