V2.2.1: Membership & Billing, USDT TRC20 payment, VIP free indicators, AI Trading Radar, simplified strategy creation, system settings simplification, bug fixes and UI improvements
This commit is contained in:
+182
-1
@@ -4,6 +4,184 @@ This document records version updates, new features, bug fixes, and database mig
|
||||
|
||||
---
|
||||
|
||||
## V2.2.1 (2026-02-27)
|
||||
|
||||
### 🚀 New Features
|
||||
|
||||
#### Membership & Billing System
|
||||
- **Subscription Plans**: Monthly / Yearly / Lifetime tiers with configurable pricing and credit bundles
|
||||
- **Credit System**: Each plan includes credits; lifetime members receive recurring monthly credit bonuses
|
||||
- **Plan Management**: All plan prices, credits, and bonus amounts configurable via System Settings → Billing Configuration
|
||||
- **Membership Orders**: Order tracking with status management (paid / pending / failed / refunded)
|
||||
|
||||
#### USDT On-Chain Payment (TRC20)
|
||||
- **HD Wallet Integration**: Per-order unique receiving address derived from xpub (BIP-32/44) — no private key on server
|
||||
- **Automatic Reconciliation**: Background polling via TronGrid API detects incoming payments and confirms orders
|
||||
- **Depth-Flexible xpub**: Supports both account-level (depth=3) and change-level (depth=4) xpub keys
|
||||
- **Configurable Expiry**: Order expiration time and confirmation delay configurable in System Settings
|
||||
- **Scan-to-Pay Modal**: Professional checkout UI with QR code, step indicator, real-time status, copy-to-clipboard, dark theme support
|
||||
|
||||
#### VIP Free Indicators
|
||||
- **VIP Free Tag**: Admins can mark community indicators as "VIP Free" when publishing
|
||||
- **Zero-Credit Access**: VIP members can use VIP-free indicators without spending credits
|
||||
- **Visual Badge**: VIP Free indicators display a distinct badge in the Indicator Market
|
||||
|
||||
#### AI Trading Opportunities Radar
|
||||
- **Multi-Market Scanning**: Auto-scans Crypto, US Stocks, and Forex markets every hour
|
||||
- **Rolling Carousel**: Opportunities displayed in a rotating carousel with market-specific styling
|
||||
- **Signal Classification**: BUY / SELL signals with percentage change and reason text
|
||||
- **Multi-Language**: All radar card content fully internationalized
|
||||
|
||||
#### Simplified Strategy Creation
|
||||
- **Simple / Advanced Mode Toggle**: New users start with simplified mode, power users can switch to advanced
|
||||
- **Smart Defaults**: 15-minute K-line period, 5x leverage, market order, sensible TP/SL percentages
|
||||
- **Live Trading Disclaimer**: Mandatory risk acknowledgment checkbox before enabling live trading
|
||||
|
||||
#### System Settings Simplification
|
||||
- **Streamlined Configuration**: Removed redundant config groups (server, strategy); consolidated into essential categories
|
||||
- **Market Order Default**: Changed default order mode to market order for reliable execution
|
||||
- **Billing Config i18n**: All billing configuration items fully multi-language supported
|
||||
|
||||
#### Indicator Market Performance Tracking
|
||||
- **Live Performance Data**: Fixed aggregation to correctly parse backtest `result_json` and include live trade data
|
||||
- **Combined Metrics**: Backtest return, live PnL, and win rate now properly displayed on indicator cards
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- Fixed "Live Performance" data showing all zeros in Indicator Market (incorrect SQL query referencing non-existent columns)
|
||||
- Fixed incorrect entry price display in Position Records (was falling back to current price)
|
||||
- Fixed inaccurate System Overview statistics for running strategies, total capital, and total PnL
|
||||
- Fixed multiple duplicate i18n key issues in `zh-CN.js` and `en-US.js` causing ESLint build failures
|
||||
- Fixed exposed i18n keys (`common.loading`, `common.noData`, `systemOverview.*`) not configured
|
||||
- Fixed HTML nesting issues in trading assistant strategy creation form
|
||||
- Fixed `ed25519-blake2b` build failure in Docker by adding temporary build dependencies
|
||||
- Fixed "Current depth (3) is not suitable for deriving address" error for xpub — now compatible with both depth 3 and depth 4
|
||||
|
||||
### 🎨 UI/UX Improvements
|
||||
- Removed "Total Analyses" / "Accuracy Rate" row from homepage AI Analysis section
|
||||
- Removed "Search" and "Portfolio Checkup" features from AI Asset Analysis page
|
||||
- Professional USDT checkout modal with custom header, step indicator, dual-column layout
|
||||
- Dark theme and mobile responsive support for payment modal
|
||||
- Trading Opportunities Radar carousel with smooth scrolling animation
|
||||
|
||||
### 📋 Database Migration
|
||||
|
||||
**Run the following SQL on your PostgreSQL database before deploying V2.2.1:**
|
||||
|
||||
```sql
|
||||
-- ============================================================
|
||||
-- QuantDinger V2.2.1 Database Migration
|
||||
-- Membership, USDT Payment, VIP Free Indicators
|
||||
-- ============================================================
|
||||
|
||||
-- 1. User Table: Add membership columns
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'qd_users' AND column_name = 'vip_plan'
|
||||
) THEN
|
||||
ALTER TABLE qd_users ADD COLUMN vip_plan VARCHAR(20) DEFAULT '';
|
||||
RAISE NOTICE 'Added vip_plan column to qd_users';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'qd_users' AND column_name = 'vip_is_lifetime'
|
||||
) THEN
|
||||
ALTER TABLE qd_users ADD COLUMN vip_is_lifetime BOOLEAN DEFAULT FALSE;
|
||||
RAISE NOTICE 'Added vip_is_lifetime column to qd_users';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'qd_users' AND column_name = 'vip_monthly_credits_last_grant'
|
||||
) THEN
|
||||
ALTER TABLE qd_users ADD COLUMN vip_monthly_credits_last_grant TIMESTAMP;
|
||||
RAISE NOTICE 'Added vip_monthly_credits_last_grant column to qd_users';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 2. Indicator Codes: Add VIP Free flag
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'qd_indicator_codes' AND column_name = 'vip_free'
|
||||
) THEN
|
||||
ALTER TABLE qd_indicator_codes ADD COLUMN vip_free BOOLEAN DEFAULT FALSE;
|
||||
RAISE NOTICE 'Added vip_free column to qd_indicator_codes';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 3. Membership Orders table
|
||||
CREATE TABLE IF NOT EXISTS qd_membership_orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES qd_users(id) ON DELETE CASCADE,
|
||||
plan VARCHAR(20) NOT NULL,
|
||||
price_usd DECIMAL(10,2) DEFAULT 0,
|
||||
status VARCHAR(20) DEFAULT 'paid',
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
paid_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_membership_orders_user_id ON qd_membership_orders(user_id);
|
||||
|
||||
-- 4. USDT Orders table (on-chain payment tracking)
|
||||
CREATE TABLE IF NOT EXISTS qd_usdt_orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES qd_users(id) ON DELETE CASCADE,
|
||||
plan VARCHAR(20) NOT NULL,
|
||||
chain VARCHAR(20) NOT NULL DEFAULT 'TRC20',
|
||||
amount_usdt DECIMAL(20,6) NOT NULL DEFAULT 0,
|
||||
address_index INTEGER NOT NULL DEFAULT 0,
|
||||
address VARCHAR(80) NOT NULL DEFAULT '',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
tx_hash VARCHAR(120) DEFAULT '',
|
||||
paid_at TIMESTAMP,
|
||||
confirmed_at TIMESTAMP,
|
||||
expires_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_usdt_orders_address_unique ON qd_usdt_orders(chain, address);
|
||||
CREATE INDEX IF NOT EXISTS idx_usdt_orders_user_id ON qd_usdt_orders(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_usdt_orders_status ON qd_usdt_orders(status);
|
||||
|
||||
-- Migration Complete
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE '✅ QuantDinger V2.2.1 database migration completed!';
|
||||
END $$;
|
||||
```
|
||||
|
||||
**Migration Notes:**
|
||||
- All statements use `IF NOT EXISTS` — safe to run multiple times
|
||||
- No existing data is modified or deleted
|
||||
- New `.env` variables required for USDT payment: `USDT_PAY_ENABLED`, `USDT_TRC20_XPUB`, `TRONGRID_API_KEY`
|
||||
- New `.env` variables for membership pricing: `MEMBERSHIP_MONTHLY_PRICE_USD`, `MEMBERSHIP_MONTHLY_CREDITS`, etc.
|
||||
- See `backend_api_python/env.example` for all new configuration options
|
||||
|
||||
### 📝 Configuration Notes
|
||||
|
||||
New environment variables (all optional, with defaults):
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `MEMBERSHIP_MONTHLY_PRICE_USD` | `19.9` | Monthly plan price |
|
||||
| `MEMBERSHIP_MONTHLY_CREDITS` | `500` | Credits included in monthly plan |
|
||||
| `MEMBERSHIP_YEARLY_PRICE_USD` | `169` | Yearly plan price |
|
||||
| `MEMBERSHIP_YEARLY_CREDITS` | `8000` | Credits included in yearly plan |
|
||||
| `MEMBERSHIP_LIFETIME_PRICE_USD` | `499` | Lifetime plan price |
|
||||
| `MEMBERSHIP_LIFETIME_CREDITS` | `30000` | Initial credits for lifetime plan |
|
||||
| `MEMBERSHIP_LIFETIME_MONTHLY_BONUS` | `500` | Monthly bonus credits for lifetime members |
|
||||
| `USDT_PAY_ENABLED` | `false` | Enable USDT TRC20 payment |
|
||||
| `USDT_TRC20_XPUB` | _(empty)_ | TRC20 HD wallet xpub for address derivation |
|
||||
| `TRONGRID_API_KEY` | _(empty)_ | TronGrid API key for on-chain monitoring |
|
||||
| `USDT_ORDER_EXPIRE_MINUTES` | `30` | USDT order expiration time |
|
||||
|
||||
---
|
||||
|
||||
## V2.1.3 (2026-02-XX)
|
||||
|
||||
### 🚀 New Features
|
||||
@@ -195,7 +373,7 @@ output = {
|
||||
- Fixed progress bar and timer not animating during AI analysis
|
||||
- Fixed missing i18n translations for various components
|
||||
- Fixed Tiingo API rate limit issues with caching
|
||||
- Fixed A-share and H-share data fetching with multiple fallback sources
|
||||
- Fixed data fetching with multiple fallback sources
|
||||
- Fixed watchlist price batch fetch timeout handling
|
||||
- Fixed heatmap multi-language support for commodities and forex
|
||||
- **Fixed AI analysis history not filtered by user** - All users were seeing the same history records; now each user only sees their own analysis history
|
||||
@@ -418,6 +596,9 @@ END $$;
|
||||
|
||||
| Version | Date | Highlights |
|
||||
|---------|------|------------|
|
||||
| V2.2.1 | 2026-02-27 | Membership & Billing, USDT TRC20 payment, VIP free indicators, AI Trading Radar, simplified strategy creation |
|
||||
| V2.1.3 | 2026-02-XX | Cross-sectional strategy support |
|
||||
| V2.1.2 | 2026-02-01 | Indicator parameters, cross-indicator calling |
|
||||
| V2.1.1 | 2026-01-31 | AI Analysis overhaul, Global Market integration, Indicator Community enhancements |
|
||||
|
||||
---
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
# 盈透证券 (IBKR) 实盘交易指南
|
||||
|
||||
QuantDinger 支持通过盈透证券 TWS 或 IB Gateway 进行美股和港股的实盘交易。
|
||||
|
||||
## 概述
|
||||
|
||||
此功能可通过您的盈透证券账户实现美股和港股的自动化交易执行。配置完成后,您的交易策略可以通过 IBKR API 自动下单。
|
||||
|
||||
## 前置条件
|
||||
|
||||
- 盈透证券账户
|
||||
- 已安装 TWS (Trader Workstation) 或 IB Gateway
|
||||
- 已订阅市场数据(用于实时报价)
|
||||
|
||||
## 安装
|
||||
|
||||
`ib_insync` 库已包含在 `requirements.txt` 中。如需手动安装:
|
||||
|
||||
```bash
|
||||
pip install ib_insync
|
||||
```
|
||||
|
||||
## 端口参考
|
||||
|
||||
| 客户端 | 实盘端口 | 模拟盘端口 |
|
||||
|--------|----------|------------|
|
||||
| TWS | 7497 | 7496 |
|
||||
| IB Gateway | 4001 | 4002 |
|
||||
|
||||
## TWS / IB Gateway 配置
|
||||
|
||||
1. 打开 TWS 或 IB Gateway
|
||||
2. 进入 **配置** → **API** → **设置**
|
||||
3. 启用以下选项:
|
||||
- ✅ 启用 ActiveX 和 Socket 客户端
|
||||
- ✅ 仅允许来自本地主机的连接
|
||||
4. 设置 Socket 端口(参考上表)
|
||||
5. 点击 应用 / 确定
|
||||
|
||||
## 策略配置
|
||||
|
||||
创建美股或港股策略时,在"实盘交易"部分配置 IBKR 连接:
|
||||
|
||||
| 字段 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| **券商** | 选择"盈透证券" | - |
|
||||
| **主机地址** | TWS/Gateway 主机地址 | `127.0.0.1` |
|
||||
| **端口** | TWS/Gateway API 端口 | `7497`(TWS 实盘) |
|
||||
| **客户端 ID** | 唯一客户端标识 | `1` |
|
||||
| **账户号** | 账户 ID(可选) | 留空自动选择 |
|
||||
|
||||
## 代码格式
|
||||
|
||||
| 市场 | 格式 | 示例 |
|
||||
|------|------|------|
|
||||
| 美股 | 股票代码 | `AAPL`, `TSLA`, `GOOGL`, `MSFT` |
|
||||
| 港股 | `XXXX.HK` 或数字 | `0700.HK`, `00700`, `700` |
|
||||
|
||||
## 交易流程
|
||||
|
||||
```
|
||||
策略信号 → 待执行订单队列 → IBKR 执行 → 持仓更新
|
||||
```
|
||||
|
||||
1. 您的策略生成买入/卖出信号
|
||||
2. 信号作为待执行订单入队
|
||||
3. 后台工作线程连接 IBKR 并执行订单
|
||||
4. 更新持仓和交易记录
|
||||
|
||||
## 支持的信号类型
|
||||
|
||||
| 信号 | 动作 | 说明 |
|
||||
|------|------|------|
|
||||
| `open_long` | 买入 | 开多仓 |
|
||||
| `add_long` | 买入 | 加多仓 |
|
||||
| `close_long` | 卖出 | 平多仓 |
|
||||
| `reduce_long` | 卖出 | 减多仓 |
|
||||
|
||||
> **注意**:当前版本暂不支持做空交易。
|
||||
|
||||
## API 接口
|
||||
|
||||
### 连接管理
|
||||
|
||||
```
|
||||
GET /api/ibkr/status # 获取连接状态
|
||||
POST /api/ibkr/connect # 连接到 TWS/Gateway
|
||||
POST /api/ibkr/disconnect # 断开连接
|
||||
```
|
||||
|
||||
### 账户查询
|
||||
|
||||
```
|
||||
GET /api/ibkr/account # 账户信息
|
||||
GET /api/ibkr/positions # 当前持仓
|
||||
GET /api/ibkr/orders # 未成交订单
|
||||
```
|
||||
|
||||
### 交易
|
||||
|
||||
```
|
||||
POST /api/ibkr/order # 下单
|
||||
DELETE /api/ibkr/order/<id> # 撤单
|
||||
```
|
||||
|
||||
### 行情数据
|
||||
|
||||
```
|
||||
GET /api/ibkr/quote?symbol=AAPL&marketType=USStock
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 测试连接(通过 curl)
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:5000/api/ibkr/connect \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"host": "127.0.0.1", "port": 7497, "clientId": 1}'
|
||||
```
|
||||
|
||||
### 下单
|
||||
|
||||
```bash
|
||||
# 市价单:买入 10 股苹果
|
||||
curl -X POST http://localhost:5000/api/ibkr/order \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"symbol": "AAPL", "side": "buy", "quantity": 10, "marketType": "USStock"}'
|
||||
|
||||
# 限价单:卖出 100 股腾讯
|
||||
curl -X POST http://localhost:5000/api/ibkr/order \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"symbol": "0700.HK", "side": "sell", "quantity": 100, "marketType": "HShare", "orderType": "limit", "price": 300}'
|
||||
```
|
||||
|
||||
## 重要说明
|
||||
|
||||
1. **TWS/Gateway 必须运行**:交易前确保 TWS 或 IB Gateway 已启动并登录
|
||||
2. **市场数据订阅**:实时报价可能需要向 IBKR 订阅市场数据
|
||||
3. **客户端 ID**:如果多个程序连接同一个 TWS/Gateway,使用不同的 clientId
|
||||
4. **账户选择**:如有多个子账户,请指定 `account` 参数
|
||||
5. **交易时间**:订单仅在市场交易时间执行
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
| 错误 | 原因 | 解决方案 |
|
||||
|------|------|----------|
|
||||
| 连接失败 | TWS/Gateway 未运行 | 启动并登录 TWS/Gateway |
|
||||
| 连接失败 | 端口错误 | 检查 TWS/Gateway 中的 API 端口设置 |
|
||||
| 连接失败 | API 未启用 | 在 TWS/Gateway 设置中启用 Socket API |
|
||||
| 客户端 ID 冲突 | 相同 clientId 已连接 | 使用不同的 clientId |
|
||||
| 无效合约 | 代码格式错误 | 检查股票代码格式 |
|
||||
| 订单被拒绝 | 资金/保证金不足 | 检查账户余额 |
|
||||
|
||||
## Docker 部署
|
||||
|
||||
在 Docker 中运行 QuantDinger 时,TWS/IB Gateway 必须能从容器中访问:
|
||||
|
||||
1. 在宿主机上运行 TWS/Gateway
|
||||
2. 使用 `host.docker.internal` 作为主机地址(Docker Desktop)
|
||||
3. 或配置 host 网络模式
|
||||
|
||||
## 安全建议
|
||||
|
||||
- 在 TWS/Gateway 中仅启用"仅允许来自本地主机的连接"
|
||||
- 使用模拟盘账户进行测试
|
||||
- 在策略中设置适当的仓位限制
|
||||
- 定期监控您的账户
|
||||
|
||||
## 参见
|
||||
|
||||
- [Python 策略开发指南](STRATEGY_DEV_GUIDE_CN.md)
|
||||
- [盈透证券 API 文档](https://interactivebrokers.github.io/tws-api/)
|
||||
@@ -1,10 +1,10 @@
|
||||
# Interactive Brokers (IBKR) Trading Guide
|
||||
|
||||
QuantDinger supports US stocks and Hong Kong stocks live trading via Interactive Brokers TWS or IB Gateway.
|
||||
QuantDinger supports US stocks live trading via Interactive Brokers TWS or IB Gateway.
|
||||
|
||||
## Overview
|
||||
|
||||
This feature enables automated trading execution for US and HK stock markets through your Interactive Brokers account. Once configured, your trading strategies can automatically place orders via the IBKR API.
|
||||
This feature enables automated trading execution for US stock markets through your Interactive Brokers account. Once configured, your trading strategies can automatically place orders via the IBKR API.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -39,7 +39,7 @@ pip install ib_insync
|
||||
|
||||
## Strategy Configuration
|
||||
|
||||
When creating a strategy for US or HK stocks, configure the IBKR connection in the "Live Trading" section:
|
||||
When creating a strategy for US stocks, configure the IBKR connection in the "Live Trading" section:
|
||||
|
||||
| Field | Description | Example |
|
||||
|-------|-------------|---------|
|
||||
@@ -54,7 +54,6 @@ When creating a strategy for US or HK stocks, configure the IBKR connection in t
|
||||
| Market | Format | Examples |
|
||||
|--------|--------|----------|
|
||||
| US Stock | Ticker symbol | `AAPL`, `TSLA`, `GOOGL`, `MSFT` |
|
||||
| HK Stock | `XXXX.HK` or digits | `0700.HK`, `00700`, `700` |
|
||||
|
||||
## Trading Flow
|
||||
|
||||
@@ -126,11 +125,6 @@ curl -X POST http://localhost:5000/api/ibkr/connect \
|
||||
curl -X POST http://localhost:5000/api/ibkr/order \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"symbol": "AAPL", "side": "buy", "quantity": 10, "marketType": "USStock"}'
|
||||
|
||||
# Limit order: sell 100 shares of Tencent
|
||||
curl -X POST http://localhost:5000/api/ibkr/order \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"symbol": "0700.HK", "side": "sell", "quantity": 100, "marketType": "HShare", "orderType": "limit", "price": 300}'
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
Reference in New Issue
Block a user