Skip to content

Commit ba4122d

Browse files
v3.0.15
Signed-off-by: Dinger <[email protected]>
1 parent 7e2bc43 commit ba4122d

30 files changed

Lines changed: 1548 additions & 604 deletions

README.md

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
<h1>QuantDinger</h1>
77
<h3>Your Private AI Quant Operating System</h3>
8-
<p><strong>One deployable stack for charting, AI market research, Python indicators &amp; strategies, backtests, and live execution—on your own servers and your own keys.</strong></p>
9-
<p><em>Self-hosted quantitative platform: from idea and AI-assisted coding to paper-style workflows and exchange-connected live trading, with optional multi-user and billing primitives for operators.</em></p>
8+
<p><strong>One Docker stack for charting, multi-LLM research, Python strategies, institutional-grade backtests, and multi-venue live execution — fully self-hosted, your keys, your data.</strong></p>
9+
<p><em>Open-source quant OS: AI-assisted coding → backtest → paper → live on crypto, IBKR, MT5 &amp; Alpaca — with Agent Gateway, MCP tools, and optional multi-tenant billing.</em></p>
1010

1111
<div align="center" style="max-width: 680px; margin: 1.25rem auto 0; padding: 20px 22px 22px; border: 1px solid #d1d9e0; border-radius: 16px;">
1212
<p style="margin: 0 0 14px; line-height: 1.65;">
@@ -50,6 +50,8 @@
5050
<img src="https://img.shields.io/badge/Python-3.10%2B%20%7C%20Docker%20image%203.12-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
5151
<img src="https://img.shields.io/badge/Docker-Compose%20Ready-2496ED?style=flat-square&logo=docker&logoColor=white" alt="Docker">
5252
<img src="https://img.shields.io/badge/Frontend-Prebuilt-1f8b4c?style=flat-square" alt="Frontend">
53+
<img src="https://img.shields.io/badge/Agent%20Gateway-MCP%20Ready-6f42c1?style=flat-square" alt="Agent Gateway">
54+
<img src="https://img.shields.io/badge/PostgreSQL-16-336791?style=flat-square&logo=postgresql&logoColor=white" alt="PostgreSQL">
5355
<img src="https://img.shields.io/github/stars/brokermr810/QuantDinger?style=flat-square&logo=github" alt="Stars">
5456
</p>
5557
<p style="margin: 10px 0 12px;">
@@ -67,22 +69,49 @@
6769

6870
## Contents
6971

