mirror of
https://github.com/OpenByteInc/QuantDinger.git
synced 2026-09-28 15:22:56 +08:00
488 lines
18 KiB
Plaintext
488 lines
18 KiB
Plaintext
# QuantDinger local configuration (copy to `.env` and edit)
|
|
# `run.py` will load `backend_api_python/.env` automatically if present.
|
|
#
|
|
# This file is organized as:
|
|
# 1) first-time deployment settings at the top
|
|
# 2) advanced / rarely changed settings at the bottom
|
|
# For Docker image source / ports, use the project-root `.env`.
|
|
|
|
# =========================
|
|
# Brand / identity (drives logo, footer, version label, legal modals)
|
|
# =========================
|
|
# Frontend reads these via /api/settings/brand-config — leave any field empty
|
|
# to fall back to the bundled QuantDinger defaults. Change here (or via the
|
|
# Settings page) to rebrand a deployment without rebuilding the frontend.
|
|
BRAND_APP_NAME=QuantDinger
|
|
BRAND_APP_VERSION=3.0.8
|
|
BRAND_COPYRIGHT=© 2025-2026 QuantDinger. All rights reserved.
|
|
|
|
# Logo / favicon URLs (HTTPS recommended; leave empty to use bundled assets)
|
|
BRAND_LOGO_LIGHT_URL=
|
|
BRAND_LOGO_DARK_URL=
|
|
BRAND_LOGO_COLLAPSED_URL=
|
|
BRAND_FAVICON_URL=
|
|
|
|
# Contact & support links surfaced in the sidebar footer.
|
|
BRAND_CONTACT_EMAIL=brokermr810@gmail.com
|
|
BRAND_CONTACT_SUPPORT_URL=https://t.me/quantdinger
|
|
BRAND_CONTACT_LIVE_CHAT_URL=https://t.me/quantdinger
|
|
BRAND_CONTACT_FEATURE_REQUEST_URL=https://github.com/brokermr810/QuantDinger/issues
|
|
|
|
# Social accounts shown as icons in the sidebar footer. Leave any single
|
|
# entry empty to hide that icon.
|
|
BRAND_SOCIAL_GITHUB=https://github.com/brokermr810/QuantDinger
|
|
BRAND_SOCIAL_X=https://x.com/quantdinger_en
|
|
BRAND_SOCIAL_DISCORD=https://discord.com/invite/tyx5B6TChr
|
|
BRAND_SOCIAL_TELEGRAM=https://t.me/quantdinger
|
|
BRAND_SOCIAL_YOUTUBE=https://youtube.com/@quantdinger
|
|
|
|
# Legal: external URL takes priority; if both URL and inline text are empty,
|
|
# the frontend falls back to the built-in i18n copy.
|
|
BRAND_LEGAL_USER_AGREEMENT_URL=
|
|
BRAND_LEGAL_USER_AGREEMENT_TEXT=
|
|
BRAND_LEGAL_PRIVACY_POLICY_URL=
|
|
BRAND_LEGAL_PRIVACY_POLICY_TEXT=
|
|
|
|
# =========================
|
|
# Auth (required)
|
|
# =========================
|
|
# Also derives Fernet key for encrypting qd_exchange_credentials.encrypted_config (do not rotate casually).
|
|
SECRET_KEY=quantdinger-secret-key-change-me
|
|
ADMIN_USER=quantdinger
|
|
ADMIN_PASSWORD=123456
|
|
ADMIN_EMAIL=
|
|
|
|
# =========================
|
|
# Core app
|
|
# =========================
|
|
DATABASE_URL=postgresql://quantdinger:quantdinger123@postgres:5432/quantdinger
|
|
# FRONTEND_URL: the canonical user-facing URL of the web app.
|
|
# - Used for: CORS allow-list, default post-login OAuth redirect target.
|
|
# - Comma-separated multi-origin IS supported (the first entry is the
|
|
# default OAuth redirect; every entry is added to the CORS / OAuth
|
|
# allow-list). Prefer the simpler `OAUTH_ALLOWED_REDIRECTS` below for
|
|
# the second / third front-end origin so that this stays a single URL.
|
|
# - You do NOT need to add Capacitor / Cordova / Ionic mobile-app origins
|
|
# here (https://localhost, capacitor://localhost, ionic://localhost,
|
|
# http://localhost). The backend whitelists those automatically because
|
|
# they are fixed synthetic origins controlled by the OS, not user input.
|
|
# - If your mobile app uses a separate API subdomain like
|
|
# https://api.quantdinger.com, make sure your nginx server_block for that
|
|
# host is reverse-proxying /api/* to the backend port (5000).
|
|
# Examples:
|
|
# FRONTEND_URL=https://ai.quantdinger.com
|
|
# FRONTEND_URL=https://ai.quantdinger.com,https://m.quantdinger.com
|
|
FRONTEND_URL=http://localhost:8888
|
|
# Extra front-end origins allowed as OAuth post-login redirect targets.
|
|
# Comma-separated, scheme + host (+ optional port). Used when multiple clients
|
|
# (e.g. PC web + mobile web) share the same backend. FRONTEND_URL is always
|
|
# allowed implicitly; list every additional front-end here.
|
|
# Example: OAUTH_ALLOWED_REDIRECTS=https://m.quantdinger.com,https://app.quantdinger.com
|
|
OAUTH_ALLOWED_REDIRECTS=
|
|
# OAuth CSRF state TTL (minutes); stored in Postgres for multi-worker. Default 20, clamped [5,120].
|
|
OAUTH_STATE_TTL_MINUTES=20
|
|
ENABLE_REGISTRATION=true
|
|
|
|
# =========================
|
|
# Mobile app (in-app version check)
|
|
# =========================
|
|
# Semver-like string shown to clients; leave empty to avoid "new version" prompts.
|
|
MOBILE_APP_LATEST_VERSION=
|
|
# APK / install page URL for one-tap update on Android (HTTPS recommended).
|
|
MOBILE_APP_DOWNLOAD_URL=https://www.quantdinger.com/download/app.apk
|
|
|
|
# =========================
|
|
# Database bootstrap behaviour
|
|
# =========================
|
|
# On every backend startup we auto-apply `migrations/init.sql` so a fresh
|
|
# install (especially bare-metal / Windows local PG) gets the full schema
|
|
# without anyone remembering to `psql -f` first. The file uses
|
|
# `CREATE TABLE IF NOT EXISTS` everywhere so re-running is a no-op.
|
|
# Set to `true` if you manage schema externally (Flyway, Liquibase, etc.)
|
|
# and don't want the backend touching DDL on boot. Permission probing on
|
|
# critical tables still runs either way.
|
|
SKIP_AUTO_MIGRATE=false
|
|
|
|
# =========================
|
|
# Database connection pool (psycopg2 ThreadedConnectionPool)
|
|
# =========================
|
|
# Tune these if you see `psycopg2.pool.PoolError: connection pool exhausted`
|
|
# or if you run many trading bots / portfolios concurrently.
|
|
# Make sure PG `max_connections` (docker-compose: PG_MAX_CONNECTIONS) is
|
|
# comfortably larger than DB_POOL_MAX.
|
|
DB_POOL_MIN=5
|
|
DB_POOL_MAX=50
|
|
DB_POOL_ACQUIRE_TIMEOUT=10
|
|
DB_POOL_HEALTH_CHECK=true
|
|
|
|
# Route-level parallel fetch executors. Each worker may hold one DB
|
|
# connection, so keep MARKET_EXECUTOR_WORKERS + PORTFOLIO_EXECUTOR_WORKERS
|
|
# well below DB_POOL_MAX.
|
|
MARKET_EXECUTOR_WORKERS=6
|
|
PORTFOLIO_EXECUTOR_WORKERS=3
|
|
|
|
# Gunicorn worker/thread model
|
|
GUNICORN_WORKERS=1
|
|
GUNICORN_THREADS=8
|
|
|
|
# =========================
|
|
# AI / LLM (choose one provider)
|
|
# =========================
|
|
LLM_PROVIDER=openrouter
|
|
|
|
OPENROUTER_API_KEY=
|
|
OPENROUTER_MODEL=openai/gpt-4o
|
|
# Optional: dedicated model for AI code generation (fallback to provider default if empty)
|
|
AI_CODE_GEN_MODEL=
|
|
|
|
OPENAI_API_KEY=
|
|
OPENAI_MODEL=gpt-4o
|
|
|
|
GOOGLE_API_KEY=
|
|
GOOGLE_MODEL=gemini-1.5-flash
|
|
|
|
DEEPSEEK_API_KEY=
|
|
DEEPSEEK_MODEL=deepseek-chat
|
|
|
|
GROK_API_KEY=
|
|
GROK_MODEL=grok-beta
|
|
|
|
# OpenAI-compatible third-party API (set LLM_PROVIDER=custom)
|
|
# Local Ollama example (backend must reach this host; Docker Desktop: http://host.docker.internal:11434/v1):
|
|
# CUSTOM_API_URL=http://127.0.0.1:11434/v1
|
|
# CUSTOM_MODEL=llama3.2
|
|
# Ollama usually needs no key — leave CUSTOM_API_KEY empty.
|
|
CUSTOM_API_URL=
|
|
CUSTOM_API_KEY=
|
|
CUSTOM_MODEL=
|
|
|
|
# MiniMax (set LLM_PROVIDER=minimax)
|
|
MINIMAX_API_KEY=
|
|
MINIMAX_MODEL=MiniMax-M2.7
|
|
MINIMAX_BASE_URL=https://api.minimax.io/v1
|
|
|
|
# =========================
|
|
# Common background jobs
|
|
# =========================
|
|
ENABLE_PENDING_ORDER_WORKER=true
|
|
ENABLE_PORTFOLIO_MONITOR=true
|
|
DISABLE_RESTORE_RUNNING_STRATEGIES=false
|
|
|
|
# =========================
|
|
# Agent Gateway (/api/agent/v1) — see docs/agent/AI_INTEGRATION_DESIGN.md
|
|
# =========================
|
|
# Thread pool size for async agent jobs (backtests, experiment pipelines).
|
|
AGENT_JOBS_MAX_WORKERS=4
|
|
# Hard kill switch for live trading from agent tokens. Even when a token is
|
|
# issued with paper_only=false, live order routing remains disabled until this
|
|
# flag is true AND a live executor implementation is wired in. Until then,
|
|
# `T`-class agent calls always record paper orders in qd_agent_paper_orders.
|
|
AGENT_LIVE_TRADING_ENABLED=false
|
|
# Deployment topology hint for the Agent Gateway.
|
|
# (unset) — single-tenant / self-hosted; admins keep full control of
|
|
# paper_only and the T (Trading) scope.
|
|
# saas / hosted — multi-tenant hosted instance (e.g. ai.quantdinger.com):
|
|
# `paper_only` is force-pinned to true and any attempt to
|
|
# issue a T-scope agent token returns 403. Use this on every
|
|
# deployment that serves more than one operator's data, so a
|
|
# misconfigured token can never route real-money orders.
|
|
QUANTDINGER_DEPLOYMENT_MODE=
|
|
|
|
# =========================
|
|
# Email / SMTP (optional)
|
|
# =========================
|
|
SMTP_HOST=
|
|
SMTP_PORT=587
|
|
SMTP_USER=
|
|
SMTP_PASSWORD=
|
|
SMTP_FROM=
|
|
SMTP_USE_TLS=true
|
|
SMTP_USE_SSL=false
|
|
|
|
# =========================
|
|
# Proxy (optional)
|
|
# =========================
|
|
# PROXY_URL=socks5h://127.0.0.1:10808 # local
|
|
# PROXY_URL=socks5h://host.docker.internal:10808 # Docker
|
|
PROXY_URL=
|
|
|
|
# Outbound HTTPS to exchanges when using PROXY_URL (especially SOCKS). If you see
|
|
# SSLCertVerificationError / "unable to get local issuer certificate":
|
|
# - Prefer: install OS ca-certificates in the image, or point to a PEM bundle:
|
|
# LIVE_TRADING_CA_BUNDLE=/path/to/ca-bundle.pem
|
|
# (REQUESTS_CA_BUNDLE / SSL_CERT_FILE are also honored.)
|
|
# - Last resort only: LIVE_TRADING_SSL_VERIFY=false # disables TLS verify — insecure
|
|
#LIVE_TRADING_CA_BUNDLE=
|
|
#LIVE_TRADING_SSL_VERIFY=
|
|
|
|
# =========================
|
|
# Local desktop brokers (IBKR / MT5)
|
|
# =========================
|
|
# Interactive Brokers and MetaTrader 5 need TWS/IB Gateway or the MT5 terminal on a
|
|
# machine reachable from this API (typically your own PC or a VPS with those apps).
|
|
# On a public multi-tenant cloud deployment, set to false so users see a clear message
|
|
# instead of broken flows. Crypto exchange API keys are unaffected.
|
|
ALLOW_LOCAL_DESKTOP_BROKERS=true
|
|
|
|
# IBKR: clientId for live orders (strategy worker). Must differ from POST /api/ibkr/connect
|
|
# default (1) or TWS will disconnect one of the sessions within seconds.
|
|
#IBKR_ORDER_CLIENT_ID=7
|
|
|
|
# =========================
|
|
# Captcha / OAuth (optional)
|
|
# =========================
|
|
TURNSTILE_SITE_KEY=
|
|
TURNSTILE_SECRET_KEY=
|
|
|
|
GOOGLE_CLIENT_ID=
|
|
GOOGLE_CLIENT_SECRET=
|
|
GOOGLE_REDIRECT_URI=http://localhost:5000/api/auth/oauth/google/callback
|
|
|
|
GITHUB_CLIENT_ID=
|
|
GITHUB_CLIENT_SECRET=
|
|
GITHUB_REDIRECT_URI=http://localhost:5000/api/auth/oauth/github/callback
|
|
|
|
# =========================
|
|
# Billing / payments
|
|
# =========================
|
|
BILLING_ENABLED=false
|
|
|
|
# 积分单价
|
|
BILLING_COST_AI_ANALYSIS=10
|
|
BILLING_COST_AI_CODE_GEN=30
|
|
|
|
CREDITS_REGISTER_BONUS=100
|
|
CREDITS_REFERRAL_BONUS=50
|
|
|
|
# Membership plans
|
|
MEMBERSHIP_MONTHLY_PRICE_USD=19.9
|
|
MEMBERSHIP_YEARLY_PRICE_USD=199
|
|
MEMBERSHIP_LIFETIME_PRICE_USD=499
|
|
MEMBERSHIP_MONTHLY_CREDITS=500
|
|
MEMBERSHIP_YEARLY_CREDITS=8000
|
|
MEMBERSHIP_LIFETIME_MONTHLY_CREDITS=800
|
|
|
|
# =========================
|
|
# USDT payment (v3.0.6+: single fixed address per chain + amount-suffix matching)
|
|
# =========================
|
|
# How it works (replaces the old xpub HD-derived per-order address model):
|
|
# - One fixed receiving address per chain (your own main wallet).
|
|
# - Every order is identified on-chain by a unique amount suffix in the
|
|
# low decimals, e.g. base $19.9 -> 19.991234 USDT, where .001234 is the
|
|
# unique order tag. Funds land directly in your wallet, no consolidation.
|
|
# - Chains without an address configured are auto-hidden in the UI.
|
|
#
|
|
# Global switch.
|
|
USDT_PAY_ENABLED=false
|
|
|
|
# Comma-separated list of enabled chains. Any code not in this list is rejected
|
|
# at order creation even if its address is configured. Valid codes:
|
|
# TRC20 / BEP20 / ERC20 / SOL
|
|
USDT_PAY_ENABLED_CHAINS=TRC20,BEP20,ERC20,SOL
|
|
|
|
# --- Receiving addresses (one per chain). Leave blank to hide that chain ---
|
|
# TRON (base58, starts with T...)
|
|
USDT_TRC20_ADDRESS=
|
|
# BSC (EVM 0x..., the same Ethereum-style address)
|
|
USDT_BEP20_ADDRESS=
|
|
# Ethereum (EVM 0x...)
|
|
USDT_ERC20_ADDRESS=
|
|
# Solana (wallet address; the SPL USDT mint ATA is computed on-chain by the wallet)
|
|
USDT_SOL_ADDRESS=
|
|
|
|
# --- USDT contract / mint per chain (override only if you know what you're doing) ---
|
|
USDT_TRC20_CONTRACT=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
|
|
USDT_BEP20_CONTRACT=0x55d398326f99059fF775485246999027B3197955
|
|
USDT_ERC20_CONTRACT=0xdAC17F958D2ee523a2206206994597C13D831ec7
|
|
USDT_SOL_MINT=Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
|
|
|
|
# --- Block explorers / RPC endpoints used to reconcile incoming transfers ---
|
|
TRONGRID_BASE_URL=https://api.trongrid.io
|
|
TRONGRID_API_KEY=
|
|
|
|
# BSC (BEP20) USDT reconciliation runs on public BSC JSON-RPC by default
|
|
# — Etherscan's V2 free plan no longer covers BSC and the legacy v1 host
|
|
# is deprecated. The watcher calls eth_getLogs against the USDT contract,
|
|
# filtered by Transfer(from, to, value) events, which every public BSC
|
|
# node supports natively at no cost. Comma-separated list; leave blank
|
|
# to use the curated defaults baked into the code.
|
|
BSC_RPC_URLS=https://bsc-dataseed1.binance.org,https://bsc.publicnode.com,https://rpc.ankr.com/bsc
|
|
|
|
# ERC20 (Ethereum) USDT reconciliation uses Etherscan V2 first because
|
|
# its free plan still covers Ethereum mainnet, falling back to public
|
|
# Ethereum RPC if the explorer call fails. Set ETHERSCAN_API_KEY to a
|
|
# key from https://etherscan.io/myapikey (free tier is enough for ETH).
|
|
ETHERSCAN_API_KEY=
|
|
ETHERSCAN_V2_BASE_URL=https://api.etherscan.io/v2/api
|
|
ETH_RPC_URLS=https://ethereum-rpc.publicnode.com,https://rpc.ankr.com/eth
|
|
|
|
# Override per-chain reconciliation strategy. Set BEP20_PREFER_EXPLORER=true
|
|
# only if you upgrade to an Etherscan API paid plan that covers BSC; leave
|
|
# it false (default) for RPC-only reconciliation. Same idea for ERC20.
|
|
# BEP20_PREFER_EXPLORER=false
|
|
# ERC20_PREFER_EXPLORER=true
|
|
|
|
# Legacy v1 explorer overrides — only set these if you intentionally pin
|
|
# to a deprecated v1 host (api.bscscan.com / api.etherscan.io). Leave them
|
|
# commented out for new deployments; the v2 unified API + RPC fallback
|
|
# above is preferred.
|
|
# ETHERSCAN_BASE_URL=
|
|
# BSCSCAN_BASE_URL=
|
|
# BSCSCAN_API_KEY=
|
|
|
|
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
|
|
|
|
# --- Amount suffix policy ---
|
|
# Number of decimals used for the suffix portion. 6 means ±0.000001 USDT
|
|
# granularity, giving a collision space of ~10^5 per (chain, base_price)
|
|
# inside the active window. The unique index on (chain, amount_usdt) where
|
|
# status IN ('pending','paid') guarantees no two live orders collide.
|
|
USDT_AMOUNT_SUFFIX_DECIMALS=6
|
|
|
|
# --- Confirm / expiry / worker tuning ---
|
|
USDT_PAY_CONFIRM_SECONDS=30
|
|
USDT_PAY_EXPIRE_MINUTES=30
|
|
USDT_WORKER_POLL_INTERVAL=30
|
|
|
|
# =========================
|
|
# Advanced / rarely changed
|
|
# =========================
|
|
|
|
# Network / App tuning
|
|
PYTHON_API_HOST=0.0.0.0
|
|
PYTHON_API_PORT=5000
|
|
PYTHON_API_DEBUG=false
|
|
RATE_LIMIT=100
|
|
ENABLE_CACHE=false
|
|
ENABLE_REQUEST_LOG=true
|
|
|
|
# Strategy / execution tuning
|
|
PENDING_ORDER_STALE_SEC=90
|
|
ORDER_MODE=market
|
|
MAKER_WAIT_SEC=10
|
|
MAKER_OFFSET_BPS=2
|
|
STRATEGY_TICK_INTERVAL_SEC=10
|
|
# 单进程内「实盘/信号策略」并发线程上限(每个运行中策略约占用 1 条线程)。默认 64;调高需评估内存与系统线程上限,改后重启 API。
|
|
STRATEGY_MAX_THREADS=64
|
|
PRICE_CACHE_TTL_SEC=10
|
|
K_LINE_HISTORY_GET_NUMBER=500
|
|
SIGNAL_NOTIFY_TIMEOUT_SEC=6
|
|
|
|
# LLM advanced tuning
|
|
OPENROUTER_API_URL=https://openrouter.ai/api/v1/chat/completions
|
|
OPENROUTER_TEMPERATURE=0.7
|
|
OPENROUTER_MAX_TOKENS=4000
|
|
OPENROUTER_TIMEOUT=300
|
|
OPENROUTER_CONNECT_TIMEOUT=30
|
|
OPENAI_BASE_URL=https://api.openai.com/v1
|
|
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
|
|
GROK_BASE_URL=https://api.x.ai/v1
|
|
MINIMAX_BASE_URL=https://api.minimax.io/v1
|
|
|
|
# Data sources
|
|
DATA_SOURCE_TIMEOUT=30
|
|
DATA_SOURCE_RETRY=3
|
|
DATA_SOURCE_RETRY_BACKOFF=0.5
|
|
FINNHUB_API_KEY=
|
|
FINNHUB_TIMEOUT=10
|
|
FINNHUB_RATE_LIMIT=60
|
|
CCXT_DEFAULT_EXCHANGE=coinbase
|
|
CCXT_TIMEOUT=10000
|
|
AKSHARE_TIMEOUT=30
|
|
YFINANCE_TIMEOUT=30
|
|
TIINGO_API_KEY=
|
|
TIINGO_TIMEOUT=10
|
|
|
|
# Crypto derivatives / on-chain data (optional, used by some AI prompts)
|
|
COINGLASS_API_KEY=
|
|
CRYPTOQUANT_API_KEY=
|
|
|
|
# Twelve Data (CN/HK stock K-lines — recommended for overseas servers)
|
|
# Free tier: 800 API credits/day, 8 requests/minute. https://twelvedata.com
|
|
TWELVE_DATA_API_KEY=
|
|
|
|
# Adanos Market Sentiment (optional US stock sentiment enrichment)
|
|
# If ADANOS_API_KEY is empty, /api/global-market/adanos-sentiment returns enabled=false.
|
|
ADANOS_API_KEY=
|
|
ADANOS_SENTIMENT_SOURCE=reddit
|
|
ADANOS_API_BASE_URL=https://api.adanos.org
|
|
ADANOS_API_TIMEOUT=10
|
|
|
|
# AI search / news
|
|
SEARCH_PROVIDER=google
|
|
SEARCH_MAX_RESULTS=10
|
|
SEARCH_GOOGLE_API_KEY=
|
|
SEARCH_GOOGLE_CX=
|
|
SEARCH_BING_API_KEY=
|
|
TAVILY_API_KEYS=
|
|
SERPAPI_KEYS=
|
|
|
|
# SMS / phone (optional)
|
|
TWILIO_ACCOUNT_SID=
|
|
TWILIO_AUTH_TOKEN=
|
|
TWILIO_FROM_NUMBER=
|
|
|
|
# Security / verification tuning
|
|
SECURITY_IP_MAX_ATTEMPTS=10
|
|
SECURITY_IP_WINDOW_MINUTES=5
|
|
SECURITY_IP_BLOCK_MINUTES=15
|
|
SECURITY_ACCOUNT_MAX_ATTEMPTS=5
|
|
SECURITY_ACCOUNT_WINDOW_MINUTES=60
|
|
SECURITY_ACCOUNT_BLOCK_MINUTES=30
|
|
VERIFICATION_CODE_EXPIRE_MINUTES=10
|
|
VERIFICATION_CODE_RATE_LIMIT=60
|
|
VERIFICATION_CODE_IP_HOURLY_LIMIT=10
|
|
VERIFICATION_CODE_MAX_ATTEMPTS=5
|
|
VERIFICATION_CODE_LOCK_MINUTES=30
|
|
|
|
# AI analysis tuning
|
|
ENABLE_CONFIDENCE_CALIBRATION=false
|
|
ENABLE_AI_ENSEMBLE=false
|
|
AI_ENSEMBLE_MODELS=openai/gpt-4o,openai/gpt-4o-mini
|
|
ENABLE_REFLECTION_WORKER=false
|
|
REFLECTION_WORKER_INTERVAL_SEC=86400
|
|
REFLECTION_MIN_AGE_DAYS=7
|
|
REFLECTION_VALIDATE_LIMIT=200
|
|
AI_CALIBRATION_MARKETS=Crypto
|
|
AI_CALIBRATION_LOOKBACK_DAYS=30
|
|
AI_CALIBRATION_MIN_SAMPLES=80
|
|
AI_ANALYSIS_CONSENSUS_TIMEFRAMES=1D,4H
|
|
|
|
# Redis cache (auto-configured by docker-compose; set CACHE_ENABLED=true to use)
|
|
REDIS_HOST=redis
|
|
REDIS_PORT=6379
|
|
CACHE_ENABLED=true
|
|
|
|
# Internal
|
|
INTERNAL_API_KEY=
|
|
|
|
# Market visibility (which markets appear in the watchlist picker /
|
|
# Agent API catalog / home AI radar).
|
|
#
|
|
# Primary knob (recommended):
|
|
# ENABLED_MARKETS — CSV whitelist. When set, ONLY these markets are
|
|
# visible everywhere. Unknown values are ignored. Empty = whitelist
|
|
# disabled (falls back to the legacy SHOW_* flags below).
|
|
# Valid values: Crypto, USStock, CNStock, HKStock, Forex, Futures, MOEX
|
|
# Examples:
|
|
# ENABLED_MARKETS=Crypto,USStock # crypto + US stocks only
|
|
# ENABLED_MARKETS=Crypto # crypto-only deployment
|
|
# ENABLED_MARKETS= # unset → legacy flags apply
|
|
# ENABLED_MARKETS=
|
|
#
|
|
# Legacy flags (kept for back-compat; ignored when ENABLED_MARKETS is set):
|
|
# SHOW_CN_STOCK (default false) — China A-shares
|
|
# SHOW_HK_STOCK (default true) — Hong Kong stocks
|
|
# All other known markets default to visible.
|
|
SHOW_CN_STOCK=false
|
|
# SHOW_HK_STOCK=true
|
|
# ============================================================
|
|
# ALPACA MARKETS (US stocks, ETFs, crypto)
|
|
# ============================================================
|
|
# Paper: keys start with "PK..." (paper-api.alpaca.markets)
|
|
# Live: keys start with "AK..." (api.alpaca.markets)
|
|
# Get keys: https://app.alpaca.markets
|
|
ALPACA_API_KEY=
|
|
ALPACA_SECRET_KEY=
|
|
ALPACA_PAPER=true
|