QuantDinger Documentation
Self-hosted AI trading platform for quant research, Python strategy development, backtesting, and live execution. One stack for AI analysis, charting, strategy code, backtests, quick trade, and live operations — on infrastructure you fully control.
Docker-first install
One command spins up the full backend, PostgreSQL, Redis, and Nginx-served frontend.
Python-native
Write strategies in pandas dataframes or event-driven on_bar scripts.
AI built into the loop
OpenAI, Claude, Gemini, DeepSeek, Grok — analysis, generation, ensemble, calibration.
Mobile + Web + Native
Full mobile H5, Android Capacitor build, Vue desktop — all talk to the same API.
Introduction #
QuantDinger is a self-hosted quantitative trading and algorithmic trading platform for AI-assisted research, Python strategy development, backtesting, and live execution. Your credentials, strategy code, market workflows, and operational data stay under your control.
Capabilities include:
- AI market analysis — structured, low-latency analysis with memory, ensemble voting, and confidence calibration across OpenAI, Claude, Gemini, DeepSeek, Grok and more.
- Python strategy development — dataframe-based
IndicatorStrategyor event-drivenScriptStrategy. AI can draft a starting point; you stay in control of the code. - Deterministic backtesting — commission and slippage modeling, trade-by-trade analytics, equity curves. Every run is pinned to a code hash and config snapshot.
- Autonomous trading bots — Grid, Martingale, Trend Following, and DCA. Execution-aware, restart-resilient, signal or live execution modes.
- Operator-ready — multi-user PostgreSQL, role-based access, Google / GitHub OAuth, memberships, credits, USDT payments, Telegram / Email / SMS / Discord / Webhook alerts.
Architecture #
QuantDinger runs as a self-hosted application stack:
| Layer | Technology |
|---|---|
| Frontend | Prebuilt Vue application served by Nginx |
| Backend | Flask API, Python services, strategy runtime |
| Storage | PostgreSQL 16 |
| Cache / worker support | Redis 7 |
| Trading layer | Exchange adapters, IBKR, MT5 |
| AI layer | LLM provider integration, memory, calibration, optional workers |
| Billing | Membership, credits, USDT TRC20 payment flow |
| Deployment | Docker Compose with health checks |
Execution model
- Market data is pulled through a pluggable data layer.
- Backtests run on the server-side strategy engine, including strategy snapshot handling.
- Live strategies run through runtime services that generate order intent.
- Pending orders are dispatched through exchange-specific execution adapters.
- Crypto live execution is intentionally separated from market-data collection concerns.
Quick Start #
The fastest way to try QuantDinger locally — everything runs in Docker, no Node.js required:
git clone https://github.com/brokermr810/QuantDinger.git
cd QuantDinger
cp backend_api_python/env.example backend_api_python/.env
./scripts/generate-secret-key.sh
docker-compose up -d --build
git clone https://github.com/brokermr810/QuantDinger.git
cd QuantDinger
Copy-Item backend_api_python\env.example -Destination backend_api_python\.env
$key = py -c "import secrets; print(secrets.token_hex(32))"
(Get-Content backend_api_python\.env) -replace '^SECRET_KEY=.*$', "SECRET_KEY=$key" | Set-Content backend_api_python\.env -Encoding UTF8
docker-compose up -d --build
After startup:
- Frontend:
http://localhost:8888 - Backend health check:
http://localhost:5000/api/health - Default login:
quantdinger/123456
SECRET_KEY still uses the default value. Always regenerate it and change the admin password before exposing the service to the internet.
Prerequisites #
- Docker 20+ and Docker Compose v2
- A clean host with at least 2 vCPU / 4 GB RAM / 20 GB disk for small teams
- (Optional) Nginx on the host for custom domains, SSL, and reverse proxying — the stack already ships with its own Nginx for local use
Node.js is not required for deployment because this repository ships the prebuilt frontend in frontend/dist.
Docker Compose #
The default stack includes frontend, backend, postgres, and redis, wired together with health checks. The main application config lives in backend_api_python/.env.
Spin it up
docker-compose up -d --build
Stop and remove
docker-compose down
# keep data (Postgres/Redis volumes); pass -v to wipe volumes
docker-compose down -v
Common commands #
docker-compose ps # show container status
docker-compose logs -f backend # tail backend logs
docker-compose restart backend # restart only the backend
docker-compose up -d --build # rebuild after config/code changes
docker-compose exec backend bash # open a shell inside the backend container
backend_api_python/.env, you can just run docker-compose restart backend — there is no need to rebuild the image.
Optional root .env #
If you need custom ports or image mirrors, create a root .env next to docker-compose.yml:
FRONTEND_PORT=3000
BACKEND_PORT=127.0.0.1:5001
IMAGE_PREFIX=docker.m.daocloud.io/library/
Binding the backend to 127.0.0.1:5001 means only your host Nginx can reach it — recommended for production where a reverse proxy terminates SSL.
Configuration overview #
All runtime configuration happens through backend_api_python/.env. Start from env.example in the same folder and change values in place.
| Area | Example keys |
|---|---|
| Authentication | SECRET_KEY, ADMIN_USER, ADMIN_PASSWORD |
| Database | DATABASE_URL |
| LLM / AI | LLM_PROVIDER, OPENAI_API_KEY, OPENROUTER_API_KEY |
| OAuth | GOOGLE_CLIENT_ID, GITHUB_CLIENT_ID |
| Security | TURNSTILE_SITE_KEY, ENABLE_REGISTRATION |
| Billing | BILLING_ENABLED, BILLING_COST_AI_ANALYSIS |
| Membership | MEMBERSHIP_MONTHLY_PRICE_USD, MEMBERSHIP_MONTHLY_CREDITS |
| USDT payments | USDT_PAY_ENABLED, USDT_TRC20_XPUB, TRONGRID_API_KEY |
| Proxy | PROXY_URL |
| Workers | ENABLE_PENDING_ORDER_WORKER, ENABLE_PORTFOLIO_MONITOR, ENABLE_REFLECTION_WORKER |
| AI tuning | ENABLE_AI_ENSEMBLE, ENABLE_CONFIDENCE_CALIBRATION, AI_ENSEMBLE_MODELS |
Authentication #
The SECRET_KEY signs all JWT tokens. It must be a cryptographically-random 64-char hex string — the backend refuses to start with the default placeholder.
SECRET_KEY=<run: python -c "import secrets; print(secrets.token_hex(32))">
ADMIN_USER=quantdinger
ADMIN_PASSWORD=change-me-before-going-live
# Token lifetime in seconds (default 7 days)
JWT_EXPIRATION=604800
Database #
Point DATABASE_URL at PostgreSQL 16. The default value targets the in-stack postgres service from Docker Compose:
DATABASE_URL=postgresql://quantdinger:quantdinger@postgres:5432/quantdinger
Migrations run automatically on startup from backend_api_python/migrations/init.sql. For managed database providers (Supabase, Neon, AWS RDS…), replace the URL and make sure inbound connections are allowed from your host.
AI providers #
QuantDinger ships adapters for several LLM providers. Pick any subset that matches your budget and compliance posture.
| Provider | Key | Typical use |
|---|---|---|
| OpenRouter | OPENROUTER_API_KEY | Aggregator — best first choice |
| OpenAI | OPENAI_API_KEY | GPT-4o / GPT-5 family |
| Anthropic | CLAUDE_API_KEY | Claude 3.x / 4.x |
GEMINI_API_KEY | Gemini 1.5 / 2.0 | |
| DeepSeek | DEEPSEEK_API_KEY | Cost-effective reasoning |
| xAI | GROK_API_KEY | Grok family |
Ensemble and calibration
For teams that want more robust AI outputs, turn on ensemble voting and confidence calibration:
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 keeps the login experience modern and removes password friction. Register an application on each provider, then set:
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
# Whitelist of frontend origins the backend will redirect back to after OAuth.
# Include every domain you serve the app from (PC, mobile, staging).
OAUTH_ALLOWED_REDIRECTS=https://ai.quantdinger.com,https://m.quantdinger.com
# Primary frontend URL for redirect fallback
FRONTEND_URL=https://ai.quantdinger.com
/api/auth/oauth/<provider>/callback, not the frontend URL. The backend then redirects back to the frontend origin listed in OAUTH_ALLOWED_REDIRECTS.
If the mobile app is served on a different origin, make sure that origin is added to
OAUTH_ALLOWED_REDIRECTS before you test — otherwise the backend will redirect users to the fallback FRONTEND_URL.
Cloudflare Turnstile #
Turnstile gates the login, register, and password-reset flows to keep bots out. Enable it once you go public:
TURNSTILE_ENABLED=true
TURNSTILE_SITE_KEY=0x4AAA...
TURNSTILE_SECRET_KEY=0x4AAA...
Content-Security-Policy header (via Nginx or Cloudflare), the widget will fail to load. Whitelist https://challenges.cloudflare.com for both script-src and frame-src.
Billing & membership #
The backend ships with first-class memberships, credits, and per-action pricing. Start with a conservative default, then adjust as you see real usage:
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 payments #
The USDT TRC20 flow generates a unique deposit address per user and polls TronGrid for confirmations. Fund credits are issued automatically when the network confirms.
USDT_PAY_ENABLED=true
USDT_TRC20_XPUB=xpub6... # BIP-32 extended public key (TRC20 HD derivation)
TRONGRID_API_KEY=...
USDT_CONFIRMATIONS_REQUIRED=12
Notifications #
Each user can wire their own Telegram / Email / SMS / Discord / Webhook from the in-app Profile → Notifications page. The system-level fallbacks (admin alerts, cron digests) are configured here:
# 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 toggles #
Background workers run inside the backend container. Disable any that you do not need — they save CPU and reduce startup noise:
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
Strategy Development #
QuantDinger supports two complementary strategy authoring models. Pick the one that matches the shape of your logic:
IndicatorStrategy
Dataframe-based Python. Transform the df and return buy/sell boolean columns. Great for research, signal prototyping, and chart overlays.
ScriptStrategy
Event-driven. Implement on_init(ctx) / on_bar(ctx, bar) and call ctx.buy() / ctx.sell() / ctx.close_position() explicitly. Great for stateful, execution-oriented logic.
IndicatorStrategy #
A minimal dual-moving-average crossover:
# @param sma_short int 14 Short moving average
# @param sma_long int 28 Long moving average
sma_short_period = params.get('sma_short', 14)
sma_long_period = params.get('sma_long', 28)
my_indicator_name = "Dual Moving Average Strategy"
my_indicator_description = f"SMA {sma_short_period}/{sma_long_period} crossover"
df = df.copy()
sma_short = df["close"].rolling(sma_short_period).mean()
sma_long = df["close"].rolling(sma_long_period).mean()
buy = (sma_short > sma_long) & (sma_short.shift(1) <= sma_long.shift(1))
sell = (sma_short < sma_long) & (sma_short.shift(1) >= sma_long.shift(1))
df["buy"] = buy.fillna(False).astype(bool)
df["sell"] = sell.fillna(False).astype(bool)
Inputs available to the script:
df— pandas DataFrame with at leastopen,high,low,close,volume,ts.params— dict of the user-supplied parameters declared via# @param.
Expected outputs:
df["buy"],df["sell"]— boolean signal columns (required).my_indicator_name,my_indicator_description— display metadata (optional).- Any additional float columns on
df— plotted as indicators on the chart.
ScriptStrategy #
Skeleton of a grid-style bot in ScriptStrategy form:
def on_init(ctx):
ctx.grid_pct = float(ctx.param("grid_pct", 0.012))
ctx.grid_levels = int( ctx.param("grid_levels", 6))
ctx.order_pct = float(ctx.param("order_pct", 0.08))
ctx.anchor_price = None
ctx.log("Init grid bot: grid_pct=%.4f levels=%d"
% (ctx.grid_pct, ctx.grid_levels))
def on_bar(ctx, bar):
price = float(bar.close)
if ctx.anchor_price is None:
ctx.anchor_price = price
return
lower = ctx.anchor_price * (1.0 - ctx.grid_pct)
upper = ctx.anchor_price * (1.0 + ctx.grid_pct)
if price <= lower:
amount = (float(ctx.balance) * ctx.order_pct) / price
if amount > 0:
ctx.buy(price, amount)
ctx.anchor_price = price
elif price >= upper and ctx.position:
ctx.sell(price, float(ctx.position["size"]))
ctx.anchor_price = price
def on_stop(ctx):
ctx.log("Grid bot stopped")
Context API
| Member | Description |
|---|---|
ctx.param(name, default) | User-configurable parameter lookup. |
ctx.balance | Available quote-currency balance. |
ctx.equity | Total account equity (balance + open positions marked-to-market). |
ctx.position | Current open position as {size, entry_price, side} or None. |
ctx.bars(n) | Most recent n bars (list, oldest first). |
ctx.buy(price, amount) | Submit a buy order. |
ctx.sell(price, amount) | Submit a sell order. |
ctx.close_position() | Flatten the current position. |
ctx.log(msg) | Write to the strategy log. |
Lifecycle hooks
on_init(ctx)— called once when the strategy starts.on_bar(ctx, bar)— called for each new closed candle.on_order_filled(ctx, order)— called after an order is executed.on_stop(ctx)— called once on shutdown.
Declaring parameters #
Both strategy types use the same comment syntax so the UI can render a typed form:
# @param sma_short int 14 Short moving average
# @param sma_long int 28 Long moving average
# @param use_filter bool true Require trend filter
# @param symbol string BTCUSDT Instrument to trade
Supported types: int, float, bool, string. The last field is the human-readable label.
Backtesting #
Every backtest is pinned to:
- the exact code hash of the script,
- a frozen parameter snapshot,
- the commission and slippage model you chose,
- the market data range.
Outputs are persisted to PostgreSQL and include per-trade P&L, equity curve, max drawdown, Sharpe, win rate, and exposure time. Re-running with the same snapshot reproduces results deterministically.
Trading Bots #
Four built-in bot archetypes cover most mechanical-trading workflows. Each one is a first-class ScriptStrategy template with a guided UI.
Grid #
Classic range trader that lays a ladder of buy/sell orders around an anchor price. Best for sideways, mean-reverting instruments.
| Parameter | Meaning |
|---|---|
| grid_pct | Price step between grid levels, as a fraction of the anchor. |
| grid_levels | How many levels exist on each side. |
| order_pct | Order size per level as a fraction of balance. |
| max_position_value_pct | Cap on total capital deployed. |
| take_profit_pct | Close the whole stack when P&L crosses this threshold. |
Martingale #
Averaging-down system that increases position size after adverse moves. Highest reward when markets mean-revert, highest risk when trends break out.
max_daily_loss and max_position_value. Martingale can wipe out an account during a single prolonged trend.
Trend #
Break-out and moving-average crossover bot. Enters with the trend, rides momentum, and uses trailing stops to lock in gains. Best for directional markets.
DCA #
Dollar-cost averaging bot that buys a fixed notional on a schedule — daily, weekly, or on dips past a threshold. Ideal for long-horizon accumulation in spot markets.
Crypto exchanges #
| Venue | Coverage |
|---|---|
| Binance | Spot, Futures, Margin |
| OKX | Spot, Perpetual, Options |
| Bitget | Spot, Futures, Copy Trading |
| Bybit | Spot, Linear Futures |
| Coinbase | Spot |
| Kraken | Spot, Futures |
| KuCoin | Spot, Futures |
| Gate.io | Spot, Futures |
| Deepcoin | Derivatives integration |
| HTX | Spot, USDT-margined perpetuals |
Add credentials from Profile → API keys. Keys are encrypted at rest and only decrypted in the execution path.
US stocks via IBKR #
Interactive Brokers is wired up through the standard TWS / IB Gateway bridge. Data is available through Yahoo Finance and Finnhub when a live IBKR subscription is not desired for research.
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
Forex via MT5 #
MT5 integration runs through the Python MetaTrader 5 bridge. Both data and execution are supported. OANDA is supported as a read-only data source.
Polymarket #
Polymarket is currently supported as a research and analysis workflow — market lookup, divergence analysis, opportunity scoring, AI-assisted review — not as direct in-platform live execution.
Mobile web (H5) #
The mobile client is a separate Vue 3 + Vant app that talks to the same backend API as the desktop one. To build the H5 bundle for deployment:
cd quantdinger_mobile
npm install # first time only
npm run build # outputs to ./dist
Serve dist/ with any static web server. A production Nginx config is documented in Mobile Nginx config below.
Android APK build #
The mobile app is wrapped with Capacitor. To produce a debug APK:
1. Install Android Studio
Install the stable release of Android Studio. It bundles the JDK (jbr/) and the Android SDK you need.
2. Set environment variables
$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. Build the web bundle and sync
npm run build
npx cap sync android
4. Point Gradle at the SDK
Create android/local.properties:
sdk.dir=C\:\\Users\\YourName\\AppData\\Local\\Android\\Sdk
5. Run the Gradle build
cd android
./gradlew assembleDebug # Linux/macOS
.\gradlew.bat assembleDebug # Windows
The APK lands at android/app/build/outputs/apk/debug/app-debug.apk.
android/gradle/wrapper/gradle-wrapper.properties — for example https://mirrors.cloud.tencent.com/gradle/gradle-8.2.1-all.zip. This is the most common fix in regions where services.gradle.org is slow.
Release APK
Generate a keystore, add a signingConfigs block in android/app/build.gradle, then run ./gradlew assembleRelease. Output: android/app/build/outputs/apk/release/app-release.apk.
Mobile Nginx config #
Reference Nginx config for serving the H5 bundle on m.quantdinger.com, with SPA history-mode fallback and reverse-proxy to the backend:
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;
}
}
Production checklist #
- Regenerate
SECRET_KEYwith 64 random hex bytes. - Change
ADMIN_USER/ADMIN_PASSWORDfrom the defaults. - Bind the backend to
127.0.0.1and terminate TLS at the host Nginx. - Enable Turnstile on public login/register/reset endpoints.
- Point
DATABASE_URLat a managed PostgreSQL with automated backups — or snapshot the Docker volume daily. - Allowlist mobile + desktop origins in
OAUTH_ALLOWED_REDIRECTS. - Turn off any worker you don't use (reflection, portfolio monitor).
- Rotate exchange API keys quarterly; create read-only keys wherever possible.
PC site Nginx #
For the desktop app at ai.quantdinger.com, use a similar config but proxy the frontend container (the prebuilt Vue app lives inside the frontend service on port 80 by default):
server {
listen 443 ssl http2;
server_name ai.quantdinger.com;
ssl_certificate /etc/letsencrypt/live/ai.quantdinger.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ai.quantdinger.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location /api/ {
proxy_pass http://127.0.0.1:5000/api/;
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;
}
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}
SSL / HTTPS #
Use Let's Encrypt with certbot or your hosting panel's built-in ACME. Keep only TLSv1.2 and TLSv1.3 — older versions (TLSv1, TLSv1.1) are rejected by modern browsers and will surface as ERR_SSL_PROTOCOL_ERROR.
OAuth allowed redirects #
After OAuth, the backend issues a short-lived oauth_token and redirects the user to the frontend origin. For that redirect to succeed:
- The frontend origin must be listed in
OAUTH_ALLOWED_REDIRECTS. - The frontend route must exist — for history-mode SPAs, ensure
/loginis reachable and not a 404 (see the SPA fallback rule). - If your desktop client uses hash-mode routing, the backend preserves the hash (
/#/user/login) automatically.
Troubleshooting #
Backend refuses to start: "SECRET_KEY is unsafe"
Regenerate the key and restart:
python -c "import secrets; print(secrets.token_hex(32))"
# copy the output into backend_api_python/.env → SECRET_KEY=...
docker-compose restart backend
Google / GitHub OAuth redirects to the wrong domain
- Add the exact origin (including scheme and port if non-default) to
OAUTH_ALLOWED_REDIRECTS. - Rebuild the backend:
docker-compose up -d --build backend. - Clear cookies for the OAuth provider and retry.
Mobile H5 shows 404 on /login after OAuth
The Nginx config is missing the SPA fallback. Add try_files $uri $uri/ /index.html; inside location /.
Turnstile widget fails to load (code 600010)
- Check the response headers for
Content-Security-Policy. - Whitelist
https://challenges.cloudflare.comunderscript-srcandframe-src, or remove the CSP header entirely while you debug. - Confirm the Site Key's Hostname Management in the Cloudflare dashboard includes the domain you are serving from.
Gradle wrapper download times out
Edit android/gradle/wrapper/gradle-wrapper.properties and swap distributionUrl to a nearby mirror:
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.2.1-all.zip
networkTimeout=60000
ERR_SSL_PROTOCOL_ERROR in the browser
- Restrict
ssl_protocolstoTLSv1.2 TLSv1.3only — dropTLSv1andTLSv1.1. - Verify the certificate files exist at the paths configured in Nginx.
- Reload Nginx (
nginx -t && nginx -s reload).
FAQ #
Is QuantDinger really self-hosted?
Yes. The default deployment model is your own Docker Compose stack with your own database, Redis instance, credentials, and environment configuration.
Is it only for crypto trading?
No. Crypto is a major focus, but the platform also includes IBKR workflows for US stocks, MT5 workflows for forex, and Polymarket research support.
Can I write strategies directly in Python?
Yes — both IndicatorStrategy and ScriptStrategy are raw Python. You can also use AI to generate a starting point and then edit it yourself.
Is this a research tool or a live trading platform?
Both. QuantDinger is built to connect AI research, charting, strategy development, backtesting, quick trade flows, and live execution operations in one system.
Can I use QuantDinger commercially?
The backend is Apache 2.0. The frontend has a separate source-available license — commercial use is supported but review the license files in the repository first.
License #
- Backend: Apache License 2.0 (see
LICENSE). - Frontend UI is distributed here as prebuilt files. The Vue source lives at QuantDinger-Vue under the QuantDinger Frontend Source-Available License v1.0.
- Non-commercial and eligible qualified non-profit use of the frontend is free of charge; commercial use requires a separate commercial license.
- Trademark, branding, attribution, and watermark usage are governed by
TRADEMARKS.md.
Community & support #
- GitHub: brokermr810/QuantDinger
- Telegram: @quantdinger
- Discord: Join the server
- YouTube: @quantdinger
- Email: support@quantdinger.com
Found a bug or have a feature request? Open an issue on GitHub — we triage weekly.
QuantDinger