ReplayEdge Algorithm API
用脚本交易匿名历史行情
REST API 与网页交易台使用同一套撮合、手续费、滑点、杠杆和排行榜系统。算法只能读取已经揭示的 Tick;下单统一在下一根 Tick 的开盘价成交;股票代码和历史日期会在结算报告中公布。
http://localhost:5178/api/v1认证
API 文档可以在未登录时访问;真实交易接口必须使用 API Key。请先登录网页账户,点击顶部 API 生成 Key。带 Key 创建的回放会绑定账户,并在结算后进入最近 10 局和排行榜。
Authorization: Bearer redge_live_your_key
REPLAYEDGE_API_KEY 注入。重新生成或撤销后,旧 Key 立即失效。速率限制
每个 API Key 在一分钟窗口内最多请求 500 次,其中创建新回放最多 2 次。公开文档、API 概览和排行榜不计入 Key 额度;创建失败不会消耗开局额度,但仍计为一次 API 请求。
| 限制 | 响应头 | 额度 |
|---|---|---|
| 全部认证请求 | X-RateLimit-Limit / Remaining / Reset | 500 次 / 分钟 / Key |
| 创建回放 | X-ReplayLimit-Limit / Remaining / Reset | 2 局 / 分钟 / Key |
超过额度返回 429 rate_limited。脚本应读取 Retry-After 等待对应秒数,避免立即循环重试;Reset 是 Unix 秒级时间戳。
30 秒快速开始
export REPLAYEDGE_API_KEY="redge_live_..."
curl -X POST http://localhost:5178/api/v1/replays \
-H "Authorization: Bearer $REPLAYEDGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"universe":"mega","volatility":"any","trend":"any","timeOfDay":"any","totalTicks":180,"startAtOpen":false}'
保存响应中的 data.replayId。创建成功时返回最初 60 根 K 线,之后调用 advance 才会揭示新行情。
回放生命周期
60 / N→读取行情计算信号→提交订单
下一 Tick 成交→主动或自动结算
生成报告
- 初始资金固定为
$100,000,最大总杠杆为2x。 - 订单提交后不会立刻成交;市价、限价和止损触发单统一按下一根 Tick 的
open价格计算成交,市价/止损会加滑点。 - 每个回放绑定创建它的 API Key 用户,其他用户无法读取或操作。
- 回放闲置 3 小时后可能失效。完成后成绩自动进入该用户排行榜。
/replays创建匿名回放
| 字段 | 允许值 | 默认 |
|---|---|---|
universe | all, mega, tech, etf | all |
volatility | any, low, medium, high | any |
trend | any, up, down, range | any |
timeOfDay | any, open, midday, close | any |
totalTicks | 90-390 的整数,常用 120/180/240/390 | 180 |
startAtOpen | true 时样本从美东 09:30 开始 | false |
{
"data": {
"replayId": "6d90...",
"status": "active",
"tick": 60,
"totalTicks": 180,
"currentBar": { "o": 189.2, "h": 189.4, "l": 189.1, "c": 189.3, "v": 48210, "vw": 189.27, "time": "10:29" },
"revealedBars": ["60 bar objects"],
"account": { "equity": 100000, "buyingPower": 200000, "position": 0, "currentPrice": 189.3 }
}
}
/replays/{replayId}查询账户与订单状态
返回当前 Tick、账户、持仓、全部订单和成交记录,不重复返回 K 线数组。回放结束后还会包含 data.report。
/replays/{replayId}/market?from_tick=61读取已揭示行情
from_tick 是从 1 开始的 Tick 编号。接口最多返回当前 Tick,无法通过参数获取未来数据。
{ "data": { "replayId": "...", "fromTick": 61, "toTick": 65, "totalTicks": 180, "bars": [] } }/replays/{replayId}/advance推进行情
一次推进 1-30 个 Tick。revealedBars 只包含本次新揭示的数据。
{ "steps": 1 }/replays/{replayId}/orders提交订单
| 字段 | 类型 | 说明 |
|---|---|---|
side | string | buy 或 sell |
type | string | market, limit, stop |
quantity | integer | 至少 1 股;小数会向下取整 |
triggerPrice | number | 限价单和止损触发单必填 |
stopLoss | number | 可选;成交后创建保护单 |
takeProfit | number | 可选;与止损组成 OCO |
{
"side": "buy",
"type": "market",
"quantity": 100,
"stopLoss": 187.50,
"takeProfit": 193.00
}
/replays/{replayId}/orders/{orderId}撤销挂单
仅 pending 或 partial 状态的订单可以撤销,已成交和已拒绝订单不可撤销。
/replays/{replayId}/settle结算并获取报告
未平仓持仓会按当前行情平仓,所有挂单撤销。响应的 data.report 会公布股票代码、交易日期和完整复盘统计。
/leaderboard?mode=score读取排行榜
无需认证。mode 可为 score 或 pnl,只返回公开昵称、选填大学和训练统计。评分、收益和胜率按每位用户最近 10 局计算。
行情与账户字段
| 字段 | 含义 |
|---|---|
o/h/l/c | 当前分钟开、高、低、收价格 |
v | 成交量 |
vw | 该分钟成交量加权平均价;成交额可按 vw × v 计算 |
time | 美东时间 HH:mm |
position | 正数为多仓,负数为空仓 |
buyingPower | 考虑 2x 杠杆和当前敞口后的剩余买力 |
liquidationPrice | 维持保证金强平参考价;空仓时为 null |
错误处理
{ "error": { "code": "invalid_request", "message": "quantity 必须至少为 1 股整数。" } }| HTTP | code | 处理建议 |
|---|---|---|
| 400 | invalid_request | 修正参数,不要原样重试 |
| 401 | unauthorized | 检查 API Key 是否撤销或复制不完整 |
| 403 | forbidden | 回放不属于当前账户 |
| 404 | not_found | 检查 ID,回放也可能已过期 |
| 429 | rate_limited | 按 Retry-After 等待后重试 |
| 502 | market_data_unavailable | 稍后重新创建回放 |
完整 Python 策略骨架
示例使用 10/20 均线交叉,按 25% 可用买力下单。它仅演示 API 生命周期,不代表投资建议。
import math
import os
import requests
BASE = "http://localhost:5178/api/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['REPLAYEDGE_API_KEY']}",
"Content-Type": "application/json",
}
def api(method, path, **kwargs):
response = requests.request(method, BASE + path, headers=HEADERS, timeout=30, **kwargs)
response.raise_for_status()
return response.json()["data"]
replay = api("POST", "/replays", json={"universe": "mega", "totalTicks": 180, "startAtOpen": False})
replay_id = replay["replayId"]
bars = replay["revealedBars"]
while replay["status"] == "active":
closes = [bar["c"] for bar in bars]
fast = sum(closes[-10:]) / 10
slow = sum(closes[-20:]) / 20
position = replay["account"]["position"]
if fast > slow and position == 0:
price = replay["account"]["currentPrice"]
qty = math.floor(replay["account"]["buyingPower"] * 0.25 / price)
if qty >= 1:
replay = api("POST", f"/replays/{replay_id}/orders", json={
"side": "buy", "type": "market", "quantity": qty
})
elif fast < slow and position > 0:
replay = api("POST", f"/replays/{replay_id}/orders", json={
"side": "sell", "type": "market", "quantity": position
})
replay = api("POST", f"/replays/{replay_id}/advance", json={"steps": 1})
bars.extend(replay.get("revealedBars") or [])
report = replay["report"]
print(report["symbol"], report["timeRange"], report["pnl"], report["score"])