QuantDinger 文档
自托管 AI 交易平台,面向量化研究、Python 策略开发、回测与实盘执行。一套技术栈覆盖 AI 分析、图表、策略代码、回测、快捷交易与实盘运维——基础设施完全由您掌控。
GHCR 预构建镜像
从 GHCR 拉取 quantdinger-backend 与 quantdinger-frontend — 无需 Node.js,无需本地构建前端。
Python 原生
使用 pandas DataFrame 或事件驱动的 on_bar 脚本编写策略。
AI 融入工作流
支持 OpenAI、Claude、Gemini、DeepSeek、Grok — 分析、生成、集成投票与置信度校准。
移动 + Web + 原生
完整移动 H5、Android Capacitor 构建、Vue 桌面端 — 均对接同一 API。
简介 #
QuantDinger 是自托管的量化交易与算法交易平台,面向 AI 辅助研究、Python 策略开发、回测与实盘执行。您的凭证、策略代码、市场工作流与运营数据始终由您掌控。
主要能力包括:
- AI 市场分析 — 结构化、低延迟分析,支持记忆、集成投票与置信度校准,兼容 OpenAI、Claude、Gemini、DeepSeek、Grok 等。
- Python 策略开发 — 四路
IndicatorStrategy(open_long/close_long/open_short/close_short)配合# @strategy风控默认值,或事件驱动ScriptStrategy的显式ctx.open_*/ctx.close_*意图。AI 可生成起点代码,最终由您掌控。 - 确定性回测 — 手续费与滑点建模、逐笔交易分析、权益曲线。可选
strict_mode使成交与实盘执行语义对齐。 - AI 智能体(MCP) — PyPI 上的
quantdinger-mcp0.2.0 针对/api/agent/v1暴露 26 个范围化工具(读取、工作区、指标、回测、SSE 任务等)。 - 自主交易机器人 — 网格、马丁格尔、趋势跟踪与定投(DCA)。感知执行、重启可恢复,支持信号或实盘执行模式。
- 运维就绪 — 多用户 PostgreSQL、基于角色的访问控制、Google / GitHub OAuth、会员、积分、USDT 支付,以及 Telegram / Email / SMS / Discord / Webhook 告警。
架构 #
QuantDinger 以自托管应用栈运行:
| 层级 | 技术 |
|---|---|
| 前端 | 预构建 Vue SPA:ghcr.io/brokermr810/quantdinger-frontend(Nginx + 通过 BACKEND_URL 代理 API) |
| 后端 | Flask API:ghcr.io/brokermr810/quantdinger-backend(或从 backend_api_python/ 本地构建) |
| 存储 | PostgreSQL 16 |
| 缓存 / Worker 支持 | Redis 7 |
| 交易层 | 交易所适配器、IBKR、MT5 |
| AI 层 | LLM 提供商集成、记忆、校准、可选 Worker |
| 计费 | 会员、积分、USDT TRC20 支付流程 |
| 部署 | Docker Compose — docker-compose.ghcr.yml(零克隆)或 docker-compose.yml(开发 / 补丁) |
执行模型
- 行情数据通过可插拔数据层拉取。
- 回测在服务端策略引擎运行,含策略快照处理。
- 实盘策略通过运行时服务生成订单意图。
- 待处理订单通过交易所专用执行适配器分发。
- 加密货币实盘执行有意与行情采集解耦。
部署路径 #
QuantDinger v3.0.20 支持两种一等公民安装路径。根据是否需要在服务器上保留完整 Git 仓库来选择。
| 路径 | Compose 文件 | 适用场景 |
|---|---|---|
| A · GHCR 拉取(推荐) | docker-compose.ghcr.yml |
生产 VPS、1Panel、Railway 式部署 — 仅需两个文件 + backend.env |
| B · 克隆仓库 | docker-compose.yml |
需要修改后端 Python、阅读迁移脚本,或使用 docker-compose.build.yml 本地构建 Vue 的开发者 |
镜像来源(两种路径):
ghcr.io/brokermr810/quantdinger-frontend:<tag>— 预构建 UI(源码位于 QuantDinger-Vue)ghcr.io/brokermr810/quantdinger-backend:<tag>— API 镜像(GHCR 路径)或本地 Docker 构建(克隆路径)- 在项目根目录
.env中设置IMAGE_TAG=3.0.20固定版本(GHCR 的 semver 标签省略前导v)
完整云部署指南(中文):docs/CLOUD_DEPLOYMENT_CN.md · 英文:CLOUD_DEPLOYMENT_EN.md
快速开始 #
最快路径:拉取 GHCR 预构建镜像,无需克隆仓库。
mkdir quantdinger && cd quantdinger
curl -fsSLO https://raw.githubusercontent.com/brokermr810/QuantDinger/main/docker-compose.ghcr.yml
curl -fsSLO https://raw.githubusercontent.com/brokermr810/QuantDinger/main/backend_api_python/env.example \
-o backend.env
# optional: pin release
echo 'IMAGE_TAG=3.0.20' >> .env
docker compose -f docker-compose.ghcr.yml up -d
docker compose -f docker-compose.ghcr.yml ps
后端入口在首次启动时自动生成 SECRET_KEY 并写回 backend.env。请在其中修改管理员密码与 API 密钥,然后重启后端。
git clone https://github.com/brokermr810/QuantDinger.git
cd QuantDinger
cp backend_api_python/env.example backend_api_python/.env
./scripts/generate-secret-key.sh
docker compose up -d --build
git clone https://github.com/brokermr810/QuantDinger.git
cd QuantDinger
Copy-Item backend_api_python\env.example -Destination backend_api_python\.env
$key = py -c "import secrets; print(secrets.token_hex(32))"
(Get-Content backend_api_python\.env) -replace '^SECRET_KEY=.*$', "SECRET_KEY=$key" | Set-Content backend_api_python\.env -Encoding UTF8
docker compose up -d --build
启动后:
- 前端 UI:
http://localhost:8888 - 后端健康检查:
http://localhost:5000/api/health(或通过前端代理/api/health) - 默认登录:
quantdinger/123456— 暴露到公网前务必修改
GHCR 安装(推荐) #
使用 docker-compose.ghcr.yml,您只需:
docker-compose.ghcr.ymlbackend.env— 运行时密钥与功能开关(挂载为/app/.env)- 可选的项目根目录
.env— 端口、IMAGE_TAG、镜像加速前缀
重要:backend.env 必须是普通文件。若 Docker 在该路径创建了空目录,后端将无法读取配置。
生产环境端口绑定
# project-root .env (recommended on VPS)
FRONTEND_PORT=127.0.0.1:8888
BACKEND_PORT=127.0.0.1:5000
DB_PORT=127.0.0.1:5432
IMAGE_TAG=3.0.20
IMAGE_PREFIX=
架构迁移:与克隆路径不同,GHCR 后端每次启动都会幂等重放 migrations/init.sql — 无需在主机挂载 SQL。
克隆仓库并 Compose #
使用仓库中的 docker-compose.yml:
- 后端 — 从
backend_api_python/Dockerfile构建(本地补丁可通过--build立即生效) - 前端 — 默认从 GHCR 拉取;若本地克隆 QuantDinger-Vue,可用
docker-compose.build.yml覆盖 - 配置 —
backend_api_python/.env(不是backend.env)
docker compose up -d --build # default: GHCR frontend + local backend build
docker compose down # stop; add -v to wipe volumes
docker compose logs -f backend
本地前端构建(可选)
将 QuantDinger-Vue 克隆到 ./QuantDinger-Vue/,然后:
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
前置条件 #
- Docker 20+ 与 Docker Compose v2(
docker compose) - 小型团队建议主机至少 2 vCPU / 4 GB 内存 / 20 GB 磁盘
- 常规部署无需 Node.js — UI 以 GHCR 镜像交付
- (生产环境) 主机 Nginx、Caddy 或面板(1Panel / OpenResty)监听
80/443,反代到127.0.0.1:8888
常用命令 #
docker compose ps
docker compose logs -f backend
docker compose restart backend
docker compose up -d --build
docker compose exec backend bash
backend.env 或 backend_api_python/.env),运行 docker compose restart backend 即可 — 无需重建。
Compose .env 参数 #
项目根目录 .env 控制 Docker Compose 变量替换 — 端口、镜像标签、镜像加速前缀。它与后端运行时配置相互独立。
| 文件 | 使用者 | 内容 |
|---|---|---|
backend.env | GHCR 路径 | SECRET_KEY、API 密钥、OAuth、计费、Worker |
backend_api_python/.env | 克隆路径 | 相同的运行时键,挂载进后端容器 |
.env(项目根目录) | docker compose | IMAGE_TAG、FRONTEND_PORT、BACKEND_URL、IMAGE_PREFIX |
# Production — bind to localhost; host Nginx terminates TLS
FRONTEND_PORT=127.0.0.1:8888
BACKEND_PORT=127.0.0.1:5000
DB_PORT=127.0.0.1:5432
# Pin GHCR release (optional; default pulls :latest)
IMAGE_TAG=3.0.20
# FRONTEND_TAG=3.0.20
# BACKEND_TAG=3.0.20
# Slow Docker Hub? pick a mirror prefix:
# IMAGE_PREFIX=docker.m.daocloud.io/library/
# Frontend container → backend API (default inside compose network)
BACKEND_URL=http://backend:5000
# Host-only backend (1Panel split proxy): BACKEND_URL=http://172.17.0.1:5000
配置概览 #
运行时配置位于 backend.env(GHCR)或 backend_api_python/.env(克隆)。从仓库中的 backend_api_python/env.example 复制。
| 领域 | 示例键 |
|---|---|
| 身份认证 | SECRET_KEY、ADMIN_USER、ADMIN_PASSWORD |
| 数据库 | DATABASE_URL |
| LLM / AI | LLM_PROVIDER、OPENAI_API_KEY、OPENROUTER_API_KEY |
| OAuth | GOOGLE_CLIENT_ID、GITHUB_CLIENT_ID |
| 安全 | TURNSTILE_SITE_KEY、ENABLE_REGISTRATION |
| 计费 | BILLING_ENABLED、BILLING_COST_AI_ANALYSIS |
| 会员 | MEMBERSHIP_MONTHLY_PRICE_USD、MEMBERSHIP_MONTHLY_CREDITS |
| USDT 支付 | USDT_PAY_ENABLED、USDT_TRC20_XPUB、TRONGRID_API_KEY |
| 代理 | PROXY_URL |
| Worker | ENABLE_PENDING_ORDER_WORKER、ENABLE_PORTFOLIO_MONITOR、ENABLE_REFLECTION_WORKER |
| AI 调优 | ENABLE_AI_ENSEMBLE、ENABLE_CONFIDENCE_CALIBRATION、AI_ENSEMBLE_MODELS |
身份认证 #
SECRET_KEY 用于签署所有 JWT 令牌。它必须是密码学安全的 64 位十六进制字符串 — 后端在检测到默认占位符时会拒绝启动。
SECRET_KEY=<run: python -c "import secrets; print(secrets.token_hex(32))">
ADMIN_USER=quantdinger
ADMIN_PASSWORD=change-me-before-going-live
# Token lifetime in seconds (default 7 days)
JWT_EXPIRATION=604800
数据库 #
将 DATABASE_URL 指向 PostgreSQL 16。默认值针对 Docker Compose 栈内的 postgres 服务:
DATABASE_URL=postgresql://quantdinger:quantdinger@postgres:5432/quantdinger
启动时自动从 backend_api_python/migrations/init.sql 运行迁移。若使用托管数据库(Supabase、Neon、AWS RDS 等),请替换 URL 并确保允许来自主机的入站连接。
AI 提供商 #
QuantDinger 内置多家 LLM 提供商适配器。按预算与合规要求任选子集即可。
| 提供商 | 密钥 | 典型用途 |
|---|---|---|
| OpenRouter | OPENROUTER_API_KEY | 聚合器 — 首选 |
| OpenAI | OPENAI_API_KEY | GPT-4o / GPT-5 系列 |
| Anthropic | CLAUDE_API_KEY | Claude 3.x / 4.x |
GEMINI_API_KEY | Gemini 1.5 / 2.0 | |
| DeepSeek | DEEPSEEK_API_KEY | 高性价比推理 |
| xAI | GROK_API_KEY | Grok 系列 |
集成与校准
若团队需要更稳健的 AI 输出,可开启集成投票与置信度校准:
ENABLE_AI_ENSEMBLE=true
AI_ENSEMBLE_MODELS=openai:gpt-4o,anthropic:claude-3-5-sonnet,google:gemini-2.0-flash
ENABLE_CONFIDENCE_CALIBRATION=true
Google / GitHub OAuth #
OAuth 使登录体验更现代并减少密码摩擦。在各提供商注册应用后设置:
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
# Whitelist of frontend origins the backend will redirect back to after OAuth.
# Include every domain you serve the app from (PC, mobile, staging).
OAUTH_ALLOWED_REDIRECTS=https://ai.quantdinger.com,https://m.quantdinger.com
# Primary frontend URL for redirect fallback
FRONTEND_URL=https://ai.quantdinger.com
/api/auth/oauth/<provider>/callback,不是前端 URL。后端随后重定向到 OAUTH_ALLOWED_REDIRECTS 中列出的前端源。
若移动应用部署在不同源,测试前请将该源加入
OAUTH_ALLOWED_REDIRECTS — 否则后端会将用户重定向到回退 FRONTEND_URL。
Cloudflare Turnstile #
Turnstile 为登录、注册与密码重置流程设防,阻挡机器人。公开上线后启用:
TURNSTILE_ENABLED=true
TURNSTILE_SITE_KEY=0x4AAA...
TURNSTILE_SECRET_KEY=0x4AAA...
Content-Security-Policy 头,组件将无法加载。请在 script-src 与 frame-src 中白名单 https://challenges.cloudflare.com。
计费与会员 #
后端内置一等公民的会员、积分与按次计费。先从保守默认值开始,再根据实际用量调整:
BILLING_ENABLED=true
BILLING_COST_AI_ANALYSIS=1
BILLING_COST_STRATEGY_GEN=3
BILLING_COST_BACKTEST=2
MEMBERSHIP_MONTHLY_PRICE_USD=29
MEMBERSHIP_MONTHLY_CREDITS=1500
MEMBERSHIP_YEARLY_PRICE_USD=299
MEMBERSHIP_YEARLY_CREDITS=21000
USDT 支付 #
USDT TRC20 流程为每位用户生成唯一充值地址并轮询 TronGrid 确认。网络确认后自动发放积分。
USDT_PAY_ENABLED=true
USDT_TRC20_XPUB=xpub6... # BIP-32 extended public key (TRC20 HD derivation)
TRONGRID_API_KEY=...
USDT_CONFIRMATIONS_REQUIRED=12
通知 #
每位用户可在应用内「个人资料 → 通知」配置 Telegram / Email / SMS / Discord / Webhook。系统级回退(管理员告警、定时摘要)在此配置:
# Email (SMTP)
SMTP_HOST=smtp.zoho.com
SMTP_PORT=465
SMTP_USER=alerts@yourdomain.com
SMTP_PASSWORD=...
SMTP_FROM=QuantDinger <alerts@yourdomain.com>
# Telegram (used for admin alerts; per-user bots are set in app)
TELEGRAM_BOT_TOKEN=...
TELEGRAM_ADMIN_CHAT_ID=...
# SMS (Twilio-compatible)
SMS_PROVIDER=twilio
TWILIO_ACCOUNT_SID=...
TWILIO_AUTH_TOKEN=...
TWILIO_FROM_NUMBER=+1555...
Worker 开关 #
后台 Worker 在后端容器内运行。禁用不需要的 Worker 可节省 CPU 并减少启动噪音:
ENABLE_PENDING_ORDER_WORKER=true # watches pending limit orders across exchanges
ENABLE_PORTFOLIO_MONITOR=true # P&L, risk, alert triggers
ENABLE_REFLECTION_WORKER=false # long-horizon AI self-review
ENABLE_BACKTEST_QUEUE=true # async backtest runner
策略开发 #
QuantDinger 支持两种互补的策略编写模式。选择与逻辑形态匹配的一种:
IndicatorStrategy
基于 DataFrame 的 Python:计算指标后输出四路执行列(open_long / close_long / open_short / close_short)并做边缘触发 — 平台默认形态,回测与实盘语义对齐。
ScriptStrategy
事件驱动 on_init / on_bar。推荐显式四路下单 — ctx.open_long、ctx.close_long、ctx.open_short、ctx.close_short — 配合对冲感知的 ctx.position。回测与实盘共用同一运行时。
IndicatorStrategy #
IndicatorStrategy 在 pandas df 上运行:计算指标、用 # @strategy 声明默认风控、
用 output 字典输出图表叠加。执行语义遵循
《信号与执行标准 v1》。
信号形态
| 形态 | 执行列 | 适用场景 |
|---|---|---|
| B · 四路(平台默认) | open_long、close_long、open_short、close_short |
新策略、多空分离、显式平仓/反手、回测与实盘队列一一对应 |
| A · 两路(兼容旧版) | buy、sell |
简单金叉/死叉;含义由 tradeDirection(long / short / both)决定。同一脚本勿混用 A、B 两套执行列。 |
通用要求:首行可变操作为 df = df.copy();执行列为 bool 且 fillna(False).astype(bool);建议边缘触发(见下);禁止 shift(-1) 及任何未来数据。
四路模板(双 EMA 交叉)
与 IDE 默认模板一致 — 金叉开多/平空,死叉开空/平多,止损止盈由 # @strategy 交给引擎:
# QuantDinger 默认模板 — 形态 B(四路信号)· 契约 v1
# signal_form: four_way exit_owner: engine flip_mode: R2
my_indicator_name = "双 EMA 交叉(四路)"
my_indicator_description = "双 EMA 金叉/死叉,显式开平四路 + 边缘触发。"
# @strategy stopLossPct 0.03
# @strategy takeProfitPct 0.06
# @strategy entryPct 0.25
# @strategy trailingEnabled false
# @strategy tradeDirection both
# @param fast_period int 10 快线 EMA 周期
# @param slow_period int 30 慢线 EMA 周期
def edge(s):
"""边缘触发:仅 false→true 的 K 线记为信号。"""
s = s.fillna(False).astype(bool)
return s & ~s.shift(1).fillna(False)
fast_period = int(params.get("fast_period", 10))
slow_period = int(params.get("slow_period", 30))
df = df.copy()
ema_fast = df["close"].ewm(span=fast_period, adjust=False).mean()
ema_slow = df["close"].ewm(span=slow_period, adjust=False).mean()
golden = (ema_fast > ema_slow) & (ema_fast.shift(1) <= ema_slow.shift(1))
death = (ema_fast < ema_slow) & (ema_fast.shift(1) >= ema_slow.shift(1))
# 反手 bar:先平对侧再开(R2)
raw_open_long = golden
raw_open_short = death
raw_close_long = death
raw_close_short = golden
df["open_long"] = edge(raw_open_long)
df["open_short"] = edge(raw_open_short)
df["close_long"] = edge(raw_close_long)
df["close_short"] = edge(raw_close_short)
n = len(df)
open_long_marks = [
df["low"].iloc[i] * 0.995 if bool(df["open_long"].iloc[i]) else None for i in range(n)
]
open_short_marks = [
df["high"].iloc[i] * 1.005 if bool(df["open_short"].iloc[i]) else None for i in range(n)
]
output = {
"name": my_indicator_name,
"plots": [
{"name": f"EMA{fast_period}", "data": ema_fast.fillna(0).tolist(),
"color": "#FF9800", "overlay": True},
{"name": f"EMA{slow_period}", "data": ema_slow.fillna(0).tolist(),
"color": "#3F51B5", "overlay": True},
],
"signals": [
{"type": "buy", "text": "L", "data": open_long_marks, "color": "#00E676"},
{"type": "sell", "text": "S", "data": open_short_marks, "color": "#FF5252"},
],
}
四路列含义
| 列 | 含义 |
|---|---|
open_long | 开多 / 加多 |
close_long | 平多(全平或按 reduce 配置减仓) |
open_short | 开空 / 加空 |
close_short | 平空 |
output["signals"] 仅用于图表标记 — 成交只认上述四列 bool。同一根 K 上反手时优先 close_* 再 open_*;避免同 bar 同时 open_long 与 open_short 为 true。默认止损、止盈、仓位与方向见 # @strategy 风控参数。
脚本输入
df— 含 OHLCV 与ts的 pandas DataFrame。params— 由# @param暴露的用户参数。
close_* — 不要在 tradeDirection both 下用 buy/sell 表达「仅平仓」。若需分批加减仓、部分止盈或强状态机逻辑,请改用 ScriptStrategy 的 ctx.open_* / ctx.close_* 显式 API。
风控参数(# @strategy) #
在 IndicatorStrategy 脚本顶部用 # @strategy <键> <值> 声明默认风控与仓位。
回测引擎与实盘执行器会读取这些默认值(可在指标 IDE 或已保存策略面板中覆盖)。
它们属于引擎托管的退出,与四路 close_* 信号列是不同层级。
# 单位:0–1 表示标的涨跌幅(非保证金盈亏;勿除以杠杆)
# @strategy stopLossPct 0.03 # 价格反向 3% 止损
# @strategy takeProfitPct 0.06 # 价格正向 6% 止盈
# @strategy entryPct 0.25 # 每次开仓用 25% 资金(1 = 100%)
# @strategy trailingEnabled false
# @strategy trailingStopPct 0.015 # 激活后从极值回撤 1.5% 触发移动止损
# @strategy trailingActivationPct 0.03 # 浮盈达 3% 后启用移动止损
# @strategy tradeDirection both # long | short | both
支持的键
| 键 | 类型 | 范围 | 含义 |
|---|---|---|---|
stopLossPct | float | 0–1 | 持仓后价格反向达到该比例则止损(0.001=0.1%,0.03=3%)。0 表示关闭。 |
takeProfitPct | float | 0–5 | 价格正向达到该比例则止盈。0 表示关闭。 |
entryPct | float | 0.01–1 | 单次开仓占用资金比例(1=100%,0.25=25%)。大于 1 的旧写法会自动归一化。 |
trailingEnabled | bool | true / false | 是否在达到激活阈值后由引擎启用移动止损。 |
trailingStopPct | float | 0–1 | 移动止损:从多头最高价或空头最低价回撤的价格比例。 |
trailingActivationPct | float | 0–1 | 浮盈达到该比例后才启动移动止损;未写时引擎可能复用 takeProfitPct。 |
tradeDirection | 枚举 | long · short · both | 允许的交易方向,过滤四路/两路信号;不能替代执行列本身。 |
退出由谁负责?
| 层级 | 机制 | 典型场景 |
|---|---|---|
| 指标信号 | 四路 close_*(边缘触发) | 趋势反转、逻辑驱动平仓、「只平不反手」 |
| 引擎风控 | # @strategy 止损 / 止盈 / 移动止损 | 每笔持仓的固定保护 bracket |
同一类风险事件只应有一个主负责人。若指标内已用 close_* 表达触及型止盈止损,
请保持 trailingEnabled false,除非你明确需要引擎移动止损叠加 — 否则易出现双重平仓,并放大回测与实盘的时间差。
不在 @strategy 里配置的项
- 杠杆 — 在指标 IDE 回测面板或实盘策略设置中指定(代码里写
@strategy leverage会被忽略)。 signal_mode/exit_signal_mode— 属于策略/trading 配置(推荐confirmed:只在上一根已收盘 K 上读信号,与回测对齐)。详见 《信号与执行标准》。
@strategy 中所有 *Pct 均指标的价格涨跌幅,不是保证金收益率。3 倍杠杆下仍用 stopLossPct 0.03 表示价格反向 3% — 脚本中勿除以杠杆。
ScriptStrategy #
ScriptStrategy 是事件驱动 Python:引擎按 K 线(或 bot 模式下的类 tick)逐根调用你的钩子。
回测与实盘共用 strategy_script_runtime.py 中的同一套上下文,持仓与成交语义一致。
适用于依赖运行时持仓状态的逻辑 — 分批加减仓、网格多空腿、只平不反手、冷却期等 — 而不是仅在 dataframe 上输出布尔列。
何时选用 ScriptStrategy
- 止损/止盈需读取当前入场价或腿仓位
- 分批进出,或同时持有多空腿(对冲 / 中性网格)
- 网格、DCA 等 bot 风格、由伪 tick 驱动的执行
生命周期
| 钩子 | 是否必需 | 说明 |
|---|---|---|
on_bar(ctx, bar) | 必需 | 无此函数编译不通过。传入最新收盘 K(或 bot 伪 bar)。 |
on_init(ctx) | 建议 | 初始化 ctx.param(...) 默认值并打日志。部分 UI 校验路径要求两个钩子都存在。 |
bar 提供 open、high、low、close、volume、timestamp。
下单意图(推荐:四路显式 API)
优先使用下列方法 — 与执行信号一一对应,在对冲/网格模式下避免「买单是平空还是加多」的歧义:
| 方法 | 含义 |
|---|---|
ctx.open_long(amount=, price=, reason=) | 开多 / 加多 |
ctx.close_long(amount=, price=, reason=) | 减多 / 平多(amount 为计价货币名义) |
ctx.open_short(amount=, price=, reason=) | 开空 / 加空 |
ctx.close_short(amount=, price=, reason=) | 减空 / 平空 |
ctx.close_position() | 按净敞口全部平仓(兼容旧写法) |
兼容旧 API:ctx.buy(...) / ctx.sell(...) 支持
intent=(如 open_long、close_short)与 reason=。
新代码请优先用四路显式方法 — 内置网格 bot 已采用此写法。
上下文 API
| 成员 | 说明 |
|---|---|
ctx.param(name, default) | 脚本级可调参数(网格上下轨、均线周期等),跨 bar 保存在 ctx._params。 |
ctx.bars(n) | 含当前 bar 在内的最近 n 根 K 线(最旧在前)。 |
ctx.balance / ctx.equity | 计价余额与按市价计的权益。 |
ctx.position | 对冲感知:long_size、short_size、long_entry、short_entry,及 has_long()、has_short()、is_flat()。 |
int(ctx.position) | 净方向视图:>0 净多、<0 净空、0 空仓 — 旧脚本仍可用。 |
ctx.log(msg) | 写入策略日志。 |
示例 — 双 EMA 交叉(四路显式意图)
def on_init(ctx):
ctx.param("fast_len", 10)
ctx.param("slow_len", 30)
ctx.param("order_usdt", 100.0)
ctx.log("EMA 脚本已初始化")
def on_bar(ctx, bar):
fast_len = int(ctx.param("fast_len", 10))
slow_len = int(ctx.param("slow_len", 30))
order_usdt = float(ctx.param("order_usdt", 100.0))
price = float(bar.close or 0)
if price <= 0:
return
bars = ctx.bars(slow_len + 2)
if len(bars) < slow_len:
return
closes = [b.close for b in bars]
fast_ma = sum(closes[-fast_len:]) / fast_len
slow_ma = sum(closes[-slow_len:]) / slow_len
if fast_ma > slow_ma:
if ctx.position.has_short():
ctx.close_short(amount=order_usdt, price=price, reason="flip_close_short")
if not ctx.position.has_long():
ctx.open_long(amount=order_usdt, price=price, reason="golden_cross")
elif fast_ma < slow_ma:
if ctx.position.has_long():
ctx.close_long(amount=order_usdt, price=price, reason="flip_close_long")
if not ctx.position.has_short():
ctx.open_short(amount=order_usdt, price=price, reason="death_cross")
网格 bot 模式(多空腿独立)
标准网格脚本分别读取 ctx.position.long_size / short_size 并发出显式意图 — 见仓库 bot_scripts/grid_template.py:
# 向下穿格:先平空,再用剩余名义开多
if short_size > 0:
ctx.close_short(amount=use_usdt, price=price, reason="grid_buy_cover")
ctx.open_long(amount=leftover_usdt, price=price, reason="grid_buy_open")
else:
ctx.open_long(amount=amt, price=price, reason="grid_buy_open")
运行模式与仓位
- 标准 bar 收盘 — 每根确认收盘后调用
on_bar(默认回测/实盘脚本路径)。 - Bot 模式 — 网格/DCA 使用伪 tick bar;请与 bar 收盘策略分开测试。
- 仓位 — ctx 方法的
amount是下单意图;保存为策略后的回测仍会通过entryPct等 trading 配置归一化(见 风控参数)。上线前务必用「保存后的策略回测」核对实际敞口。 - 引擎 SL/TP — 策略面板 /
# @strategy的服务端 bracket 可与脚本意图并存;同一风险事件勿重复定义。
声明参数 #
两种策略类型使用相同注释语法以便 UI 渲染表单。可调参数用 # @param;引擎风控默认值见 风控参数。
# 引擎风控默认值(IndicatorStrategy)— 见「风控参数」
# @strategy stopLossPct 0.03
# @strategy takeProfitPct 0.06
# @strategy entryPct 0.25
# @strategy tradeDirection both
# @param sma_short int 14 短期均线
# @param sma_long int 28 长期均线
# @param use_filter bool true 启用趋势过滤
# @param symbol string BTCUSDT 交易标的
支持的类型:int、float、bool、string。最后一个字段为人类可读标签。
回测 #
每次回测固定绑定:
- 脚本的确切代码哈希,
- 冻结的参数快照,
- 所选手续费与滑点模型,
- 行情数据区间。
输出持久化到 PostgreSQL,含逐笔 P&L、权益曲线、最大回撤、Sharpe、胜率与暴露时间。相同快照重跑可确定性复现结果。
指标回测按
《信号与执行标准》
消费边缘触发的四路列(或兼容旧版 buy/sell)。
已保存策略建议使用 signal_mode / exit_signal_mode 为 confirmed,使开平仓均读取上一根已收盘 K — 与回测时序一致。
若需回测成交与实盘执行语义对齐,启用 strictMode(UI 开关或 Agent API 字段)— 参见 策略开发指南。
MCP 概览 #
QuantDinger 在 /api/agent/v1 提供 Agent Gateway,并在 PyPI 发布 MCP 服务器:
- 包名:
quantdinger-mcp· 当前版本 0.2.0 - 26 个范围化工具 — 读取、工作区、指标、回测(
strictMode)、SSE 任务等 - 传输:
stdio(Cursor / Claude Code)、sse、streamable-http
uvx quantdinger-mcp
# set QUANTDINGER_BASE_URL=https://ai.quantdinger.com (hosted, paper-only)
# or http://localhost:8888 (self-host)
深入阅读:MCP_SETUP.md · AGENT_QUICKSTART.md · OpenAPI:agent-openapi.json
智能体快速入门 #
- 以管理员登录 → 签发带范围(
R读取、B回测等)的 Agent 令牌。 - 冒烟测试:
GET /api/agent/v1/whoami,请求头Authorization: Bearer <token>。 - 运行回测任务(可选
"strictMode": true);轮询/api/agent/v1/jobs/<id>或订阅 SSE。 - 将相同 base URL 配置到
quantdinger-mcp,供 Cursor / Claude Code / Codex 使用。
托管 SaaS(ai.quantdinger.com)固定为仅模拟执行;自托管通过 AGENT_LIVE_TRADING_ENABLED 控制实盘。
交易机器人 #
四种内置机器人类型覆盖大多数机械交易工作流。每种均为带引导 UI 的一等公民 ScriptStrategy 模板。
网格 #
经典区间交易者,围绕锚定价格铺设买卖订单阶梯。适合横盘、均值回归品种。
| 参数 | 含义 |
|---|---|
| grid_pct | 网格层级间价格步长,占锚定价格的比例。 |
| grid_levels | 每侧层级数量。 |
| order_pct | 每层订单大小,占余额的比例。 |
| max_position_value_pct | 总部署资金上限。 |
| take_profit_pct | P&L 越过该阈值时平掉整组仓位。 |
马丁格尔 #
逆势加仓的摊平系统。市场均值回归时收益最高,趋势突破时风险最大。
max_daily_loss 与 max_position_value。马丁格尔在单次长期趋势中可能清空账户。
趋势 #
突破与均线交叉机器人。顺势入场、跟随动量,并用移动止损锁定利润。适合趋势市场。
定投(DCA) #
定投机器人,按日程买入固定名义金额 — 每日、每周或跌破阈值时加仓。适合现货市场长期积累。
加密货币交易所 #
| 交易所 | 覆盖范围 |
|---|---|
| Binance | 现货、合约、杠杆 |
| OKX | 现货、永续、期权 |
| Bitget | 现货、合约、跟单 |
| Bybit | 现货、线性合约 |
| Coinbase | 现货 |
| Kraken | 现货、合约 |
| KuCoin | 现货、合约 |
| Gate.io | 现货、合约 |
| Deepcoin | 衍生品集成 |
| HTX | 现货、USDT 本位永续 |
在个人资料 → API 密钥中添加凭证。密钥静态加密,仅在执行路径解密。
通过 IBKR 交易美股 #
Interactive Brokers 通过标准 TWS / IB Gateway 桥接。研究场景若无需 IBKR 实时订阅,可使用 Yahoo Finance 与 Finnhub 数据。
IBKR_HOST=127.0.0.1
IBKR_PORT=7497 # TWS paper: 7497, live: 7496. Gateway paper: 4002, live: 4001.
IBKR_CLIENT_ID=17
FINNHUB_API_KEY=... # optional, richer fundamentals
通过 MT5 交易外汇 #
MT5 集成通过 Python MetaTrader 5 桥接,支持数据与执行。OANDA 作为只读数据源受支持。
移动 Web(H5) #
移动客户端是独立的 Vue 3 + Vant 应用,与桌面端对接同一后端 API。构建可部署的 H5 包:
cd quantdinger_mobile
npm install # first time only
npm run build # outputs to ./dist
使用任意静态 Web 服务器托管 dist/。生产环境 Nginx 配置见下文移动端 Nginx 配置。
Android APK 构建 #
移动应用使用 Capacitor 封装。生成调试 APK:
1. 安装 Android Studio
安装 Android Studio 稳定版。它捆绑所需的 JDK(jbr/)与 Android SDK。
2. 设置环境变量
$env:JAVA_HOME = "C:\Program Files\Android\Android Studio\jbr"
$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
$env:Path = "$env:JAVA_HOME\bin;$env:ANDROID_HOME\platform-tools;$env:Path"
3. 构建 Web 包并同步
npm run build
npx cap sync android
4. 配置 Gradle SDK 路径
创建 android/local.properties:
sdk.dir=C\:\\Users\\YourName\\AppData\\Local\\Android\\Sdk
5. 运行 Gradle 构建
cd android
./gradlew assembleDebug # Linux/macOS
.\gradlew.bat assembleDebug # Windows
APK 输出路径:android/app/build/outputs/apk/debug/app-debug.apk。
android/gradle/wrapper/gradle-wrapper.properties 中更换 Gradle 镜像 — 例如 https://mirrors.cloud.tencent.com/gradle/gradle-8.2.1-all.zip。在 services.gradle.org 较慢的地区这是最常见修复。
发布 APK
生成 keystore,在 android/app/build.gradle 中添加 signingConfigs 块,然后运行 ./gradlew assembleRelease。输出:android/app/build/outputs/apk/release/app-release.apk。
移动端 Nginx 配置 #
在 m.quantdinger.com 托管 H5 包的参考 Nginx 配置,含 SPA history 模式回退与后端反代:
server {
listen 80;
server_name m.quantdinger.com;
location ^~ /.well-known/acme-challenge { allow all; root /usr/share/nginx/html; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
server_name m.quantdinger.com;
ssl_certificate /www/sites/m.quantdinger.com/ssl/fullchain.pem;
ssl_certificate_key /www/sites/m.quantdinger.com/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000" always;
root /www/sites/m.quantdinger.com/index;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:5000/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
location ~* \.(?:js|css|woff2?|ttf|eot|svg|png|jpg|jpeg|gif|ico|webp|map)$ {
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
access_log off;
}
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
expires off;
}
# SPA history-mode fallback — required for routes like /login, /trading, etc.
location / {
try_files $uri $uri/ /index.html;
}
}
生产环境检查清单 #
- 用 64 字节随机十六进制重新生成
SECRET_KEY。 - 修改默认的
ADMIN_USER/ADMIN_PASSWORD。 - 将后端绑定到
127.0.0.1,在主机 Nginx 终止 TLS。 - 在公开登录/注册/重置端点启用 Turnstile。
- 将
DATABASE_URL指向带自动备份的托管 PostgreSQL — 或每日快照 Docker 卷。 - 在
OAUTH_ALLOWED_REDIRECTS中白名单移动与桌面源。 - 关闭不需要的 Worker(reflection、portfolio monitor)。
- 每季度轮换交易所 API 密钥;尽可能创建只读密钥。
推荐拓扑 #
生产部署应仅在主机暴露 80 与 443 端口。将 Docker 服务绑定到 localhost,由主机 Nginx(或 1Panel / OpenResty)终止 TLS。
| 层级 | 绑定地址 | 角色 |
|---|---|---|
| 主机 Nginx | 0.0.0.0:443 | TLS、client_max_body_size、速率限制 |
frontend 容器 | 127.0.0.1:8888 | Vue SPA + 内置 /api/* 反代 |
backend 容器 | 127.0.0.1:5000 | Flask API(无需暴露公网) |
postgres | 127.0.0.1:5432 | 数据库(切勿公开暴露) |
同域(推荐):将全部流量 — /、/assets/* 与 /api/* — 反代到前端容器。前端镜像已在 Compose 网络内将 /api/* 转发到 backend:5000。
Browser
→ https://app.example.com
→ Host Nginx :443
→ 127.0.0.1:8888 (frontend container)
└─ /api/* → backend:5000 (inside Docker network)
双域(进阶):UI 在 app.example.com → :8888,API 在 api.example.com → :5000。须配置 CORS 与前端 API 基址 — 仅在使用自定义前端构建时采用。
完整部署指南(中文 / 英文):CLOUD_DEPLOYMENT_CN.md · CLOUD_DEPLOYMENT_EN.md
主机 Nginx / 1Panel #
桌面应用(如 ai.example.com)应将整站反代到前端容器。不要从主机目录提供静态文件 — UI 在 GHCR 镜像内。
/assets/*.js 返回 404,可能是面板指向了本地静态根目录而非反代到 127.0.0.1:8888。移除主机侧静态根,将 /与/assets/* 反代到前端容器。
server {
listen 443 ssl http2;
server_name ai.example.com;
ssl_certificate /etc/letsencrypt/live/ai.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ai.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 20m;
# Same-domain: one upstream — frontend handles /api internally
location / {
proxy_pass http://127.0.0.1:8888;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
}
若必须将 API 拆到后端端口(双域部署),为 api.example.com → 127.0.0.1:5000 添加独立 server 块并相应配置前端构建 — 默认 GHCR 镜像不需要。
SSL / HTTPS #
使用 certbot 或托管面板内置 ACME 申请 Let's Encrypt。仅保留 TLSv1.2 与 TLSv1.3 — 旧版本(TLSv1、TLSv1.1)会被现代浏览器拒绝并显示 ERR_SSL_PROTOCOL_ERROR。
OAuth 允许的重定向 #
OAuth 完成后,后端签发短期 oauth_token 并重定向用户到前端源。要使重定向成功:
- 前端源必须在
OAUTH_ALLOWED_REDIRECTS中列出。 - 前端路由必须存在 — 对于 history 模式 SPA,确保
/login可访问且非 404(参见SPA 回退规则)。 - 若桌面客户端使用 hash 模式路由,后端会自动保留 hash(
/#/user/login)。
故障排查 #
GHCR 镜像拉取失败或极慢
- 在项目根
.env中设置IMAGE_PREFIX作为 postgres/redis 镜像前缀,例如docker.m.daocloud.io/library/。 - 固定已知可用标签:
IMAGE_TAG=3.0.20。 - GHCR 路径在
up -d前先运行docker compose -f docker-compose.ghcr.yml pull。
backend.env 存在但后端忽略配置
主机文件缺失时 Docker 会在挂载路径创建目录。删除该目录,从 env.example 重建普通文件 backend.env,然后重启:
docker compose -f docker-compose.ghcr.yml down
rm -rf backend.env # if it became a directory
curl -o backend.env https://raw.githubusercontent.com/brokermr810/QuantDinger/main/backend_api_python/env.example
docker compose -f docker-compose.ghcr.yml up -d
首页可加载但 /assets/*.js 404(1Panel / Nginx)
面板正在从主机静态根目录提供文件,而非反代到 127.0.0.1:8888。请移除本地静态根目录,将整站反代到前端容器(参见主机 Nginx / 1Panel)。
后端拒绝启动:"SECRET_KEY is unsafe"
重新生成密钥并重启:
python -c "import secrets; print(secrets.token_hex(32))"
# GHCR path → backend.env | clone path → backend_api_python/.env
docker compose restart backend
Google / GitHub OAuth 重定向到错误域名
- 将精确源(非默认端口时含 scheme 与 port)加入
OAUTH_ALLOWED_REDIRECTS。 - 修改 env 后重建或重启后端:
docker compose up -d --build backend(克隆)或docker compose restart backend(GHCR)。 - 清除 OAuth 提供商 Cookie 后重试。
OAuth 后移动 H5 在 /login 显示 404
Nginx 配置缺少 SPA 回退。在 location / 内添加 try_files $uri $uri/ /index.html;(移动 H5 仍从主机静态文件提供 — 与 GHCR 桌面前端不同)。
Turnstile 组件加载失败(code 600010)
- 检查响应头中的
Content-Security-Policy。 - 在
script-src与frame-src中白名单https://challenges.cloudflare.com,或调试期间完全移除 CSP 头。 - 确认 Cloudflare 控制台中 Site Key 的主机名管理包含您服务的域名。
Gradle wrapper 下载超时
编辑 android/gradle/wrapper/gradle-wrapper.properties,将 distributionUrl 换为就近镜像:
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.2.1-all.zip
networkTimeout=60000
浏览器出现 ERR_SSL_PROTOCOL_ERROR
- 将
ssl_protocols限制为仅TLSv1.2 TLSv1.3— 移除TLSv1与TLSv1.1。 - 确认 Nginx 配置路径下证书文件存在。
- 重载 Nginx(
nginx -t && nginx -s reload)。
常见问题 #
QuantDinger 真的是自托管吗?
是的。默认部署模型是您自己的 Docker Compose 栈,含自有数据库、Redis 实例、凭证与环境配置。
只能做加密货币交易吗?
不是。加密货币是重点,但平台也包含 IBKR 美股工作流与 MT5 外汇工作流。
可以直接用 Python 写策略吗?
可以 — 两种模型均为原生 Python。IndicatorStrategy 输出边缘触发的四路执行列(平台默认);
ScriptStrategy 通过 on_bar(ctx, bar) 使用显式 ctx.open_* / ctx.close_* 意图。
也可用 AI 生成起点后自行编辑。详见 策略开发。
这是研究工具还是实盘平台?
两者皆是。QuantDinger 旨在将 AI 研究、图表、策略开发、回测、快捷交易与实盘运维连接于同一系统。
可以商用 QuantDinger 吗?
后端为 Apache 2.0。前端有独立的源码可用许可证 — 支持商用但请先阅读仓库中的许可证文件。
许可证 #
- 后端:Apache License 2.0(见
LICENSE)。 - 前端 UI 在此以预构建文件分发。Vue 源码位于 QuantDinger-Vue,遵循QuantDinger Frontend Source-Available License v1.0。
- 前端非商业及符合资格的非营利使用免费;商用需单独商业许可证 — 请在产品首页申请。
- 商标、品牌、署名与水印使用受
TRADEMARKS.md约束。
社区与支持 #
- GitHub: brokermr810/QuantDinger
- Telegram: @quantdinger
- Discord:加入服务器
- YouTube: @quantdinger
- Email: support@quantdinger.com
发现 Bug 或有功能建议?在 GitHub 提交 Issue — 我们每周处理。
QuantDinger