This commit is contained in:
薇薇安 2026-01-17 01:28:39 +08:00
parent 90f3d019ed
commit 6d2498b717
8 changed files with 1062 additions and 0 deletions

207
DYNAMIC_LEVERAGE.md Normal file
View File

@ -0,0 +1,207 @@
# 动态杠杆功能说明
## 功能概述
根据信号质量动态调整杠杆倍数,让高质量信号使用更高杠杆来最大化收益。
## 工作原理
### 杠杆计算公式
```
动态杠杆 = 基础杠杆 + (信号强度 - 最小信号强度) × (最大杠杆 - 基础杠杆) / (10 - 最小信号强度)
```
### 示例
假设配置:
- 基础杠杆10倍
- 最大杠杆20倍
- 最小信号强度7
| 信号强度 | 计算过程 | 动态杠杆 |
|---------|---------|---------|
| 7 | 10 + (7-7) × (20-10) / (10-7) = 10 | 10x |
| 8 | 10 + (8-7) × (20-10) / (10-7) = 13.3 | 13x |
| 9 | 10 + (9-7) × (20-10) / (10-7) = 16.7 | 17x |
| 10 | 10 + (10-7) × (20-10) / (10-7) = 20 | 20x |
## 配置参数
### 数据库配置
`backend/database/init.sql` 中已添加:
```sql
('USE_DYNAMIC_LEVERAGE', 'true', 'boolean', 'strategy', '是否启用动态杠杆(根据信号强度调整杠杆倍数)'),
('MAX_LEVERAGE', '20', 'number', 'strategy', '最大杠杆倍数(动态杠杆上限)'),
```
### 配置说明
- **USE_DYNAMIC_LEVERAGE**: 是否启用动态杠杆
- `true`: 启用,根据信号强度动态调整杠杆
- `false`: 禁用始终使用基础杠杆LEVERAGE
- **LEVERAGE**: 基础杠杆倍数默认10倍
- 当信号强度 = 最小信号强度时使用
- 当动态杠杆禁用时使用
- **MAX_LEVERAGE**: 最大杠杆倍数默认20倍
- 动态杠杆的上限
- 即使信号强度为10也不会超过此值
- **MIN_SIGNAL_STRENGTH**: 最小信号强度默认7
- 低于此强度的信号使用基础杠杆
- 高于此强度的信号按比例增加杠杆
## 收益影响分析
### 收益放大效果
假设:
- 账户余额100 USDT
- 仓位比例5%
- 基础杠杆10倍
- 最大杠杆20倍
- 信号强度10/10
**使用固定杠杆10倍**
- 仓位价值100 × 5% = 5 USDT
- 保证金5 / 10 = 0.5 USDT
- 如果盈利5%收益5 × 5% = 0.25 USDT
**使用动态杠杆20倍**
- 仓位价值100 × 5% = 5 USDT
- 保证金5 / 20 = 0.25 USDT
- 如果盈利5%收益5 × 5% = 0.25 USDT相同
- **但使用更少的保证金,可以开更多仓位**
或者保持保证金不变:
- 保证金0.5 USDT与固定杠杆相同
- 仓位价值0.5 × 20 = 10 USDT是固定杠杆的2倍
- 如果盈利5%收益10 × 5% = 0.5 USDT是固定杠杆的2倍
### 风险提示
⚠️ **重要提示**
- 杠杆越高,风险越大
- 高杠杆会放大亏损
- 建议:
- 保守策略MAX_LEVERAGE = 15
- 平衡策略MAX_LEVERAGE = 20
- 激进策略MAX_LEVERAGE = 25需谨慎
## 使用建议
### 1. 保守配置(推荐新手)
```sql
USE_DYNAMIC_LEVERAGE = true
LEVERAGE = 10
MAX_LEVERAGE = 15
MIN_SIGNAL_STRENGTH = 7
```
- 信号强度7-810倍杠杆
- 信号强度912-13倍杠杆
- 信号强度1015倍杠杆
### 2. 平衡配置(推荐)
```sql
USE_DYNAMIC_LEVERAGE = true
LEVERAGE = 10
MAX_LEVERAGE = 20
MIN_SIGNAL_STRENGTH = 7
```
- 信号强度710倍杠杆
- 信号强度813倍杠杆
- 信号强度917倍杠杆
- 信号强度1020倍杠杆
### 3. 激进配置(需谨慎)
```sql
USE_DYNAMIC_LEVERAGE = true
LEVERAGE = 10
MAX_LEVERAGE = 25
MIN_SIGNAL_STRENGTH = 7
```
- 信号强度710倍杠杆
- 信号强度815倍杠杆
- 信号强度920倍杠杆
- 信号强度1025倍杠杆
## 代码实现
### 1. RiskManager.calculate_dynamic_leverage()
位置:`trading_system/risk_manager.py`
```python
def calculate_dynamic_leverage(self, signal_strength: int) -> int:
"""
根据信号强度计算动态杠杆倍数
信号强度越高,杠杆倍数越高,以最大化收益
"""
# 获取配置参数
use_dynamic_leverage = self.config.get('USE_DYNAMIC_LEVERAGE', True)
base_leverage = self.config.get('LEVERAGE', 10)
max_leverage = self.config.get('MAX_LEVERAGE', 20)
min_signal_strength = self.config.get('MIN_SIGNAL_STRENGTH', 7)
# 如果未启用动态杠杆,返回基础杠杆
if not use_dynamic_leverage:
return int(base_leverage)
# 计算动态杠杆...
return dynamic_leverage
```
### 2. Strategy 中使用动态杠杆
位置:`trading_system/strategy.py`
```python
# 根据信号强度计算动态杠杆(高质量信号使用更高杠杆)
dynamic_leverage = self.risk_manager.calculate_dynamic_leverage(signal_strength)
# 开仓时使用动态杠杆
position = await self.position_manager.open_position(
symbol=symbol,
change_percent=change_percent,
leverage=dynamic_leverage, # 使用动态杠杆
...
)
```
## 监控建议
建议监控以下指标:
1. **平均杠杆倍数**
- 观察实际使用的杠杆分布
- 确保在合理范围内
2. **信号强度分布**
- 观察信号强度的分布情况
- 如果大部分信号强度都很高,可能需要调整策略
3. **收益对比**
- 对比启用/禁用动态杠杆的收益
- 评估动态杠杆的实际效果
4. **风险指标**
- 监控最大回撤
- 确保高杠杆不会导致过度风险
## 总结
动态杠杆功能可以根据信号质量自动调整杠杆倍数,让高质量信号使用更高杠杆来最大化收益。但需要注意:
- ✅ **优点**:高质量信号可以获得更高收益
- ⚠️ **风险**:高杠杆会放大亏损,需要谨慎配置
- 💡 **建议**:从保守配置开始,根据实际效果逐步调整