70-
[Quick start](#try-in-2-minutes) · [Repositories](#related-repositories) · [AI agents & MCP](#use-it-from-an-ai-agent-cursor--claude-code--codex--mcp) · [Overview](#product-overview) · [Features](#features-at-a-glance) · [Visual tour](#visual-tour) · [Architecture](#architecture) · [Install](#installation--first-time-setup-docker-compose) · [Docs](#documentation) · [FAQ](#faq) · [License](#license-and-commercial-terms)
72+
[Quick start](#try-in-2-minutes) · [Technical highlights](#technical-highlights) · [Repositories](#related-repositories) · [AI agents & MCP](#use-it-from-an-ai-agent-cursor--claude-code--codex--mcp) · [Overview](#product-overview) · [Features](#features-at-a-glance) · [Visual tour](#visual-tour) · [Architecture](#architecture) · [Install](#installation--first-time-setup-docker-compose) · [Docs](#documentation) · [FAQ](#faq) · [License](#license-and-commercial-terms)
7173

7274
---
7375

74-
> QuantDinger is a **self-hosted, local-first** quantitative platform: **AI-assisted research**, **Python-native strategies**, **backtesting**, and **live trading** (crypto, IBKR stocks, MT5 forex, Alpaca US stocks/ETFs/crypto) in one product—not a loose collection of scripts and SaaS tabs.
76+
> QuantDinger is a **self-hosted, local-first** quantitative OS — not a chatbot with a buy button. It unifies **multi-LLM research**, **Python-native strategy engines**, **server-side backtesting**, and **multi-broker live execution** (10+ crypto venues, IBKR, MT5, Alpaca) in one production-grade stack you fully control.
77+
78+
<div align="center">
79+
<img src="docs/screenshots/ezgif.com-animated-gif-maker.gif" alt="QuantDinger quick demo: install, sign in, charting, AI analysis, and strategy workflow" width="920" style="border-radius: 12px; border: 1px solid #eaeef2;">
80+
<p><sub><em>From zero to running stack — charting, AI research, and strategy workflow in minutes.</em></sub></p>
81+
</div>
7582

7683
<div align="center">
7784
<img src="docs/screenshots/architecture.png" alt="QuantDinger system architecture: Data Sources → Indicator / Signal / Strategy / Backtesting / AI Analysis layers → Execution, with the closed-loop quant workflow (Idea → Indicator → Strategy → Backtest → Optimize → Execute → Monitor)" width="960">
78-
<p><sub><em>End-to-end architecture: market data feeds the five-layer engine and exits to live execution, closing the quant loop from idea to monitoring.</em></sub></p>
85+
<p><sub><em>Five-layer quant engine on a closed loop: <strong>Idea → Indicator → Strategy → Backtest → Optimize → Execute → Monitor</strong> — market data in, audited orders out.</em></sub></p>
7986
</div>
8087

88+
## Technical highlights
89+
90+
| | What makes QuantDinger different |
91+
|---|----------------------------------|
92+
| **Full-stack quant OS** | Charting, indicator IDE, AI research, backtests, live bots, quick trade, and broker account management — one product, one Postgres state store. |
93+
| **Agent-native** | First-class **Agent Gateway** (`/api/agent/v1`) + **[`quantdinger-mcp`](https://pypi.org/project/quantdinger-mcp/)** on PyPI — Cursor, Claude Code, and Codex can read markets, run backtests, and trade (paper by default) with full audit logs. |
94+
| **Dual strategy runtimes** | **`IndicatorStrategy`** (vectorized dataframe signals + chart overlays) and **`ScriptStrategy`** (event-driven `on_bar`, explicit orders) — research and production in the same codebase. |
95+
| **Multi-venue execution** | CCXT crypto (Binance, OKX, Bybit, …), **IBKR** stocks, **MT5** forex, **Alpaca** US equities/ETFs/crypto — unified Broker Accounts page with isolated multi-tenant sessions. |
96+
| **Production-grade infra** | **PostgreSQL 16** + **Redis 7**, connection pooling, background workers (orders, portfolio monitor, reflection), idempotent schema bootstrap, GHCR multi-arch images (amd64/arm64). |
97+
| **Security by default** | Refuses default `SECRET_KEY`, agent tokens hashed at rest, **paper-only trading** unless explicitly unlocked server-side, every agent call audit-logged. |
98+
| **Operator-ready** | OAuth, multi-user roles, credits/membership/USDT billing toggles, AWS Marketplace AMI, 7-language docs — build a commercial quant product on top, not just a hobby bot. |
99+
81100
## Try in 2 minutes
82101

83-
> **Lightest path: pull images, start the stack — no `npm`, no Vue source folder, and no `docker compose up --build`.** The UI comes from GHCR (`quantdinger-frontend:latest` by default); only the backend is built locally on first boot.
102+
> **Fastest path: one command.** No `git clone`, no `npm`, no Vue source tree. Prebuilt images from GHCR; `SECRET_KEY` auto-generated on first backend start.
103+
104+
**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) with Compose v2 (Docker Desktop on Windows/macOS). **Node.js is not required.**
84105

85-
**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) with Compose v2 (Docker Desktop on Windows/macOS). **Git** for the standard path below. **Node.js is not required.**
106+
### One-line install (Linux / macOS)
107+
108+
```bash
109+
curl -fsSL https://raw.githubusercontent.com/brokermr810/QuantDinger/main/install.sh | bash
110+
```
111+
112+
Installs to `~/quantdinger` by default (override: `… | bash -s -- /opt/quantdinger`). Re-run the same command to pull latest images and restart.
113+
114+
Then open **`http://localhost:8888`**, sign in with **`quantdinger` / `123456`**, and **change the default admin password**.
86115

87116
### Lightest: two files only (no `git clone`)
88117

@@ -193,15 +222,17 @@ Deeper references: [AI Integration design](docs/agent/AI_INTEGRATION_DESIGN.md)
193222

194223
## Product overview
195224

196-
QuantDinger is a **self-hosted** quantitative OS: **AI-assisted research**, **Python-native strategies** (`IndicatorStrategy` + `ScriptStrategy`), **backtesting**, and **live trading** (crypto, IBKR, MT5, Alpaca)—with optional multi-user roles, notifications, credits, and USDT billing. It replaces a patchwork of charts, notebooks, bots, and disconnected LLM chats with **one Compose stack** and **your** credentials in Postgres + `.env`.
225+
QuantDinger is a **self-hosted quantitative operating system** — not a single-purpose trading bot. It replaces the typical patchwork of TradingView + Jupyter + ChatGPT + exchange scripts with **one audited, Docker-native stack**: multi-LLM research, Python strategy IDEs, server-side backtests, and live execution across crypto, equities, forex, and ETFs — with optional multi-user billing for operators who resell access.
197226

198227
| Typical DIY stack | QuantDinger |
199228
|-------------------|-------------|
200-
| Chat AI separate from execution | Analysis, NL→code, backtests, and execution in one product |
201-
| Many tools wired by hand | Nginx + Vue UI, Flask API, workers, exchange/LLM adapters |
202-
| Opaque SaaS keys | Your infra, your exchange keys, your LLM keys |
229+
| Chat AI disconnected from execution | Research, NL→code, backtests, and orders in one product with shared Postgres state |
230+
| 5–10 tools wired by hand | Nginx + Vue UI, Flask API, Redis-backed workers, env-driven exchange/LLM adapters |
231+
| Opaque SaaS holds your keys | Your infra, your exchange keys, your LLM keys — Apache 2.0 backend |
232+
| Script bots with no audit trail | Agent Gateway with scope limits, rate limits, and append-only audit log |
233+
| Research code ≠ live code | `IndicatorStrategy` and `ScriptStrategy` share the same runtime and data layer |
203234

204-
**Audience:** traders and quants, Python strategy authors, small teams building internal or commercial trading products.
235+
**Audience:** independent quants, Python strategy authors, prop/small teams, and operators building white-label quant products on private infrastructure.
205236

206237
## Visual Tour
207238

@@ -233,17 +264,21 @@ QuantDinger is a **self-hosted** quantitative OS: **AI-assisted research**, **Py
233264

234265
## Features at a glance
235266

236-
- **Research & AI** — Multi-LLM analysis, watchlists, analysis history; optional ensemble/calibration; NL→indicator/strategy; post-backtest AI hints. **[Agent Gateway + MCP](#use-it-from-an-ai-agent-cursor--claude-code--codex--mcp)** for Cursor / Claude Code / Codex.
237-
- **Build**`IndicatorStrategy` (dataframe signals, chart overlays) and `ScriptStrategy` (`on_bar`, explicit orders); professional chart UI.
238-
- **Validate** — Server-side backtests, metrics, equity curves, strategy snapshots.
239-
- **Operate**Crypto execution, quick trade, IBKR / MT5 / Alpaca (US stocks, ETFs, crypto), notifications (Telegram, email, SMS, Discord, webhooks). **Unified Broker Accounts page** centralises connection, account KPIs, positions and open-order management across all brokers.
240-
- **Platform** — Docker Compose, Postgres, Redis, OAuth, multi-user patterns, credits / membership / USDT billing toggles.
267+
- **Research & AI** — Multi-LLM ensemble analysis, watchlists, opportunity radar, NL→indicator/strategy, post-backtest AI hints; optional confidence calibration. **[Agent Gateway + MCP](#use-it-from-an-ai-agent-cursor--claude-code--codex--mcp)** for Cursor / Claude Code / Codex with scoped tokens and SSE job streaming.
268+
- **Build**Professional KLine chart UI; `IndicatorStrategy` (dataframe `buy`/`sell` signals) and `ScriptStrategy` (`on_bar`, `ctx.buy()` / `ctx.sell()`); AI code generation as a starting point, Python as source of truth.
269+
- **Validate** — Server-side backtests with equity curves, drawdown metrics, trade logs, and strategy snapshots — no client-side-only backtest theater.
270+
- **Operate**Live strategy bots, quick trade, **10+ crypto exchanges** via CCXT, **IBKR** / **MT5** / **Alpaca** (US stocks, ETFs, crypto); unified **Broker Accounts** page; notifications (Telegram, email, SMS, Discord, webhooks).
271+
- **Platform** — Docker Compose + GHCR images, PostgreSQL 16, Redis 7, OAuth, multi-user RBAC, credits / membership / USDT billing toggles, AWS Marketplace AMI, 7-language documentation.
241272

242273
## Architecture
243274

244-
**Stack:** Nginx serves the prebuilt Vue app (published as `ghcr.io/brokermr810/quantdinger-frontend`); **Flask** API runs strategy/AI/billing services; **PostgreSQL** holds state; **Redis** backs workers. Exchanges, brokers, LLMs, and payments plug in through env-driven adapters. Crypto **market data** and **order execution** paths are separated by design.
275+
**Design principle:** separate **market data ingestion**, **strategy/backtest compute**, and **order execution** so research never shares a code path with live capital unless you explicitly promote a strategy.
276+
277+
**Stack:** Nginx serves the prebuilt Vue SPA (`ghcr.io/brokermr810/quantdinger-frontend`); **Flask + Gunicorn** API hosts strategy, AI, billing, and agent services; **PostgreSQL 16** is the system of record; **Redis 7** backs cache and worker coordination. Exchanges, brokers, LLMs, and payment rails plug in through env-driven adapters — swap providers without forking core code.
278+
279+
**Runtime flow:** market feeds → indicator/signal layer → strategy engine → backtest or live runtime → venue-specific execution adapters; pending orders dispatched by background workers with health checks and retry semantics.
245280

246-
**Runtime (short):** data feeds → backtest/strategy engine → live runtime → exchange adapters; pending orders dispatched per venue.
281+
**Deploy surfaces:** one-line `install.sh`, zero-repo GHCR Compose, full-repo Compose (local backend build), AWS Marketplace AMI, and SaaS at [ai.quantdinger.com](https://ai.quantdinger.com) for trials.
247282

248283
### System diagram
249284

@@ -566,7 +601,9 @@ QuantDinger/
566601
│ ├── env.example # Main environment template
567602
│ └── Dockerfile
568603
├── docs/ # Product, strategy, and deployment documentation
604+
├── install.sh # One-line GHCR install (curl | bash)
569605
├── docker-compose.yml # Web UI via GHCR; optional ./QuantDinger-Vue/ for local UI builds
606+
├── docker-compose.ghcr.yml # Zero-repo deploy — both images from GHCR
570607
├── LICENSE
571608
└── TRADEMARKS.md
572609
```

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.14
1+
3.0.15

backend_api_python/app/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
CI). Do **not** edit by hand — run the bump script instead.
66
"""
77

8-
APP_VERSION = "3.0.14"
8+
APP_VERSION = "3.0.15"

backend_api_python/app/data_providers/commodities.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
{"td": "BZ", "yf": "BZ=F", "tiingo": None, "name_cn": "原油 Brent", "name_en": "Brent Oil", "unit": "USD/bbl"},
1818
{"td": "HG", "yf": "HG=F", "tiingo": None, "name_cn": "铜", "name_en": "Copper", "unit": "USD/lb"},
1919
{"td": "NG", "yf": "NG=F", "tiingo": None, "name_cn": "天然气", "name_en": "Natural Gas", "unit": "USD/MMBtu"},
20+
{"td": "PL", "yf": "PL=F", "tiingo": None, "name_cn": "铂金", "name_en": "Platinum", "unit": "USD/oz"},
21+
{"td": "PA", "yf": "PA=F", "tiingo": None, "name_cn": "钯金", "name_en": "Palladium", "unit": "USD/oz"},
22+
{"td": "ALI", "yf": "ALI=F", "tiingo": None, "name_cn": "铝", "name_en": "Aluminum", "unit": "USD/lb"},
23+
{"td": "ZW", "yf": "ZW=F", "tiingo": None, "name_cn": "小麦", "name_en": "Wheat", "unit": "USD/bu"},
24+
{"td": "ZC", "yf": "ZC=F", "tiingo": None, "name_cn": "玉米", "name_en": "Corn", "unit": "USD/bu"},
25+
{"td": "SB", "yf": "SB=F", "tiingo": None, "name_cn": "糖", "name_en": "Sugar", "unit": "USD/lb"},
2026
]
2127

2228

backend_api_python/app/data_providers/crypto.py

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@
99

1010
logger = get_logger(__name__)
1111

12+
TOP_CRYPTO_SYMBOLS = [
13+
{"yf": "BTC-USD", "symbol": "BTC", "name": "Bitcoin"},
14+
{"yf": "ETH-USD", "symbol": "ETH", "name": "Ethereum"},
15+
{"yf": "BNB-USD", "symbol": "BNB", "name": "Binance Coin"},
16+
{"yf": "SOL-USD", "symbol": "SOL", "name": "Solana"},
17+
{"yf": "XRP-USD", "symbol": "XRP", "name": "Ripple"},
18+
{"yf": "ADA-USD", "symbol": "ADA", "name": "Cardano"},
19+
{"yf": "DOGE-USD", "symbol": "DOGE", "name": "Dogecoin"},
20+
{"yf": "AVAX-USD", "symbol": "AVAX", "name": "Avalanche"},
21+
{"yf": "DOT-USD", "symbol": "DOT", "name": "Polkadot"},
22+
{"yf": "POL-USD", "symbol": "POL", "name": "Polygon"},
23+
{"yf": "LINK-USD", "symbol": "LINK", "name": "Chainlink"},
24+
{"yf": "LTC-USD", "symbol": "LTC", "name": "Litecoin"},
25+
]
26+
1227

1328
def fetch_crypto_prices_ccxt() -> List[Dict[str, Any]]:
1429
"""Fetch crypto prices using CCXT (system's existing data source)."""
@@ -55,20 +70,7 @@ def fetch_crypto_prices_yfinance() -> List[Dict[str, Any]]:
5570
try:
5671
import yfinance as yf
5772

58-
symbols = [
59-
{"yf": "BTC-USD", "symbol": "BTC", "name": "Bitcoin"},
60-
{"yf": "ETH-USD", "symbol": "ETH", "name": "Ethereum"},
61-
{"yf": "BNB-USD", "symbol": "BNB", "name": "Binance Coin"},
62-
{"yf": "SOL-USD", "symbol": "SOL", "name": "Solana"},
63-
{"yf": "XRP-USD", "symbol": "XRP", "name": "Ripple"},
64-
{"yf": "ADA-USD", "symbol": "ADA", "name": "Cardano"},
65-
{"yf": "DOGE-USD", "symbol": "DOGE", "name": "Dogecoin"},
66-
{"yf": "AVAX-USD", "symbol": "AVAX", "name": "Avalanche"},
67-
{"yf": "DOT-USD", "symbol": "DOT", "name": "Polkadot"},
68-
{"yf": "POL-USD", "symbol": "POL", "name": "Polygon"},
69-
{"yf": "LINK-USD", "symbol": "LINK", "name": "Chainlink"},
70-
{"yf": "LTC-USD", "symbol": "LTC", "name": "Litecoin"},
71-
]
73+
symbols = TOP_CRYPTO_SYMBOLS
7274

7375
yf_symbols = [s["yf"] for s in symbols]
7476
tickers = yf.Tickers(" ".join(yf_symbols))
@@ -115,12 +117,13 @@ def fetch_crypto_prices_yfinance() -> List[Dict[str, Any]]:
115117
return []
116118

117119

118-
def fetch_crypto_prices() -> List[Dict[str, Any]]:
120+
def fetch_crypto_prices(*, fast: bool = False) -> List[Dict[str, Any]]:
119121
"""Fetch top crypto prices — try CCXT → yfinance → CoinGecko."""
120-
result = fetch_crypto_prices_ccxt()
121-
if result and len(result) >= 5:
122-
logger.info("Fetched %d crypto prices via CCXT", len(result))
123-
return result
122+
if not fast:
123+
result = fetch_crypto_prices_ccxt()
124+
if result and len(result) >= 5:
125+
logger.info("Fetched %d crypto prices via CCXT", len(result))
126+
return result
124127

125128
result = fetch_crypto_prices_yfinance()
126129
if result and len(result) >= 5:
@@ -161,11 +164,9 @@ def fetch_crypto_prices() -> List[Dict[str, Any]]:
161164

162165
logger.warning("All crypto data sources failed, returning placeholder data")
163166
return [
164-
{"symbol": "BTC", "name": "Bitcoin", "price": 0, "change_24h": 0, "change_7d": 0, "market_cap": 0, "volume_24h": 0, "image": "", "category": "crypto"},
165-
{"symbol": "ETH", "name": "Ethereum", "price": 0, "change_24h": 0, "change_7d": 0, "market_cap": 0, "volume_24h": 0, "image": "", "category": "crypto"},
166-
{"symbol": "BNB", "name": "BNB", "price": 0, "change_24h": 0, "change_7d": 0, "market_cap": 0, "volume_24h": 0, "image": "", "category": "crypto"},
167-
{"symbol": "SOL", "name": "Solana", "price": 0, "change_24h": 0, "change_7d": 0, "market_cap": 0, "volume_24h": 0, "image": "", "category": "crypto"},
168-
{"symbol": "XRP", "name": "XRP", "price": 0, "change_24h": 0, "change_7d": 0, "market_cap": 0, "volume_24h": 0, "image": "", "category": "crypto"},
167+
{"symbol": s["symbol"], "name": s["name"], "price": 0, "change_24h": 0, "change_7d": 0,
168+
"market_cap": 0, "volume_24h": 0, "image": "", "category": "crypto"}
169+
for s in TOP_CRYPTO_SYMBOLS
169170
]
170171

171172

0 commit comments

Comments
 (0)