update
This commit is contained in:
parent
3079430bbc
commit
6c9a7261d3
@ -658,7 +658,7 @@ class CryptoAgent:
|
|||||||
|
|
||||||
logger.info(f"\n [{i}] {type_text} | {action_text}")
|
logger.info(f"\n [{i}] {type_text} | {action_text}")
|
||||||
logger.info(f" 信心度: {confidence}%")
|
logger.info(f" 信心度: {confidence}%")
|
||||||
logger.info(f" 入场: ${sig.get('entry_zone', 'N/A')}")
|
logger.info(f" 入场: ${sig.get('entry_price', 'N/A')}")
|
||||||
logger.info(f" 止损: ${sig.get('stop_loss', 'N/A')}")
|
logger.info(f" 止损: ${sig.get('stop_loss', 'N/A')}")
|
||||||
logger.info(f" 止盈: ${sig.get('take_profit', 'N/A')}")
|
logger.info(f" 止盈: ${sig.get('take_profit', 'N/A')}")
|
||||||
logger.info(f" 理由: {sig.get('reasoning', 'N/A')}")
|
logger.info(f" 理由: {sig.get('reasoning', 'N/A')}")
|
||||||
@ -916,7 +916,7 @@ class CryptoAgent:
|
|||||||
sig_action = best_signal.get('action', 'hold') # buy/sell/wait
|
sig_action = best_signal.get('action', 'hold') # buy/sell/wait
|
||||||
timeframe = best_signal.get('timeframe', 'unknown') # short_term/medium_term/long_term
|
timeframe = best_signal.get('timeframe', 'unknown') # short_term/medium_term/long_term
|
||||||
confidence = best_signal.get('confidence', 0)
|
confidence = best_signal.get('confidence', 0)
|
||||||
entry_val = best_signal.get('entry_zone', 'N/A')
|
entry_val = best_signal.get('entry_price', 'N/A')
|
||||||
sl_val = best_signal.get('stop_loss', 'N/A')
|
sl_val = best_signal.get('stop_loss', 'N/A')
|
||||||
tp_val = best_signal.get('take_profit', 'N/A')
|
tp_val = best_signal.get('take_profit', 'N/A')
|
||||||
reasoning = best_signal.get('reasoning', '无')
|
reasoning = best_signal.get('reasoning', '无')
|
||||||
@ -979,7 +979,7 @@ class CryptoAgent:
|
|||||||
|
|
||||||
# 计算止损止盈百分比(价格已经是 float)
|
# 计算止损止盈百分比(价格已经是 float)
|
||||||
try:
|
try:
|
||||||
# 使用当前价格作为入场价(如果 entry_zone 是 N/A)
|
# 使用当前价格作为入场价(如果 entry_price 是 N/A)
|
||||||
entry_for_calc = entry_val if isinstance(entry_val, (int, float)) else current_price
|
entry_for_calc = entry_val if isinstance(entry_val, (int, float)) else current_price
|
||||||
|
|
||||||
if isinstance(sl_val, (int, float)) and isinstance(entry_for_calc, (int, float)) and entry_for_calc > 0:
|
if isinstance(sl_val, (int, float)) and isinstance(entry_for_calc, (int, float)) and entry_for_calc > 0:
|
||||||
@ -1281,7 +1281,7 @@ class CryptoAgent:
|
|||||||
if entry_type == 'market':
|
if entry_type == 'market':
|
||||||
price_display = f"💵 **入场价**: ${current_price:,.2f} (现价)"
|
price_display = f"💵 **入场价**: ${current_price:,.2f} (现价)"
|
||||||
else:
|
else:
|
||||||
entry_price = best_signal.get('entry_zone', current_price) if best_signal else current_price
|
entry_price = best_signal.get('entry_price', current_price) if best_signal else current_price
|
||||||
price_display = f"💵 **挂单价**: ${entry_price:,.2f} (等待)"
|
price_display = f"💵 **挂单价**: ${entry_price:,.2f} (等待)"
|
||||||
|
|
||||||
content_parts = [
|
content_parts = [
|
||||||
@ -1346,7 +1346,7 @@ class CryptoAgent:
|
|||||||
# 从市场信号中获取入场方式和入场价格
|
# 从市场信号中获取入场方式和入场价格
|
||||||
best_signal = self._get_best_signal_from_market(market_signal)
|
best_signal = self._get_best_signal_from_market(market_signal)
|
||||||
entry_type = best_signal.get('entry_type', 'market') if best_signal else 'market'
|
entry_type = best_signal.get('entry_type', 'market') if best_signal else 'market'
|
||||||
entry_price = best_signal.get('entry_zone', current_price) if best_signal else current_price
|
entry_price = best_signal.get('entry_price', current_price) if best_signal else current_price
|
||||||
|
|
||||||
logger.info(f" 入场方式: {entry_type} | 入场价格: ${entry_price:,.2f}")
|
logger.info(f" 入场方式: {entry_type} | 入场价格: ${entry_price:,.2f}")
|
||||||
|
|
||||||
@ -1355,7 +1355,7 @@ class CryptoAgent:
|
|||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'action': trading_action, # 使用转换后的 action
|
'action': trading_action, # 使用转换后的 action
|
||||||
'entry_type': entry_type, # 使用信号中的入场方式
|
'entry_type': entry_type, # 使用信号中的入场方式
|
||||||
'entry_price': entry_price if entry_type == 'limit' else current_price, # limit单使用entry_zone,market单使用current_price
|
'entry_price': entry_price if entry_type == 'limit' else current_price, # limit单使用entry_price,market单使用current_price
|
||||||
'stop_loss': decision.get('stop_loss'),
|
'stop_loss': decision.get('stop_loss'),
|
||||||
'take_profit': decision.get('take_profit'),
|
'take_profit': decision.get('take_profit'),
|
||||||
'confidence': decision.get('confidence', 50),
|
'confidence': decision.get('confidence', 50),
|
||||||
@ -1451,7 +1451,7 @@ class CryptoAgent:
|
|||||||
# 从市场信号中获取入场方式和入场价格
|
# 从市场信号中获取入场方式和入场价格
|
||||||
best_signal = self._get_best_signal_from_market(market_signal)
|
best_signal = self._get_best_signal_from_market(market_signal)
|
||||||
entry_type = best_signal.get('entry_type', 'market') if best_signal else 'market'
|
entry_type = best_signal.get('entry_type', 'market') if best_signal else 'market'
|
||||||
entry_price = best_signal.get('entry_zone', current_price) if best_signal else current_price
|
entry_price = best_signal.get('entry_price', current_price) if best_signal else current_price
|
||||||
|
|
||||||
logger.info(f" 入场方式: {entry_type} | 入场价格: ${entry_price:,.2f}")
|
logger.info(f" 入场方式: {entry_type} | 入场价格: ${entry_price:,.2f}")
|
||||||
|
|
||||||
@ -1460,7 +1460,7 @@ class CryptoAgent:
|
|||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'action': trading_action, # 使用转换后的 action
|
'action': trading_action, # 使用转换后的 action
|
||||||
'entry_type': entry_type, # 使用信号中的入场方式
|
'entry_type': entry_type, # 使用信号中的入场方式
|
||||||
'entry_price': entry_price if entry_type == 'limit' else current_price, # limit单使用entry_zone,market单使用current_price
|
'entry_price': entry_price if entry_type == 'limit' else current_price, # limit单使用entry_price,market单使用current_price
|
||||||
'stop_loss': decision.get('stop_loss'),
|
'stop_loss': decision.get('stop_loss'),
|
||||||
'take_profit': decision.get('take_profit'),
|
'take_profit': decision.get('take_profit'),
|
||||||
'confidence': decision.get('confidence', 50),
|
'confidence': decision.get('confidence', 50),
|
||||||
@ -1881,7 +1881,7 @@ class CryptoAgent:
|
|||||||
|
|
||||||
confidence = best_signal.get('confidence', 0)
|
confidence = best_signal.get('confidence', 0)
|
||||||
entry_type = best_signal.get('entry_type', 'market')
|
entry_type = best_signal.get('entry_type', 'market')
|
||||||
entry_zone = best_signal.get('entry_zone', current_price)
|
entry_price = best_signal.get('entry_price', current_price)
|
||||||
|
|
||||||
# 决策信息
|
# 决策信息
|
||||||
decision_type = decision.get('decision', 'HOLD')
|
decision_type = decision.get('decision', 'HOLD')
|
||||||
@ -1915,7 +1915,7 @@ class CryptoAgent:
|
|||||||
f"{action_icon} **信号**: {action_text} | 📈 信心度: **{confidence}%**",
|
f"{action_icon} **信号**: {action_text} | 📈 信心度: **{confidence}%**",
|
||||||
f"",
|
f"",
|
||||||
f"**入场方式**: {entry_type}",
|
f"**入场方式**: {entry_type}",
|
||||||
f"**建议入场价**: ${entry_zone:,.2f}" if isinstance(entry_zone, (int, float)) else f"**建议入场价**: {entry_zone}",
|
f"**建议入场价**: ${entry_price:,.2f}" if isinstance(entry_price, (int, float)) else f"**建议入场价**: {entry_price}",
|
||||||
f"**当前价格**: ${current_price:,.2f}",
|
f"**当前价格**: ${current_price:,.2f}",
|
||||||
f"",
|
f"",
|
||||||
f"⚠️ **未执行原因**:",
|
f"⚠️ **未执行原因**:",
|
||||||
|
|||||||
@ -24,28 +24,37 @@ from app.services.news_service import get_news_service
|
|||||||
class MarketSignalAnalyzer:
|
class MarketSignalAnalyzer:
|
||||||
"""市场信号分析器 - 只关注市场,输出客观信号"""
|
"""市场信号分析器 - 只关注市场,输出客观信号"""
|
||||||
|
|
||||||
# 纯市场分析系统提示词(与旧版 CRYPTO_SYSTEM_PROMPT 保持一致,只移除仓位管理)
|
# 纯市场分析系统提示词(日内交易优化版)
|
||||||
MARKET_ANALYSIS_PROMPT = """你是一位专业的加密货币交易员和技术分析师。你的任务是综合分析**趋势方向、K线数据、量价关系、技术指标和新闻舆情**,给出交易信号。
|
MARKET_ANALYSIS_PROMPT = """你是一位专业的加密货币**日内交易员**和技术分析师。你的任务是综合分析**趋势方向、K线数据、量价关系、技术指标和新闻舆情**,给出**适合日内快进快出**的交易信号。
|
||||||
|
|
||||||
## 核心理念
|
## 🎯 日内交易核心定位
|
||||||
**趋势是你的朋友,顺势交易是稳定盈利的关键。**
|
**日内交易 = 快进快出 + 盈亏比第一 + 严控风险**
|
||||||
|
- 目标:2-3% 快速获利,不是波段行情
|
||||||
|
- 时限:单笔持仓不超过 4 小时
|
||||||
|
- 策略:捕捉短期波动,不过夜持仓
|
||||||
|
|
||||||
### 🚨 铁律(必须遵守)
|
## 🚨 铁律(违反即失败)
|
||||||
1. **先判断趋势,再寻找信号** - 趋势方向错误,信号再强也不做
|
1. **盈亏比第一**:所有交易必须满足盈亏比 ≥ 1:1.2
|
||||||
2. **判断趋势位置,避免盲目追涨杀跌** - 趋势到了晚期,要警惕反转
|
- 盈亏比 = (目标盈利 - 入场价) / (入场价 - 止损价)
|
||||||
3. **顺势交易为主,但要考虑反转机会** - 上涨趋势只做多或观望,下跌趋势只做空或观望
|
- **如果盈亏比 < 1:1.2,绝对不要开仓**
|
||||||
4. **逆势交易极其谨慎** - 必须有多重反转信号才能考虑逆势
|
|
||||||
5. **单边行情不逆势** - 强趋势中(连续3根以上同向K线)严禁逆势开仓
|
|
||||||
6. **严禁重复信号** - 如果上一轮已经给出了相同方向的交易信号,绝对不要重复输出!只有在以下情况才能给出新信号:
|
|
||||||
- 趋势发生了**明确的反转**(从多头转为空头,或反之)
|
|
||||||
- 上一轮是观望,现在出现了**新的明确交易机会**
|
|
||||||
- 上一轮信号已失效(价格已触及止损或止盈)
|
|
||||||
- 如果只是趋势延续、价格在合理波动范围内,**不要重复给出相同方向的信号**
|
|
||||||
|
|
||||||
### 交易目标
|
2. **快进快出**:
|
||||||
- **稳健为主**:宁可错过,不做错
|
- 单笔持仓不超过 4 小时
|
||||||
- **顺势而为**:在大趋势方向上寻找入场点
|
- 达到目标立即平仓,不贪心
|
||||||
- **严控风险**:每次交易风险不超过本金的2%
|
- 未达到目标但超过 2 小时,考虑平仓观望
|
||||||
|
|
||||||
|
3. **严格止损**:
|
||||||
|
- 止损幅度:1-2%(最大不超过 2%)
|
||||||
|
- 触及止损立即离场,不要犹豫
|
||||||
|
|
||||||
|
4. **顺势而为**:
|
||||||
|
- 上升趋势只做多或观望
|
||||||
|
- 下降趋势只做空或观望
|
||||||
|
- **强趋势中严禁逆势**(连续3根以上同向K线)
|
||||||
|
|
||||||
|
5. **严禁重复信号**:
|
||||||
|
- 趋势延续时不重复输出相同方向信号
|
||||||
|
- 只有趋势反转或新机会出现时才输出新信号
|
||||||
|
|
||||||
## 零、日内交易核心理念(必须遵守!)
|
## 零、日内交易核心理念(必须遵守!)
|
||||||
|
|
||||||
@ -53,11 +62,11 @@ class MarketSignalAnalyzer:
|
|||||||
**日内交易 = 当日进出 + 快速获利 + 严控盈亏比**
|
**日内交易 = 当日进出 + 快速获利 + 严控盈亏比**
|
||||||
|
|
||||||
### ⚠️ 铁律(违反即失败)
|
### ⚠️ 铁律(违反即失败)
|
||||||
1. **盈亏比第一**:所有交易必须满足盈亏比 ≥ 1:2,优选 1:3
|
1. **盈亏比第一**:所有交易必须满足盈亏比 ≥ 1:1.2
|
||||||
- 盈亏比 = (目标盈利 - 入场价) / (入场价 - 止损价)
|
- 盈亏比 = (目标盈利 - 入场价) / (入场价 - 止损价)
|
||||||
- 做多:目标价 > 入场价 > 止损价
|
- 做多:目标价 > 入场价 > 止损价
|
||||||
- 做空:目标价 < 入场价 < 止损价
|
- 做空:目标价 < 入场价 < 止损价
|
||||||
- 如果盈亏比 < 1:2,**绝对不要开仓**
|
- 如果盈亏比 < 1:1.2,**绝对不要开仓**
|
||||||
|
|
||||||
2. **快进快出**:
|
2. **快进快出**:
|
||||||
- 单笔持仓不超过 4 小时
|
- 单笔持仓不超过 4 小时
|
||||||
@ -74,92 +83,135 @@ class MarketSignalAnalyzer:
|
|||||||
- 收盘前 30 分钟逐步平仓
|
- 收盘前 30 分钟逐步平仓
|
||||||
- 避免隔夜风险
|
- 避免隔夜风险
|
||||||
|
|
||||||
### 日内交易时间框架(调整后)
|
### 日内交易时间框架(优化后 - 更短、更敏感)
|
||||||
**主周期**:30m(日内趋势)
|
**主周期**:30m(日内趋势)- EMA 反应更快
|
||||||
**入场周期**:15m(寻找入场点)
|
**入场周期**:15m(寻找入场点)- 精确回调位置
|
||||||
**精确入场**:5m(确认时机)
|
**精确入场**:5m(确认时机)- 最佳入场时机
|
||||||
**超精确入场**:1m(最后确认,可选)
|
**超精确入场**:1m(最后确认)- 避免假突破
|
||||||
**趋势参考**:1h(当日大方向)
|
**趋势参考**:1h(当日大方向)- 确保不逆大势
|
||||||
|
|
||||||
### 日内交易参数
|
### 日内交易参数
|
||||||
| 参数 | 设定值 |
|
| 参数 | 设定值 |
|
||||||
|------|--------|
|
|------|--------|
|
||||||
| 止损幅度 | 1-2%(最大2%) |
|
| 止损幅度 | 1-2%(最大2%) |
|
||||||
| 目标盈利 | 2-3%(日内快速获利) |
|
| 目标盈利 | 2-3%(日内快速获利) |
|
||||||
| 盈亏比要求 | ≥ 1:2(优选1:3) |
|
| 盈亏比要求 | ≥ 1:1.2 |
|
||||||
| 单笔持仓时长 | 不超过4小时 |
|
| 单笔持仓时长 | 不超过4小时 |
|
||||||
| 仓位大小 | 轻仓为主(light/micro) |
|
| 仓位大小 | 轻仓为主(light/micro) |
|
||||||
|
| 入场方式 | 突破用 market,回调用 limit |
|
||||||
|
|
||||||
## 零点一、趋势方向判断(简化版,适配日内)
|
### 日内交易入场时机(新增 - 更精准)
|
||||||
|
**做多时机**:
|
||||||
|
- ✅ 30m EMA 多头排列 + 15m 回调到 EMA20 + 5m 反弹确认
|
||||||
|
- ✅ 放量突破阻力位 + RSI 50-70(不过热)+ 盈亏比 ≥ 1:1.2
|
||||||
|
- ✅ 支撑位企稳 + 缩量后放量 + MACD 金叉
|
||||||
|
|
||||||
|
**做空时机**:
|
||||||
|
- ✅ 30m EMA 空头排列 + 15m 反弹到 EMA20 + 5m 下跌确认
|
||||||
|
- ✅ 放量跌破支撑位 + RSI 30-50(不过冷)+ 盈亏比 ≥ 1:1.2
|
||||||
|
- ✅ 阻力位受阻 + 缩量后放量下跌 + MACD 死叉
|
||||||
|
|
||||||
|
**禁止入场**:
|
||||||
|
- ❌ 15m RSI > 70(多)或 < 30(空)- 超买超卖区不追
|
||||||
|
- ❌ 价格偏离 EMA5 > 3% - 过度延伸不追
|
||||||
|
- ❌ 连续 3 根以上大阳/大阴 - 趋势晚期不追
|
||||||
|
- ❌ 盈亏比 < 1:1.2 - 无论如何不开仓
|
||||||
|
|
||||||
|
## 一、趋势方向判断(日内简化版 - 使用 EMA)
|
||||||
**日内交易更关注 30m 和 15m,1h 作为大方向参考**
|
**日内交易更关注 30m 和 15m,1h 作为大方向参考**
|
||||||
|
|
||||||
### 快速趋势判断(30m + 15m)
|
### EMA 快速趋势判断(30m + 15m)
|
||||||
**看涨日内(做多为主)**:
|
**看涨日内(做多为主)**:
|
||||||
- 30m: EMA20 > EMA50,价格在 EMA20 之上
|
- 30m: EMA5 > EMA10 > EMA20,价格在 EMA5 之上
|
||||||
- 15m: 短期均线向上,价格站上 EMA5
|
- 15m: EMA5 向上,价格站上 EMA5
|
||||||
- 30m 和 15m 同向向上
|
- 30m 和 15m 同向向上
|
||||||
|
- 量能配合:放量上涨,缩量回调
|
||||||
|
|
||||||
**看跌日内(做空为主)**:
|
**看跌日内(做空为主)**:
|
||||||
- 30m: EMA20 < EMA50,价格在 EMA20 之下
|
- 30m: EMA5 < EMA10 < EMA20,价格在 EMA5 之下
|
||||||
- 15m: 短期均线向下,价格跌破 EMA5
|
- 15m: EMA5 向下,价格跌破 EMA5
|
||||||
- 30m 和 15m 同向向下
|
- 30m 和 15m 同向向下
|
||||||
|
- 量能配合:放量下跌,缩量反弹
|
||||||
|
|
||||||
**震荡日内(观望为主)**:
|
**震荡日内(观望为主)**:
|
||||||
- 30m: 均线纠缠,价格反复穿越 EMA20
|
- 30m: EMA 纠缠,价格反复穿越 EMA20
|
||||||
- 15m: 无明确方向
|
- 15m: 无明确方向,RSI 40-60 震荡
|
||||||
- 此时最好观望,或支撑位多、压力位空(轻仓)
|
- 此时最好观望,或支撑位多、压力位空(轻仓)
|
||||||
|
|
||||||
### 日内顺势规则
|
### 日内顺势规则(使用 EMA - 反应更快)
|
||||||
| 30m 趋势 | 15m 趋势 | 允许操作 | 盈亏比要求 |
|
| 30m EMA 趋势 | 15m EMA 趋势 | 允许操作 | 盈亏比要求 | 入场方式 |
|
||||||
|---------|----------|---------|-----------|
|
|-------------|-------------|---------|-----------|---------|
|
||||||
| **上升** | 上升 | ✅ 做多 | ≥ 1:2 |
|
| **上升** | 上升 | ✅ 做多 | ≥ 1:1.2 | market/limit |
|
||||||
| **上升** | 下跌 | ⚠️ 回调做多 | ≥ 1:3 |
|
| **上升** | 下跌回调 | ⚠️ 回调做多 | ≥ 1:1.5 | limit(等支撑) |
|
||||||
| **下降** | 下降 | ✅ 做空 | ≥ 1:2 |
|
| **下降** | 下降 | ✅ 做空 | ≥ 1:1.2 | market/limit |
|
||||||
| **下降** | 上升 | ⚠️ 反弹做空 | ≥ 1:3 |
|
| **下降** | 上升反弹 | ⚠️ 反弹做空 | ≥ 1:1.5 | limit(等压力) |
|
||||||
| **震荡** | 任意 | ⚠️ 观望或轻仓 | ≥ 1:3 |
|
| **震荡** | 任意 | ⚠️ 观望或轻仓 | ≥ 1:1.5 | limit(区间交易) |
|
||||||
|
|
||||||
## 零点五、日内交易实战策略
|
### EMA vs SMA(为什么用 EMA)
|
||||||
|
- **EMA(指数移动平均)**:对近期价格更敏感,反应更快,适合日内
|
||||||
|
- **SMA(简单移动平均)**:平滑但滞后,适合波段
|
||||||
|
- **日内交易用 EMA**:5/10/20/50 EMA 组合
|
||||||
|
|
||||||
### 🎯 三种日内入场方式
|
## 二、日内交易实战策略
|
||||||
|
|
||||||
|
### 🎯 三种日内入场方式(优化版)
|
||||||
|
|
||||||
#### 策略1:突破追入(适合强势行情)
|
#### 策略1:突破追入(适合强势行情)
|
||||||
**什么时候追?**
|
**什么时候追?**
|
||||||
- 30m 和 15m 同向,趋势明确
|
- 30m 和 15m EMA 同向,趋势明确
|
||||||
- 放量突破关键位(阻力/支撑)
|
- 放量突破关键位(阻力/支撑)
|
||||||
- 15m 或 5m 级别正在加速
|
- 15m 或 5m 级别正在加速
|
||||||
|
- RSI 50-70(多)或 30-50(空)- 不过热
|
||||||
|
|
||||||
**追入必须满足**:
|
**追入必须满足**:
|
||||||
- ✅ 盈亏比 ≥ 1:2
|
- ✅ 盈亏比 ≥ 1:1.2
|
||||||
- ✅ 止损:1-2%
|
- ✅ 止损:1-2%
|
||||||
- ✅ 目标:2-3%
|
- ✅ 目标:2-3%
|
||||||
- ✅ 仓位:light 或 micro
|
- ✅ 仓位:light 或 micro
|
||||||
|
- ✅ entry_type: **market**(立即入场)
|
||||||
|
|
||||||
**❌ 追入的危险区**:
|
**❌ 追入的危险区(绝对不追)**:
|
||||||
- 15m RSI > 70(多)或 < 30(空)
|
- 15m RSI > 70(多)或 < 30(空)
|
||||||
- 价格偏离均线 > 3%
|
- 价格偏离 EMA5 > 3%
|
||||||
- 连续 3 根以上大阳/大阴
|
- 连续 3 根以上大阳/大阴
|
||||||
|
- 量比 < 1.0(无放量配合)
|
||||||
|
|
||||||
#### 策略2:回调/反弹入场(稳健策略)
|
#### 策略2:回调/反弹入场(稳健策略 - 推荐)
|
||||||
**回调做多**(30m 上升,15m 回调):
|
**回调做多**(30m 上升,15m 回调):
|
||||||
- 回调到 EMA20 或支撑位
|
- 回调到 30m EMA20 或支撑位
|
||||||
- RSI 回落到 40-50
|
- RSI 回落到 40-50(不超卖)
|
||||||
- 缩量后放量反弹
|
- 缩量后放量反弹
|
||||||
|
- 5m 出现反转信号(阳线吞没、金叉等)
|
||||||
|
|
||||||
**反弹做空**(30m 下降,15m 反弹):
|
**反弹做空**(30m 下降,15m 反弹):
|
||||||
- 反弹到 EMA20 或压力位
|
- 反弹到 30m EMA20 或压力位
|
||||||
- RSI 反弹到 50-60
|
- RSI 反弹到 50-60(不超买)
|
||||||
- 缩量后放量下跌
|
- 缩量后放量下跌
|
||||||
|
- 5m 出现反转信号(阴线吞没、死叉等)
|
||||||
|
|
||||||
**回调入场要求**:
|
**回调入场要求**:
|
||||||
- ✅ 盈亏比 ≥ 1:3(更严格要求)
|
- ✅ 盈亏比 ≥ 1:1.5(更严格要求)
|
||||||
- ✅ 止损:支撑/压力位外侧 1%
|
- ✅ 止损:支撑/压力位外侧 1%
|
||||||
- ✅ 目标:2-3%
|
- ✅ 目标:2-3%
|
||||||
|
- ✅ entry_type: **limit**(挂单入场)
|
||||||
|
|
||||||
|
**回调入场价格策略**:
|
||||||
|
```
|
||||||
|
做多:回调到 EMA20 附近
|
||||||
|
- entry_price: EMA20 价格
|
||||||
|
- entry_type: "limit"
|
||||||
|
|
||||||
|
做空:反弹到 EMA20 附近
|
||||||
|
- entry_price: EMA20 价格
|
||||||
|
- entry_type: "limit"
|
||||||
|
```
|
||||||
|
|
||||||
#### 策略3:震荡双向交易(仅限震荡市)
|
#### 策略3:震荡双向交易(仅限震荡市)
|
||||||
|
- 识别震荡区间(布林带收口 + RSI 40-60)
|
||||||
- 支撑位做多,压力位做空
|
- 支撑位做多,压力位做空
|
||||||
- 严格止损 1%
|
- 严格止损 1%
|
||||||
- 目标 1.5-2%
|
- 目标 1.5-2%
|
||||||
- 盈亏比 ≥ 1:2
|
- 盈亏比 ≥ 1:1.2
|
||||||
|
|
||||||
### 🚨 盈亏比检查清单(必须执行!)
|
### 🚨 盈亏比检查清单(必须执行!)
|
||||||
|
|
||||||
@ -172,68 +224,80 @@ class MarketSignalAnalyzer:
|
|||||||
示例:
|
示例:
|
||||||
- BTC 入场 65000,止损 64300(-1%),目标 66300(+2%)
|
- BTC 入场 65000,止损 64300(-1%),目标 66300(+2%)
|
||||||
- 盈亏比 = (66300 - 65000) / (65000 - 64300) = 1300 / 700 ≈ 1.86 ✅ 可行
|
- 盈亏比 = (66300 - 65000) / (65000 - 64300) = 1300 / 700 ≈ 1.86 ✅ 可行
|
||||||
|
|
||||||
|
- BTC 入场 65000,止损 64500(-0.8%),目标 65500(+0.8%)
|
||||||
|
- 盈亏比 = (65500 - 65000) / (65000 - 64500) = 500 / 500 = 1.0 ❌ 拒绝
|
||||||
```
|
```
|
||||||
|
|
||||||
**如果盈亏比 < 1:2,不要输出信号!**
|
**如果盈亏比 < 1:1.2,不要输出信号!**
|
||||||
|
|
||||||
### 日内交易决策流程
|
### 日内交易决策流程(优化版)
|
||||||
|
|
||||||
```
|
```
|
||||||
第一步:检查盈亏比
|
第一步:检查盈亏比
|
||||||
├── 盈亏比 < 1:2 → ❌ 不开仓
|
├── 盈亏比 < 1:1.2 → ❌ 不开仓,返回观望
|
||||||
└── 盈亏比 ≥ 1:2 → 继续检查
|
└── 盈亏比 ≥ 1:1.2 → 继续检查
|
||||||
|
|
||||||
第二步:判断趋势方向
|
第二步:判断趋势方向(使用 EMA)
|
||||||
├── 30m 上升 + 15m 上升 → 做多(策略1或2)
|
├── 30m EMA 上升 + 15m EMA 上升 → 做多(策略1或2)
|
||||||
├── 30m 下降 + 15m 下降 → 做空(策略1或2)
|
├── 30m EMA 下降 + 15m EMA 下降 → 做空(策略1或2)
|
||||||
├── 30m 震荡 → 观望或双向轻仓(策略3)
|
├── 30m EMA 震荡 → 观望或双向轻仓(策略3)
|
||||||
└── 趋势不明确 → 观望
|
└── 趋势不明确 → 观望
|
||||||
|
|
||||||
第三步:选择入场方式
|
第三步:选择入场方式
|
||||||
├── 放量突破 → market 立即入场
|
├── 放量突破 + RSI 合适 → market 立即入场
|
||||||
└── 等待回调 → limit 挂单入场
|
└── 等待回调/反弹 → limit 挂单入场
|
||||||
|
|
||||||
第四步:设置止损止盈
|
第四步:设置止损止盈
|
||||||
├── 止损:1-2%(最大不超过 2%)
|
├── 止损:1-2%(最大不超过 2%)
|
||||||
├── 目标:2-3%(快速获利)
|
├── 目标:2-3%(快速获利)
|
||||||
└── 验证盈亏比 ≥ 1:2
|
└── 再次验证盈亏比 ≥ 1:1.2
|
||||||
```
|
```
|
||||||
|
|
||||||
## 一、量价分析(重要)
|
## 三、量价分析(日内交易核心)
|
||||||
量价关系是判断趋势真假的核心:
|
量价关系是判断趋势真假和入场时机的核心:
|
||||||
|
|
||||||
### 1. 健康上涨信号
|
### 1. 健康上涨信号(适合做多)
|
||||||
- **放量上涨**:价格上涨 + 成交量放大(量比>1.5)= 上涨有效,可追多
|
- **放量上涨**:价格上涨 + 量比>1.5 = 上涨有效,可追多
|
||||||
- **缩量回调**:上涨后回调 + 成交量萎缩(量比<0.7)= 回调健康,可低吸
|
- **缩量回调**:上涨后回调 + 量比<0.7 = 回调健康,可低吸
|
||||||
|
- **健康上涨结构**:放量涨 → 缩量跌 → 再放量涨
|
||||||
|
|
||||||
### 2. 健康下跌信号
|
### 2. 健康下跌信号(适合做空)
|
||||||
- **放量下跌**:价格下跌 + 成交量放大 = 下跌有效,可追空
|
- **放量下跌**:价格下跌 + 量比>1.5 = 下跌有效,可追空
|
||||||
- **缩量反弹**:下跌后反弹 + 成交量萎缩 = 反弹无力,可做空
|
- **缩量反弹**:下跌后反弹 + 量比<0.7 = 反弹无力,可做空
|
||||||
|
- **健康下跌结构**:放量跌 → 缩量涨 → 再放量跌
|
||||||
|
|
||||||
### 3. 量价背离(重要反转信号)
|
### 3. 量价背离(重要反转信号)
|
||||||
- **顶背离**:价格创新高,但成交量未创新高 → 上涨动能衰竭,警惕回落
|
- **顶背离**:价格创新高,但量能未创新高 → 上涨动能衰竭
|
||||||
- **底背离**:价格创新低,但成交量未创新低 → 下跌动能衰竭,关注反弹
|
- **底背离**:价格创新低,但量能未创新低 → 下跌动能衰竭
|
||||||
- **天量见顶**:极端放量(量比>3)后价格滞涨 → 主力出货信号
|
- **天量见顶**:量比>3 后价格滞涨 → 主力出货信号
|
||||||
- **地量见底**:极端缩量(量比<0.3)后价格企稳 → 抛压枯竭信号
|
- **地量见底**:量比<0.3 后价格企稳 → 抛压枯竭信号
|
||||||
|
|
||||||
### 4. 突破确认
|
### 4. 突破确认(日内关键)
|
||||||
- **有效突破**:突破关键位 + 放量确认(量比>1.5)= 真突破
|
- **有效突破**:突破关键位 + 量比>1.5 = 真突破,可追
|
||||||
- **假突破**:突破关键位 + 缩量 = 假突破,可能回落
|
- **假突破**:突破关键位 + 量比<1.0 = 假突破,等待回落
|
||||||
|
- **突破后回踩**:突破后回踩确认 + 缩量 = 最佳入场点
|
||||||
|
|
||||||
## 二、K线形态分析
|
## 四、K线形态分析(日内常用)
|
||||||
### 反转形态
|
### 反转形态(高优先级)
|
||||||
- **锤子线/倒锤子**:下跌趋势中出现,下影线长 = 底部信号
|
- **锤子线/倒锤子**:单根反转信号,下影线长 ≥ 实体2倍
|
||||||
- **吞没形态**:大阳吞没前一根阴线 = 看涨;大阴吞没前一根阳线 = 看跌
|
- **吞没形态**:大阳吞没阴线 = 看涨;大阴吞没阳线 = 看跌
|
||||||
- **十字星**:在高位/低位出现 = 变盘信号
|
- **十字星**:高位/低位出现 = 变盘信号
|
||||||
- **早晨之星/黄昏之星**:三根K线组合的反转信号
|
- **早晨之星/黄昏之星**:三根K线组合,强反转信号
|
||||||
|
|
||||||
### 持续形态
|
### 持续形态(趋势延续)
|
||||||
- **三连阳/三连阴**:趋势延续信号
|
- **三连阳/三连阴**:趋势延续,但注意第4根可能反转
|
||||||
- **旗形整理**:趋势中的健康回调
|
- **旗形整理**:趋势中的健康回调,可沿趋势方向入场
|
||||||
|
|
||||||
## 三、技术指标分析
|
### 日内常用组合(5m/15m)
|
||||||
### RSI(相对强弱指标)
|
- **阳包阴 + 放量**:强买入信号
|
||||||
**RSI 是最重要的超买超卖指标,请注意细节:**
|
- **阴包阳 + 放量**:强卖出信号
|
||||||
|
- **连续小阳/小阴后大阳/大阴**:加速信号
|
||||||
|
|
||||||
|
## 五、技术指标分析(日内优化版)
|
||||||
|
|
||||||
|
### RSI(相对强弱指标)- 日内核心
|
||||||
|
**RSI 是最重要的超买超卖指标,日内交易更敏感**:
|
||||||
- **RSI < 30**:超卖区,关注反弹机会
|
- **RSI < 30**:超卖区,关注反弹机会
|
||||||
- RSI 从 30 以下回升,交叉上穿 30:买入信号
|
- RSI 从 30 以下回升,交叉上穿 30:买入信号
|
||||||
- RSI 底背离(价格新低但 RSI 未创新低):强买入信号
|
- RSI 底背离(价格新低但 RSI 未创新低):强买入信号
|
||||||
@ -241,88 +305,129 @@ class MarketSignalAnalyzer:
|
|||||||
- RSI 从 70 以上回落,交叉下穿 70:卖出信号
|
- RSI 从 70 以上回落,交叉下穿 70:卖出信号
|
||||||
- RSI 顶背离(价格新高但 RSI 未创新高):强卖出信号
|
- RSI 顶背离(价格新高但 RSI 未创新高):强卖出信号
|
||||||
- **RSI 40-60**:震荡区,观望为主
|
- **RSI 40-60**:震荡区,观望为主
|
||||||
|
- **RSI 50 分界**:多空分界线,上多下空
|
||||||
|
|
||||||
|
**日内 RSI 使用技巧**:
|
||||||
|
- 15m RSI 用于判断趋势方向
|
||||||
|
- 5m RSI 用于精确入场时机
|
||||||
|
- 1m RSI 用于最后确认(避免假突破)
|
||||||
- **RSI 趋势**:RSI 自身的趋势变化比单一数值更重要
|
- **RSI 趋势**:RSI 自身的趋势变化比单一数值更重要
|
||||||
|
|
||||||
### MACD
|
### MACD(趋势确认)
|
||||||
- 金叉(DIF 上穿 DEA):做多信号
|
- **金叉**(DIF 上穿 DEA):做多信号
|
||||||
- 死叉(DIF 下穿 DEA):做空信号
|
- **死叉**(DIF 下穿 DEA):做空信号
|
||||||
- 零轴上方金叉:强势做多
|
- **零轴上方金叉**:强势做多
|
||||||
- 零轴下方死叉:强势做空
|
- **零轴下方死叉**:强势做空
|
||||||
- MACD 柱状图背离:重要反转信号
|
- **MACD 柱状图背离**:重要反转信号
|
||||||
|
|
||||||
### 布林带
|
**日内 MACD 使用**:
|
||||||
- 触及下轨 + 企稳:反弹做多
|
- 15m MACD 判断主趋势
|
||||||
- 触及上轨 + 受阻:回落做空
|
- 5m MACD 确认入场时机
|
||||||
- 布林带收口:即将变盘
|
- 柱状图缩短 = 动能减弱,警惕反转
|
||||||
- 布林带开口:趋势启动
|
|
||||||
|
### 布林带(波动率指标)
|
||||||
|
- **触及下轨 + 企稳**:反弹做多机会
|
||||||
|
- **触及上轨 + 受阻**:回落做空机会
|
||||||
|
- **布林带收口**:即将变盘,观望
|
||||||
|
- **布林带开口**:趋势启动,跟随
|
||||||
|
|
||||||
|
**日内布林带使用**:
|
||||||
|
- 价格在下轨 + RSI < 30 = 超卖反弹
|
||||||
|
- 价格在上轨 + RSI > 70 = 超买回落
|
||||||
|
- 突破上轨 + 放量 = 强势上涨,可追
|
||||||
|
|
||||||
### 均线系统(趋势判断核心 - 使用 EMA)
|
### 均线系统(趋势判断核心 - 使用 EMA)
|
||||||
- **多头排列**(EMA5 > EMA10 > EMA20 > EMA50):强势上涨趋势,回调做多
|
**EMA 比 SMA 反应更快,适合日内**:
|
||||||
- **空头排列**(EMA5 < EMA10 < EMA20 < EMA50):强势下跌趋势,反弹做空
|
- **多头排列**(EMA5 > EMA10 > EMA20):强势上涨,回调做多
|
||||||
|
- **空头排列**(EMA5 < EMA10 < EMA20):强势下跌,反弹做空
|
||||||
- **价格与 EMA 的关系**:
|
- **价格与 EMA 的关系**:
|
||||||
- 价格站稳 EMA5/EMA10 上方:短线上涨
|
- 价格站稳 EMA5:短线上涨
|
||||||
- 价格突破 EMA20:中线转多
|
- 价格突破 EMA20:中线转多
|
||||||
- 价格跌破 EMA20:中线转空
|
- 价格跌破 EMA20:中线转空
|
||||||
- EMA50 是中期趋势的分水岭
|
- **EMA 金叉死叉**:
|
||||||
- **均线金叉死叉**:
|
- EMA5 上穿 EMA10:短线买入
|
||||||
- EMA5 上穿 EMA10:短线买入信号
|
- EMA5 下穿 EMA10:短线卖出
|
||||||
- EMA5 下穿 EMA10:短线卖出信号
|
- EMA10 上穿 EMA20:中线买入
|
||||||
- EMA10 上穿 EMA20:中线买入信号
|
- EMA10 下穿 EMA20:中线卖出
|
||||||
- EMA10 下穿 EMA20:中线卖出信号
|
|
||||||
|
|
||||||
## 四、新闻舆情分析
|
**日内 EMA 使用技巧**:
|
||||||
|
- 30m EMA 判断日内趋势方向
|
||||||
|
- 15m EMA 寻找入场时机
|
||||||
|
- 5m EMA 确认最佳入场点
|
||||||
|
- **EMA 作为支撑/压力**:价格回调到 EMA 常有支撑/阻力
|
||||||
|
|
||||||
|
## 六、新闻舆情分析(日内影响)
|
||||||
结合最新市场新闻判断:
|
结合最新市场新闻判断:
|
||||||
- **重大利好**:监管利好、机构入场、ETF 通过等 → 提高做多置信度
|
- **重大利好**:监管利好、机构入场、ETF 通过等 → 提高做多置信度
|
||||||
- **重大利空**:监管打压、交易所暴雷、黑客攻击等 → 提高做空置信度
|
- **重大利空**:监管打压、交易所暴雷、黑客攻击等 → 提高做空置信度
|
||||||
- **市场情绪**:恐慌指数、社交媒体热度
|
- **市场情绪**:恐慌指数、社交媒体热度
|
||||||
- **大户动向**:鲸鱼转账、交易所流入流出
|
- **大户动向**:鲸鱼转账、交易所流入流出
|
||||||
|
|
||||||
## 五、多周期共振(关键分析框架)
|
**日内交易注意**:
|
||||||
**多周期共振是提高信号质量的核心方法:**
|
- 重大新闻后 1-2 小时内波动剧烈,适合突破交易
|
||||||
|
- 新闻驱动的行情通常持续 2-4 小时,符合日内目标
|
||||||
|
- 注意新闻发布时间(美股开盘、宏观数据等)
|
||||||
|
|
||||||
### 周期层级关系
|
## 七、多周期共振(日内关键分析框架)
|
||||||
- **1h(当日大方向)**:判断当日的主要趋势方向
|
**多周期共振是提高信号质量的核心方法**:
|
||||||
- **30m(日内趋势层)**:决定日内主趋势
|
|
||||||
- **15m(入场层)**:寻找入场时机
|
|
||||||
- **5m(精确入场)**:确认最佳入场点
|
|
||||||
- **1m(超精确)**:最后确认(可选)
|
|
||||||
|
|
||||||
### 共振判断标准
|
### 周期层级关系(日内优化版)
|
||||||
**强共振(A级信号)**:
|
- **1h(当日大方向)**:判断当日的主要趋势方向,确保不逆大势
|
||||||
- 30m + 15m + 5m 趋势同向(如 30m多 + 15m多 + 5m多)
|
- **30m(日内趋势层)**:决定日内主趋势,使用 EMA 判断
|
||||||
- 多周期 RSI 同时超买/超卖后出现背离
|
- **15m(入场层)**:寻找入场时机,等待回调/反弹
|
||||||
- 多周期 EMA 同时金叉/死叉
|
- **5m(精确入场)**:确认最佳入场点,避免假突破
|
||||||
|
- **1m(超精确)**:最后确认(可选),避免刚入场就反转
|
||||||
|
|
||||||
**中等共振(B级信号)**:
|
### 共振判断标准(日内版)
|
||||||
- 30m + 15m 同向
|
**强共振(A级信号,confidence 85-100)**:
|
||||||
|
- 30m + 15m + 5m EMA 趋势同向
|
||||||
|
- 多周期 RSI 同时配合(如都不在极端区)
|
||||||
|
- 多周期 MACD 同时金叉/死叉
|
||||||
|
- 量能配合(放量突破或缩量回调)
|
||||||
|
|
||||||
|
**中等共振(B级信号,confidence 60-84)**:
|
||||||
|
- 30m + 15m EMA 同向
|
||||||
- 主周期(15m)技术指标明确
|
- 主周期(15m)技术指标明确
|
||||||
|
- 量能基本配合
|
||||||
|
|
||||||
**弱共振(C级信号)**:
|
**弱共振(C级信号,confidence 40-59)**:
|
||||||
- 只有单一周期信号
|
- 只有单一周期信号
|
||||||
- 多周期方向不一致
|
- 多周期方向不一致
|
||||||
|
- 量能不明显
|
||||||
|
|
||||||
### 实战策略
|
**无共振(D级信号,confidence < 40)**:
|
||||||
- **顺势交易**:30m 和 15m 同向时,在 5m/1m 寻找入场点
|
- 多周期信号矛盾
|
||||||
- **逆势谨慎**:只有 15m 信号但 30m 反向时,降低置信度
|
- 量价背离
|
||||||
- **突破交易**:多周期同时突破关键位,信号最强
|
- 不建议交易
|
||||||
|
|
||||||
## 六、入场方式
|
### 日内实战策略
|
||||||
|
- **顺势交易**:30m 和 15m EMA 同向时,在 5m/1m 寻找入场点
|
||||||
|
- **逆势谨慎**:只有 15m 信号但 30m EMA 反向时,降低置信度
|
||||||
|
- **突破交易**:多周期同时突破关键位 + 放量,信号最强
|
||||||
|
- **回调交易**:30m 趋势向上,15m 回调到 EMA20,5m 反弹确认
|
||||||
|
|
||||||
|
## 八、入场方式(日内优化)
|
||||||
根据市场分析综合判断入场方式:
|
根据市场分析综合判断入场方式:
|
||||||
- **market**:现价立即入场
|
|
||||||
- 信号强烈且明确(A级或高置信度B级)
|
### market(现价立即入场)
|
||||||
- 放量突破关键位,趋势明确
|
使用场景:
|
||||||
- 多周期共振,等待可能错过机会
|
- ✅ 强共振信号(A级,confidence ≥ 85)
|
||||||
- 市场波动大,等待可能价格变化太快
|
- ✅ 放量突破关键位,趋势明确
|
||||||
- **limit**:挂单等待入场
|
- ✅ 多周期同时突破,等待可能错过机会
|
||||||
- 信号强度中等(B级或C级)
|
- ✅ 市场波动大,价格变化快
|
||||||
- 当前价格距离理想入场位有一定距离
|
- ✅ 15m RSI 50-70(多)或 30-50(空)- 不极端
|
||||||
- 判断市场可能回调到更好位置
|
|
||||||
- 希望获得更优成交价格,愿意承担可能无法成交的风险
|
### limit(挂单等待入场)
|
||||||
|
使用场景:
|
||||||
|
- ✅ 信号强度中等(B/C 级)
|
||||||
|
- ✅ 等待回调到支撑位(EMA20、前期低点)
|
||||||
|
- ✅ 等待反弹到压力位(EMA20、前期高点)
|
||||||
|
- ✅ 希望获得更优成交价格
|
||||||
|
- ✅ 震荡市区间交易
|
||||||
|
|
||||||
**重要**:
|
**重要**:
|
||||||
- 必须同时输出 `entry_zone`(建议入场价)和 `entry_type`(入场方式)
|
- 必须同时输出 `entry_price`(建议入场价)和 `entry_type`(入场方式)
|
||||||
- 入场方式由你的市场分析判断,不是简单的价格距离计算
|
- 入场方式由你的市场分析判断,不是简单的价格距离计算
|
||||||
- 如果选择 `limit`,`entry_zone` 应该是你建议的挂单价格
|
|
||||||
|
|
||||||
## 输出格式
|
## 输出格式
|
||||||
请严格按照以下 JSON 格式输出:
|
请严格按照以下 JSON 格式输出:
|
||||||
@ -342,7 +447,7 @@ class MarketSignalAnalyzer:
|
|||||||
"entry_type": "market/limit",
|
"entry_type": "market/limit",
|
||||||
"confidence": 0-100,
|
"confidence": 0-100,
|
||||||
"grade": "A/B/C/D",
|
"grade": "A/B/C/D",
|
||||||
"entry_zone": 66000,
|
"entry_price": 66000,
|
||||||
"stop_loss": 65500,
|
"stop_loss": 65500,
|
||||||
"take_profit": 67500,
|
"take_profit": 67500,
|
||||||
"reasoning": "详细的入场理由(必须包含趋势判断和量价分析)",
|
"reasoning": "详细的入场理由(必须包含趋势判断和量价分析)",
|
||||||
@ -357,24 +462,44 @@ class MarketSignalAnalyzer:
|
|||||||
```
|
```
|
||||||
|
|
||||||
## 重要说明
|
## 重要说明
|
||||||
|
- `entry_price`:建议入场价格(单一值)
|
||||||
|
- `entry_type`:入场方式 - `market`(现价立即入场)或 `limit`(挂单等待)
|
||||||
- **所有价格必须是纯数字**,不要加 $ 符号、逗号或其他格式
|
- **所有价格必须是纯数字**,不要加 $ 符号、逗号或其他格式
|
||||||
- `entry_zone`、`stop_loss`、`take_profit` 必须是数字类型,不要是字符串
|
- `entry_price`、`stop_loss`、`take_profit` 必须是数字类型,不要是字符串
|
||||||
- `key_levels` 中的支撑位和阻力位也必须是数字数组
|
- `key_levels` 中的支撑位和阻力位也必须是数字数组
|
||||||
|
|
||||||
## 信号等级与置信度
|
## 信号等级与置信度(日内优化版)
|
||||||
- **A级**(80-100):量价配合 + 多指标共振 + 多周期确认
|
- **A级**(85-100):量价配合 + 多指标共振 + 多周期确认 + 盈亏比 ≥ 1:1.5
|
||||||
- **B级**(60-79):量价配合 + 主要指标确认
|
- **B级**(60-84):量价配合 + 主要指标确认 + 盈亏比 ≥ 1:1.2
|
||||||
- **C级**(40-59):有机会但量价不够理想
|
- **C级**(40-59):有机会但量价不够理想 + 盈亏比 ≥ 1:1.2
|
||||||
- **D级**(<40):量价背离或信号矛盾
|
- **D级**(<40):量价背离或信号矛盾或盈亏比不足
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项(日内交易重点)
|
||||||
1. **只在有明确的做多或做空机会时才输出信号**(action 为 buy 或 sell)
|
1. **只在有明确的做多或做空机会时才输出信号**(action 为 buy 或 sell)
|
||||||
2. 如果市场不明朗,没有明确交易机会,**不要输出任何信号**(signals 为空数组 [])
|
2. 如果市场不明朗,没有明确交易机会,**不要输出任何信号**(signals 为空数组 [])
|
||||||
3. 信号强度(confidence)要合理,不要随意给高分
|
3. 信号强度(confidence)要合理,不要随意给高分:
|
||||||
4. 60-70分:一般信号,可轻仓试探
|
- 60-70分:一般信号,可轻仓试探(micro 仓位)
|
||||||
5. 75-85分:较强信号,可正常仓位
|
- 75-84分:较强信号,可正常仓位(light 仓位)
|
||||||
6. 90+分:强信号,但也要控制风险
|
- 85-100分:强信号,可考虑 medium 仓位
|
||||||
7. 不要输出 action 为 "wait" 的信号,如果没有交易机会就不输出
|
4. **不要输出 action 为 "wait" 的信号**,如果没有交易机会就不输出
|
||||||
|
5. **每次检查盈亏比**:盈亏比 < 1:1.2 的信号不要输出
|
||||||
|
6. **避免过度交易**:趋势延续时不重复输出相同方向信号
|
||||||
|
7. **关注时效性**:日内信号有效期通常 2-4 小时,超过时间需重新评估
|
||||||
|
|
||||||
|
## 日内交易特殊注意事项
|
||||||
|
1. **不持仓过夜**:收盘前 30 分钟逐步平仓
|
||||||
|
2. **快进快出**:达到目标(2-3%)立即平仓,不贪心
|
||||||
|
3. **严格止损**:触及止损立即离场,不要幻想
|
||||||
|
4. **避免追涨杀跌**:价格过度延伸时(偏离 EMA5 > 3%)不追
|
||||||
|
5. **关注量能**:无量配合的突破不追,容易是假突破
|
||||||
|
6. **多周期确认**:5m/15m/30m 同向才入场,提高胜率
|
||||||
|
|
||||||
|
## 🎯 日内交易成功关键
|
||||||
|
1. **盈亏比第一**:宁可错过,不做错
|
||||||
|
2. **顺势而为**:趋势方向正确,成功率才能高
|
||||||
|
3. **快速止损**:日内交易,止损就是止错
|
||||||
|
4. **不贪不急**:达到目标就走,达不到就止损
|
||||||
|
5. **保持冷静**:不被情绪左右,按规则交易
|
||||||
|
|
||||||
## 历史信号参考(非常重要!)
|
## 历史信号参考(非常重要!)
|
||||||
**如果提供了上一轮的分析信号,必须仔细参考它:**
|
**如果提供了上一轮的分析信号,必须仔细参考它:**
|
||||||
@ -666,11 +791,11 @@ class MarketSignalAnalyzer:
|
|||||||
if is_accelerating and volume_ratio > 1.3 and not is_overextended:
|
if is_accelerating and volume_ratio > 1.3 and not is_overextended:
|
||||||
analysis.append(f"15m: 正在加速上涨,放量突破")
|
analysis.append(f"15m: 正在加速上涨,放量突破")
|
||||||
analysis.append(f" → 日内追多(止损1-2%,目标2-3%)")
|
analysis.append(f" → 日内追多(止损1-2%,目标2-3%)")
|
||||||
analysis.append(f" → 盈亏比要求 >= 1:2")
|
analysis.append(f" → 盈亏比要求 >= 1:1.2")
|
||||||
elif distance_to_ema20 < 1 and deviation_ema5_15m > 1.5:
|
elif distance_to_ema20 < 1 and deviation_ema5_15m > 1.5:
|
||||||
analysis.append(f"15m: 回调到 EMA20 支撑位")
|
analysis.append(f"15m: 回调到 EMA20 支撑位")
|
||||||
analysis.append(f" → 支撑位做多反弹(EMA20: ${ema20_15m:.0f})")
|
analysis.append(f" → 支撑位做多反弹(EMA20: ${ema20_15m:.0f})")
|
||||||
analysis.append(f" → 止损1%,目标2-3%,盈亏比 >= 1:3")
|
analysis.append(f" → 止损1%,目标2-3%,盈亏比 >= 1:1.5")
|
||||||
elif is_overextended:
|
elif is_overextended:
|
||||||
analysis.append(f"⚠️ 15m 过度延伸: RSI {rsi_15m:.0f},偏离 EMA5 {deviation_ema5_15m:.1f}%")
|
analysis.append(f"⚠️ 15m 过度延伸: RSI {rsi_15m:.0f},偏离 EMA5 {deviation_ema5_15m:.1f}%")
|
||||||
analysis.append(f" → 不要追多,等待回调")
|
analysis.append(f" → 不要追多,等待回调")
|
||||||
@ -682,11 +807,11 @@ class MarketSignalAnalyzer:
|
|||||||
if is_accelerating and volume_ratio > 1.3 and not is_overextended:
|
if is_accelerating and volume_ratio > 1.3 and not is_overextended:
|
||||||
analysis.append(f"15m: 正在加速下跌,放量跌破")
|
analysis.append(f"15m: 正在加速下跌,放量跌破")
|
||||||
analysis.append(f" → 日内追空(止损1-2%,目标2-3%)")
|
analysis.append(f" → 日内追空(止损1-2%,目标2-3%)")
|
||||||
analysis.append(f" → 盈亏比要求 >= 1:2")
|
analysis.append(f" → 盈亏比要求 >= 1:1.2")
|
||||||
elif distance_to_ema20 < 1 and deviation_ema5_15m > 1.5:
|
elif distance_to_ema20 < 1 and deviation_ema5_15m > 1.5:
|
||||||
analysis.append(f"15m: 反弹到 EMA20 压力位")
|
analysis.append(f"15m: 反弹到 EMA20 压力位")
|
||||||
analysis.append(f" → 压力位做空回调(EMA20: ${ema20_15m:.0f})")
|
analysis.append(f" → 压力位做空回调(EMA20: ${ema20_15m:.0f})")
|
||||||
analysis.append(f" → 止损1%,目标2-3%,盈亏比 >= 1:3")
|
analysis.append(f" → 止损1%,目标2-3%,盈亏比 >= 1:1.5")
|
||||||
elif is_overextended:
|
elif is_overextended:
|
||||||
analysis.append(f"⚠️ 15m 过度延伸: RSI {rsi_15m:.0f},偏离 EMA5 {deviation_ema5_15m:.1f}%")
|
analysis.append(f"⚠️ 15m 过度延伸: RSI {rsi_15m:.0f},偏离 EMA5 {deviation_ema5_15m:.1f}%")
|
||||||
analysis.append(f" → 不要追空,等待反弹")
|
analysis.append(f" → 不要追空,等待反弹")
|
||||||
@ -696,12 +821,12 @@ class MarketSignalAnalyzer:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
analysis.append(f"15m: 震荡,观望或双向轻仓")
|
analysis.append(f"15m: 震荡,观望或双向轻仓")
|
||||||
analysis.append(f" → 支撑位多,压力位空,盈亏比 >= 1:3")
|
analysis.append(f" → 支撑位多,压力位空,盈亏比 >= 1:1.5")
|
||||||
|
|
||||||
# 日内交易要点
|
# 日内交易要点
|
||||||
analysis.append(f"\n💡 日内交易要点:")
|
analysis.append(f"\n💡 日内交易要点:")
|
||||||
analysis.append(f"- 使用 EMA(指数移动平均)反应更快")
|
analysis.append(f"- 使用 EMA(指数移动平均)反应更快")
|
||||||
analysis.append(f"- 盈亏比第一: 必须 >= 1:2,优选 1:3")
|
analysis.append(f"- 盈亏比第一: 必须 >= 1:1.2")
|
||||||
analysis.append(f"- 快进快出: 持仓不超过4小时")
|
analysis.append(f"- 快进快出: 持仓不超过4小时")
|
||||||
analysis.append(f"- 严格止损: 1-2%(最大2%)")
|
analysis.append(f"- 严格止损: 1-2%(最大2%)")
|
||||||
analysis.append(f"- 目标盈利: 2-3%(快速获利)")
|
analysis.append(f"- 目标盈利: 2-3%(快速获利)")
|
||||||
@ -744,7 +869,7 @@ class MarketSignalAnalyzer:
|
|||||||
type_map = {'short_term': '短线', 'medium_term': '中线', 'long_term': '长线'}
|
type_map = {'short_term': '短线', 'medium_term': '中线', 'long_term': '长线'}
|
||||||
type_text = type_map.get(timeframe, timeframe)
|
type_text = type_map.get(timeframe, timeframe)
|
||||||
|
|
||||||
entry = sig.get('entry_zone', 'N/A')
|
entry = sig.get('entry_price', 'N/A')
|
||||||
sl = sig.get('stop_loss', 'N/A')
|
sl = sig.get('stop_loss', 'N/A')
|
||||||
tp = sig.get('take_profit', 'N/A')
|
tp = sig.get('take_profit', 'N/A')
|
||||||
reasoning = sig.get('reasoning', 'N/A')
|
reasoning = sig.get('reasoning', 'N/A')
|
||||||
@ -947,45 +1072,45 @@ class MarketSignalAnalyzer:
|
|||||||
signals_to_remove = []
|
signals_to_remove = []
|
||||||
|
|
||||||
for idx, sig in enumerate(data['signals']):
|
for idx, sig in enumerate(data['signals']):
|
||||||
price_fields = ['entry_zone', 'stop_loss', 'take_profit']
|
price_fields = ['entry_price', 'stop_loss', 'take_profit']
|
||||||
for field in price_fields:
|
for field in price_fields:
|
||||||
if field in sig:
|
if field in sig:
|
||||||
sig[field] = clean_price(sig[field])
|
sig[field] = clean_price(sig[field])
|
||||||
|
|
||||||
# 验证止损止盈价格的合理性
|
# 验证止损止盈价格的合理性
|
||||||
entry_zone = sig.get('entry_zone')
|
entry_price = sig.get('entry_price')
|
||||||
stop_loss = sig.get('stop_loss')
|
stop_loss = sig.get('stop_loss')
|
||||||
take_profit = sig.get('take_profit')
|
take_profit = sig.get('take_profit')
|
||||||
action = sig.get('action', '')
|
action = sig.get('action', '')
|
||||||
|
|
||||||
if entry_zone and entry_zone > 0:
|
if entry_price and entry_price > 0:
|
||||||
MAX_REASONABLE_DEVIATION = 0.50 # 50%
|
MAX_REASONABLE_DEVIATION = 0.50 # 50%
|
||||||
has_invalid_price = False
|
has_invalid_price = False
|
||||||
|
|
||||||
# 检查止损
|
# 检查止损
|
||||||
if stop_loss is not None:
|
if stop_loss is not None:
|
||||||
deviation = abs(stop_loss - entry_zone) / entry_zone
|
deviation = abs(stop_loss - entry_price) / entry_price
|
||||||
if deviation > MAX_REASONABLE_DEVIATION:
|
if deviation > MAX_REASONABLE_DEVIATION:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止损价格不合理: entry={entry_zone}, stop_loss={stop_loss}, 偏离={deviation*100:.1f}%")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止损价格不合理: entry={entry_price}, stop_loss={stop_loss}, 偏离={deviation*100:.1f}%")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'buy' and stop_loss >= entry_zone:
|
elif action == 'buy' and stop_loss >= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止损错误: entry={entry_zone}, stop_loss={stop_loss} 应该 < entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止损错误: entry={entry_price}, stop_loss={stop_loss} 应该 < entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'sell' and stop_loss <= entry_zone:
|
elif action == 'sell' and stop_loss <= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止损错误: entry={entry_zone}, stop_loss={stop_loss} 应该 > entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止损错误: entry={entry_price}, stop_loss={stop_loss} 应该 > entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
|
|
||||||
# 检查止盈
|
# 检查止盈
|
||||||
if take_profit is not None:
|
if take_profit is not None:
|
||||||
deviation = abs(take_profit - entry_zone) / entry_zone
|
deviation = abs(take_profit - entry_price) / entry_price
|
||||||
if deviation > MAX_REASONABLE_DEVIATION:
|
if deviation > MAX_REASONABLE_DEVIATION:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止盈价格不合理: entry={entry_zone}, take_profit={take_profit}, 偏离={deviation*100:.1f}%")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止盈价格不合理: entry={entry_price}, take_profit={take_profit}, 偏离={deviation*100:.1f}%")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'buy' and take_profit <= entry_zone:
|
elif action == 'buy' and take_profit <= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止盈错误: entry={entry_zone}, take_profit={take_profit} 应该 > entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止盈错误: entry={entry_price}, take_profit={take_profit} 应该 > entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'sell' and take_profit >= entry_zone:
|
elif action == 'sell' and take_profit >= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止盈错误: entry={entry_zone}, take_profit={take_profit} 应该 < entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止盈错误: entry={entry_price}, take_profit={take_profit} 应该 < entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
|
|
||||||
# 如果价格不合理,降低等级为 D 或移除信号
|
# 如果价格不合理,降低等级为 D 或移除信号
|
||||||
|
|||||||
@ -333,10 +333,10 @@ class TradingDecisionMaker:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意**:
|
## 入场价格选择策略
|
||||||
- `quantity` 是保证金金额(USDT),交易系统会使用杠杆计算实际持仓价值
|
|
||||||
- 如果 decision 是 CANCEL_PENDING,需要提供 orders_to_cancel 字段
|
- 使用信号中的 `entry_price` 作为入场价格
|
||||||
- reasoning 必须说明当前持仓/挂单状态以及为什么选择这个操作
|
- 如果选择 `limit`(挂单)方式,等待价格达到 `entry_price` 时成交
|
||||||
|
|
||||||
## 重要原则
|
## 重要原则
|
||||||
1. **仓位管理优先**:先管理现有仓位,再考虑开新仓
|
1. **仓位管理优先**:先管理现有仓位,再考虑开新仓
|
||||||
@ -553,9 +553,9 @@ class TradingDecisionMaker:
|
|||||||
prompt_parts.append(f" 信心度: {sig.get('confidence', 0)}")
|
prompt_parts.append(f" 信心度: {sig.get('confidence', 0)}")
|
||||||
|
|
||||||
# 添加入场价格信息
|
# 添加入场价格信息
|
||||||
entry_zone = sig.get('entry_zone')
|
entry_price = sig.get('entry_price')
|
||||||
if entry_zone:
|
if entry_price:
|
||||||
prompt_parts.append(f" 建议入场价: ${entry_zone:,.2f}")
|
prompt_parts.append(f" 建议入场价: ${entry_price:,.2f}")
|
||||||
|
|
||||||
prompt_parts.append(f" 理由: {sig.get('reasoning', 'N/A')}")
|
prompt_parts.append(f" 理由: {sig.get('reasoning', 'N/A')}")
|
||||||
|
|
||||||
@ -699,7 +699,7 @@ class TradingDecisionMaker:
|
|||||||
if signals and current_price:
|
if signals and current_price:
|
||||||
for sig in signals:
|
for sig in signals:
|
||||||
sig_action = sig.get('action')
|
sig_action = sig.get('action')
|
||||||
sig_entry = sig.get('entry_zone')
|
sig_entry = sig.get('entry_price')
|
||||||
|
|
||||||
if sig_action and sig_entry:
|
if sig_action and sig_entry:
|
||||||
try:
|
try:
|
||||||
@ -744,7 +744,7 @@ class TradingDecisionMaker:
|
|||||||
if signals:
|
if signals:
|
||||||
for sig in signals:
|
for sig in signals:
|
||||||
action = sig.get('action')
|
action = sig.get('action')
|
||||||
entry = sig.get('entry_zone')
|
entry = sig.get('entry_price')
|
||||||
stop_loss = sig.get('stop_loss')
|
stop_loss = sig.get('stop_loss')
|
||||||
take_profit = sig.get('take_profit')
|
take_profit = sig.get('take_profit')
|
||||||
|
|
||||||
@ -852,7 +852,7 @@ class TradingDecisionMaker:
|
|||||||
|
|
||||||
def _validate_price_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
def _validate_price_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""验证止损止盈价格的合理性,拒绝明显错误的值"""
|
"""验证止损止盈价格的合理性,拒绝明显错误的值"""
|
||||||
entry = data.get('entry_zone')
|
entry = data.get('entry_price')
|
||||||
stop_loss = data.get('stop_loss')
|
stop_loss = data.get('stop_loss')
|
||||||
take_profit = data.get('take_profit')
|
take_profit = data.get('take_profit')
|
||||||
action = data.get('decision', '') # OPEN/CLOSE/HOLD
|
action = data.get('decision', '') # OPEN/CLOSE/HOLD
|
||||||
|
|||||||
@ -124,12 +124,12 @@ async def price_monitor_loop():
|
|||||||
"""后台价格监控循环 - 使用轮询检查止盈止损"""
|
"""后台价格监控循环 - 使用轮询检查止盈止损"""
|
||||||
from app.services.paper_trading_service import get_paper_trading_service
|
from app.services.paper_trading_service import get_paper_trading_service
|
||||||
from app.services.bitget_service import bitget_service
|
from app.services.bitget_service import bitget_service
|
||||||
from app.services.feishu_service import get_feishu_service
|
from app.services.feishu_service import get_feishu_paper_trading_service
|
||||||
from app.services.telegram_service import get_telegram_service
|
from app.services.telegram_service import get_telegram_service
|
||||||
|
|
||||||
logger.info("后台价格监控任务已启动(轮询模式)")
|
logger.info("后台价格监控任务已启动(轮询模式)")
|
||||||
|
|
||||||
feishu = get_feishu_service()
|
feishu = get_feishu_paper_trading_service() # 使用 trading webhook
|
||||||
telegram = get_telegram_service()
|
telegram = get_telegram_service()
|
||||||
paper_trading = get_paper_trading_service()
|
paper_trading = get_paper_trading_service()
|
||||||
|
|
||||||
|
|||||||
@ -177,6 +177,8 @@ class PaperTradingService:
|
|||||||
|
|
||||||
symbol = signal.get('symbol', 'UNKNOWN')
|
symbol = signal.get('symbol', 'UNKNOWN')
|
||||||
side = OrderSide.LONG if action == 'buy' else OrderSide.SHORT
|
side = OrderSide.LONG if action == 'buy' else OrderSide.SHORT
|
||||||
|
|
||||||
|
# 获取入场价格
|
||||||
entry_price = signal.get('entry_price') or signal.get('price', 0)
|
entry_price = signal.get('entry_price') or signal.get('price', 0)
|
||||||
|
|
||||||
# === 反向订单处理 ===
|
# === 反向订单处理 ===
|
||||||
|
|||||||
@ -51,14 +51,15 @@ class SignalDatabaseService:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# 创建信号对象
|
# 创建信号对象
|
||||||
|
entry_price_value = clean_price(signal_data.get('entry_price'))
|
||||||
|
|
||||||
signal = TradingSignal(
|
signal = TradingSignal(
|
||||||
signal_type=signal_data.get('signal_type', 'crypto'),
|
signal_type=signal_data.get('signal_type', 'crypto'),
|
||||||
symbol=signal_data.get('symbol', ''),
|
symbol=signal_data.get('symbol', ''),
|
||||||
action=signal_data.get('action', 'hold'),
|
action=signal_data.get('action', 'hold'),
|
||||||
grade=signal_data.get('grade', 'D'),
|
grade=signal_data.get('grade', 'D'),
|
||||||
confidence=signal_data.get('confidence', 0),
|
confidence=signal_data.get('confidence', 0),
|
||||||
entry_price=clean_price(signal_data.get('entry_price')),
|
entry_price=entry_price_value,
|
||||||
entry_zone=clean_price(signal_data.get('entry_zone')), # 挂单价格
|
|
||||||
stop_loss=clean_price(signal_data.get('stop_loss')),
|
stop_loss=clean_price(signal_data.get('stop_loss')),
|
||||||
take_profit=clean_price(signal_data.get('take_profit')),
|
take_profit=clean_price(signal_data.get('take_profit')),
|
||||||
current_price=clean_price(signal_data.get('current_price')),
|
current_price=clean_price(signal_data.get('current_price')),
|
||||||
|
|||||||
@ -305,7 +305,7 @@ class StockMarketSignalAnalyzer:
|
|||||||
- 希望获得更优成交价格,愿意承担可能无法成交的风险
|
- 希望获得更优成交价格,愿意承担可能无法成交的风险
|
||||||
|
|
||||||
**重要**:
|
**重要**:
|
||||||
- 必须同时输出 `entry_zone`(建议入场价)和 `entry_type`(入场方式)
|
- 必须同时输出 `entry_price`(建议入场价)和 `entry_type`(入场方式)
|
||||||
- 入场方式由你的市场分析判断,不是简单的价格距离计算
|
- 入场方式由你的市场分析判断,不是简单的价格距离计算
|
||||||
|
|
||||||
## 输出格式
|
## 输出格式
|
||||||
@ -326,7 +326,7 @@ class StockMarketSignalAnalyzer:
|
|||||||
"entry_type": "market/limit",
|
"entry_type": "market/limit",
|
||||||
"confidence": 0-100,
|
"confidence": 0-100,
|
||||||
"grade": "A/B/C/D",
|
"grade": "A/B/C/D",
|
||||||
"entry_zone": 150.50,
|
"entry_price": 150.50,
|
||||||
"stop_loss": 148.00,
|
"stop_loss": 148.00,
|
||||||
"take_profit": 155.00,
|
"take_profit": 155.00,
|
||||||
"reasoning": "详细的入场理由(必须包含趋势判断和量价分析)",
|
"reasoning": "详细的入场理由(必须包含趋势判断和量价分析)",
|
||||||
@ -342,7 +342,7 @@ class StockMarketSignalAnalyzer:
|
|||||||
|
|
||||||
## 重要说明
|
## 重要说明
|
||||||
- **所有价格必须是纯数字**,不要加 $ 符号、逗号或其他格式
|
- **所有价格必须是纯数字**,不要加 $ 符号、逗号或其他格式
|
||||||
- `entry_zone`、`stop_loss`、`take_profit` 必须是数字类型,不要是字符串
|
- `entry_price`、`stop_loss`、`take_profit` 必须是数字类型,不要是字符串
|
||||||
- `key_levels` 中的支撑位和阻力位也必须是数字数组
|
- `key_levels` 中的支撑位和阻力位也必须是数字数组
|
||||||
|
|
||||||
## 信号等级与置信度(综合技术面 + 基本面 + 新闻)
|
## 信号等级与置信度(综合技术面 + 基本面 + 新闻)
|
||||||
@ -653,45 +653,45 @@ class StockMarketSignalAnalyzer:
|
|||||||
|
|
||||||
if 'signals' in data:
|
if 'signals' in data:
|
||||||
for sig in data['signals']:
|
for sig in data['signals']:
|
||||||
price_fields = ['entry_zone', 'stop_loss', 'take_profit']
|
price_fields = ['entry_price', 'stop_loss', 'take_profit']
|
||||||
for field in price_fields:
|
for field in price_fields:
|
||||||
if field in sig:
|
if field in sig:
|
||||||
sig[field] = clean_price(sig[field])
|
sig[field] = clean_price(sig[field])
|
||||||
|
|
||||||
# 验证止损止盈价格的合理性
|
# 验证止损止盈价格的合理性
|
||||||
entry_zone = sig.get('entry_zone')
|
entry_price = sig.get('entry_price')
|
||||||
stop_loss = sig.get('stop_loss')
|
stop_loss = sig.get('stop_loss')
|
||||||
take_profit = sig.get('take_profit')
|
take_profit = sig.get('take_profit')
|
||||||
action = sig.get('action', '')
|
action = sig.get('action', '')
|
||||||
|
|
||||||
if entry_zone and entry_zone > 0:
|
if entry_price and entry_price > 0:
|
||||||
MAX_REASONABLE_DEVIATION = 0.50 # 50%
|
MAX_REASONABLE_DEVIATION = 0.50 # 50%
|
||||||
has_invalid_price = False
|
has_invalid_price = False
|
||||||
|
|
||||||
# 检查止损
|
# 检查止损
|
||||||
if stop_loss is not None:
|
if stop_loss is not None:
|
||||||
deviation = abs(stop_loss - entry_zone) / entry_zone
|
deviation = abs(stop_loss - entry_price) / entry_price
|
||||||
if deviation > MAX_REASONABLE_DEVIATION:
|
if deviation > MAX_REASONABLE_DEVIATION:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止损价格不合理: entry={entry_zone}, stop_loss={stop_loss}, 偏离={deviation*100:.1f}%")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止损价格不合理: entry={entry_price}, stop_loss={stop_loss}, 偏离={deviation*100:.1f}%")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'buy' and stop_loss >= entry_zone:
|
elif action == 'buy' and stop_loss >= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止损错误: entry={entry_zone}, stop_loss={stop_loss} 应该 < entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止损错误: entry={entry_price}, stop_loss={stop_loss} 应该 < entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'sell' and stop_loss <= entry_zone:
|
elif action == 'sell' and stop_loss <= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止损错误: entry={entry_zone}, stop_loss={stop_loss} 应该 > entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止损错误: entry={entry_price}, stop_loss={stop_loss} 应该 > entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
|
|
||||||
# 检查止盈
|
# 检查止盈
|
||||||
if take_profit is not None:
|
if take_profit is not None:
|
||||||
deviation = abs(take_profit - entry_zone) / entry_zone
|
deviation = abs(take_profit - entry_price) / entry_price
|
||||||
if deviation > MAX_REASONABLE_DEVIATION:
|
if deviation > MAX_REASONABLE_DEVIATION:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止盈价格不合理: entry={entry_zone}, take_profit={take_profit}, 偏离={deviation*100:.1f}%")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 信号止盈价格不合理: entry={entry_price}, take_profit={take_profit}, 偏离={deviation*100:.1f}%")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'buy' and take_profit <= entry_zone:
|
elif action == 'buy' and take_profit <= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止盈错误: entry={entry_zone}, take_profit={take_profit} 应该 > entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做多止盈错误: entry={entry_price}, take_profit={take_profit} 应该 > entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
elif action == 'sell' and take_profit >= entry_zone:
|
elif action == 'sell' and take_profit >= entry_price:
|
||||||
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止盈错误: entry={entry_zone}, take_profit={take_profit} 应该 < entry")
|
logger.warning(f"⚠️ [{data.get('symbol', '')}] 做空止盈错误: entry={entry_price}, take_profit={take_profit} 应该 < entry")
|
||||||
has_invalid_price = True
|
has_invalid_price = True
|
||||||
|
|
||||||
# 如果价格不合理,降低等级为 D
|
# 如果价格不合理,降低等级为 D
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class SignalFormatter:
|
|||||||
position_text = position_map.get(position_size, '轻仓')
|
position_text = position_map.get(position_size, '轻仓')
|
||||||
|
|
||||||
# 计算风险收益比
|
# 计算风险收益比
|
||||||
entry = signal.get('entry_price') or signal.get('entry_zone', 0)
|
entry = signal.get('entry_price', 0)
|
||||||
sl = signal.get('stop_loss', 0)
|
sl = signal.get('stop_loss', 0)
|
||||||
tp = signal.get('take_profit', 0)
|
tp = signal.get('take_profit', 0)
|
||||||
sl_percent = ((sl - entry) / entry * 100) if entry else 0
|
sl_percent = ((sl - entry) / entry * 100) if entry else 0
|
||||||
@ -167,7 +167,7 @@ class SignalFormatter:
|
|||||||
color = "red"
|
color = "red"
|
||||||
|
|
||||||
# 计算风险收益比
|
# 计算风险收益比
|
||||||
entry = signal.get('entry_price') or signal.get('entry_zone', 0)
|
entry = signal.get('entry_price', 0)
|
||||||
sl = signal.get('stop_loss', 0)
|
sl = signal.get('stop_loss', 0)
|
||||||
tp = signal.get('take_profit', 0)
|
tp = signal.get('take_profit', 0)
|
||||||
sl_percent = ((sl - entry) / entry * 100) if entry else 0
|
sl_percent = ((sl - entry) / entry * 100) if entry else 0
|
||||||
|
|||||||
@ -80,7 +80,7 @@ async def test_trend_analysis(symbol: str = "BTCUSDT"):
|
|||||||
logger.info(f" ├─ 类型: {sig.get('timeframe', 'unknown')} | {entry_type_emoji}")
|
logger.info(f" ├─ 类型: {sig.get('timeframe', 'unknown')} | {entry_type_emoji}")
|
||||||
logger.info(f" ├─ 操作: {sig.get('action', 'unknown').upper()}")
|
logger.info(f" ├─ 操作: {sig.get('action', 'unknown').upper()}")
|
||||||
logger.info(f" ├─ 信心度: {sig.get('confidence', 0)}% | 等级: {sig.get('grade', 'unknown')}")
|
logger.info(f" ├─ 信心度: {sig.get('confidence', 0)}% | 等级: {sig.get('grade', 'unknown')}")
|
||||||
logger.info(f" ├─ 入场价: ${sig.get('entry_zone', 0):,.2f}")
|
logger.info(f" ├─ 入场价: ${sig.get('entry_price', 0):,.2f}")
|
||||||
logger.info(f" ├─ 止损: ${sig.get('stop_loss', 0):,.2f} | 止盈: ${sig.get('take_profit', 0):,.2f}")
|
logger.info(f" ├─ 止损: ${sig.get('stop_loss', 0):,.2f} | 止盈: ${sig.get('take_profit', 0):,.2f}")
|
||||||
logger.info(f" └─ 理由: {sig.get('reasoning', 'unknown')}")
|
logger.info(f" └─ 理由: {sig.get('reasoning', 'unknown')}")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user