61
FIX_CURSOR_PATH_ISSUE.md Normal file
View File

@ -0,0 +1,61 @@
# 修复 Cursor Worktree 路径问题
## 问题描述
Cursor 在应用 worktree 更改时,错误地尝试写入 `/Users/work/python/auto_trade_sys/...` 而不是 `/Users/vivian/work/python/auto_trade_sys/...`,导致权限错误。
## 解决方案
### 方案1创建符号链接推荐需要管理员权限
在终端执行:
```bash
sudo ln -sf /Users/vivian/work /Users/work
```
这将创建符号链接,让 Cursor 能够访问正确的路径。
### 方案2手动复制文件如果确实有差异
如果 worktree 中有未同步的更改,可以手动复制:
```bash
# 检查哪些文件有差异
cd /Users/vivian/.cursor/worktrees/auto_trade_sys/tcu
git diff --name-only master
# 如果有差异,手动复制文件
cp backend/config_manager.py /Users/vivian/work/python/auto_trade_sys/backend/
cp frontend/src/components/ConfigPanel.jsx /Users/vivian/work/python/auto_trade_sys/frontend/src/components/
# ... 其他文件
```
### 方案3直接在主分支工作避免 worktree
关闭 worktree直接在主分支工作
```bash
cd /Users/vivian/work/python/auto_trade_sys
# 在这里直接编辑文件
```
### 方案4忽略错误推荐如果文件已同步
如果所有文件已经同步(已验证),可以安全地忽略这些错误提示。功能不受影响。
## 验证文件是否已同步
运行以下命令验证:
```bash
for file in "backend/config_manager.py" "backend/database/init.sql" "frontend/src/components/ConfigPanel.jsx"; do
diff -q /Users/vivian/.cursor/worktrees/auto_trade_sys/tcu/$file /Users/vivian/work/python/auto_trade_sys/$file
done
```
如果没有输出,说明文件已同步。
## 当前状态
✅ 所有代码文件已同步
✅ worktree 和主分支在同一个 commit (90f3d01)
✅ 功能正常
这是 Cursor 的路径解析 bug不影响实际功能。

182
MIN_MARGIN_ANALYSIS.md Normal file
View File

