QuantDinger QuantDinger 文档
首页 GitHub 打开应用
QuantDinger v3.0.20

QuantDinger 文档

自托管 AI 交易平台,面向量化研究、Python 策略开发、回测与实盘执行。一套技术栈覆盖 AI 分析、图表、策略代码、回测、快捷交易与实盘运维——基础设施完全由您掌控。

GHCR 预构建镜像

从 GHCR 拉取 quantdinger-backendquantdinger-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 策略开发 — 四路 IndicatorStrategyopen_long / close_long / open_short / close_short)配合 # @strategy 风控默认值,或事件驱动 ScriptStrategy 的显式 ctx.open_* / ctx.close_* 意图。AI 可生成起点代码,最终由您掌控。
  • 确定性回测 — 手续费与滑点建模、逐笔交易分析、权益曲线。可选 strict_mode 使成交与实盘执行语义对齐。
  • AI 智能体(MCP) — PyPI 上的 quantdinger-mcp 0.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 预构建镜像,无需克隆仓库。

bash
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 密钥,然后重启后端。

bash
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
powershell
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 — 暴露到公网前务必修改
上线前
重新生成 SECRET_KEY,修改 ADMIN_PASSWORD,将服务绑定到 127.0.0.1,并在主机 Nginx 终止 TLS(参见推荐拓扑)。

GHCR 安装(推荐) #

使用 docker-compose.ghcr.yml,您只需:

  • docker-compose.ghcr.yml
  • backend.env — 运行时密钥与功能开关(挂载为 /app/.env
  • 可选的项目根目录 .env — 端口、IMAGE_TAG、镜像加速前缀

重要:backend.env 必须是普通文件。若 Docker 在该路径创建了空目录,后端将无法读取配置。

生产环境端口绑定

ini
# 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
bash
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/,然后:

bash
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

常用命令 #

bash
docker compose ps
docker compose logs -f backend
docker compose restart backend
docker compose up -d --build
docker compose exec backend bash
更快重建
若仅修改了后端环境(backend.envbackend_api_python/.env),运行 docker compose restart backend 即可 — 无需重建。

Compose .env 参数 #

项目根目录 .env 控制 Docker Compose 变量替换 — 端口、镜像标签、镜像加速前缀。它与后端运行时配置相互独立

文件使用者内容
backend.envGHCR 路径SECRET_KEY、API 密钥、OAuth、计费、Worker
backend_api_python/.env克隆路径相同的运行时键,挂载进后端容器
.env(项目根目录)docker composeIMAGE_TAGFRONTEND_PORTBACKEND_URLIMAGE_PREFIX
ini
# 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_KEYADMIN_USERADMIN_PASSWORD
数据库DATABASE_URL
LLM / AILLM_PROVIDEROPENAI_API_KEYOPENROUTER_API_KEY
OAuthGOOGLE_CLIENT_IDGITHUB_CLIENT_ID
安全TURNSTILE_SITE_KEYENABLE_REGISTRATION
计费BILLING_ENABLEDBILLING_COST_AI_ANALYSIS
会员MEMBERSHIP_MONTHLY_PRICE_USDMEMBERSHIP_MONTHLY_CREDITS
USDT 支付USDT_PAY_ENABLEDUSDT_TRC20_XPUBTRONGRID_API_KEY
代理PROXY_URL
WorkerENABLE_PENDING_ORDER_WORKERENABLE_PORTFOLIO_MONITORENABLE_REFLECTION_WORKER
AI 调优ENABLE_AI_ENSEMBLEENABLE_CONFIDENCE_CALIBRATIONAI_ENSEMBLE_MODELS

身份认证 #

SECRET_KEY 用于签署所有 JWT 令牌。它必须是密码学安全的 64 位十六进制字符串 — 后端在检测到默认占位符时会拒绝启动。

env
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
轮换 SECRET_KEY
轮换密钥会立即使所有用户令牌失效,已登录用户将被强制重新登录。请在上线前完成,而非运行期间。

数据库 #

DATABASE_URL 指向 PostgreSQL 16。默认值针对 Docker Compose 栈内的 postgres 服务:

env
DATABASE_URL=postgresql://quantdinger:quantdinger@postgres:5432/quantdinger

启动时自动从 backend_api_python/migrations/init.sql 运行迁移。若使用托管数据库(Supabase、Neon、AWS RDS 等),请替换 URL 并确保允许来自主机的入站连接。

AI 提供商 #

QuantDinger 内置多家 LLM 提供商适配器。按预算与合规要求任选子集即可。

提供商密钥典型用途
OpenRouterOPENROUTER_API_KEY聚合器 — 首选
OpenAIOPENAI_API_KEYGPT-4o / GPT-5 系列
AnthropicCLAUDE_API_KEYClaude 3.x / 4.x
GoogleGEMINI_API_KEYGemini 1.5 / 2.0
DeepSeekDEEPSEEK_API_KEY高性价比推理
xAIGROK_API_KEYGrok 系列

集成与校准

若团队需要更稳健的 AI 输出,可开启集成投票与置信度校准:

env
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 使登录体验更现代并减少密码摩擦。在各提供商注册应用后设置:

env
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
回调 URL
在 Google / GitHub 注册的回调 URL 始终是后端的 /api/auth/oauth/<provider>/callback不是前端 URL。后端随后重定向到 OAUTH_ALLOWED_REDIRECTS 中列出的前端源。

若移动应用部署在不同源,测试前请将该源加入 OAUTH_ALLOWED_REDIRECTS — 否则后端会将用户重定向到回退 FRONTEND_URL

Cloudflare Turnstile #

Turnstile 为登录、注册与密码重置流程设防,阻挡机器人。公开上线后启用:

env
TURNSTILE_ENABLED=true
TURNSTILE_SITE_KEY=0x4AAA...
TURNSTILE_SECRET_KEY=0x4AAA...
CSP 须允许 challenges.cloudflare.com
若通过 Nginx 或 Cloudflare 添加了 Content-Security-Policy 头,组件将无法加载。请在 script-srcframe-src 中白名单 https://challenges.cloudflare.com

计费与会员 #

后端内置一等公民的会员、积分与按次计费。先从保守默认值开始,再根据实际用量调整:

env
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 确认。网络确认后自动发放积分。

env
USDT_PAY_ENABLED=true
USDT_TRC20_XPUB=xpub6...    # BIP-32 extended public key (TRC20 HD derivation)
TRONGRID_API_KEY=...
USDT_CONFIRMATIONS_REQUIRED=12
热钱包安全
xpub 仅生成收款地址 — 永不包含对应私钥。将匹配的冷钱包保存在离线机器上,并定期归集余额。

通知 #

每位用户可在应用内「个人资料 → 通知」配置 Telegram / Email / SMS / Discord / Webhook。系统级回退(管理员告警、定时摘要)在此配置:

env
# 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 并减少启动噪音:

env
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_longctx.close_longctx.open_shortctx.close_short — 配合对冲感知的 ctx.position。回测与实盘共用同一运行时。

IndicatorStrategy #

IndicatorStrategy 在 pandas df 上运行:计算指标、用 # @strategy 声明默认风控、 用 output 字典输出图表叠加。执行语义遵循 《信号与执行标准 v1》

信号形态

形态执行列适用场景
B · 四路(平台默认) open_longclose_longopen_shortclose_short 新策略、多空分离、显式平仓/反手、回测与实盘队列一一对应
A · 两路(兼容旧版) buysell 简单金叉/死叉;含义由 tradeDirectionlong / short / both)决定。同一脚本勿混用 A、B 两套执行列。

