Open-source AI Trading OS, agent trading, and vibe trading, with Jev System One integration. Research, build Python strategies, backtest, and paper/live trade across crypto, stocks, and forex. Launch your own multi-tenant trading SaaS with built-in user management, billing, payments, and settlement.
See the code
Open-source AI Trading OS
Turn trading ideas into Python strategies, backtests, paper trading, live execution, and monitoring — all in one self-hosted stack.
QuantDinger is a product of Open Byte Inc.
AI research → Strategy code → Backtest → Paper/Live execution → Monitoring
English · 简体中文 · API · AI Agents & MCP
Live App · Website · Video Demo · Official Support Email
SUPPORTED BY
Want to contribute? Explore the public roadmap or claim a scoped task from Ready for contributors.
QuantDinger can submit real orders when live trading is explicitly enabled. Start with paper trading, use restricted API keys, and review the risk and compliance requirements for your jurisdiction. This project does not provide investment advice.
QuantDinger is an open-source AI Trading OS for independent traders, Python strategy authors, and small teams. Its local-first, self-hosted design keeps market data, strategy code, broker credentials, and deployment under the operator's control.
The project combines:
It is not a black-box signal service. Strategy code, risk settings, credentials, and deployment remain under the operator's control.
The v5 backend is organized around explicit runtime and operational boundaries:
The source version is declared in VERSION. Git release tags use the
same semantic version with a leading v, for example v5.0.1.
The editable source is architecture-v5.svg; the Mermaid topology below is the detailed runtime source of truth.
The static diagram above is the product-level view. The runtime topology below is the current source of truth for container ownership and event/data flow.
flowchart TB
C["Web / Mobile / API / MCP clients"]
FE["Nginx frontend services"]
API["Flask + Gunicorn API"]
PG[("PostgreSQL")]
CACHE[("Redis cache")]
JOBS[("Redis jobs")]
KAFKA[("Kafka event backbone")]
TW["Trading workers\ncontrol, realtime, execution, grid actors"]
DISPATCH["Strategy dispatcher workers"]
EVAL["Strategy evaluator workers\nhot bar runtimes"]
AUDIT["Kafka audit worker"]
SW["Scheduler worker"]
CW["Celery worker"]
BEAT["Celery beat"]
PROM["Prometheus"]
GRAF["Grafana"]
ALERT["Alertmanager"]
C --> FE --> API
API --> PG
API --> CACHE
API -->|"durable commands"| PG
TW -->|"leases, order intents, fills, grid actor state"| PG
TW -->|"closed bars and lifecycle events"| KAFKA
KAFKA --> DISPATCH --> KAFKA
KAFKA --> EVAL
EVAL -->|"inbox, leases, checkpoints, order intents"| PG
KAFKA --> AUDIT --> PG
PG -->|"owned pending orders"| TW
SW -->|"schedules, monitoring, heartbeats"| PG
API -->|"finite async jobs"| JOBS
BEAT --> JOBS --> CW
CW --> PG
API -. metrics .-> PROM
PG -. exporter .-> PROM
CACHE -. exporter .-> PROM
JOBS -. exporter .-> PROM
PROM --> GRAF
PROM --> ALERT
One backend image is reused by several containers with different commands:
| Process | Responsibility |
|---|---|
migration | Applies the database schema and exits before application services start. |
kafka-init | Creates the versioned runtime topics and exits before event consumers start. |
backend | Handles HTTP, authentication, validation, and durable command submission. |
trading-worker | Owns control/realtime runtimes, exchange sessions, the fenced order gateway, reconciliation, and durable grid actors. |
strategy-dispatcher-worker | Converts closed-bar events into stable strategy-shard evaluation batches. |
strategy-evaluator-worker | Owns hot distributed bar runtimes and evaluates fenced strategy inbox events. |
kafka-audit-worker | Validates and records the versioned event stream independently of execution. |
scheduler-worker | Runs portfolio, deployment, payment, and signal schedules. |
celery-worker | Executes finite AI, backtest, experiment, report, and maintenance jobs. |
celery-beat | Dispatches periodic Celery tasks. |
See Backend process roles, architecture, and concurrency model for the ownership rules. Use the distributed runtime deployment and scaling guide before changing replica counts or moving the stack to multiple hosts.
Prerequisites: Docker with Compose v2. Node.js and a local Python environment are not required.
Linux or macOS:
curl -fsSL https://raw.githubusercontent.com/OpenByteInc/QuantDinger/main/install.sh | bash
Windows PowerShell:
irm https://raw.githubusercontent.com/OpenByteInc/QuantDinger/main/install.ps1 | iex
The installer asks for the initial administrator credentials, generates the required secrets, downloads the GHCR Compose stack, and starts it.
Open:
On a fresh database, the backend creates the initial administrator from
ADMIN_USER, ADMIN_PASSWORD, and optional ADMIN_EMAIL. Passwords are stored
as hashes, never as plaintext. An existing PostgreSQL volume is not overwritten:
the backend only replaces the untouched legacy quantdinger / 123456
administrator when a non-default administrator is explicitly configured. It
never overwrites an account whose password was already changed, and it refuses
to promote an existing account that already uses the requested username.
Manual Docker deployments retain quantdinger / 123456 only for backward
compatibility when the administrator variables are left at their defaults. This
credential is not suitable for an internet-facing deployment; change it before
first start or immediately after the first login. The one-command installer does
not accept 123456 as the chosen password.
The Settings UI writes runtime configuration to /app/.env, which is the
project-root .env on the host for both GHCR and source deployments. Current backend images automatically give runtime UID
10001 ownership and keep mode 600. Do not use chmod 755 or recursive 777:
these files contain passwords and API keys, and 755 still does not grant write
access to UID 10001 when root owns the file.
Verify write access with:
docker compose exec -u 10001:10001 -T backend \
sh -c 'test -w /app/.env && echo writable=yes || echo writable=no'
The hardened production override intentionally mounts /app/.env read-only.
When using docker-compose.production.yml, manage configuration on the host and
recreate the services instead of saving it from the Settings UI. See the
English guide or
中文指南 for
legacy-image recovery and rootless/NFS notes.
git clone https://github.com/OpenByteInc/QuantDinger.git
cd QuantDinger
cp .env.example .env
Before the first start, replace the example values in the unified environment file:
| File | Required production values |
|---|---|
.env | SECRET_KEY, CREDENTIAL_ENCRYPTION_KEY, administrator, PostgreSQL, Redis, and Grafana credentials |
After an update, docker compose up runs the one-shot env-sync service before
database and Kafka initialization. It appends newly introduced settings, imports
missing values from the legacy backend env files, preserves existing values and
comments, and creates a timestamped backup only when the unified file changes.
The command below remains available for a manual preview or maintenance run:
python scripts/sync_env.py --env-file .env --template .env.example --backup
For a manual one-time migration from older releases, add
--legacy backend_api_python/.env (source deployment) or --legacy backend.env
(old GHCR deployment). The old file is not deleted.
Generate independent secrets with:
python -c "import secrets; print(secrets.token_hex(32))"
Start the core stack from local backend source:
docker compose up -d --build
docker compose ps
The base stack does not start Prometheus, Grafana, or Alertmanager. This keeps the default open-source installation smaller.
For detailed installation paths, Windows notes, China mirror settings, and PostgreSQL migration guidance, see Installation troubleshooting and the cloud deployment guide.
Validate secrets before starting a production stack:
python backend_api_python/scripts/check_production_config.py \
--env-file .env
Start the hardened runtime with optional observability:
docker compose \
-f docker-compose.yml \
-f docker-compose.production.yml \
-f docker-compose.observability.yml \
up -d --build
Omit docker-compose.observability.yml when the host is resource-constrained or
monitoring is provided externally.
Production rules:
redis-jobs volume;The full checklist is in Production hardening.
All published ports bind to loopback by default.
| Service | Default URL | Purpose |
|---|---|---|
| Web | http://127.0.0.1:8888 | Desktop web client and same-origin API proxy. |
| Mobile H5 | http://127.0.0.1:8889 | Mobile web client and same-origin API proxy. |
| Backend | http://127.0.0.1:5000 | Direct API access and health endpoints. |
| Grafana | http://127.0.0.1:3000 | Dashboards; available only with the observability overlay. |
| Prometheus | http://127.0.0.1:9090 | Metrics storage and queries; optional. |
| Alertmanager | http://127.0.0.1:9093 | Alert grouping, silencing, and delivery; optional. |
Container-only ports such as the job Redis and exporters are not published to the host.
The monitoring stack is optional by design:
Start it for local diagnostics without the production overlay:
docker compose \
-f docker-compose.yml \
-f docker-compose.observability.yml \
up -d
Monitoring services stay on 127.0.0.1. Use a VPN, SSH tunnel, or authenticated
reverse proxy for remote administration. See
Observability for dashboards, alerts, retention, and
receiver configuration.
CREDENTIAL_ENCRYPTION_KEY.Report vulnerabilities privately according to SECURITY.md. Do not include credentials, account data, or exploitable details in public issues.
| Area | Current surface |
|---|---|
| Indicators | Python chart overlays, markers, bands, and signals. |
| Strategies | Strategy API V2 intents, sizing, risk, backtests, and live runtime. |
| Crypto | Binance, OKX, Bitget, Bybit, Gate, HTX, and adapter extensions. |
| Traditional brokers | IBKR and Alpaca workflows. |
| AI providers | OpenRouter, OpenAI-compatible APIs, Google, DeepSeek, Grok, MiniMax, and custom endpoints. |
| Automation | Human API, Agent Gateway, MCP server, Celery jobs, schedules, and notifications. |
Start with the Indicator guide, Strategy guide, and Extension guide.
QuantDinger can place a structured AI decision gate directly in front of live entry orders. Enable AI Decision Filter when creating a regular live strategy, or turn it on in Quick Trade. Before an entry reaches the exchange, QuantDinger sends the order, strategy context, exposure, positions, and budget state to TypeSafe Jev. Jev returns typed Choice results, probabilities, and confidence instead of prose that must be parsed. The app shows the provider, checks, result, confidence, latency, and reason in an auditable decision timeline.
| Previous LLM-only gate | JEV decision gate |
|---|---|
| Generate prose or JSON and recover a decision through parsing | Receive a typed Choice with the selected outcome, full probabilities, and confidence |
| One opaque answer is difficult to inspect after execution | Independent entry and risk checks are stored with the order context and latency |
| Provider failure can accidentally block position management | Provider failure is audited and fails open, while every exit bypasses AI |
The execution policy stays in QuantDinger code: rejected entries never reach the exchange; exits, stop-loss, take-profit, and emergency actions bypass the filter. Grid, DCA, and martingale runtimes are excluded from this first version. When Jev is not configured, QuantDinger tries the configured LLM. If no AI provider is available, the order is allowed and the fail-open result is logged, so an AI outage cannot trap an existing position.
flowchart TD
A["Strategy signal / Quick Trade instruction"] --> B["Deterministic risk and order budget checks"]
B -->|"Basic checks fail"| R["Reject order"]
B -->|"Basic checks pass"| C["Build Decision Context V2"]
C --> C1["Strategy parameters and signal rationale"]
C --> C2["Multi-timeframe market data and indicators"]
C --> C3["Positions, exposure, equity, and drawdown"]
C --> C4["Recent PnL and consecutive losses"]
C --> C5["Take-profit, stop-loss, and execution conditions"]
C1 --> D
C2 --> D
C3 --> D
C4 --> D
C5 --> D
D{"JEV configured?"}
D -->|"Yes"| E["JEV System One"]
E --> E1["Evidence quality"]
E --> E2["Signal consistency"]
E --> E3["Market regime"]
E --> E4["Account risk"]
E --> E5["Execution quality"]
E --> E6["Entry decision: pass/reject"]
E1 --> F["Validate schema, probabilities, and confidence"]
E2 --> F
E3 --> F
E4 --> F
E5 --> F
E6 --> F
F -->|"Valid result and confidence threshold met"| G["Deterministic decision converger"]
F -->|"Timeout, error, invalid format, or low confidence"| H
D -->|"No"| H{"LLM configured?"}
H -->|"Yes"| I["LLM reads the same context"]
I --> J["Require strict JSON output"]
J --> K{"decision"}
H -->|"No"| O["Fail open and log the reason"]
G -->|"PASS"| P["Enter pending order queue"]
G -->|"REJECT"| R
K -->|"pass"| P
K -->|"reject"| R
K -->|"Invalid output or provider failure"| O
P --> Q["Submit to exchange asynchronously"]
R --> S["Record ai_rejected and the decision trace"]
O --> T["Place order normally and record provider unavailable"]
Configure JEV_API_KEY, JEV_BASE_URL, JEV_MODEL, and
JEV_TIMEOUT_SECONDS in System Settings → AI / LLM. TypeSafe documents the
HTTP contract at POST /v1/systemone.
The Agent Gateway is exposed under /api/agent/v1. The included MCP server lets
clients such as Cursor, Claude Code, and Codex call approved tools without
receiving broker credentials or administrator JWTs.
Live trading through an agent requires all of the following:
paper_only=false on that token;AGENT_LIVE_TRADING_ENABLED=true on the server;See MCP setup, Agent quick start, and the Agent OpenAPI document.
Backend development uses Python 3.12:
cd backend_api_python
python -m venv .venv
python -m pip install -r requirements-dev.txt
python -m pytest -m "not integration and not stress" --ignore=tests/release_gate -q
ruff check app scripts tests
Useful repository checks:
python scripts/check_version.py
python scripts/check_mojibake.py
docker compose -f docker-compose.yml config -q
docker compose -f docker-compose.yml -f docker-compose.production.yml -f docker-compose.observability.yml config -q
API changes should follow API conventions, update the OpenAPI artifact when required, and pass the compatibility workflow.
This repository contains the backend, worker processes, deployment definitions, operations configuration, documentation, and MCP server. The desktop and mobile client source code live in separate repositories; this repository consumes their published images in the Compose stacks.
QuantDinger/
|-- .github/workflows/ CI, security, compatibility, and release checks
|-- backend_api_python/ Backend application and all backend processes
| |-- app/
| | |-- __init__.py Flask application factory and core wiring
| | |-- startup.py Process-aware startup hooks and service singletons
| | |-- celery_app.py Celery application and task registration
| | |-- commands/ Migration, scheduler, trading, and health entrypoints
| | |-- config/ Environment-backed database, Redis, and provider config
| | |-- routes/ Human HTTP API route facades
| | | `-- agent_v1/ Scoped Agent Gateway API under /api/agent/v1
| | |-- openapi/ OpenAPI schemas, tags, registration, and export support
| | |-- services/ Domain workflows and third-party integrations
| | | |-- backtest_engine/ Backtest execution components
| | | |-- factors/ Point-in-time factor research and diagnostics
| | | |-- strategy_evolution/ Parameter search, walk-forward validation, and robustness tests
| | | |-- pending_orders/ Queued order submission, recovery, and reconciliation
| | | |-- live_trading/ Normalized crypto exchange adapters
| | | |-- alpaca_trading/ Alpaca broker integration
| | | |-- ibkr_trading/ Interactive Brokers integration
| | | |-- strategy_runtime/ Strategy signals, intents, execution, and state
| | | |-- strategy_v2/ Versioned strategy contracts and runtime services
| | | `-- virtual_trading.py Isolated signal-mode account, positions, and fills
| | |-- data_sources/ Raw market-data source adapters
| | |-- data_providers/ Aggregated market, macro, news, and sentiment providers
| | |-- markets/ Market and symbol normalization
| | |-- tasks/ Finite, retryable Celery jobs
| | |-- workers/ Long-lived worker process shells
| | |-- runtime/ Process-role and ownership helpers
| | |-- observability/ Request context, metrics, and HTTP instrumentation
| | `-- utils/ Shared low-level database, cache, auth, and logging helpers
| |-- migrations/ PostgreSQL schema and seed migrations
| |-- scripts/ Backend maintenance and validation commands
| |-- tests/ Unit, contract, integration, and release-gate tests
| |-- run.py Local Flask and Gunicorn application entrypoint
| |-- Dockerfile Shared image for API and worker containers
| `-- docker-entrypoint.sh Container command dispatcher
|-- docs/
| |-- architecture/ Boundaries, concurrency, API, and extension design
| |-- deployment/ Installation, production, and observability operations
| |-- trading/ Strategy and indicator development guides
| |-- strategies/ Strategy authoring and validation references
| |-- api/ Human API documentation
| |-- agent/ Agent Gateway and MCP documentation
| |-- getting-started/ Onboarding and first-run guides
| |-- product/ Product workflows and feature documentation
| `-- security/ Security model and operational guidance
|-- mcp_server/ Standalone QuantDinger MCP server package
| |-- src/quantdinger_mcp/ MCP server and security implementation
| `-- tests/ MCP contract and security tests
|-- ops/ Runtime operations configuration
| |-- prometheus/ Scrape configuration and alert rules
| |-- grafana/ Provisioned data sources and dashboards
| `-- alertmanager/ Alert routing configuration
|-- scripts/ Repository-level version, encoding, and setup checks
|-- docker-compose.yml Core local/source stack
|-- docker-compose.ghcr.yml Prebuilt-image installation stack
|-- docker-compose.production.yml Production hardening overlay
|-- docker-compose.observability.yml Optional monitoring overlay
|-- install.sh / install.ps1 Linux/macOS and Windows installers
`-- VERSION Canonical source version
| Flow | Path through the repository |
|---|---|
| Synchronous API request | app/routes -> app/services -> database, cache, market-data, or trading adapter |
| Durable strategy command | API route -> PostgreSQL command record -> trading-worker -> strategy runtime and broker adapter |
| Finite background job | API or Celery beat -> job Redis -> app/tasks in celery-worker -> PostgreSQL result |
| Scheduled domain work | app/commands/scheduler.py -> scheduling services -> durable state and notifications |
| Monitoring | API and workers -> app/observability metrics -> Prometheus -> Grafana and Alertmanager |
| Agent or MCP call | MCP client -> mcp_server -> /api/agent/v1 -> the same service layer used by human APIs |
Long-lived trading loops belong to the trading worker. Finite, retryable work belongs to Celery. HTTP routes validate and delegate; they must not own trading loops, exchange-specific behavior, or large database workflows.
| Change | Primary location | Usually update as well |
|---|---|---|
| Add or modify an HTTP endpoint | backend_api_python/app/routes/ | app/openapi/, route/contract tests, API docs |
| Add a business workflow | backend_api_python/app/services/ | focused service tests |
| Add an exchange or broker integration | app/services/live_trading/ or the broker package | credential policy, adapter tests, docs |
| Add a market-data source | app/data_sources/ | provider aggregation, cache keys, tests |
| Add dashboard, news, or macro aggregation | app/data_providers/ | route facade and cache policy |
| Add a finite asynchronous task | app/tasks/ | celery_app.py, queue routing, task tests |
| Add long-lived process behavior | app/workers/, app/commands/, or app/runtime/ | Compose command, health checks, ownership tests |
| Change the database schema | backend_api_python/migrations/ | migration/release-gate tests and docs |
| Add metrics or alerts | app/observability/ and ops/ | dashboard, alert rule, observability docs |
| Add an MCP tool | mcp_server/src/quantdinger_mcp/ | Agent Gateway scope, security tests, agent docs |
The web and mobile repositories publish their own GHCR images. Node.js is only needed when building those clients from source. For deeper ownership rules, read Architecture, Module boundaries, and Process roles.
The maintained documentation index is available at docs/README.md.
| Topic | Document |
|---|---|
| Contributor architecture | Architecture |
| Module ownership | Module boundaries |
| Process and task ownership | Process roles |
| Production runtime | Production hardening |
| Metrics and alerts | Observability |
| Human API contracts | API conventions |
| OpenAPI artifacts | API documentation |
| Strategy development | Strategy guide |
| Indicator development | Indicator guide |
| MCP and agents | Agent documentation |
| Cloud deployment | Cloud deployment |
| Installation problems | Troubleshooting |
Read CONTRIBUTING.md and DEVELOPMENT.md before opening a pull request. Keep routes thin, preserve API compatibility, place long-running behavior in the correct process, and include focused tests for high-risk changes.
The public roadmap lists active product themes, planning stages, and the process for claiming scoped contributor work.
For commercial licensing, frontend source access, branding authorization, or deployment support:
QuantDinger is intended for lawful research, education, and compliant trading only. It must not be used for fraud, market manipulation, sanctions evasion, money laundering, or other illegal activity. Operators are responsible for following the laws, licensing requirements, tax rules, broker or exchange terms, and data regulations that apply in every jurisdiction where they deploy or use the software.
This project does not provide legal, tax, investment, financial, or regulatory advice. Trading, including automated and leveraged trading, can result in the loss of some or all capital. Historical data, backtests, simulated results, AI output, indicators, and strategy examples do not guarantee future performance. Users must independently review strategies, permissions, order limits, and risk controls before enabling live execution.
The software is provided under the terms of the applicable license and is used at the operator's own risk. To the extent permitted by law, project maintainers and contributors disclaim liability for trading losses, data loss, service interruption, third-party failures, security incidents, or regulatory consequences arising from use or misuse of the software.
QuantDinger's continued development and open-source community are supported by:
We are grateful to Atlas Cloud for supporting AI model inference and to Amazon Web Services for supporting the cloud infrastructure that helps QuantDinger serve its community.
QuantDinger stands on top of a strong open-source ecosystem. Special thanks to the maintainers and contributors of projects including:
QuantDinger is a small tribute to Erwin Schrödinger — the “-dinger” in our name is the tail of “Schrödinger”. The cat in the box was a thought experiment; every un-fired strategy is its own little version of it — simultaneously winning and losing until the order actually fills. Backtests open the box. Live trading collapses the wavefunction. Trade carefully.
If QuantDinger is useful to you, a GitHub star helps the project a lot.
18 followers · starred Jul 2026
878 followers · starred Jan 2026
122 followers · starred Jul 2026
27 followers · starred Jun 2026
Python
97.9%
PLpgSQL
1.7%
Open-source AI Trading OS, agent trading, and vibe trading, with Jev System One integration. Research, build Python strategies, backtest, and paper/live trade across crypto, stocks, and forex. Launch your own multi-tenant trading SaaS with built-in user management, billing, payments, and settlement.
See the code
Open-source AI Trading OS
Turn trading ideas into Python strategies, backtests, paper trading, live execution, and monitoring — all in one self-hosted stack.
QuantDinger is a product of Open Byte Inc.
AI research → Strategy code → Backtest → Paper/Live execution → Monitoring
English · 简体中文 · API · AI Agents & MCP
Live App · Website · Video Demo · Official Support Email
SUPPORTED BY
Want to contribute? Explore the public roadmap or claim a scoped task from Ready for contributors.
QuantDinger can submit real orders when live trading is explicitly enabled. Start with paper trading, use restricted API keys, and review the risk and compliance requirements for your jurisdiction. This project does not provide investment advice.
QuantDinger is an open-source AI Trading OS for independent traders, Python strategy authors, and small teams. Its local-first, self-hosted design keeps market data, strategy code, broker credentials, and deployment under the operator's control.
The project combines:
It is not a black-box signal service. Strategy code, risk settings, credentials, and deployment remain under the operator's control.
The v5 backend is organized around explicit runtime and operational boundaries:
The source version is declared in VERSION. Git release tags use the
same semantic version with a leading v, for example v5.0.1.
The editable source is architecture-v5.svg; the Mermaid topology below is the detailed runtime source of truth.
The static diagram above is the product-level view. The runtime topology below is the current source of truth for container ownership and event/data flow.
flowchart TB
C["Web / Mobile / API / MCP clients"]
FE["Nginx frontend services"]
API["Flask + Gunicorn API"]
PG[("PostgreSQL")]
CACHE[("Redis cache")]
JOBS[("Redis jobs")]
KAFKA[("Kafka event backbone")]
TW["Trading workers\ncontrol, realtime, execution, grid actors"]
DISPATCH["Strategy dispatcher workers"]
EVAL["Strategy evaluator workers\nhot bar runtimes"]
AUDIT["Kafka audit worker"]
SW["Scheduler worker"]
CW["Celery worker"]
BEAT["Celery beat"]
PROM["Prometheus"]
GRAF["Grafana"]
ALERT["Alertmanager"]
C --> FE --> API
API --> PG
API --> CACHE
API -->|"durable commands"| PG
TW -->|"leases, order intents, fills, grid actor state"| PG
TW -->|"closed bars and lifecycle events"| KAFKA
KAFKA --> DISPATCH --> KAFKA
KAFKA --> EVAL
EVAL -->|"inbox, leases, checkpoints, order intents"| PG
KAFKA --> AUDIT --> PG
PG -->|"owned pending orders"| TW
SW -->|"schedules, monitoring, heartbeats"| PG
API -->|"finite async jobs"| JOBS
BEAT --> JOBS --> CW
CW --> PG
API -. metrics .-> PROM
PG -. exporter .-> PROM
CACHE -. exporter .-> PROM
JOBS -. exporter .-> PROM
PROM --> GRAF
PROM --> ALERT
One backend image is reused by several containers with different commands:
| Process | Responsibility |
|---|---|
migration | Applies the database schema and exits before application services start. |
kafka-init | Creates the versioned runtime topics and exits before event consumers start. |
backend | Handles HTTP, authentication, validation, and durable command submission. |
trading-worker | Owns control/realtime runtimes, exchange sessions, the fenced order gateway, reconciliation, and durable grid actors. |
strategy-dispatcher-worker | Converts closed-bar events into stable strategy-shard evaluation batches. |
strategy-evaluator-worker | Owns hot distributed bar runtimes and evaluates fenced strategy inbox events. |
kafka-audit-worker | Validates and records the versioned event stream independently of execution. |
scheduler-worker | Runs portfolio, deployment, payment, and signal schedules. |
celery-worker | Executes finite AI, backtest, experiment, report, and maintenance jobs. |
celery-beat | Dispatches periodic Celery tasks. |
See Backend process roles, architecture, and concurrency model for the ownership rules. Use the distributed runtime deployment and scaling guide before changing replica counts or moving the stack to multiple hosts.
Prerequisites: Docker with Compose v2. Node.js and a local Python environment are not required.
Linux or macOS:
curl -fsSL https://raw.githubusercontent.com/OpenByteInc/QuantDinger/main/install.sh | bash
Windows PowerShell:
irm https://raw.githubusercontent.com/OpenByteInc/QuantDinger/main/install.ps1 | iex
The installer asks for the initial administrator credentials, generates the required secrets, downloads the GHCR Compose stack, and starts it.
Open:
On a fresh database, the backend creates the initial administrator from
ADMIN_USER, ADMIN_PASSWORD, and optional ADMIN_EMAIL. Passwords are stored
as hashes, never as plaintext. An existing PostgreSQL volume is not overwritten:
the backend only replaces the untouched legacy quantdinger / 123456
administrator when a non-default administrator is explicitly configured. It
never overwrites an account whose password was already changed, and it refuses
to promote an existing account that already uses the requested username.
Manual Docker deployments retain quantdinger / 123456 only for backward
compatibility when the administrator variables are left at their defaults. This
credential is not suitable for an internet-facing deployment; change it before
first start or immediately after the first login. The one-command installer does
not accept 123456 as the chosen password.
The Settings UI writes runtime configuration to /app/.env, which is the
project-root .env on the host for both GHCR and source deployments. Current backend images automatically give runtime UID
10001 ownership and keep mode 600. Do not use chmod 755 or recursive 777:
these files contain passwords and API keys, and 755 still does not grant write
access to UID 10001 when root owns the file.
Verify write access with:
docker compose exec -u 10001:10001 -T backend \
sh -c 'test -w /app/.env && echo writable=yes || echo writable=no'
The hardened production override intentionally mounts /app/.env read-only.
When using docker-compose.production.yml, manage configuration on the host and
recreate the services instead of saving it from the Settings UI. See the
English guide or
中文指南 for
legacy-image recovery and rootless/NFS notes.
git clone https://github.com/OpenByteInc/QuantDinger.git
cd QuantDinger
cp .env.example .env
Before the first start, replace the example values in the unified environment file:
| File | Required production values |
|---|---|
.env | SECRET_KEY, CREDENTIAL_ENCRYPTION_KEY, administrator, PostgreSQL, Redis, and Grafana credentials |
After an update, docker compose up runs the one-shot env-sync service before
database and Kafka initialization. It appends newly introduced settings, imports
missing values from the legacy backend env files, preserves existing values and
comments, and creates a timestamped backup only when the unified file changes.
The command below remains available for a manual preview or maintenance run:
python scripts/sync_env.py --env-file .env --template .env.example --backup
For a manual one-time migration from older releases, add
--legacy backend_api_python/.env (source deployment) or --legacy backend.env
(old GHCR deployment). The old file is not deleted.
Generate independent secrets with:
python -c "import secrets; print(secrets.token_hex(32))"
Start the core stack from local backend source:
docker compose up -d --build
docker compose ps
The base stack does not start Prometheus, Grafana, or Alertmanager. This keeps the default open-source installation smaller.
For detailed installation paths, Windows notes, China mirror settings, and PostgreSQL migration guidance, see Installation troubleshooting and the cloud deployment guide.
Validate secrets before starting a production stack:
python backend_api_python/scripts/check_production_config.py \
--env-file .env
Start the hardened runtime with optional observability:
docker compose \
-f docker-compose.yml \
-f docker-compose.production.yml \
-f docker-compose.observability.yml \
up -d --build
Omit docker-compose.observability.yml when the host is resource-constrained or
monitoring is provided externally.
Production rules:
redis-jobs volume;The full checklist is in Production hardening.
All published ports bind to loopback by default.
| Service | Default URL | Purpose |
|---|---|---|
| Web | http://127.0.0.1:8888 | Desktop web client and same-origin API proxy. |
| Mobile H5 | http://127.0.0.1:8889 | Mobile web client and same-origin API proxy. |
| Backend | http://127.0.0.1:5000 | Direct API access and health endpoints. |
| Grafana | http://127.0.0.1:3000 | Dashboards; available only with the observability overlay. |
| Prometheus | http://127.0.0.1:9090 | Metrics storage and queries; optional. |
| Alertmanager | http://127.0.0.1:9093 | Alert grouping, silencing, and delivery; optional. |
Container-only ports such as the job Redis and exporters are not published to the host.
The monitoring stack is optional by design:
Start it for local diagnostics without the production overlay:
docker compose \
-f docker-compose.yml \
-f docker-compose.observability.yml \
up -d
Monitoring services stay on 127.0.0.1. Use a VPN, SSH tunnel, or authenticated
reverse proxy for remote administration. See
Observability for dashboards, alerts, retention, and
receiver configuration.
CREDENTIAL_ENCRYPTION_KEY.Report vulnerabilities privately according to SECURITY.md. Do not include credentials, account data, or exploitable details in public issues.
| Area | Current surface |
|---|---|
| Indicators | Python chart overlays, markers, bands, and signals. |
| Strategies | Strategy API V2 intents, sizing, risk, backtests, and live runtime. |
| Crypto | Binance, OKX, Bitget, Bybit, Gate, HTX, and adapter extensions. |
| Traditional brokers | IBKR and Alpaca workflows. |
| AI providers | OpenRouter, OpenAI-compatible APIs, Google, DeepSeek, Grok, MiniMax, and custom endpoints. |
| Automation | Human API, Agent Gateway, MCP server, Celery jobs, schedules, and notifications. |
Start with the Indicator guide, Strategy guide, and Extension guide.
QuantDinger can place a structured AI decision gate directly in front of live entry orders. Enable AI Decision Filter when creating a regular live strategy, or turn it on in Quick Trade. Before an entry reaches the exchange, QuantDinger sends the order, strategy context, exposure, positions, and budget state to TypeSafe Jev. Jev returns typed Choice results, probabilities, and confidence instead of prose that must be parsed. The app shows the provider, checks, result, confidence, latency, and reason in an auditable decision timeline.
| Previous LLM-only gate | JEV decision gate |
|---|---|
| Generate prose or JSON and recover a decision through parsing | Receive a typed Choice with the selected outcome, full probabilities, and confidence |
| One opaque answer is difficult to inspect after execution | Independent entry and risk checks are stored with the order context and latency |
| Provider failure can accidentally block position management | Provider failure is audited and fails open, while every exit bypasses AI |
The execution policy stays in QuantDinger code: rejected entries never reach the exchange; exits, stop-loss, take-profit, and emergency actions bypass the filter. Grid, DCA, and martingale runtimes are excluded from this first version. When Jev is not configured, QuantDinger tries the configured LLM. If no AI provider is available, the order is allowed and the fail-open result is logged, so an AI outage cannot trap an existing position.
flowchart TD
A["Strategy signal / Quick Trade instruction"] --> B["Deterministic risk and order budget checks"]
B -->|"Basic checks fail"| R["Reject order"]
B -->|"Basic checks pass"| C["Build Decision Context V2"]
C --> C1["Strategy parameters and signal rationale"]
C --> C2["Multi-timeframe market data and indicators"]
C --> C3["Positions, exposure, equity, and drawdown"]
C --> C4["Recent PnL and consecutive losses"]
C --> C5["Take-profit, stop-loss, and execution conditions"]
C1 --> D
C2 --> D
C3 --> D
C4 --> D
C5 --> D
D{"JEV configured?"}
D -->|"Yes"| E["JEV System One"]
E --> E1["Evidence quality"]
E --> E2["Signal consistency"]
E --> E3["Market regime"]
E --> E4["Account risk"]
E --> E5["Execution quality"]
E --> E6["Entry decision: pass/reject"]
E1 --> F["Validate schema, probabilities, and confidence"]
E2 --> F
E3 --> F
E4 --> F
E5 --> F
E6 --> F
F -->|"Valid result and confidence threshold met"| G["Deterministic decision converger"]
F -->|"Timeout, error, invalid format, or low confidence"| H
D -->|"No"| H{"LLM configured?"}
H -->|"Yes"| I["LLM reads the same context"]
I --> J["Require strict JSON output"]
J --> K{"decision"}
H -->|"No"| O["Fail open and log the reason"]
G -->|"PASS"| P["Enter pending order queue"]
G -->|"REJECT"| R
K -->|"pass"| P
K -->|"reject"| R
K -->|"Invalid output or provider failure"| O
P --> Q["Submit to exchange asynchronously"]
R --> S["Record ai_rejected and the decision trace"]
O --> T["Place order normally and record provider unavailable"]
Configure JEV_API_KEY, JEV_BASE_URL, JEV_MODEL, and
JEV_TIMEOUT_SECONDS in System Settings → AI / LLM. TypeSafe documents the
HTTP contract at POST /v1/systemone.
The Agent Gateway is exposed under /api/agent/v1. The included MCP server lets
clients such as Cursor, Claude Code, and Codex call approved tools without
receiving broker credentials or administrator JWTs.
Live trading through an agent requires all of the following:
paper_only=false on that token;AGENT_LIVE_TRADING_ENABLED=true on the server;See MCP setup, Agent quick start, and the Agent OpenAPI document.
Backend development uses Python 3.12:
cd backend_api_python
python -m venv .venv
python -m pip install -r requirements-dev.txt
python -m pytest -m "not integration and not stress" --ignore=tests/release_gate -q
ruff check app scripts tests
Useful repository checks:
python scripts/check_version.py
python scripts/check_mojibake.py
docker compose -f docker-compose.yml config -q
docker compose -f docker-compose.yml -f docker-compose.production.yml -f docker-compose.observability.yml config -q
API changes should follow API conventions, update the OpenAPI artifact when required, and pass the compatibility workflow.
This repository contains the backend, worker processes, deployment definitions, operations configuration, documentation, and MCP server. The desktop and mobile client source code live in separate repositories; this repository consumes their published images in the Compose stacks.
QuantDinger/
|-- .github/workflows/ CI, security, compatibility, and release checks
|-- backend_api_python/ Backend application and all backend processes
| |-- app/
| | |-- __init__.py Flask application factory and core wiring
| | |-- startup.py Process-aware startup hooks and service singletons
| | |-- celery_app.py Celery application and task registration
| | |-- commands/ Migration, scheduler, trading, and health entrypoints
| | |-- config/ Environment-backed database, Redis, and provider config
| | |-- routes/ Human HTTP API route facades
| | | `-- agent_v1/ Scoped Agent Gateway API under /api/agent/v1
| | |-- openapi/ OpenAPI schemas, tags, registration, and export support
| | |-- services/ Domain workflows and third-party integrations
| | | |-- backtest_engine/ Backtest execution components
| | | |-- factors/ Point-in-time factor research and diagnostics
| | | |-- strategy_evolution/ Parameter search, walk-forward validation, and robustness tests
| | | |-- pending_orders/ Queued order submission, recovery, and reconciliation
| | | |-- live_trading/ Normalized crypto exchange adapters
| | | |-- alpaca_trading/ Alpaca broker integration
| | | |-- ibkr_trading/ Interactive Brokers integration
| | | |-- strategy_runtime/ Strategy signals, intents, execution, and state
| | | |-- strategy_v2/ Versioned strategy contracts and runtime services
| | | `-- virtual_trading.py Isolated signal-mode account, positions, and fills
| | |-- data_sources/ Raw market-data source adapters
| | |-- data_providers/ Aggregated market, macro, news, and sentiment providers
| | |-- markets/ Market and symbol normalization
| | |-- tasks/ Finite, retryable Celery jobs
| | |-- workers/ Long-lived worker process shells
| | |-- runtime/ Process-role and ownership helpers
| | |-- observability/ Request context, metrics, and HTTP instrumentation
| | `-- utils/ Shared low-level database, cache, auth, and logging helpers
| |-- migrations/ PostgreSQL schema and seed migrations
| |-- scripts/ Backend maintenance and validation commands
| |-- tests/ Unit, contract, integration, and release-gate tests
| |-- run.py Local Flask and Gunicorn application entrypoint
| |-- Dockerfile Shared image for API and worker containers
| `-- docker-entrypoint.sh Container command dispatcher
|-- docs/
| |-- architecture/ Boundaries, concurrency, API, and extension design
| |-- deployment/ Installation, production, and observability operations
| |-- trading/ Strategy and indicator development guides
| |-- strategies/ Strategy authoring and validation references
| |-- api/ Human API documentation
| |-- agent/ Agent Gateway and MCP documentation
| |-- getting-started/ Onboarding and first-run guides
| |-- product/ Product workflows and feature documentation
| `-- security/ Security model and operational guidance
|-- mcp_server/ Standalone QuantDinger MCP server package
| |-- src/quantdinger_mcp/ MCP server and security implementation
| `-- tests/ MCP contract and security tests
|-- ops/ Runtime operations configuration
| |-- prometheus/ Scrape configuration and alert rules
| |-- grafana/ Provisioned data sources and dashboards
| `-- alertmanager/ Alert routing configuration
|-- scripts/ Repository-level version, encoding, and setup checks
|-- docker-compose.yml Core local/source stack
|-- docker-compose.ghcr.yml Prebuilt-image installation stack
|-- docker-compose.production.yml Production hardening overlay
|-- docker-compose.observability.yml Optional monitoring overlay
|-- install.sh / install.ps1 Linux/macOS and Windows installers
`-- VERSION Canonical source version
| Flow | Path through the repository |
|---|---|
| Synchronous API request | app/routes -> app/services -> database, cache, market-data, or trading adapter |
| Durable strategy command | API route -> PostgreSQL command record -> trading-worker -> strategy runtime and broker adapter |
| Finite background job | API or Celery beat -> job Redis -> app/tasks in celery-worker -> PostgreSQL result |
| Scheduled domain work | app/commands/scheduler.py -> scheduling services -> durable state and notifications |
| Monitoring | API and workers -> app/observability metrics -> Prometheus -> Grafana and Alertmanager |
| Agent or MCP call | MCP client -> mcp_server -> /api/agent/v1 -> the same service layer used by human APIs |
Long-lived trading loops belong to the trading worker. Finite, retryable work belongs to Celery. HTTP routes validate and delegate; they must not own trading loops, exchange-specific behavior, or large database workflows.
| Change | Primary location | Usually update as well |
|---|---|---|
| Add or modify an HTTP endpoint | backend_api_python/app/routes/ | app/openapi/, route/contract tests, API docs |
| Add a business workflow | backend_api_python/app/services/ | focused service tests |
| Add an exchange or broker integration | app/services/live_trading/ or the broker package | credential policy, adapter tests, docs |
| Add a market-data source | app/data_sources/ | provider aggregation, cache keys, tests |
| Add dashboard, news, or macro aggregation | app/data_providers/ | route facade and cache policy |
| Add a finite asynchronous task | app/tasks/ | celery_app.py, queue routing, task tests |
| Add long-lived process behavior | app/workers/, app/commands/, or app/runtime/ | Compose command, health checks, ownership tests |
| Change the database schema | backend_api_python/migrations/ | migration/release-gate tests and docs |
| Add metrics or alerts | app/observability/ and ops/ | dashboard, alert rule, observability docs |
| Add an MCP tool | mcp_server/src/quantdinger_mcp/ | Agent Gateway scope, security tests, agent docs |
The web and mobile repositories publish their own GHCR images. Node.js is only needed when building those clients from source. For deeper ownership rules, read Architecture, Module boundaries, and Process roles.
The maintained documentation index is available at docs/README.md.
| Topic | Document |
|---|---|
| Contributor architecture | Architecture |
| Module ownership | Module boundaries |
| Process and task ownership | Process roles |
| Production runtime | Production hardening |
| Metrics and alerts | Observability |
| Human API contracts | API conventions |
| OpenAPI artifacts | API documentation |
| Strategy development | Strategy guide |
| Indicator development | Indicator guide |
| MCP and agents | Agent documentation |
| Cloud deployment | Cloud deployment |
| Installation problems | Troubleshooting |
Read CONTRIBUTING.md and DEVELOPMENT.md before opening a pull request. Keep routes thin, preserve API compatibility, place long-running behavior in the correct process, and include focused tests for high-risk changes.
The public roadmap lists active product themes, planning stages, and the process for claiming scoped contributor work.
For commercial licensing, frontend source access, branding authorization, or deployment support:
QuantDinger is intended for lawful research, education, and compliant trading only. It must not be used for fraud, market manipulation, sanctions evasion, money laundering, or other illegal activity. Operators are responsible for following the laws, licensing requirements, tax rules, broker or exchange terms, and data regulations that apply in every jurisdiction where they deploy or use the software.
This project does not provide legal, tax, investment, financial, or regulatory advice. Trading, including automated and leveraged trading, can result in the loss of some or all capital. Historical data, backtests, simulated results, AI output, indicators, and strategy examples do not guarantee future performance. Users must independently review strategies, permissions, order limits, and risk controls before enabling live execution.
The software is provided under the terms of the applicable license and is used at the operator's own risk. To the extent permitted by law, project maintainers and contributors disclaim liability for trading losses, data loss, service interruption, third-party failures, security incidents, or regulatory consequences arising from use or misuse of the software.
QuantDinger's continued development and open-source community are supported by:
We are grateful to Atlas Cloud for supporting AI model inference and to Amazon Web Services for supporting the cloud infrastructure that helps QuantDinger serve its community.
QuantDinger stands on top of a strong open-source ecosystem. Special thanks to the maintainers and contributors of projects including:
QuantDinger is a small tribute to Erwin Schrödinger — the “-dinger” in our name is the tail of “Schrödinger”. The cat in the box was a thought experiment; every un-fired strategy is its own little version of it — simultaneously winning and losing until the order actually fills. Backtests open the box. Live trading collapses the wavefunction. Trade carefully.
If QuantDinger is useful to you, a GitHub star helps the project a lot.
18 followers · starred Jul 2026
878 followers · starred Jan 2026
122 followers · starred Jul 2026
27 followers · starred Jun 2026
Python
97.9%
PLpgSQL
1.7%