@ -0,0 +1,182 @@
# 最小保证金限制分析
## 问题背景
系统出现下0.01U保证金的单子,收益非常小,可能被手续费侵蚀。
### 为什么会出现0.01U保证金?
**保证金计算公式**`保证金 = 仓位价值(名义价值)/ 杠杆`
**示例**
- 账户余额10 USDT
- 仓位比例5% (MAX_POSITION_PERCENT)
- 杠杆10倍
- 仓位价值 = 10 × 5% = 0.5 USDT
- **保证金 = 0.5 / 10 = 0.05 USDT**
如果账户余额更小如2 USDT或仓位比例更小如1%就会出现0.01U甚至更小的保证金。
### 手续费侵蚀问题
币安合约交易手续费:
- **开仓手续费**0.02% - 0.04%maker/taker
- **平仓手续费**0.02% - 0.04%maker/taker
- **总手续费**:约 0.04% - 0.08%
**0.01U保证金的单子**
- 仓位价值10倍杠杆0.1 USDT
- 开仓手续费0.1 × 0.04% = 0.00004 USDT
- 平仓手续费0.1 × 0.04% = 0.00004 USDT
- **总手续费占比**0.00008 / 0.01 = **0.8%**
即使盈利1%扣除手续费后实际收益只有0.2%,收益微乎其微。
## 解决方案:最小保证金限制
### 设置 MIN_MARGIN_USDT = 0.5 USDT
**效果**
- 确保每笔交易的保证金至少为 0.5 USDT
- 10倍杠杆下仓位价值至少为 5 USDT
- 手续费占比降低到约 0.008% - 0.016%
### 计算示例
#### 设置前0.01U保证金)
- 账户余额10 USDT
- 仓位价值0.5 USDT
- 保证金0.05 USDT
- 手续费0.0002 USDT
- **手续费/保证金 = 0.4%**
#### 设置后0.5U最小保证金)
- 账户余额10 USDT
- 仓位价值5 USDT自动调整
- 保证金0.5 USDT
- 手续费0.002 USDT
- **手续费/保证金 = 0.4%** ✅(但绝对金额更合理)
### 不同账户余额的影响
| 账户余额 | 5%仓位价值 | 10倍杠杆保证金 | 是否满足0.5U要求 | 系统行为 |
|---------|-----------|--------------|----------------|---------|
| 10 USDT | 0.5 USDT | 0.05 USDT | ❌ 不满足 | 自动调整到5 USDT仓位价值0.5U保证金) |
| 50 USDT | 2.5 USDT | 0.25 USDT | ❌ 不满足 | 自动调整到5 USDT仓位价值0.5U保证金) |
| 100 USDT | 5 USDT | 0.5 USDT | ✅ 满足 | 正常使用5 USDT仓位价值 |
| 200 USDT | 10 USDT | 1.0 USDT | ✅ 满足 | 正常使用10 USDT仓位价值 |
## 实现逻辑
### 1. 配置参数
```sql
-- 数据库配置
('MIN_MARGIN_USDT', '0.5', 'number', 'position', '最小保证金要求0.5 USDT避免手续费侵蚀收益')
```
### 2. 仓位计算流程
1. **计算基础仓位价值**`仓位价值 = 账户余额 × 仓位比例`
2. **检查币安最小名义价值**:确保 >= 5 USDT
3. **计算保证金**`保证金 = 仓位价值 / 杠杆`
4. **检查最小保证金要求**:确保 >= MIN_MARGIN_USDT (0.5 USDT)
5. **如果不足,自动调整**
- 计算需要的仓位价值:`所需仓位价值 = MIN_MARGIN_USDT × 杠杆`
- 检查是否超过最大仓位限制
- 如果不超过,调整仓位价值;如果超过,拒绝交易
### 3. 代码实现位置
- `trading_system/risk_manager.py` - `calculate_position_size()` 方法
- 在检查币安最小名义价值之后,添加最小保证金检查
## 影响分析
### 优点
1. **避免手续费侵蚀**
- 确保每笔交易有足够的保证金
- 手续费占比相对降低
2. **提高交易质量**
- 过滤掉过小的交易
- 专注于更有价值的交易机会
3. **更好的风险收益比**
- 保证金越大,单笔交易的潜在收益也越大
- 避免"蚊子腿"交易
### 缺点
1. **小账户可能无法交易**
- 如果账户余额 < 10 USDT10倍杠杆下需要5 USDT仓位价值
- 系统会拒绝交易,提示增加账户余额
2. **可能错过一些机会**
- 如果账户余额刚好在临界值附近
- 可能会因为保证金不足而跳过一些交易
3. **仓位可能被强制放大**
- 如果账户余额较小,系统会自动调整仓位价值以满足最小保证金
- 可能超过原本计划的仓位比例
## 建议配置
### 根据账户规模调整
| 账户规模 | 建议 MIN_MARGIN_USDT | 说明 |
|---------|---------------------|------|
| < 50 USDT | 0.5 USDT | 确保手续费占比合理 |
| 50-200 USDT | 0.5-1.0 USDT | 平衡交易频率和收益 |
| 200-1000 USDT | 1.0-2.0 USDT | 提高单笔交易质量 |
| > 1000 USDT | 2.0-5.0 USDT | 专注于高质量交易 |
### 计算公式
**最小账户余额要求**
```
最小账户余额 = MIN_MARGIN_USDT × 杠杆 / MAX_POSITION_PERCENT
```
**示例MIN_MARGIN_USDT=0.5, 杠杆=10, MAX_POSITION_PERCENT=5%**
```
最小账户余额 = 0.5 × 10 / 0.05 = 100 USDT
```
这意味着:
- 如果账户余额 < 100 USDT系统会自动调整仓位价值以满足最小保证金
- 如果账户余额 >= 100 USDT系统按正常仓位比例计算
## 监控指标
建议监控以下指标:
1. **被拒绝的交易数量**
- 因保证金不足被拒绝的交易
- 如果过多,考虑降低 MIN_MARGIN_USDT
2. **平均保证金**
- 实际交易的保证金分布
- 确保大部分交易满足最小要求
3. **手续费占比**
- 手续费 / 保证金
- 目标:< 1%
4. **账户余额分布**
- 如果账户余额经常 < 最小要求考虑调整参数
## 总结
设置 `MIN_MARGIN_USDT = 0.5 USDT` 可以有效:
- ✅ 避免手续费侵蚀收益
- ✅ 提高交易质量
- ✅ 确保每笔交易有足够的保证金
**建议**
- 小账户(< 100 USDT使用 0.5 USDT 最小保证金
- 中等账户100-500 USDT使用 1.0 USDT 最小保证金
- 大账户(> 500 USDT使用 2.0 USDT 最小保证金
这样可以确保每笔交易都有合理的收益空间,不会被手续费侵蚀。

View File

@ -0,0 +1,77 @@
# 推荐交易对数量分析
## 核心问题分析
推荐交易对不多的核心原因有以下几个:
### 1. 市场扫描阶段的严格过滤 ⚠️ **主要瓶颈**
**问题1涨跌幅阈值过高**
- `MIN_CHANGE_PERCENT: 2.0%` - 要求涨跌幅至少2%
- **影响**过滤掉了大量波动在0.5%-2%之间的交易对,这些可能是很好的交易机会
- **建议**:降低到 0.5% 或 1.0%
**问题2成交量阈值过高**
- `MIN_VOLUME_24H: 10000000` (1000万USDT) - 要求24小时成交量至少1000万
- **影响**:过滤掉了大量中小币种,这些币种虽然成交量较小,但波动性大,交易机会多
- **建议**:降低到 500万 或 1000万根据市场情况调整
**问题3扫描数量限制**
- `MAX_SCAN_SYMBOLS: 500` - 只扫描前500个交易对
- `TOP_N_SYMBOLS: 30` - 只取前30个
- **影响**如果前500个交易对中符合条件的少最终推荐也会少
- **建议**:增加扫描范围或降低过滤条件
### 2. 信号分析阶段的严格规则 ⚠️ **关键瓶颈**
**问题1禁止逆4H趋势交易**
- 规则如果4H趋势向下禁止做多如果4H趋势向上禁止做空
- **影响**:这个规则非常严格,过滤掉了大量潜在的反弹/回调机会
- **建议**:对于推荐系统,可以放宽这个限制,允许逆趋势交易(但标记为高风险)
**问题2信号强度要求**
- `MIN_SIGNAL_STRENGTH: 5` - 虽然已经降低,但信号生成逻辑可能不够宽松
- **影响**很多交易对可能信号强度只有3-4就被过滤掉了
- **建议**进一步降低到3或者改进信号强度计算逻辑
### 3. 信号强度计算逻辑
**当前逻辑**
- 震荡市场RSI超卖/超买 +4分布林带 +3分
- 趋势市场MACD +3分均线 +2分
- 4H共振 +2分
- **问题**如果市场处于中性状态信号强度可能只有2-4分无法达到阈值
**建议**
- 增加基础分数即使没有明确信号也给1-2分
- 降低各种信号的分数要求
- 增加更多信号来源(如成交量、价格形态等)
## 优化方案
### 方案1放宽市场扫描过滤条件推荐
```python
'MIN_CHANGE_PERCENT': 0.5, # 从2.0%降低到0.5%
'MIN_VOLUME_24H': 5000000, # 从1000万降低到500万
'TOP_N_SYMBOLS': 50, # 从30增加到50
```
### 方案2放宽信号分析规则推荐
```python
# 对于推荐系统,允许逆趋势交易(但标记为高风险)
# 降低信号强度阈值到3
'MIN_SIGNAL_STRENGTH': 3, # 从5降低到3
```
### 方案3改进信号强度计算
- 增加基础分数即使没有明确信号也给1-2分
- 降低各种信号的分数要求
- 增加更多信号来源
## 预期效果
- **当前**扫描500个交易对 → 初步筛选可能只剩50-100个 → 详细分析30个 → 信号强度>=5的可能只有2-5个 → 最终推荐4-10个
- **优化后**扫描500个交易对 → 初步筛选可能有200-300个 → 详细分析50个 → 信号强度>=3的可能有15-25个 → 最终推荐30-50个

262
REDIS_CACHE_ANALYSIS.md Normal file
View File

@ -0,0 +1,262 @@
# Redis 缓存优化分析
## 当前缓存情况
### 1. 内存缓存(进程内)
- **交易对信息缓存** (`_symbol_info_cache`): 缓存交易对的精度、最小数量等信息
- **价格缓存** (`_price_cache`): 缓存 WebSocket 价格数据TTL 60秒
- **配置缓存**: 数据库配置的内存缓存
### 2. 频繁的 API 调用
- `get_symbol_info()`: 每次下单前调用,获取交易对精度信息
- `get_ticker_24h()`: 频繁获取价格信息
- `get_klines()`: 每次扫描时获取 K 线数据用于技术指标计算
- `futures_exchange_info()`: 获取交易对信息
## Redis 缓存优化方案
### 高优先级(显著提升性能)
#### 1. 交易对信息缓存 ⭐⭐⭐⭐⭐
**当前问题:**
- 每次下单前都要调用 `get_symbol_info()` 获取精度信息
- 交易对信息变化频率低,但每次都要 API 请求
**Redis 缓存方案:**
```python
# 缓存键: symbol_info:{symbol}
# TTL: 1小时交易对信息很少变化
# 数据结构: Hash
{
"quantityPrecision": 3,
"pricePrecision": 2,
"minQty": 0.001,
"stepSize": 0.001,
"minNotional": 5.0
}
```
**性能提升:**
- 减少 API 调用:从每次下单 1 次 API 调用 → 0 次(缓存命中)
- 降低延迟:从 ~100ms → ~1msRedis 本地访问)
- 降低 API 频率限制风险
#### 2. K 线数据缓存 ⭐⭐⭐⭐
**当前问题:**
- 每次市场扫描都要获取 50 根 K 线数据
- 相同时间周期的 K 线数据在短时间内不会变化
- 扫描多个交易对时重复获取相同数据
**Redis 缓存方案:**
```python
# 缓存键: klines:{symbol}:{interval}:{limit}
# TTL: 根据 interval 动态设置1m=10秒, 5m=30秒, 1h=5分钟
# 数据结构: List (JSON 序列化)
```
**性能提升:**
- 减少 API 调用:扫描 10 个交易对,从 10 次 → 0-2 次(缓存命中)
- 加速市场扫描:从 ~5-10 秒 → ~1-2 秒
- 降低 API 频率限制风险
#### 3. 24小时行情数据缓存 ⭐⭐⭐⭐
**当前问题:**
- `get_all_tickers_24h()` 每次扫描都调用
- 数据更新频率相对较低24小时统计
**Redis 缓存方案:**
```python
# 缓存键: ticker_24h:{symbol} 或 ticker_24h:all
# TTL: 30秒24小时统计数据更新不频繁
# 数据结构: Hash 或 String (JSON)
```
**性能提升:**
- 减少 API 调用:从每次扫描 1 次批量请求 → 0 次(缓存命中)
- 加速市场扫描:从 ~2-3 秒 → ~0.1 秒
- 降低 API 频率限制风险
### 中优先级(适度提升性能)
#### 4. 配置信息缓存 ⭐⭐⭐
**当前问题:**
- 每次获取配置都要查询数据库
- 配置变化频率低
**Redis 缓存方案:**
```python
# 缓存键: config:{key}
# TTL: 5分钟配置可能通过前端修改
# 数据结构: String
```
**性能提升:**
- 减少数据库查询:从每次获取配置 1 次查询 → 0 次(缓存命中)
- 降低数据库负载
#### 5. 市场扫描结果缓存 ⭐⭐
**当前问题:**
- 扫描结果可以短期缓存,避免重复扫描
**Redis 缓存方案:**
```python
# 缓存键: scan_result:top_symbols
# TTL: 30秒扫描间隔内可以复用
# 数据结构: List (JSON)
```
**性能提升:**
- 减少重复计算:在扫描间隔内可以复用结果
### 低优先级(提升有限)
#### 6. 价格缓存(已有 WebSocket
**当前情况:**
- 已有 WebSocket 实时价格推送
- 内存缓存已足够
**建议:**
- 保持现有内存缓存
- Redis 可以作为 WebSocket 的备份(如果 WebSocket 断开)
## 性能提升评估
### 预期提升
| 场景 | 当前延迟 | Redis 缓存后 | 提升 |
|------|---------|-------------|------|
| 下单前获取交易对信息 | ~100ms | ~1ms | **99%** |
| 市场扫描10个交易对 | ~5-10秒 | ~1-2秒 | **70-80%** |
| 获取 K 线数据 | ~200ms/次 | ~1ms/次 | **99.5%** |
| 获取 24h 行情 | ~2-3秒 | ~0.1秒 | **95%** |
### API 调用减少
| API 端点 | 当前频率 | Redis 缓存后 | 减少 |
|---------|---------|-------------|------|
| `futures_exchange_info` | 每次下单 | 每小时 1 次 | **99%+** |
| `futures_klines` | 每次扫描 | 每 5 分钟 1 次 | **90%+** |
| `futures_ticker` | 每次扫描 | 每 30 秒 1 次 | **95%+** |
### 风险降低
1. **API 频率限制风险**:显著降低
2. **网络延迟影响**:大幅减少
3. **系统响应速度**:明显提升
## 实现建议
### 1. 使用 `aioredis` 库(异步 Redis 客户端)
```python
pip install aioredis
```
### 2. 创建 Redis 缓存管理器
```python
# trading_system/redis_cache.py
import aioredis
import json
from typing import Optional, Dict, Any
import logging
logger = logging.getLogger(__name__)
class RedisCache:
def __init__(self, redis_url: str = "redis://localhost:6379"):
self.redis_url = redis_url
self.redis: Optional[aioredis.Redis] = None
async def connect(self):
"""连接 Redis"""
try:
self.redis = await aioredis.from_url(self.redis_url)
await self.redis.ping()
logger.info("✓ Redis 连接成功")
except Exception as e:
logger.warning(f"Redis 连接失败: {e},将使用内存缓存")
self.redis = None
async def get(self, key: str) -> Optional[Any]:
"""获取缓存"""
if not self.redis:
return None
try:
data = await self.redis.get(key)
if data:
return json.loads(data)
except Exception as e:
logger.debug(f"Redis 获取失败 {key}: {e}")
return None
async def set(self, key: str, value: Any, ttl: int = 3600):
"""设置缓存"""
if not self.redis:
return False
try:
await self.redis.setex(key, ttl, json.dumps(value))
return True
except Exception as e:
logger.debug(f"Redis 设置失败 {key}: {e}")
return False
async def close(self):
"""关闭连接"""
if self.redis:
await self.redis.close()
```
### 3. 集成到现有代码
**修改 `binance_client.py`:**
```python
from .redis_cache import RedisCache
class BinanceClient:
def __init__(self, ...):
# ... 现有代码 ...
self.redis_cache = RedisCache()
async def connect(self, ...):
# ... 现有代码 ...
await self.redis_cache.connect()
async def get_symbol_info(self, symbol: str):
# 先查 Redis 缓存
cache_key = f"symbol_info:{symbol}"
cached = await self.redis_cache.get(cache_key)
if cached:
return cached
# 缓存未命中,调用 API
info = await self._fetch_symbol_info(symbol)
# 写入 Redis 缓存TTL: 1小时
if info:
await self.redis_cache.set(cache_key, info, ttl=3600)
return info
```
## 总结
### 推荐实施优先级
1. **交易对信息缓存** ⭐⭐⭐⭐⭐ - 立即实施,效果最明显
2. **K 线数据缓存** ⭐⭐⭐⭐ - 高优先级,显著提升扫描速度
3. **24小时行情缓存** ⭐⭐⭐⭐ - 高优先级,减少批量请求
4. **配置信息缓存** ⭐⭐⭐ - 中优先级,适度提升
5. **市场扫描结果缓存** ⭐⭐ - 低优先级,提升有限
### 预期效果
- **API 调用减少**: 70-90%
- **系统响应速度**: 提升 70-80%
- **API 频率限制风险**: 显著降低
- **系统稳定性**: 提升(减少网络依赖)
### 注意事项
1. **缓存一致性**: 需要合理设置 TTL确保数据及时更新
2. **Redis 可用性**: 需要处理 Redis 不可用的情况(降级到内存缓存)
3. **内存使用**: Redis 内存使用需要监控
4. **部署复杂度**: 需要部署和维护 Redis 服务

View File

@ -0,0 +1,114 @@
# Redis 缓存实现说明
## 实现概述
根据 `REDIS_CACHE_ANALYSIS.md` 的分析,已实现以下缓存功能:
### ✅ 已实现的缓存功能
#### 1. 交易对信息缓存 ⭐⭐⭐⭐⭐
- **位置**: `binance_client.py::get_symbol_info()`
- **缓存键**: `symbol_info:{symbol}`
- **TTL**: 1小时3600秒
- **数据结构**: HashJSON序列化
- **性能提升**: 减少 API 调用 99%+,延迟从 ~100ms → ~1ms
#### 2. K线数据缓存 ⭐⭐⭐⭐
- **位置**: `binance_client.py::get_klines()`
- **缓存键**: `klines:{symbol}:{interval}:{limit}`
- **TTL**: 根据 interval 动态设置
- 1m: 10秒
- 5m: 30秒
- 15m: 1分钟
- 1h: 5分钟
- 4h: 15分钟
- 1d: 1小时
- **性能提升**: 减少 API 调用 90%+,加速市场扫描 70-80%
#### 3. 24小时行情数据缓存 ⭐⭐⭐⭐
- **位置**: `binance_client.py::get_ticker_24h()``get_all_tickers_24h()`
- **缓存键**:
- 单个: `ticker_24h:{symbol}`
- 全部: `ticker_24h:all`
- **TTL**: 30秒
- **性能提升**: 减少 API 调用 95%+,加速市场扫描 95%
#### 4. 市场扫描结果缓存 ⭐⭐
- **位置**: `market_scanner.py::scan_market()`
- **缓存键**: `scan_result:top_symbols`
- **TTL**: 30秒
- **性能提升**: 在扫描间隔内可以复用结果
## 配置说明
### Redis/Valkey 连接配置
`config.py` 中支持以下配置(优先从数据库读取,回退到环境变量):
```python
# Redis 连接 URL支持 TLS
REDIS_URL = "redis://localhost:6379" # 或 "rediss://localhost:6380" (TLS)
REDIS_USE_TLS = False # 是否使用 TLS
REDIS_SSL_CERT_REQS = "required" # SSL 证书验证要求: 'none', 'optional', 'required'
REDIS_SSL_CA_CERTS = None # SSL CA 证书路径(可选)
```
### 环境变量配置示例
```bash
# 非 TLS 连接
export REDIS_URL="redis://localhost:6379"
export REDIS_USE_TLS="false"
# TLS 连接Valkey
export REDIS_URL="rediss://your-valkey-host:6380"
export REDIS_USE_TLS="true"
export REDIS_SSL_CERT_REQS="required"
export REDIS_SSL_CA_CERTS="/path/to/ca.crt" # 可选
```
### 数据库配置
也可以通过数据库 `trading_config` 表配置:
- `REDIS_URL`: Redis 连接 URL
- `REDIS_USE_TLS`: 是否使用 TLS布尔值
- `REDIS_SSL_CERT_REQS`: SSL 证书验证要求
- `REDIS_SSL_CA_CERTS`: SSL CA 证书路径(可选)
## 降级机制
如果 Redis 连接失败,系统会自动降级到内存缓存:
- 交易对信息:使用内存缓存 `_symbol_info_cache`
- 价格数据:使用 WebSocket 缓存 `_price_cache`
- 其他数据:使用内存缓存 `_memory_cache`
## 依赖安装
已更新 `requirements.txt`,添加了 `aioredis==2.0.1`
安装依赖:
```bash
pip install -r trading_system/requirements.txt
```
## 使用说明
1. **配置 Redis/Valkey 连接**:设置 `REDIS_URL` 等配置项
2. **启动交易系统**:系统会自动连接 Redis 并启用缓存
3. **监控日志**:查看日志中的缓存命中情况
## 预期效果
根据 `REDIS_CACHE_ANALYSIS.md` 的评估:
- **API 调用减少**: 70-90%
- **系统响应速度**: 提升 70-80%
- **API 频率限制风险**: 显著降低
- **系统稳定性**: 提升(减少网络依赖)
## 注意事项
1. **缓存一致性**: TTL 设置已根据数据更新频率优化
2. **Redis 可用性**: 系统会自动处理 Redis 不可用的情况(降级到内存缓存)
3. **内存使用**: Redis 内存使用需要监控
4. **TLS 连接**: 支持 TLS 连接,适用于 Valkey 等需要加密的场景

View File

@ -0,0 +1,120 @@
# 止损止盈机制说明
## 问题背景
之前基于价格的盈亏比如止损3%价格止盈5%价格现在改为基于保证金的盈亏比如止损3% of margin止盈5% of margin
**问题**基于保证金的方式在10x杠杆下
- 止损3% of margin = 价格变动约0.3%
- 止盈5% of margin = 价格变动约0.5%
这太严格了,容易被正常波动触发。
## 解决方案:混合方案
现在系统采用**混合方案**,同时考虑:
1. **基于保证金的止损止盈**:控制风险金额
2. **基于价格的最小变动**:防止止损止盈过紧
系统会取**两者中更宽松的一个**,既保证风险控制,又避免被正常波动触发。
## 配置参数
### 1. `STOP_LOSS_PERCENT` (止损百分比,相对于保证金)
- **默认值**0.03 (3%)
- **说明**:当保证金亏损达到此百分比时触发止损
- **计算**:止损金额 = 保证金 × 止损百分比
- **示例**10x杠杆100 USDT入场保证金10 USDT止损3% = 0.3 USDT
### 2. `TAKE_PROFIT_PERCENT` (止盈百分比,相对于保证金)
- **默认值**0.05 (5%)
- **说明**:当保证金盈利达到此百分比时触发止盈
- **计算**:止盈金额 = 保证金 × 止盈百分比
- **示例**10x杠杆100 USDT入场保证金10 USDT止盈5% = 0.5 USDT
### 3. `MIN_STOP_LOSS_PRICE_PCT` (最小止损价格变动百分比) ⭐ 新增
- **默认值**0.01 (1%)
- **说明**:止损价格变动的最小百分比,防止止损过紧
- **作用**即使基于保证金的止损更紧也会使用至少1%的价格变动
- **示例**如果基于保证金的止损对应0.3%价格变动但配置了1%最小变动则使用1%
### 4. `MIN_TAKE_PROFIT_PRICE_PCT` (最小止盈价格变动百分比) ⭐ 新增
- **默认值**0.015 (1.5%)
- **说明**:止盈价格变动的最小百分比,防止止盈过紧
- **作用**即使基于保证金的止盈更紧也会使用至少1.5%的价格变动
- **示例**如果基于保证金的止盈对应0.5%价格变动但配置了1.5%最小变动则使用1.5%
## 计算逻辑
### 止损计算示例10x杠杆入场价100 USDT数量1
1. **基于保证金的止损**
- 保证金 = (100 × 1) / 10 = 10 USDT
- 止损金额 = 10 × 3% = 0.3 USDT
- 止损价 = 100 - (0.3 / 1) = 99.7 USDT
- 价格变动 = 0.3%
2. **基于价格的最小止损**
- 最小价格变动 = 1%
- 止损价 = 100 × (1 - 0.01) = 99 USDT
- 价格变动 = 1%
3. **最终止损**
- 取更宽松的max(99.7, 99) = 99.7 USDT但实际会使用99 USDT因为1%更宽松)
- 实际使用99 USDT1%价格变动)
### 止盈计算示例10x杠杆入场价100 USDT数量1
1. **基于保证金的止盈**
- 保证金 = 10 USDT
- 止盈金额 = 10 × 5% = 0.5 USDT
- 止盈价 = 100 + (0.5 / 1) = 100.5 USDT
- 价格变动 = 0.5%
2. **基于价格的最小止盈**
- 最小价格变动 = 1.5%
- 止盈价 = 100 × (1 + 0.015) = 101.5 USDT
- 价格变动 = 1.5%
3. **最终止盈**
- 取更宽松的max(100.5, 101.5) = 101.5 USDT1.5%价格变动)
## 配置建议
### 保守策略
- `STOP_LOSS_PERCENT`: 0.05 (5% of margin)
- `TAKE_PROFIT_PERCENT`: 0.08 (8% of margin)
- `MIN_STOP_LOSS_PRICE_PCT`: 0.01 (1%)
- `MIN_TAKE_PROFIT_PRICE_PCT`: 0.015 (1.5%)
### 平衡策略(推荐)
- `STOP_LOSS_PERCENT`: 0.03 (3% of margin)
- `TAKE_PROFIT_PERCENT`: 0.05 (5% of margin)
- `MIN_STOP_LOSS_PRICE_PCT`: 0.01 (1%)
- `MIN_TAKE_PROFIT_PRICE_PCT`: 0.015 (1.5%)
### 激进策略
- `STOP_LOSS_PERCENT`: 0.02 (2% of margin)
- `TAKE_PROFIT_PERCENT`: 0.03 (3% of margin)
- `MIN_STOP_LOSS_PRICE_PCT`: 0.005 (0.5%)
- `MIN_TAKE_PROFIT_PRICE_PCT`: 0.01 (1%)
## 优势
1. **风险控制**:基于保证金的止损确保每笔交易的最大亏损是固定的
2. **避免误触发**:最小价格变动保护避免被正常波动触发
3. **灵活性**:可以根据不同市场条件调整参数
4. **与币安一致**:盈亏百分比显示与币安一致(相对于保证金)
## 注意事项
1. **杠杆影响**:杠杆越高,基于保证金的止损对应的价格变动越小
2. **市场波动**:在波动大的市场,可以适当提高最小价格变动百分比
3. **技术止损**:系统仍会考虑技术分析(支撑/阻力、布林带),如果技术止损更紧,会使用技术止损
## 如何配置
可以通过以下方式配置:
1. **数据库配置表**:在 `trading_config` 表中添加/修改配置项
2. **环境变量**:设置环境变量(如 `MIN_STOP_LOSS_PRICE_PCT=0.01`
3. **前端配置面板**:在配置面板中修改(如果已添加相应配置项)

39
fix_cursor_path.sh Normal file
View File

@ -0,0 +1,39 @@
#!/bin/bash
# 修复 Cursor Worktree 路径问题
echo "=== 修复 Cursor Worktree 路径问题 ==="
echo ""
# 检查是否已存在符号链接
if [ -L /Users/work ]; then
echo "✓ 符号链接已存在: /Users/work -> $(readlink /Users/work)"
if [ "$(readlink /Users/work)" = "/Users/vivian/work" ]; then
echo "✓ 符号链接指向正确路径"
exit 0
else
echo "⚠ 符号链接指向错误路径,需要重新创建"
echo "请运行: sudo rm /Users/work && sudo ln -sf /Users/vivian/work /Users/work"
exit 1
fi
fi
# 检查 /Users/work 是否存在(但不是符号链接)
if [ -e /Users/work ]; then
echo "⚠ /Users/work 已存在但不是符号链接"
echo "请手动检查并删除后重新创建符号链接"
exit 1
fi
# 创建符号链接(需要管理员权限)
echo "正在创建符号链接 /Users/work -> /Users/vivian/work"
echo "需要管理员权限,请输入密码:"
sudo ln -sf /Users/vivian/work /Users/work
if [ $? -eq 0 ]; then
echo "✓ 符号链接创建成功!"
echo "✓ Cursor 现在应该能够正常应用 worktree 更改了"
ls -la /Users/work
else
echo "✗ 创建符号链接失败"
exit 1
fi