通用要求:首行可变操作为 df = df.copy();执行列为 bool 且 fillna(False).astype(bool);建议边缘触发(见下);禁止 shift(-1) 及任何未来数据。

四路模板(双 EMA 交叉)

与 IDE 默认模板一致 — 金叉开多/平空,死叉开空/平多,止损止盈由 # @strategy 交给引擎:

python
# 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_longopen_short 为 true。默认止损、止盈、仓位与方向见 # @strategy 风控参数

脚本输入

  • df — 含 OHLCV 与 ts 的 pandas DataFrame。
  • params — 由 # @param 暴露的用户参数。
只想平仓、不想反手?
请用四路 close_* — 不要在 tradeDirection both 下用 buy/sell 表达「仅平仓」。若需分批加减仓、部分止盈或强状态机逻辑,请改用 ScriptStrategyctx.open_* / ctx.close_* 显式 API。

风控参数(# @strategy#

在 IndicatorStrategy 脚本顶部用 # @strategy <键> <值> 声明默认风控与仓位。 回测引擎与实盘执行器会读取这些默认值(可在指标 IDE 或已保存策略面板中覆盖)。 它们属于引擎托管的退出,与四路 close_* 信号列是不同层级。

python
# 单位: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

支持的键

类型范围含义
stopLossPctfloat0–1持仓后价格反向达到该比例则止损(0.001=0.1%,0.03=3%)。0 表示关闭。
takeProfitPctfloat0–5价格正向达到该比例则止盈。0 表示关闭。
entryPctfloat0.01–1单次开仓占用资金比例(1=100%,0.25=25%)。大于 1 的旧写法会自动归一化。
trailingEnabledbooltrue / false是否在达到激活阈值后由引擎启用移动止损。
trailingStopPctfloat0–1移动止损:从多头最高价或空头最低价回撤的价格比例。
trailingActivationPctfloat0–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 提供 openhighlowclosevolumetimestamp

下单意图(推荐:四路显式 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_longclose_short)与 reason=。 新代码请优先用四路显式方法 — 内置网格 bot 已采用此写法。

上下文 API

成员说明
ctx.param(name, default)脚本级可调参数(网格上下轨、均线周期等),跨 bar 保存在 ctx._params
ctx.bars(n)含当前 bar 在内的最近 n 根 K 线(最旧在前)。
ctx.balance / ctx.equity计价余额与按市价计的权益。
ctx.position对冲感知:long_sizeshort_sizelong_entryshort_entry,及 has_long()has_short()is_flat()
int(ctx.position)净方向视图:>0 净多、<0 净空、0 空仓 — 旧脚本仍可用。
ctx.log(msg)写入策略日志。

示例 — 双 EMA 交叉(四路显式意图)

python
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

python
# 向下穿格:先平空,再用剩余名义开多
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 可与脚本意图并存;同一风险事件勿重复定义。
延伸阅读
完整 ScriptStrategy 说明: STRATEGY_DEV_GUIDE_CN.md §6

声明参数 #

两种策略类型使用相同注释语法以便 UI 渲染表单。可调参数用 # @param;引擎风控默认值见 风控参数

python
# 引擎风控默认值(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 交易标的

支持的类型:intfloatboolstring。最后一个字段为人类可读标签。

回测 #

每次回测固定绑定:

  • 脚本的确切代码哈希,
  • 冻结的参数快照,
  • 所选手续费与滑点模型,
  • 行情数据区间。

输出持久化到 PostgreSQL,含逐笔 P&L、权益曲线、最大回撤、Sharpe、胜率与暴露时间。相同快照重跑可确定性复现结果。

指标回测按 《信号与执行标准》 消费边缘触发的四路列(或兼容旧版 buy/sell)。 已保存策略建议使用 signal_mode / exit_signal_modeconfirmed,使开平仓均读取上一根已收盘 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)、ssestreamable-http
bash
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

