- OKX交易自动化 (okx-auto-position, okx-crypto, okx-exchange) - 交易信号处理 (signal-confirmation-templates, trading-signal-aggregator) - 量化因子挖掘 (quant-factor-mining) - 长桥集成 (longbridge-cli, longbridge-python-sdk) - 六合彩分析 (lottery-hk) - 股息投资 (dividend-investing, dividend-scanner) - 日内交易 (intraday-trading) - 同花顺 (tonghuashun)
176 lines
4.8 KiB
Markdown
176 lines
4.8 KiB
Markdown
# OKX API 关键Pitfalls
|
||
|
||
## 1. posMode=net_mode vs long_short_mode
|
||
|
||
**问题**:账户可能是 `net_mode`(净头寸)而非 `long_short_mode`(多空分离)。
|
||
|
||
**检查方法**:
|
||
```python
|
||
GET /api/v5/account/config
|
||
# 响应中 "posMode": "net_mode" 或 "long_short_mode"
|
||
```
|
||
|
||
**影响**:
|
||
- `net_mode`:**禁止传 `posSide` 参数**,否则报错 `sCode=51000 "Parameter posSide error"`
|
||
- `long_short_mode`:**必须传 `posSide`** (long/short)
|
||
|
||
**下单示例(net_mode)**:
|
||
```python
|
||
{
|
||
"instId": "ETH-USDT-SWAP",
|
||
"tdMode": "cross",
|
||
"side": "buy", # buy=开多/平空, sell=开空/平多
|
||
"ordType": "market",
|
||
"sz": "1" # 不传posSide!
|
||
}
|
||
```
|
||
|
||
**设置杠杆(net_mode)**:
|
||
```python
|
||
{
|
||
"instId": "ETH-USDT-SWAP",
|
||
"lever": "25",
|
||
"mgnMode": "cross" # 不传posSide!
|
||
}
|
||
```
|
||
|
||
**切换模式**(需要主账户权限):
|
||
```python
|
||
POST /api/v5/account/set-position-mode
|
||
{"posMode": "long_short_mode"} # 或 "net_mode"
|
||
```
|
||
|
||
---
|
||
|
||
## 2. OCO订单合并(加仓场景)
|
||
|
||
**问题**:加仓后,旧OCO只覆盖旧仓位,新OCO只覆盖新仓位,导致多个OCO并存。
|
||
|
||
**错误示例**:
|
||
- 持仓5张,OCO(sell 5, SL=1660, TP=1746)
|
||
- 加仓1张 → 持仓6张
|
||
- 新建OCO(sell 1, SL=1666.8, TP=1775.1)
|
||
- 结果:2个OCO并存,旧OCO触发只平5张,剩1张单独走
|
||
|
||
**正确流程**:
|
||
1. 查现有OCO:`GET /api/v5/trade/orders-algo-pending?ordType=oco`
|
||
2. 找到同instId的旧OCO algoId
|
||
3. 删除旧OCO:`POST /api/v5/trade/cancel-algo` → `[{instId, algoId}]`
|
||
4. 创建新OCO覆盖全部持仓
|
||
|
||
**验证**:
|
||
```bash
|
||
# 查pending OCO
|
||
curl -X GET "https://www.okx.com/api/v5/trade/orders-algo-pending?ordType=oco" \
|
||
-H "OK-ACCESS-KEY: $KEY" ...
|
||
|
||
# 应该只有一个OCO per instId
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 补推信号必须先查持仓
|
||
|
||
**场景**:模型断线后补推积压信号。
|
||
|
||
**错误做法**:直接用历史信号数据推送推荐(如"4,290 ETH加仓到4,455")。
|
||
|
||
**正确做法**:
|
||
1. 先查当前持仓:`GET /api/v5/account/positions`
|
||
2. 再查当前algo orders:`GET /api/v5/trade/orders-algo-pending?ordType=oco`
|
||
3. 用**当前持仓数据**而非历史信号数据生成推荐
|
||
|
||
**案例**:
|
||
- 历史信号说"4,290 ETH"
|
||
- 实际持仓已是5张(可能中间已有多次变动)
|
||
- 用历史数据推"加仓到4,455"是错误的
|
||
|
||
---
|
||
|
||
## 4. 遍历查询algo orders
|
||
|
||
**问题**:`ordType` 参数不能组合查询,需逐个类型查。
|
||
|
||
```python
|
||
for algo_type in ["oco", "conditional", "trigger", "move_order_stop"]:
|
||
result = okx_get(f"/api/v5/trade/orders-algo-pending?ordType={algo_type}")
|
||
# 处理 result["data"]
|
||
```
|
||
|
||
**注意**:某些类型可能返回错误(如账户未开通该功能),需忽略错误继续。
|
||
|
||
---
|
||
|
||
## 5. 密码中含特殊字符
|
||
|
||
**问题**:`OKX_PASSPHRASE` 含 `$` 等特殊字符时,bash 会尝试变量展开。
|
||
|
||
**错误**:`export OKX_PASSPHRASE=mikeOkxID$1` → `$1` 展开为空
|
||
|
||
**正确**:
|
||
```bash
|
||
export OKX_PASSPHRASE='mikeOkxID$1' # 单引号
|
||
```
|
||
|
||
**或从文件读取**:
|
||
```python
|
||
with open("~/.bashrc", "r") as f:
|
||
for line in f:
|
||
if "OKX_PASSPHRASE" in line:
|
||
passphrase = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 凭证变量名:OKX_SECRET(不是OKX_SECRET_KEY)
|
||
|
||
bashrc里实际变量名是 `OKX_SECRET`,不是 `OKX_SECRET_KEY`。
|
||
|
||
**脚本内部**:`load_credentials()` 用 `OKX_\w+` 正则匹配,自动兼容,不受影响。
|
||
|
||
**手动ccxt初始化**(agent写临时Python时):
|
||
```python
|
||
# ❌ 错误 — 会 KeyError
|
||
creds['OKX_SECRET_KEY']
|
||
|
||
# ✅ 正确
|
||
creds['OKX_SECRET']
|
||
|
||
# ✅ 兼容写法
|
||
secret = creds.get('OKX_SECRET', '') or creds.get('OKX_SECRET_KEY', '')
|
||
```
|
||
|
||
**三个变量**:`OKX_API_KEY`、`OKX_SECRET`、`OKX_PASSPHRASE`
|
||
|
||
---
|
||
|
||
## 7. --execute 必须同时带 --rec-json
|
||
|
||
脚本代码 `if args.execute and args.rec_json:` 要求两个参数同时存在。
|
||
|
||
**错误**:只传 `--execute` 不传 `--rec-json` → 静默跳过执行,fall through到推荐流程
|
||
|
||
**正确两步流程**:
|
||
```bash
|
||
# 第1步:获取推荐JSON
|
||
python3 okx_position_advisor.py --symbol HYPE --side long --leverage 10 --json > /tmp/rec.json
|
||
|
||
# 第2步:执行下单(必须同时带 --execute 和 --rec-json)
|
||
python3 okx_position_advisor.py --symbol HYPE --side long --leverage 10 --execute --json --rec-json "$(cat /tmp/rec.json)"
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 余额为零时ZeroDivisionError
|
||
|
||
**问题**:`recommend_position()` 函数在计算 `margin_pct = total_margin / acct_info['usdt_free'] * 100` 时,如果 `usdt_free=0`(用户满仓),会抛出 `ZeroDivisionError`。
|
||
|
||
**修复**:在调用 `recommend_position()` 前检查余额:
|
||
```python
|
||
if acct_info['usdt_free'] < 0.01:
|
||
print("⚠️ 余额不足(可用0 USDT),无法开仓")
|
||
sys.exit(0)
|
||
```
|
||
|
||
**format_signal.py 已加 try/except 处理此场景。**
|