智能体快速入门 #

  1. 以管理员登录 → 签发带范围(R 读取、B 回测等)的 Agent 令牌。
  2. 冒烟测试:GET /api/agent/v1/whoami,请求头 Authorization: Bearer <token>
  3. 运行回测任务(可选 "strictMode": true);轮询 /api/agent/v1/jobs/<id> 或订阅 SSE。
  4. 将相同 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_pctP&L 越过该阈值时平掉整组仓位。

马丁格尔 #

逆势加仓的摊平系统。市场均值回归时收益最高,趋势突破时风险最大。

务必设置严格风控
务必配置 max_daily_lossmax_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 数据。

env
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 包:

bash
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. 设置环境变量

powershell
$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 包并同步

bash
npm run build
npx cap sync android

4. 配置 Gradle SDK 路径

创建 android/local.properties

ini
sdk.dir=C\:\\Users\\YourName\\AppData\\Local\\Android\\Sdk

5. 运行 Gradle 构建

bash
cd android
./gradlew assembleDebug     # Linux/macOS
.\gradlew.bat assembleDebug # Windows

APK 输出路径:android/app/build/outputs/apk/debug/app-debug.apk

Gradle 下载超时?
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 模式回退与后端反代:

nginx
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 密钥;尽可能创建只读密钥。

推荐拓扑 #

生产部署应仅在主机暴露 80443 端口。将 Docker 服务绑定到 localhost,由主机 Nginx(或 1Panel / OpenResty)终止 TLS。

层级绑定地址角色
主机 Nginx0.0.0.0:443TLS、client_max_body_size、速率限制
frontend 容器127.0.0.1:8888Vue SPA + 内置 /api/* 反代
backend 容器127.0.0.1:5000Flask API(无需暴露公网)
postgres127.0.0.1:5432数据库(切勿公开暴露)

同域(推荐):全部流量 — //assets/*/api/* — 反代到前端容器。前端镜像已在 Compose 网络内将 /api/* 转发到 backend:5000

text
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 镜像内。

1Panel / OpenResty 常见坑
若首页可加载但外部访问 /assets/*.js 返回 404,可能是面板指向了本地静态根目录而非反代到 127.0.0.1:8888。移除主机侧静态根,将 //assets/* 反代到前端容器。
nginx
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.2TLSv1.3 — 旧版本(TLSv1TLSv1.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,然后重启:

bash
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"

重新生成密钥并重启:

bash
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-srcframe-src 中白名单 https://challenges.cloudflare.com,或调试期间完全移除 CSP 头。
  • 确认 Cloudflare 控制台中 Site Key 的主机名管理包含您服务的域名。

Gradle wrapper 下载超时

编辑 android/gradle/wrapper/gradle-wrapper.properties,将 distributionUrl 换为就近镜像:

properties
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 — 移除 TLSv1TLSv1.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 约束。

社区与支持 #

发现 Bug 或有功能建议?在 GitHub 提交 Issue — 我们每周处理。