1
This commit is contained in:
parent
ef36140353
commit
51694bc787
@ -2,7 +2,7 @@
|
|||||||
LLM Context Builder - Generate structured market analysis for LLM decision making
|
LLM Context Builder - Generate structured market analysis for LLM decision making
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional, List
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
@ -21,6 +21,17 @@ from signals.quantitative import QuantitativeSignalGenerator
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# K线数量配置 - 按时间周期不同
|
||||||
|
KLINE_LIMITS = {
|
||||||
|
'5m': 288, # 1天 = 24*60/5 = 288 根
|
||||||
|
'15m': 96, # 1天 = 24*60/15 = 96 根
|
||||||
|
'1h': 72, # 3天 = 3*24 = 72 根
|
||||||
|
'4h': 18, # 3天 = 3*24/4 = 18 根
|
||||||
|
'1d': 30, # 30天
|
||||||
|
'1w': 60, # 60周
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class LLMContextBuilder:
|
class LLMContextBuilder:
|
||||||
"""Build structured context for LLM trading decisions"""
|
"""Build structured context for LLM trading decisions"""
|
||||||
|
|
||||||
@ -38,8 +49,8 @@ class LLMContextBuilder:
|
|||||||
Dict with structured market analysis
|
Dict with structured market analysis
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Fetch multi-timeframe data
|
# Fetch multi-timeframe data with custom limits
|
||||||
mtf_data = self.data_reader.get_multi_timeframe_data()
|
mtf_data = self._get_multi_timeframe_data_for_llm()
|
||||||
|
|
||||||
if '5m' not in mtf_data or mtf_data['5m'].empty:
|
if '5m' not in mtf_data or mtf_data['5m'].empty:
|
||||||
logger.error("No 5m data available for analysis")
|
logger.error("No 5m data available for analysis")
|
||||||
@ -57,17 +68,17 @@ class LLMContextBuilder:
|
|||||||
# Fetch order book data
|
# Fetch order book data
|
||||||
depth_data = self.data_reader.read_latest_depth()
|
depth_data = self.data_reader.read_latest_depth()
|
||||||
|
|
||||||
# Build context sections
|
# Build context sections (移除支撑位压力位计算)
|
||||||
context = {
|
context = {
|
||||||
'timestamp': datetime.now().isoformat(),
|
'timestamp': datetime.now().isoformat(),
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'current_price': round(current_price, 2),
|
'current_price': round(current_price, 2),
|
||||||
'market_state': self._build_market_state(df_5m, mtf_data),
|
'market_state': self._build_market_state(df_5m, mtf_data),
|
||||||
'key_prices': self._build_key_prices(df_5m, current_price),
|
|
||||||
'momentum': self._build_momentum_analysis(df_5m, depth_data),
|
'momentum': self._build_momentum_analysis(df_5m, depth_data),
|
||||||
'volatility_analysis': self._build_volatility_analysis(df_5m),
|
'volatility_analysis': self._build_volatility_analysis(df_5m),
|
||||||
'volume_analysis': self._build_volume_analysis(df_5m),
|
'volume_analysis': self._build_volume_analysis(df_5m),
|
||||||
'multi_timeframe': self._build_mtf_summary(mtf_data),
|
'multi_timeframe': self._build_mtf_summary(mtf_data),
|
||||||
|
'kline_data': self._build_kline_data(mtf_data), # 新增 K 线数据
|
||||||
'signal_consensus': self._calculate_signal_consensus(df_5m, depth_data),
|
'signal_consensus': self._calculate_signal_consensus(df_5m, depth_data),
|
||||||
'risk_metrics': self._build_risk_metrics(df_5m, current_price),
|
'risk_metrics': self._build_risk_metrics(df_5m, current_price),
|
||||||
}
|
}
|
||||||
@ -79,6 +90,68 @@ class LLMContextBuilder:
|
|||||||
logger.error(f"Error building LLM context: {e}", exc_info=True)
|
logger.error(f"Error building LLM context: {e}", exc_info=True)
|
||||||
return self._empty_context()
|
return self._empty_context()
|
||||||
|
|
||||||
|
def _get_multi_timeframe_data_for_llm(self) -> Dict[str, pd.DataFrame]:
|
||||||
|
"""
|
||||||
|
Fetch data from multiple timeframes with custom limits for LLM
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict mapping timeframe to DataFrame
|
||||||
|
"""
|
||||||
|
from .config import config as analysis_config
|
||||||
|
|
||||||
|
timeframes = {
|
||||||
|
'5m': (analysis_config.KLINE_5M_KEY, KLINE_LIMITS['5m']),
|
||||||
|
'15m': (analysis_config.KLINE_15M_KEY, KLINE_LIMITS['15m']),
|
||||||
|
'1h': (analysis_config.KLINE_1H_KEY, KLINE_LIMITS['1h']),
|
||||||
|
'4h': (analysis_config.KLINE_4H_KEY, KLINE_LIMITS['4h']),
|
||||||
|
'1d': (analysis_config.KLINE_1D_KEY, KLINE_LIMITS['1d']),
|
||||||
|
'1w': (analysis_config.KLINE_1W_KEY, KLINE_LIMITS['1w']),
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
for tf, (key, count) in timeframes.items():
|
||||||
|
df = self.data_reader.read_kline_stream(key, count=count)
|
||||||
|
if not df.empty:
|
||||||
|
data[tf] = df
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _build_kline_data(self, mtf_data: Dict[str, pd.DataFrame]) -> Dict[str, List[Dict]]:
|
||||||
|
"""
|
||||||
|
Build K-line data for LLM analysis
|
||||||
|
不同时间周期提供不同数量的K线数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict mapping timeframe to list of kline dicts
|
||||||
|
"""
|
||||||
|
kline_data = {}
|
||||||
|
|
||||||
|
for timeframe, df in mtf_data.items():
|
||||||
|
if df.empty:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 获取该周期需要的K线数量
|
||||||
|
limit = KLINE_LIMITS.get(timeframe, 50)
|
||||||
|
|
||||||
|
# 取最近的N根K线
|
||||||
|
df_limited = df.tail(limit)
|
||||||
|
|
||||||
|
# 转换为简洁格式
|
||||||
|
klines = []
|
||||||
|
for idx, row in df_limited.iterrows():
|
||||||
|
klines.append({
|
||||||
|
't': idx.strftime('%Y-%m-%d %H:%M'), # 时间
|
||||||
|
'o': round(row['open'], 2), # 开盘价
|
||||||
|
'h': round(row['high'], 2), # 最高价
|
||||||
|
'l': round(row['low'], 2), # 最低价
|
||||||
|
'c': round(row['close'], 2), # 收盘价
|
||||||
|
'v': round(row['volume'], 2), # 成交量
|
||||||
|
})
|
||||||
|
|
||||||
|
kline_data[timeframe] = klines
|
||||||
|
|
||||||
|
return kline_data
|
||||||
|
|
||||||
def _build_market_state(
|
def _build_market_state(
|
||||||
self, df: pd.DataFrame, mtf_data: Dict[str, pd.DataFrame]
|
self, df: pd.DataFrame, mtf_data: Dict[str, pd.DataFrame]
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
@ -113,32 +186,6 @@ class LLMContextBuilder:
|
|||||||
'higher_timeframe_alignment': htf_alignment,
|
'higher_timeframe_alignment': htf_alignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _build_key_prices(self, df: pd.DataFrame, current_price: float) -> Dict[str, Any]:
|
|
||||||
"""Build key price levels section"""
|
|
||||||
sr_levels = MarketStructureAnalyzer.find_support_resistance(df, current_price)
|
|
||||||
breakout_info = MarketStructureAnalyzer.detect_breakout(df, sr_levels)
|
|
||||||
|
|
||||||
# Format prices
|
|
||||||
support_str = f"${sr_levels['nearest_support']:,.0f}" if sr_levels.get('nearest_support') else "无明显支撑"
|
|
||||||
resistance_str = f"${sr_levels['nearest_resistance']:,.0f}" if sr_levels.get('nearest_resistance') else "无明显压力"
|
|
||||||
|
|
||||||
# Get Bollinger Bands
|
|
||||||
latest = df.iloc[-1]
|
|
||||||
bb_upper = latest.get('bb_upper')
|
|
||||||
bb_lower = latest.get('bb_lower')
|
|
||||||
|
|
||||||
return {
|
|
||||||
'support': support_str,
|
|
||||||
'support_level': sr_levels.get('nearest_support'),
|
|
||||||
'resistance': resistance_str,
|
|
||||||
'resistance_level': sr_levels.get('nearest_resistance'),
|
|
||||||
'all_support_levels': sr_levels.get('support', []),
|
|
||||||
'all_resistance_levels': sr_levels.get('resistance', []),
|
|
||||||
'breakout_status': breakout_info,
|
|
||||||
'bollinger_upper': round(bb_upper, 2) if bb_upper else None,
|
|
||||||
'bollinger_lower': round(bb_lower, 2) if bb_lower else None,
|
|
||||||
}
|
|
||||||
|
|
||||||
def _build_momentum_analysis(
|
def _build_momentum_analysis(
|
||||||
self, df: pd.DataFrame, depth_data: Optional[Dict[str, Any]]
|
self, df: pd.DataFrame, depth_data: Optional[Dict[str, Any]]
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
@ -243,25 +290,22 @@ class LLMContextBuilder:
|
|||||||
# Get momentum
|
# Get momentum
|
||||||
momentum = MarketStructureAnalyzer.calculate_momentum(df)
|
momentum = MarketStructureAnalyzer.calculate_momentum(df)
|
||||||
|
|
||||||
# Get support/resistance
|
# Get ATR (不再计算支撑位压力位)
|
||||||
sr_levels = MarketStructureAnalyzer.find_support_resistance(df, current_price)
|
|
||||||
|
|
||||||
# Get ATR
|
|
||||||
atr = latest.get('atr', 0)
|
atr = latest.get('atr', 0)
|
||||||
atr_pct = (atr / current_price * 100) if current_price > 0 else 0
|
atr_pct = (atr / current_price * 100) if current_price > 0 else 0
|
||||||
|
|
||||||
# Get volume ratio
|
# Get volume ratio
|
||||||
volume_ratio = latest.get('volume_ratio', 1)
|
volume_ratio = latest.get('volume_ratio', 1)
|
||||||
|
|
||||||
# ===== NEW: Calculate quantitative scores for this timeframe =====
|
# ===== Calculate quantitative scores for this timeframe =====
|
||||||
# Build mini analysis for this timeframe
|
# Build mini analysis for this timeframe (不包含支撑位压力位)
|
||||||
mini_analysis = {
|
mini_analysis = {
|
||||||
'current_price': current_price,
|
'current_price': current_price,
|
||||||
'trend_analysis': trend_info,
|
'trend_analysis': trend_info,
|
||||||
'momentum': momentum,
|
'momentum': momentum,
|
||||||
'support_resistance': sr_levels,
|
'support_resistance': {'support': [], 'resistance': [], 'nearest_support': None, 'nearest_resistance': None},
|
||||||
'breakout': {'has_breakout': False}, # Simplified for now
|
'breakout': {'has_breakout': False},
|
||||||
'orderflow': None, # Orderflow only for 5m
|
'orderflow': None,
|
||||||
'indicators': {'atr': atr}
|
'indicators': {'atr': atr}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,10 +347,6 @@ class LLMContextBuilder:
|
|||||||
'macd_signal': momentum.get('macd_signal', 'unknown'),
|
'macd_signal': momentum.get('macd_signal', 'unknown'),
|
||||||
'macd_hist': round(momentum.get('macd_hist', 0), 2),
|
'macd_hist': round(momentum.get('macd_hist', 0), 2),
|
||||||
|
|
||||||
# Support/Resistance
|
|
||||||
'support': sr_levels.get('nearest_support'),
|
|
||||||
'resistance': sr_levels.get('nearest_resistance'),
|
|
||||||
|
|
||||||
# Volatility
|
# Volatility
|
||||||
'atr': round(atr, 2),
|
'atr': round(atr, 2),
|
||||||
'atr_pct': round(atr_pct, 2),
|
'atr_pct': round(atr_pct, 2),
|
||||||
@ -314,7 +354,7 @@ class LLMContextBuilder:
|
|||||||
# Volume
|
# Volume
|
||||||
'volume_ratio': round(volume_ratio, 2),
|
'volume_ratio': round(volume_ratio, 2),
|
||||||
|
|
||||||
# ===== NEW: Quantitative scores =====
|
# Quantitative scores
|
||||||
'quantitative': quant_scores,
|
'quantitative': quant_scores,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +505,6 @@ class LLMContextBuilder:
|
|||||||
'timestamp': datetime.now().isoformat(),
|
'timestamp': datetime.now().isoformat(),
|
||||||
'error': 'Insufficient data for analysis',
|
'error': 'Insufficient data for analysis',
|
||||||
'market_state': {},
|
'market_state': {},
|
||||||
'key_prices': {},
|
|
||||||
'momentum': {},
|
'momentum': {},
|
||||||
'signal_consensus': 0.5,
|
'signal_consensus': 0.5,
|
||||||
}
|
}
|
||||||
@ -482,17 +521,13 @@ class LLMContextBuilder:
|
|||||||
if 'error' in full_context:
|
if 'error' in full_context:
|
||||||
return full_context
|
return full_context
|
||||||
|
|
||||||
# Extract and simplify to match user's example
|
# Extract and simplify (不再包含支撑位压力位)
|
||||||
return {
|
return {
|
||||||
'market_state': {
|
'market_state': {
|
||||||
'trend_direction': full_context['market_state']['trend_direction'],
|
'trend_direction': full_context['market_state']['trend_direction'],
|
||||||
'market_phase': full_context['market_state']['market_phase'],
|
'market_phase': full_context['market_state']['market_phase'],
|
||||||
'volatility': full_context['market_state']['volatility'],
|
'volatility': full_context['market_state']['volatility'],
|
||||||
},
|
},
|
||||||
'key_prices': {
|
|
||||||
'support': full_context['key_prices']['support'],
|
|
||||||
'resistance': full_context['key_prices']['resistance'],
|
|
||||||
},
|
|
||||||
'momentum': {
|
'momentum': {
|
||||||
'rsi_status': full_context['momentum']['rsi_status'],
|
'rsi_status': full_context['momentum']['rsi_status'],
|
||||||
'macd': full_context['momentum']['macd'],
|
'macd': full_context['momentum']['macd'],
|
||||||
|
|||||||
@ -71,5 +71,9 @@ class Settings(BaseSettings):
|
|||||||
LLM_MAX_CALLS_PER_DAY: int = 12 # 每天最多调用次数
|
LLM_MAX_CALLS_PER_DAY: int = 12 # 每天最多调用次数
|
||||||
LLM_MIN_INTERVAL_MINUTES: int = 15 # 最小调用间隔(分钟)
|
LLM_MIN_INTERVAL_MINUTES: int = 15 # 最小调用间隔(分钟)
|
||||||
|
|
||||||
|
# 盈利空间过滤(过滤低利润机会)
|
||||||
|
MIN_PROFIT_PCT: float = 1.0 # 最小盈利空间百分比,低于此值的机会不给操作建议
|
||||||
|
PREFER_INTRADAY: bool = True # 优先日内短线交易建议
|
||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
|
|||||||
@ -1,43 +1,43 @@
|
|||||||
{
|
{
|
||||||
"timestamp": "2025-12-02T14:50:51.220024",
|
"timestamp": "2025-12-03T16:25:01.783326",
|
||||||
"aggregated_signal": {
|
"aggregated_signal": {
|
||||||
"timestamp": "2025-12-02T14:50:51.218349",
|
"timestamp": "2025-12-03T16:25:01.781521",
|
||||||
"final_signal": "HOLD",
|
"final_signal": "HOLD",
|
||||||
"final_confidence": 0.3,
|
"final_confidence": 0.58,
|
||||||
"consensus": "CONSENSUS_HOLD",
|
"consensus": "CONSENSUS_HOLD",
|
||||||
"agreement_score": 0.3,
|
"agreement_score": 0.58,
|
||||||
"quantitative_signal": {
|
"quantitative_signal": {
|
||||||
"signal_type": "HOLD",
|
"signal_type": "HOLD",
|
||||||
"signal": "HOLD",
|
"signal": "HOLD",
|
||||||
"confidence": 0.0,
|
"confidence": 0.5,
|
||||||
"composite_score": 17.5,
|
"composite_score": -12.8,
|
||||||
"scores": {
|
"scores": {
|
||||||
"trend": 0.0,
|
"trend": -23.1,
|
||||||
"momentum": -30,
|
"momentum": -65,
|
||||||
"orderflow": 100,
|
"orderflow": 46.3,
|
||||||
"breakout": 0
|
"breakout": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"llm_signal": {
|
"llm_signal": {
|
||||||
"signal_type": "HOLD",
|
"signal_type": "HOLD",
|
||||||
"signal": "HOLD",
|
"signal": "HOLD",
|
||||||
"confidence": 0.6,
|
"confidence": 0.67,
|
||||||
"reasoning": "多周期分析显示市场处于严重分歧状态:短期(5m/15m)强劲看涨,中期(4h/1d)明确看跌,长期(1d/1w)方向矛盾。这种分歧导致整体信号为‘HOLD’。短期上涨面临中期趋势阻力和超买技术指标压制,上行空间可能受限。交易机会仅限于快进快出的日内多头,中长线需等待趋势共振。",
|
"reasoning": "多周期综合分析显示市场处于关键分歧点。短期(1h)与超短期(5m/15m)趋势不一致,中期(4h与1d)趋势完全相反,长期(1d与1w)趋势也存在矛盾。各周期未能形成共振,市场缺乏统一方向,呈现震荡格局。当前价格位于多个周期的关键位之间,方向选择有待确认。",
|
||||||
"key_factors": [
|
"key_factors": [
|
||||||
"多周期趋势严重分歧",
|
"多周期趋势严重分歧,方向不明",
|
||||||
"短期RSI超买与中期下跌趋势冲突",
|
"成交量普遍萎缩,市场动能不足",
|
||||||
"价格处于4小时关键压力位$89,177",
|
"价格位于关键支撑与压力区间内震荡",
|
||||||
"成交量在短期放量但日线缩量",
|
"大周期(日线、周线)MACD信号矛盾",
|
||||||
"周线长期趋势方向待定"
|
"市场等待突破以选择后续方向"
|
||||||
],
|
],
|
||||||
"opportunities": {
|
"opportunities": {
|
||||||
"short_term_5m_15m_1h": {
|
"short_term_5m_15m_1h": {
|
||||||
"exists": true,
|
"exists": false,
|
||||||
"direction": "LONG",
|
"direction": null,
|
||||||
"entry_price": 89158.5,
|
"entry_price": 0,
|
||||||
"stop_loss": 88800.0,
|
"stop_loss": 0,
|
||||||
"take_profit": 91592.0,
|
"take_profit": 0,
|
||||||
"reasoning": "5m和15m周期呈现强劲上涨趋势(量化评分28.4/40.9),MACD金叉,成交量放大,但RSI均超买(>80)。1h周期趋势下跌但MACD金叉扩大,价格接近1h压力位$91,592。短期存在基于小周期动量延续的做多机会,但需警惕超买回调风险。"
|
"reasoning": "短期周期趋势分歧。5m和15m显示下跌趋势(量化评分-24.3),但1h显示上涨趋势(量化评分23.4)。动量指标(MACD死叉)与部分趋势信号矛盾,RSI处于中性区域,成交量萎缩,缺乏明确的共振入场信号。价格在1h支撑($91,637)和压力($92,273)之间震荡,方向不明。"
|
||||||
},
|
},
|
||||||
"medium_term_4h_1d": {
|
"medium_term_4h_1d": {
|
||||||
"exists": false,
|
"exists": false,
|
||||||
@ -45,7 +45,7 @@
|
|||||||
"entry_price": 0,
|
"entry_price": 0,
|
||||||
"stop_loss": 0,
|
"stop_loss": 0,
|
||||||
"take_profit": 0,
|
"take_profit": 0,
|
||||||
"reasoning": "4h和1d周期均显示强劲下跌趋势(量化评分-33.4/-23.4),与短期上涨趋势形成严重分歧。4h压力位$89,177与当前价格$89,158.5几乎重合,构成关键阻力。日线MACD虽金叉但趋势向下,RSI中性偏弱,缺乏明确的中期反转或延续信号,建议观望。"
|
"reasoning": "中期周期趋势严重分歧。4h周期显示上涨趋势(量化评分29.3,趋势强度moderate,RSI 60.2强势),但1d周期显示下跌趋势(量化评分-23.4,趋势强度strong)。MACD信号不一致(4h金叉收窄,1d金叉扩大),价格接近4h压力位($93,080)但未突破。成交量萎缩,市场缺乏明确的波段方向动能,建议观望等待趋势统一。"
|
||||||
},
|
},
|
||||||
"long_term_1d_1w": {
|
"long_term_1d_1w": {
|
||||||
"exists": false,
|
"exists": false,
|
||||||
@ -53,20 +53,20 @@
|
|||||||
"entry_price": 0,
|
"entry_price": 0,
|
||||||
"stop_loss": 0,
|
"stop_loss": 0,
|
||||||
"take_profit": 0,
|
"take_profit": 0,
|
||||||
"reasoning": "日线(下跌趋势)与周线(上涨趋势)方向严重冲突。周线量化评分仅4.3,信号模糊,MACD死叉扩大,RSI弱势。日线趋势向下但MACD金叉,显示长期趋势不明朗,处于关键抉择期。无明确的长期趋势交易机会,需等待日线与周线趋势共振。"
|
"reasoning": "长期周期趋势存在分歧。1d周期显示下跌趋势(趋势强度strong),而1w周期显示上涨趋势(趋势强度moderate)。量化评分方向不一致(1d: -23.4, 1w: 11.8)。周线MACD仍为死叉(尽管收窄),日线MACD为金叉,信号矛盾。价格位于周线支撑($91,130)上方,但未形成明确的大周期共振趋势,缺乏长期布局的清晰入场点。"
|
||||||
},
|
},
|
||||||
"ambush": {
|
"ambush": {
|
||||||
"exists": true,
|
"exists": true,
|
||||||
"price_level": 86207.0,
|
"price_level": 91130.0,
|
||||||
"reasoning": "等待价格回调至1h关键支撑位$86,207附近。该位置接近4h支撑$86,261,若价格能在此企稳并出现1h或4h周期的反弹信号(如RSI从超卖区回升、MACD金叉),可考虑作为中期做多埋伏点,博弈日线下跌趋势中的反弹或反转。"
|
"reasoning": "基于周线关键支撑位$91,130设置埋伏。若价格回调至此位置,并伴随1h或4h周期出现明确的反弹反转信号(如RSI超卖反弹、MACD金叉、放量),可考虑分批布局多单,博弈周线级别上涨趋势的延续。"
|
||||||
},
|
},
|
||||||
"intraday": {
|
"intraday": {
|
||||||
"exists": true,
|
"exists": false,
|
||||||
"direction": "LONG",
|
"direction": null,
|
||||||
"entry_price": 89158.5,
|
"entry_price": 0,
|
||||||
"stop_loss": 88800.0,
|
"stop_loss": 0,
|
||||||
"take_profit": 91592.0,
|
"take_profit": 0,
|
||||||
"reasoning": "5m和15m周期呈现强劲上涨趋势(量化评分28.4/40.9),MACD金叉,成交量放大,但RSI均超买(>80)。1h周期趋势下跌但MACD金叉扩大,价格接近1h压力位$91,592。短期存在基于小周期动量延续的做多机会,但需警惕超买回调风险。"
|
"reasoning": "短期周期趋势分歧。5m和15m显示下跌趋势(量化评分-24.3),但1h显示上涨趋势(量化评分23.4)。动量指标(MACD死叉)与部分趋势信号矛盾,RSI处于中性区域,成交量萎缩,缺乏明确的共振入场信号。价格在1h支撑($91,637)和压力($92,273)之间震荡,方向不明。"
|
||||||
},
|
},
|
||||||
"swing": {
|
"swing": {
|
||||||
"exists": false,
|
"exists": false,
|
||||||
@ -74,88 +74,84 @@
|
|||||||
"entry_price": 0,
|
"entry_price": 0,
|
||||||
"stop_loss": 0,
|
"stop_loss": 0,
|
||||||
"take_profit": 0,
|
"take_profit": 0,
|
||||||
"reasoning": "4h和1d周期均显示强劲下跌趋势(量化评分-33.4/-23.4),与短期上涨趋势形成严重分歧。4h压力位$89,177与当前价格$89,158.5几乎重合,构成关键阻力。日线MACD虽金叉但趋势向下,RSI中性偏弱,缺乏明确的中期反转或延续信号,建议观望。"
|
"reasoning": "中期周期趋势严重分歧。4h周期显示上涨趋势(量化评分29.3,趋势强度moderate,RSI 60.2强势),但1d周期显示下跌趋势(量化评分-23.4,趋势强度strong)。MACD信号不一致(4h金叉收窄,1d金叉扩大),价格接近4h压力位($93,080)但未突破。成交量萎缩,市场缺乏明确的波段方向动能,建议观望等待趋势统一。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"recommendations_by_timeframe": {
|
"recommendations_by_timeframe": {
|
||||||
"short_term": "短期(5m/15m/1h)存在基于小周期动量的日内做多机会,但RSI已严重超买,风险较高。建议轻仓快进快出,严格设置止损于$88,800(基于5m ATR),目标看向1h压力位$91,592。若价格无法有效突破当前4h压力$89,177,应果断离场。",
|
"short_term": "短期(5m/15m/1h)操作建议:观望。当前5m/15m与1h趋势方向矛盾,市场处于震荡整理状态,缺乏清晰的日内交易机会。可关注价格对1h支撑$91,637和压力$92,273的突破情况,等待小周期形成共振后再考虑入场。",
|
||||||
"medium_term": "中期(4h/1d)趋势向下,但当前价格处于4h关键压力位,且与短期上涨动能背离。无明确的中期波段入场点,建议观望。可关注价格能否站稳$89,177上方以挑战日线压力$93,080,或回落至$86,200-$86,800支撑区域寻找企稳信号。",
|
"medium_term": "中期(4h/1d)操作建议:观望。4h看涨与1d看跌形成强烈分歧,市场方向不明。建议等待价格有效突破4h压力$93,080(确认中期转强)或跌破4h支撑$90,612(确认中期转弱),并结合成交量放大信号,再寻找波段交易机会。",
|
||||||
"long_term": "长期(1d/1w)趋势矛盾,日线下跌与周线上涨形成拉锯。周线支撑$88,909已被短暂跌破,长期方向待定。建议长期投资者保持观望,等待日线趋势(当前下跌)与周线趋势(当前上涨)出现明确一致信号后再做布局,或利用‘ambush’点位分批建仓。"
|
"long_term": "长期(1d/1w)操作建议:观望。日线与周线趋势不一致,长期趋势未明朗。可关注周线支撑$91,130的防守情况。若价格能站稳该支撑并推动日线趋势转涨,形成大周期共振,则可能开启长期上涨趋势;反之,若跌破,则长期趋势可能转弱。目前宜耐心等待更明确的趋势信号。"
|
||||||
},
|
},
|
||||||
"trade_type": "MULTI_TIMEFRAME",
|
"trade_type": "MULTI_TIMEFRAME",
|
||||||
"risk_level": "HIGH"
|
"risk_level": "MEDIUM"
|
||||||
},
|
},
|
||||||
"levels": {
|
"levels": {
|
||||||
"current_price": 89179.2,
|
"current_price": 92028.4,
|
||||||
"entry": 89179.2,
|
"entry": 92028.4,
|
||||||
"stop_loss": 88999.95,
|
"stop_loss": 92028.4,
|
||||||
"take_profit_1": 90395.95,
|
"take_profit_1": 92028.4,
|
||||||
"take_profit_2": 90395.95,
|
"take_profit_2": 92028.4,
|
||||||
"take_profit_3": 90395.95,
|
"take_profit_3": 92028.4
|
||||||
"take_profit_1_range": {
|
|
||||||
"quant": 89199.9,
|
|
||||||
"llm": 91592.0,
|
|
||||||
"diff_pct": 2.65
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"risk_reward_ratio": 6.79,
|
"risk_reward_ratio": 0,
|
||||||
"recommendation": "量化和AI分析均建议观望,等待更好的机会",
|
"recommendation": "量化和AI分析均建议观望,等待更好的机会",
|
||||||
"warnings": [
|
"warnings": []
|
||||||
"⚠️ 量化信号置信度较低"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"market_analysis": {
|
"market_analysis": {
|
||||||
"price": 89199.9,
|
"price": 92028.4,
|
||||||
"trend": {
|
"trend": {
|
||||||
"direction": "unknown",
|
"direction": "下跌",
|
||||||
"strength": 0
|
"strength": "weak",
|
||||||
|
"phase": "下跌中",
|
||||||
|
"adx": 12.9,
|
||||||
|
"ema_alignment": "bearish"
|
||||||
},
|
},
|
||||||
"momentum": {
|
"momentum": {
|
||||||
"rsi": 50,
|
"rsi": 44.0,
|
||||||
"rsi_status": "中性偏弱",
|
"rsi_status": "中性偏弱",
|
||||||
"rsi_trend": "中性",
|
"rsi_trend": "下降中",
|
||||||
"macd_signal": "死叉收窄",
|
"macd_signal": "死叉扩大",
|
||||||
"macd_hist": 0
|
"macd_hist": -23.7636
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"quantitative_signal": {
|
"quantitative_signal": {
|
||||||
"timestamp": "2025-12-02T14:50:04.306308",
|
"timestamp": "2025-12-03T16:24:23.426153",
|
||||||
"signal_type": "HOLD",
|
"signal_type": "HOLD",
|
||||||
"signal_strength": 0.17,
|
"signal_strength": 0.13,
|
||||||
"composite_score": 17.5,
|
"composite_score": -12.8,
|
||||||
"confidence": 0.0,
|
"confidence": 0.5,
|
||||||
"consensus_score": 0.0,
|
"consensus_score": 0.7,
|
||||||
"scores": {
|
"scores": {
|
||||||
"trend": 0.0,
|
"trend": -23.1,
|
||||||
"momentum": -30,
|
"momentum": -65,
|
||||||
"orderflow": 100,
|
"orderflow": 46.3,
|
||||||
"breakout": 0
|
"breakout": 0
|
||||||
},
|
},
|
||||||
"levels": {
|
"levels": {
|
||||||
"current_price": 89199.9,
|
"current_price": 92028.4,
|
||||||
"entry": 89199.9,
|
"entry": 92028.4,
|
||||||
"stop_loss": 89199.9,
|
"stop_loss": 92028.4,
|
||||||
"take_profit_1": 89199.9,
|
"take_profit_1": 92028.4,
|
||||||
"take_profit_2": 89199.9,
|
"take_profit_2": 92028.4,
|
||||||
"take_profit_3": 89199.9
|
"take_profit_3": 92028.4
|
||||||
},
|
},
|
||||||
"risk_reward_ratio": 0,
|
"risk_reward_ratio": 0,
|
||||||
"reasoning": "趋势unknown (0); RSI=50; MACD 死叉收窄; 订单流: 强买方主导"
|
"reasoning": "趋势下跌 (weak); RSI=44; MACD 死叉扩大; 订单流: 强买方主导"
|
||||||
},
|
},
|
||||||
"llm_signal": {
|
"llm_signal": {
|
||||||
"timestamp": "2025-12-02T14:50:51.218012",
|
"timestamp": "2025-12-03T16:25:01.781138",
|
||||||
"signal_type": "HOLD",
|
"signal_type": "HOLD",
|
||||||
"confidence": 0.6,
|
"confidence": 0.67,
|
||||||
"trade_type": "MULTI_TIMEFRAME",
|
"trade_type": "MULTI_TIMEFRAME",
|
||||||
"reasoning": "多周期分析显示市场处于严重分歧状态:短期(5m/15m)强劲看涨,中期(4h/1d)明确看跌,长期(1d/1w)方向矛盾。这种分歧导致整体信号为‘HOLD’。短期上涨面临中期趋势阻力和超买技术指标压制,上行空间可能受限。交易机会仅限于快进快出的日内多头,中长线需等待趋势共振。",
|
"reasoning": "多周期综合分析显示市场处于关键分歧点。短期(1h)与超短期(5m/15m)趋势不一致,中期(4h与1d)趋势完全相反,长期(1d与1w)趋势也存在矛盾。各周期未能形成共振,市场缺乏统一方向,呈现震荡格局。当前价格位于多个周期的关键位之间,方向选择有待确认。",
|
||||||
"opportunities": {
|
"opportunities": {
|
||||||
"short_term_5m_15m_1h": {
|
"short_term_5m_15m_1h": {
|
||||||
"exists": true,
|
"exists": false,
|
||||||
"direction": "LONG",
|
"direction": null,
|
||||||
"entry_price": 89158.5,
|
"entry_price": 0,
|
||||||
"stop_loss": 88800.0,
|
"stop_loss": 0,
|
||||||
"take_profit": 91592.0,
|
"take_profit": 0,
|
||||||
"reasoning": "5m和15m周期呈现强劲上涨趋势(量化评分28.4/40.9),MACD金叉,成交量放大,但RSI均超买(>80)。1h周期趋势下跌但MACD金叉扩大,价格接近1h压力位$91,592。短期存在基于小周期动量延续的做多机会,但需警惕超买回调风险。"
|
"reasoning": "短期周期趋势分歧。5m和15m显示下跌趋势(量化评分-24.3),但1h显示上涨趋势(量化评分23.4)。动量指标(MACD死叉)与部分趋势信号矛盾,RSI处于中性区域,成交量萎缩,缺乏明确的共振入场信号。价格在1h支撑($91,637)和压力($92,273)之间震荡,方向不明。"
|
||||||
},
|
},
|
||||||
"medium_term_4h_1d": {
|
"medium_term_4h_1d": {
|
||||||
"exists": false,
|
"exists": false,
|
||||||
@ -163,7 +159,7 @@
|
|||||||
"entry_price": 0,
|
"entry_price": 0,
|
||||||
"stop_loss": 0,
|
"stop_loss": 0,
|
||||||
"take_profit": 0,
|
"take_profit": 0,
|
||||||
"reasoning": "4h和1d周期均显示强劲下跌趋势(量化评分-33.4/-23.4),与短期上涨趋势形成严重分歧。4h压力位$89,177与当前价格$89,158.5几乎重合,构成关键阻力。日线MACD虽金叉但趋势向下,RSI中性偏弱,缺乏明确的中期反转或延续信号,建议观望。"
|
"reasoning": "中期周期趋势严重分歧。4h周期显示上涨趋势(量化评分29.3,趋势强度moderate,RSI 60.2强势),但1d周期显示下跌趋势(量化评分-23.4,趋势强度strong)。MACD信号不一致(4h金叉收窄,1d金叉扩大),价格接近4h压力位($93,080)但未突破。成交量萎缩,市场缺乏明确的波段方向动能,建议观望等待趋势统一。"
|
||||||
},
|
},
|
||||||
"long_term_1d_1w": {
|
"long_term_1d_1w": {
|
||||||
"exists": false,
|
"exists": false,
|
||||||
@ -171,20 +167,20 @@
|
|||||||
"entry_price": 0,
|
"entry_price": 0,
|
||||||
"stop_loss": 0,
|
"stop_loss": 0,
|
||||||
"take_profit": 0,
|
"take_profit": 0,
|
||||||
"reasoning": "日线(下跌趋势)与周线(上涨趋势)方向严重冲突。周线量化评分仅4.3,信号模糊,MACD死叉扩大,RSI弱势。日线趋势向下但MACD金叉,显示长期趋势不明朗,处于关键抉择期。无明确的长期趋势交易机会,需等待日线与周线趋势共振。"
|
"reasoning": "长期周期趋势存在分歧。1d周期显示下跌趋势(趋势强度strong),而1w周期显示上涨趋势(趋势强度moderate)。量化评分方向不一致(1d: -23.4, 1w: 11.8)。周线MACD仍为死叉(尽管收窄),日线MACD为金叉,信号矛盾。价格位于周线支撑($91,130)上方,但未形成明确的大周期共振趋势,缺乏长期布局的清晰入场点。"
|
||||||
},
|
},
|
||||||
"ambush": {
|
"ambush": {
|
||||||
"exists": true,
|
"exists": true,
|
||||||
"price_level": 86207.0,
|
"price_level": 91130.0,
|
||||||
"reasoning": "等待价格回调至1h关键支撑位$86,207附近。该位置接近4h支撑$86,261,若价格能在此企稳并出现1h或4h周期的反弹信号(如RSI从超卖区回升、MACD金叉),可考虑作为中期做多埋伏点,博弈日线下跌趋势中的反弹或反转。"
|
"reasoning": "基于周线关键支撑位$91,130设置埋伏。若价格回调至此位置,并伴随1h或4h周期出现明确的反弹反转信号(如RSI超卖反弹、MACD金叉、放量),可考虑分批布局多单,博弈周线级别上涨趋势的延续。"
|
||||||
},
|
},
|
||||||
"intraday": {
|
"intraday": {
|
||||||
"exists": true,
|
"exists": false,
|
||||||
"direction": "LONG",
|
"direction": null,
|
||||||
"entry_price": 89158.5,
|
"entry_price": 0,
|
||||||
"stop_loss": 88800.0,
|
"stop_loss": 0,
|
||||||
"take_profit": 91592.0,
|
"take_profit": 0,
|
||||||
"reasoning": "5m和15m周期呈现强劲上涨趋势(量化评分28.4/40.9),MACD金叉,成交量放大,但RSI均超买(>80)。1h周期趋势下跌但MACD金叉扩大,价格接近1h压力位$91,592。短期存在基于小周期动量延续的做多机会,但需警惕超买回调风险。"
|
"reasoning": "短期周期趋势分歧。5m和15m显示下跌趋势(量化评分-24.3),但1h显示上涨趋势(量化评分23.4)。动量指标(MACD死叉)与部分趋势信号矛盾,RSI处于中性区域,成交量萎缩,缺乏明确的共振入场信号。价格在1h支撑($91,637)和压力($92,273)之间震荡,方向不明。"
|
||||||
},
|
},
|
||||||
"swing": {
|
"swing": {
|
||||||
"exists": false,
|
"exists": false,
|
||||||
@ -192,31 +188,31 @@
|
|||||||
"entry_price": 0,
|
"entry_price": 0,
|
||||||
"stop_loss": 0,
|
"stop_loss": 0,
|
||||||
"take_profit": 0,
|
"take_profit": 0,
|
||||||
"reasoning": "4h和1d周期均显示强劲下跌趋势(量化评分-33.4/-23.4),与短期上涨趋势形成严重分歧。4h压力位$89,177与当前价格$89,158.5几乎重合,构成关键阻力。日线MACD虽金叉但趋势向下,RSI中性偏弱,缺乏明确的中期反转或延续信号,建议观望。"
|
"reasoning": "中期周期趋势严重分歧。4h周期显示上涨趋势(量化评分29.3,趋势强度moderate,RSI 60.2强势),但1d周期显示下跌趋势(量化评分-23.4,趋势强度strong)。MACD信号不一致(4h金叉收窄,1d金叉扩大),价格接近4h压力位($93,080)但未突破。成交量萎缩,市场缺乏明确的波段方向动能,建议观望等待趋势统一。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"recommendations_by_timeframe": {
|
"recommendations_by_timeframe": {
|
||||||
"short_term": "短期(5m/15m/1h)存在基于小周期动量的日内做多机会,但RSI已严重超买,风险较高。建议轻仓快进快出,严格设置止损于$88,800(基于5m ATR),目标看向1h压力位$91,592。若价格无法有效突破当前4h压力$89,177,应果断离场。",
|
"short_term": "短期(5m/15m/1h)操作建议:观望。当前5m/15m与1h趋势方向矛盾,市场处于震荡整理状态,缺乏清晰的日内交易机会。可关注价格对1h支撑$91,637和压力$92,273的突破情况,等待小周期形成共振后再考虑入场。",
|
||||||
"medium_term": "中期(4h/1d)趋势向下,但当前价格处于4h关键压力位,且与短期上涨动能背离。无明确的中期波段入场点,建议观望。可关注价格能否站稳$89,177上方以挑战日线压力$93,080,或回落至$86,200-$86,800支撑区域寻找企稳信号。",
|
"medium_term": "中期(4h/1d)操作建议:观望。4h看涨与1d看跌形成强烈分歧,市场方向不明。建议等待价格有效突破4h压力$93,080(确认中期转强)或跌破4h支撑$90,612(确认中期转弱),并结合成交量放大信号,再寻找波段交易机会。",
|
||||||
"long_term": "长期(1d/1w)趋势矛盾,日线下跌与周线上涨形成拉锯。周线支撑$88,909已被短暂跌破,长期方向待定。建议长期投资者保持观望,等待日线趋势(当前下跌)与周线趋势(当前上涨)出现明确一致信号后再做布局,或利用‘ambush’点位分批建仓。"
|
"long_term": "长期(1d/1w)操作建议:观望。日线与周线趋势不一致,长期趋势未明朗。可关注周线支撑$91,130的防守情况。若价格能站稳该支撑并推动日线趋势转涨,形成大周期共振,则可能开启长期上涨趋势;反之,若跌破,则长期趋势可能转弱。目前宜耐心等待更明确的趋势信号。"
|
||||||
},
|
},
|
||||||
"levels": {
|
"levels": {
|
||||||
"current_price": 89158.5,
|
"current_price": 92028.4,
|
||||||
"entry": 89158.5,
|
"entry": 92028.4,
|
||||||
"stop_loss": 88800.0,
|
"stop_loss": 0,
|
||||||
"take_profit_1": 91592.0,
|
"take_profit_1": 0,
|
||||||
"take_profit_2": 91592.0,
|
"take_profit_2": 0,
|
||||||
"take_profit_3": 91592.0
|
"take_profit_3": 0
|
||||||
},
|
},
|
||||||
"risk_level": "HIGH",
|
"risk_level": "MEDIUM",
|
||||||
"key_factors": [
|
"key_factors": [
|
||||||
"多周期趋势严重分歧",
|
"多周期趋势严重分歧,方向不明",
|
||||||
"短期RSI超买与中期下跌趋势冲突",
|
"成交量普遍萎缩,市场动能不足",
|
||||||
"价格处于4小时关键压力位$89,177",
|
"价格位于关键支撑与压力区间内震荡",
|
||||||
"成交量在短期放量但日线缩量",
|
"大周期(日线、周线)MACD信号矛盾",
|
||||||
"周线长期趋势方向待定"
|
"市场等待突破以选择后续方向"
|
||||||
],
|
],
|
||||||
"raw_response": "```json\n{\n \"signal\": \"HOLD\",\n \"confidence\": 0.6,\n \"opportunities\": {\n \"short_term_5m_15m_1h\": {\n \"exists\": true,\n \"timeframe_label\": \"短期 (5m/15m/1h)\",\n \"direction\": \"LONG\",\n \"entry_price\": 89158.5,\n \"stop_loss\": 88800.0,\n \"take_profit\": 91592.0,\n \"reasoning\": \"5m和15m周期呈现强劲上涨趋势(量化评分28.4/40.9),MACD金叉,成交量放大,但RSI均超买(>80)。1h周期趋势下跌但MACD金叉扩大,价格接近1h压力位$91,592。短期存在基于小周期动量延续的做多机会,但需警惕超买回调风险。\",\n \"持仓时间\": \"几分钟到几小时\"\n },\n \"medium_term_4h_1d\": {\n \"exists\": false,\n \"timeframe_label\": \"中期 (4h/1d)\",\n \"direction\": null,\n \"entry_price\": null,\n \"stop_loss\": null,\n \"take_profit\": null,\n \"reasoning\": \"4h和1d周期均显示强劲下跌趋势(量化评分-33.4/-23.4),与短期上涨趋势形成严重分歧。4h压力位$89,177与当前价格$89,158.5几乎重合,构成关键阻力。日线MACD虽金叉但趋势向下,RSI中性偏弱,缺乏明确的中期反转或延续信号,建议观望。\",\n \"持仓时间\": \"数天到一周\"\n },\n \"long_term_1d_1w\": {\n \"exists\": false,\n \"timeframe_label\": \"长期 (1d/1w)\",\n \"direction\": null,\n \"entry_price\": null,\n \"stop_loss\": null,\n \"take_profit\": null,\n \"reasoning\": \"日线(下跌趋势)与周线(上涨趋势)方向严重冲突。周线量化评分仅4.3,信号模糊,MACD死叉扩大,RSI弱势。日线趋势向下但MACD金叉,显示长期趋势不明朗,处于关键抉择期。无明确的长期趋势交易机会,需等待日线与周线趋势共振。\",\n \"持仓时间\": \"数周到数月\"\n },\n \"ambush\": {\n \"exists\": true,\n \"price_level\": 86207.0,\n \"reasoning\": \"等待价格回调至1h关键支撑位$86,207附近。该位置接近4h支撑$86,261,若价格能在此企稳并出现1h或4h周期的反弹信号(如RSI从超卖区回升、MACD金叉),可考虑作为中期做多埋伏点,博弈日线下跌趋势中的反弹或反转。\",\n \"timeframe\": \"基于1小时和4小时级别的关键支撑位\"\n }\n },\n \"recommendations_by_timeframe\": {\n \"short_term\": \"短期(5m/15m/1h)存在基于小周期动量的日内做多机会,但RSI已严重超买,风险较高。建议轻仓快进快出,严格设置止损于$88,800(基于5m ATR),目标看向1h压力位$91,592。若价格无法有效突破当前4h压力$89,177,应果断离场。\",\n \"medium_term\": \"中期(4h/1d)趋势向下,但当前价格处于4h关键压力位,且与短期上涨动能背离。无明确的中期波段入场点,建议观望。可关注价格能否站稳$89,177上方以挑战日线压力$93,080,或回落至$86,200-$86,800支撑区域寻找企稳信号。\",\n \"long_term\": \"长期(1d/1w)趋势矛盾,日线下跌与周线上涨形成拉锯。周线支撑$88,909已被短暂跌破,长期方向待定。建议长期投资者保持观望,等待日线趋势(当前下跌)与周线趋势(当前上涨)出现明确一致信号后再做布局,或利用‘ambush’点位分批建仓。\"\n },\n \"reasoning\": \"多周期分析显示市场处于严重分歧状态:短期(5m/15m)强劲看涨,中期(4h/1d)明确看跌,长期(1d/1w)方向矛盾。这种分歧导致整体信号为‘HOLD’。短期上涨面临中期趋势阻力和超买技术指标压制,上行空间可能受限。交易机会仅限于快进快出的日内多头,中长线需等待趋势共振。\",\n \"risk_level\": \"HIGH\",\n \"key_factors\": [\"多周期趋势严重分歧\", \"短期RSI超买与中期下跌趋势冲突\", \"价格处于4小时关键压力位$89,177\", \"成交量在短期放量但日线缩量\", \"周线长期趋势方向待定\"]\n}\n```",
|
"raw_response": "```json\n{\n \"signal\": \"HOLD\",\n \"confidence\": 0.67,\n \"opportunities\": {\n \"short_term_5m_15m_1h\": {\n \"exists\": false,\n \"timeframe_label\": \"短期 (5m/15m/1h)\",\n \"direction\": null,\n \"entry_price\": null,\n \"stop_loss\": null,\n \"take_profit\": null,\n \"reasoning\": \"短期周期趋势分歧。5m和15m显示下跌趋势(量化评分-24.3),但1h显示上涨趋势(量化评分23.4)。动量指标(MACD死叉)与部分趋势信号矛盾,RSI处于中性区域,成交量萎缩,缺乏明确的共振入场信号。价格在1h支撑($91,637)和压力($92,273)之间震荡,方向不明。\",\n \"持仓时间\": \"几分钟到几小时\"\n },\n \"medium_term_4h_1d\": {\n \"exists\": false,\n \"timeframe_label\": \"中期 (4h/1d)\",\n \"direction\": null,\n \"entry_price\": null,\n \"stop_loss\": null,\n \"take_profit\": null,\n \"reasoning\": \"中期周期趋势严重分歧。4h周期显示上涨趋势(量化评分29.3,趋势强度moderate,RSI 60.2强势),但1d周期显示下跌趋势(量化评分-23.4,趋势强度strong)。MACD信号不一致(4h金叉收窄,1d金叉扩大),价格接近4h压力位($93,080)但未突破。成交量萎缩,市场缺乏明确的波段方向动能,建议观望等待趋势统一。\",\n \"持仓时间\": \"数天到一周\"\n },\n \"long_term_1d_1w\": {\n \"exists\": false,\n \"timeframe_label\": \"长期 (1d/1w)\",\n \"direction\": null,\n \"entry_price\": null,\n \"stop_loss\": null,\n \"take_profit\": null,\n \"reasoning\": \"长期周期趋势存在分歧。1d周期显示下跌趋势(趋势强度strong),而1w周期显示上涨趋势(趋势强度moderate)。量化评分方向不一致(1d: -23.4, 1w: 11.8)。周线MACD仍为死叉(尽管收窄),日线MACD为金叉,信号矛盾。价格位于周线支撑($91,130)上方,但未形成明确的大周期共振趋势,缺乏长期布局的清晰入场点。\",\n \"持仓时间\": \"数周到数月\"\n },\n \"ambush\": {\n \"exists\": true,\n \"price_level\": 91130.0,\n \"reasoning\": \"基于周线关键支撑位$91,130设置埋伏。若价格回调至此位置,并伴随1h或4h周期出现明确的反弹反转信号(如RSI超卖反弹、MACD金叉、放量),可考虑分批布局多单,博弈周线级别上涨趋势的延续。\",\n \"timeframe\": \"基于周线(1w)的关键支撑位\"\n }\n },\n \"recommendations_by_timeframe\": {\n \"short_term\": \"短期(5m/15m/1h)操作建议:观望。当前5m/15m与1h趋势方向矛盾,市场处于震荡整理状态,缺乏清晰的日内交易机会。可关注价格对1h支撑$91,637和压力$92,273的突破情况,等待小周期形成共振后再考虑入场。\",\n \"medium_term\": \"中期(4h/1d)操作建议:观望。4h看涨与1d看跌形成强烈分歧,市场方向不明。建议等待价格有效突破4h压力$93,080(确认中期转强)或跌破4h支撑$90,612(确认中期转弱),并结合成交量放大信号,再寻找波段交易机会。\",\n \"long_term\": \"长期(1d/1w)操作建议:观望。日线与周线趋势不一致,长期趋势未明朗。可关注周线支撑$91,130的防守情况。若价格能站稳该支撑并推动日线趋势转涨,形成大周期共振,则可能开启长期上涨趋势;反之,若跌破,则长期趋势可能转弱。目前宜耐心等待更明确的趋势信号。\"\n },\n \"reasoning\": \"多周期综合分析显示市场处于关键分歧点。短期(1h)与超短期(5m/15m)趋势不一致,中期(4h与1d)趋势完全相反,长期(1d与1w)趋势也存在矛盾。各周期未能形成共振,市场缺乏统一方向,呈现震荡格局。当前价格位于多个周期的关键位之间,方向选择有待确认。\",\n \"risk_level\": \"MEDIUM\",\n \"key_factors\": [\"多周期趋势严重分歧,方向不明\", \"成交量普遍萎缩,市场动能不足\", \"价格位于关键支撑与压力区间内震荡\", \"大周期(日线、周线)MACD信号矛盾\", \"市场等待突破以选择后续方向\"]\n}\n```",
|
||||||
"risk_reward_ratio": 6.79
|
"risk_reward_ratio": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,6 +8,8 @@ from typing import Dict, Any, Optional
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from config.settings import settings
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -139,241 +141,189 @@ class LLMDecisionMaker:
|
|||||||
|
|
||||||
# Extract context elements
|
# Extract context elements
|
||||||
market_state = market_context.get('market_state', {})
|
market_state = market_context.get('market_state', {})
|
||||||
key_prices = market_context.get('key_prices', {})
|
|
||||||
momentum = market_context.get('momentum', {})
|
momentum = market_context.get('momentum', {})
|
||||||
signal_consensus = market_context.get('signal_consensus', 0.5)
|
signal_consensus = market_context.get('signal_consensus', 0.5)
|
||||||
current_price = market_context.get('current_price', 0)
|
current_price = market_context.get('current_price', 0)
|
||||||
|
kline_data = market_context.get('kline_data', {})
|
||||||
|
|
||||||
# Build structured prompt
|
# Build structured prompt
|
||||||
prompt = f"""你是一个专业的加密货币交易分析师。基于以下多时间周期市场分析数据,提供分层次的交易建议。
|
prompt = f"""你是一个专业的加密货币交易分析师。基于以下多时间周期的K线数据和技术指标,提供分层次的交易建议。
|
||||||
|
|
||||||
|
**重要**: 你需要自己从K线数据中识别支撑位和压力位,不要依赖预先计算的值。
|
||||||
|
|
||||||
## 当前价格
|
## 当前价格
|
||||||
${current_price:,.2f}
|
${current_price:,.2f}
|
||||||
|
|
||||||
|
## 你的分析任务
|
||||||
|
|
||||||
|
1. **分析K线数据** - 识别各周期的支撑位、压力位、趋势结构
|
||||||
|
2. **结合技术指标** - RSI、MACD、成交量等确认信号
|
||||||
|
3. **给出交易建议** - 分短期/中期/长期三个级别
|
||||||
|
|
||||||
## 请提供以下内容 (使用JSON格式):
|
## 请提供以下内容 (使用JSON格式):
|
||||||
{{
|
{{
|
||||||
"signal": "BUY" | "SELL" | "HOLD",
|
"signal": "BUY" | "SELL" | "HOLD",
|
||||||
"confidence": 0.0-1.0,
|
"confidence": 0.0-1.0,
|
||||||
|
|
||||||
|
// 你识别的关键价位
|
||||||
|
"key_levels": {{
|
||||||
|
"short_term": {{
|
||||||
|
"support": [支撑位数组],
|
||||||
|
"resistance": [压力位数组]
|
||||||
|
}},
|
||||||
|
"medium_term": {{
|
||||||
|
"support": [支撑位数组],
|
||||||
|
"resistance": [压力位数组]
|
||||||
|
}},
|
||||||
|
"long_term": {{
|
||||||
|
"support": [支撑位数组],
|
||||||
|
"resistance": [压力位数组]
|
||||||
|
}}
|
||||||
|
}},
|
||||||
|
|
||||||
// 分时间级别的交易机会分析
|
// 分时间级别的交易机会分析
|
||||||
"opportunities": {{
|
"opportunities": {{
|
||||||
"short_term_5m_15m_1h": {{
|
"short_term_5m_15m_1h": {{
|
||||||
"exists": true/false,
|
"exists": true/false,
|
||||||
"timeframe_label": "短期 (5m/15m/1h)",
|
|
||||||
"direction": "LONG" | "SHORT" | null,
|
"direction": "LONG" | "SHORT" | null,
|
||||||
"entry_price": 进场价格数值或null,
|
"entry_price": 进场价格数值或null,
|
||||||
"stop_loss": 止损价格数值或null,
|
"stop_loss": 止损价格数值或null,
|
||||||
"take_profit": 止盈价格数值或null,
|
"take_profit": 止盈价格数值或null,
|
||||||
"reasoning": "短期日内机会说明",
|
"reasoning": "短期日内机会说明"
|
||||||
"持仓时间": "几分钟到几小时"
|
|
||||||
}},
|
}},
|
||||||
"medium_term_4h_1d": {{
|
"medium_term_4h_1d": {{
|
||||||
"exists": true/false,
|
"exists": true/false,
|
||||||
"timeframe_label": "中期 (4h/1d)",
|
|
||||||
"direction": "LONG" | "SHORT" | null,
|
"direction": "LONG" | "SHORT" | null,
|
||||||
"entry_price": 进场价格数值或null,
|
"entry_price": 进场价格数值或null,
|
||||||
"stop_loss": 止损价格数值或null,
|
"stop_loss": 止损价格数值或null,
|
||||||
"take_profit": 止盈价格数值或null,
|
"take_profit": 止盈价格数值或null,
|
||||||
"reasoning": "中期波段机会说明",
|
"reasoning": "中期波段机会说明"
|
||||||
"持仓时间": "数天到一周"
|
|
||||||
}},
|
}},
|
||||||
"long_term_1d_1w": {{
|
"long_term_1d_1w": {{
|
||||||
"exists": true/false,
|
"exists": true/false,
|
||||||
"timeframe_label": "长期 (1d/1w)",
|
|
||||||
"direction": "LONG" | "SHORT" | null,
|
"direction": "LONG" | "SHORT" | null,
|
||||||
"entry_price": 进场价格数值或null,
|
"entry_price": 进场价格数值或null,
|
||||||
"stop_loss": 止损价格数值或null,
|
"stop_loss": 止损价格数值或null,
|
||||||
"take_profit": 止盈价格数值或null,
|
"take_profit": 止盈价格数值或null,
|
||||||
"reasoning": "长期趋势机会说明",
|
"reasoning": "长期趋势机会说明"
|
||||||
"持仓时间": "数周到数月"
|
|
||||||
}},
|
}},
|
||||||
"ambush": {{
|
"ambush": {{
|
||||||
"exists": true/false,
|
"exists": true/false,
|
||||||
"price_level": 埋伏价格数值或null,
|
"price_level": 埋伏价格数值或null,
|
||||||
"reasoning": "埋伏点位说明 (等待回调/反弹到关键位)",
|
"reasoning": "埋伏点位说明"
|
||||||
"timeframe": "基于哪个时间级别的关键位"
|
|
||||||
}}
|
}}
|
||||||
}},
|
}},
|
||||||
|
|
||||||
// 分级别操作建议(必填,即使某级别无机会也要说明原因)
|
// 分级别操作建议(必填)
|
||||||
"recommendations_by_timeframe": {{
|
"recommendations_by_timeframe": {{
|
||||||
"short_term": "短期(5m/15m/1h)操作建议",
|
"short_term": "短期(5m/15m/1h)操作建议",
|
||||||
"medium_term": "中期(4h/1d)操作建议",
|
"medium_term": "中期(4h/1d)操作建议",
|
||||||
"long_term": "长期(1d/1w)操作建议"
|
"long_term": "长期(1d/1w)操作建议"
|
||||||
}},
|
}},
|
||||||
|
|
||||||
// 综合分析
|
"reasoning": "多周期综合分析",
|
||||||
"reasoning": "多周期综合分析 (3-5句话,说明各周期是否一致)",
|
|
||||||
"risk_level": "LOW" | "MEDIUM" | "HIGH",
|
"risk_level": "LOW" | "MEDIUM" | "HIGH",
|
||||||
"key_factors": ["影响因素1", "影响因素2", ...]
|
"key_factors": ["影响因素1", "影响因素2", ...]
|
||||||
}}
|
}}
|
||||||
|
|
||||||
**输出说明**:
|
|
||||||
1. **signal**: 主要交易信号 (BUY/SELL/HOLD)
|
|
||||||
2. **confidence**: 对主要信号的信心度 (0-1)
|
|
||||||
3. **opportunities**: 分时间级别详细分析
|
|
||||||
- **short_term_5m_15m_1h**: 短期日内交易机会 (持仓几分钟到几小时)
|
|
||||||
- 基于5m/15m/1h周期共振
|
|
||||||
- 止损: 5m/15m ATR × 1.5, 通常0.3%-0.5%
|
|
||||||
- 止盈: 1h压力/支撑位, 风险回报比≥1:2
|
|
||||||
- **medium_term_4h_1d**: 中期波段交易机会 (持仓数天到一周)
|
|
||||||
- 基于4h/1d周期趋势
|
|
||||||
- 止损: 4h ATR × 1.5, 通常1%-2%
|
|
||||||
- 止盈: 日线关键位, 风险回报比≥1:2.5
|
|
||||||
- **long_term_1d_1w**: 长期趋势交易机会 (持仓数周到数月)
|
|
||||||
- 基于1d/1w周期趋势
|
|
||||||
- 止损: 日线ATR × 1.5, 通常2%-4%
|
|
||||||
- 止盈: 周线关键位, 风险回报比≥1:3
|
|
||||||
- **ambush**: 埋伏点位机会
|
|
||||||
- 基于日线/周线关键支撑压力位
|
|
||||||
- 等待价格到达后再决定入场
|
|
||||||
4. **recommendations_by_timeframe**: 各级别操作建议(必填)
|
|
||||||
- 即使某级别无明确机会,也要说明原因和观望理由
|
|
||||||
5. **reasoning**: 多周期综合分析,说明各周期是否一致,存在哪些分歧
|
|
||||||
|
|
||||||
**重要原则**:
|
**重要原则**:
|
||||||
1. **平等对待所有时间级别** - 不要偏向任何周期,根据量化评分客观分析
|
1. **优先日内短线** - 重点关注 short_term_5m_15m_1h 的日内交易机会
|
||||||
2. **可以同时存在多级别机会** - 例如: 短期做多(日内) + 中期观望 + 长期做空(趋势)
|
2. **盈利空间≥1%** - 只有预期盈利 ≥1% 时才给出操作建议,否则 exists=false
|
||||||
3. **各级别独立分析** - 短期、中期、长期分别给出建议,不要混淆
|
3. **自行识别支撑压力位** - 从K线数据中找出重要的高低点作为支撑压力位
|
||||||
4. **必须填写recommendations_by_timeframe** - 即使是HOLD也要说明理由
|
4. **响应必须是有效的JSON格式** - 不要包含注释
|
||||||
5. **止损止盈必须匹配时间级别** - 短期用小止损,长期用大止损
|
|
||||||
6. **响应必须是有效的JSON格式** - 不要包含注释
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Add comprehensive multi-timeframe analysis if available
|
# Add multi-timeframe technical indicators
|
||||||
if 'multi_timeframe' in market_context:
|
if 'multi_timeframe' in market_context:
|
||||||
mtf = market_context['multi_timeframe']
|
mtf = market_context['multi_timeframe']
|
||||||
prompt += f"\n## 多时间框架技术分析 (完整指标)\n\n"
|
prompt += "\n## 各周期技术指标\n\n"
|
||||||
|
|
||||||
# Define timeframe order and display names
|
|
||||||
tf_order = [
|
tf_order = [
|
||||||
('5m', '5分钟'),
|
('5m', '5分钟', '日内短线参考'),
|
||||||
('15m', '15分钟'),
|
('15m', '15分钟', '日内短线参考'),
|
||||||
('1h', '1小时'),
|
('1h', '1小时', '短期趋势'),
|
||||||
('4h', '4小时'),
|
('4h', '4小时', '中期趋势'),
|
||||||
('1d', '日线'),
|
('1d', '日线', '大趋势'),
|
||||||
('1w', '周线')
|
('1w', '周线', '长期趋势')
|
||||||
]
|
]
|
||||||
|
|
||||||
for tf_key, tf_name in tf_order:
|
for tf_key, tf_name, tf_desc in tf_order:
|
||||||
if tf_key not in mtf:
|
if tf_key not in mtf:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
data = mtf[tf_key]
|
data = mtf[tf_key]
|
||||||
quant = data.get('quantitative', {})
|
quant = data.get('quantitative', {})
|
||||||
|
|
||||||
prompt += f"### {tf_name}周期 ({tf_key})\n"
|
prompt += f"### {tf_name} ({tf_desc})\n"
|
||||||
|
prompt += f"- 量化评分: {quant.get('composite_score', 0):.1f} | 信号: {quant.get('signal_type', 'HOLD')}\n"
|
||||||
# ===== NEW: 量化评分优先展示 =====
|
prompt += f"- 趋势: {data.get('trend_direction', '未知')} ({data.get('trend_strength', 'weak')})\n"
|
||||||
prompt += f"**量化评分**: {quant.get('composite_score', 0):.1f} (信号: {quant.get('signal_type', 'HOLD')}, 置信度: {quant.get('confidence', 0):.0%})\n"
|
|
||||||
prompt += f"- 趋势得分: {quant.get('trend_score', 0):.1f} | 动量得分: {quant.get('momentum_score', 0):.1f} | 订单流: {quant.get('orderflow_score', 0):.1f}\n"
|
|
||||||
|
|
||||||
# 原有技术指标
|
|
||||||
prompt += f"- 趋势: {data.get('trend_direction', '未知')} (强度: {data.get('trend_strength', 'weak')})\n"
|
|
||||||
prompt += f"- RSI: {data.get('rsi', 50):.1f} ({data.get('rsi_status', '中性')})\n"
|
prompt += f"- RSI: {data.get('rsi', 50):.1f} ({data.get('rsi_status', '中性')})\n"
|
||||||
prompt += f"- MACD: {data.get('macd_signal', '未知')} (柱状图: {data.get('macd_hist', 0):.2f})\n"
|
prompt += f"- MACD: {data.get('macd_signal', '未知')}\n"
|
||||||
|
prompt += f"- ATR: ${data.get('atr', 0):.2f} ({data.get('atr_pct', 0):.2f}%)\n"
|
||||||
# Support/Resistance
|
|
||||||
support = data.get('support')
|
|
||||||
resistance = data.get('resistance')
|
|
||||||
support_str = f"${support:,.0f}" if support else "无"
|
|
||||||
resistance_str = f"${resistance:,.0f}" if resistance else "无"
|
|
||||||
prompt += f"- 支撑位: {support_str} | 压力位: {resistance_str}\n"
|
|
||||||
|
|
||||||
# Volatility
|
|
||||||
atr = data.get('atr', 0)
|
|
||||||
atr_pct = data.get('atr_pct', 0)
|
|
||||||
prompt += f"- 波动率: ATR ${atr:.2f} ({atr_pct:.2f}%)\n"
|
|
||||||
|
|
||||||
# Volume
|
|
||||||
vol_ratio = data.get('volume_ratio', 1)
|
vol_ratio = data.get('volume_ratio', 1)
|
||||||
vol_status = "放量" if vol_ratio > 1.2 else "缩量" if vol_ratio < 0.8 else "正常"
|
vol_status = "放量" if vol_ratio > 1.2 else "缩量" if vol_ratio < 0.8 else "正常"
|
||||||
prompt += f"- 成交量: {vol_status} (比率: {vol_ratio:.2f}x)\n"
|
prompt += f"- 成交量: {vol_status} ({vol_ratio:.2f}x)\n\n"
|
||||||
prompt += "\n"
|
|
||||||
|
|
||||||
# Add cross-timeframe analysis insights
|
# Add K-line data
|
||||||
prompt += "### 多周期分析方法\n\n"
|
if kline_data:
|
||||||
|
prompt += "\n## K线数据 (请从中识别支撑位和压力位)\n\n"
|
||||||
|
prompt += "格式: t=时间, o=开盘, h=最高, l=最低, c=收盘, v=成交量\n\n"
|
||||||
|
|
||||||
prompt += "#### 📊 分时间级别交易框架\n\n"
|
tf_kline_order = [
|
||||||
|
('5m', '5分钟K线 (最近1天)'),
|
||||||
|
('15m', '15分钟K线 (最近1天)'),
|
||||||
|
('1h', '1小时K线 (最近3天)'),
|
||||||
|
('4h', '4小时K线 (最近3天)'),
|
||||||
|
('1d', '日线K线 (最近30天)'),
|
||||||
|
('1w', '周线K线 (最近60周)')
|
||||||
|
]
|
||||||
|
|
||||||
prompt += "**1️⃣ 短期交易 (short_term_5m_15m_1h)** - 持仓: 几分钟到几小时\n\n"
|
for tf_key, tf_desc in tf_kline_order:
|
||||||
prompt += "判断标准:\n"
|
if tf_key not in kline_data:
|
||||||
prompt += "- ✅ **短周期共振**: 5m/15m/1h趋势方向一致\n"
|
continue
|
||||||
prompt += "- ✅ **动量确认**: 5m MACD金叉/死叉 + 15m MACD同向\n"
|
|
||||||
prompt += "- ✅ **RSI信号**: 5m/15m RSI从超卖(<30)反弹或超买(>70)回落\n"
|
|
||||||
prompt += "- ✅ **价格位置**: 触及1h或4h支撑/压力位后反弹\n"
|
|
||||||
prompt += "- ⚠️ **大趋势**: 日线/周线至少不强烈相反\n"
|
|
||||||
prompt += "- ✅ **成交量**: 5m/15m放量确认突破/反转\n\n"
|
|
||||||
prompt += "入场条件:\n"
|
|
||||||
prompt += "- 做多: 5m/15m/1h上涨 + 5m金叉 + 价格>1h支撑 + 放量\n"
|
|
||||||
prompt += "- 做空: 5m/15m/1h下跌 + 5m死叉 + 价格<1h压力 + 放量\n\n"
|
|
||||||
prompt += "止盈止损:\n"
|
|
||||||
prompt += "- 止损: 5m ATR × 1.5 或15m最近低/高点, 约0.3%-0.5%\n"
|
|
||||||
prompt += "- 止盈: 1h压力/支撑位, 风险回报比≥1:2\n"
|
|
||||||
prompt += "- 策略: 快进快出, 达成50%目标后移动止损到成本\n\n"
|
|
||||||
|
|
||||||
prompt += "**2️⃣ 中期交易 (medium_term_4h_1d)** - 持仓: 数天到一周\n\n"
|
klines = kline_data[tf_key]
|
||||||
prompt += "判断标准:\n"
|
if not klines:
|
||||||
prompt += "- ✅ **中周期趋势**: 4h/1d方向一致且趋势明显\n"
|
continue
|
||||||
prompt += "- ✅ **量化评分**: 4h和1d的量化综合得分方向一致\n"
|
|
||||||
prompt += "- ✅ **MACD共振**: 日线金叉/死叉 + 周线趋势确认\n"
|
|
||||||
prompt += "- ✅ **关键位突破**: 突破或回踩日线/周线支撑压力位\n"
|
|
||||||
prompt += "- ✅ **RSI位置**: 日线RSI从超卖(<30)反转或超买(>70)回落\n"
|
|
||||||
prompt += "- ✅ **入场时机**: 4h/1h回调到位,提供更好入场点\n"
|
|
||||||
prompt += "- ✅ **成交量**: 日线放量突破确认趋势\n\n"
|
|
||||||
prompt += "入场条件:\n"
|
|
||||||
prompt += "- 做多: 日线+周线上涨 + 日线金叉 + 4h回调到日线支撑 + 1h反弹\n"
|
|
||||||
prompt += "- 做空: 日线+周线下跌 + 日线死叉 + 4h反弹到日线压力 + 1h回落\n\n"
|
|
||||||
prompt += "止盈止损:\n"
|
|
||||||
prompt += "- 止损: 4h ATR × 1.5, 约1%-2%\n"
|
|
||||||
prompt += "- 止盈: 日线关键位, 风险回报比≥1:2.5\n"
|
|
||||||
prompt += "- 策略: 波段持仓,关注日线趋势变化\n\n"
|
|
||||||
|
|
||||||
prompt += "**3️⃣ 长期交易 (long_term_1d_1w)** - 持仓: 数周到数月\n\n"
|
prompt += f"### {tf_desc}\n"
|
||||||
prompt += "判断标准:\n"
|
prompt += "```\n"
|
||||||
prompt += "- ✅ **大周期趋势**: 1d/1w方向一致且强劲(strong/moderate)\n"
|
|
||||||
prompt += "- ✅ **量化评分**: 日线和周线的量化综合得分方向一致且分值高\n"
|
|
||||||
prompt += "- ✅ **周线MACD**: 周线金叉/死叉确认趋势\n"
|
|
||||||
prompt += "- ✅ **关键位突破**: 突破周线/月线级别支撑压力位\n"
|
|
||||||
prompt += "- ✅ **趋势确认**: 多个大周期指标共振,形成明确趋势\n\n"
|
|
||||||
prompt += "入场条件:\n"
|
|
||||||
prompt += "- 做多: 日线+周线上涨 + 周线金叉 + 日线回调到周线支撑 + 4h反弹\n"
|
|
||||||
prompt += "- 做空: 日线+周线下跌 + 周线死叉 + 日线反弹到周线压力 + 4h回落\n\n"
|
|
||||||
prompt += "止盈止损:\n"
|
|
||||||
prompt += "- 止损: 日线ATR × 1.5, 约2%-4%\n"
|
|
||||||
prompt += "- 止盈: 周线压力/支撑位, 风险回报比≥1:3\n"
|
|
||||||
prompt += "- 策略: 长期持仓,趋势不破不出,移动止损锁定利润\n\n"
|
|
||||||
|
|
||||||
prompt += "**4️⃣ 埋伏点位 (ambush)** - 提前布局等待机会\n\n"
|
# 对于短周期,显示所有K线;对于长周期,可能只显示最近的一部分
|
||||||
prompt += "适用场景:\n"
|
display_klines = klines
|
||||||
prompt += "- 📌 **当前位置不佳**: 价格处于中间位置,没有好的入场点\n"
|
for k in display_klines:
|
||||||
prompt += "- 📌 **关键位等待**: 有明确的日线/周线支撑压力位可等待\n"
|
prompt += f"{k['t']} | o:{k['o']} h:{k['h']} l:{k['l']} c:{k['c']} v:{k['v']:.0f}\n"
|
||||||
prompt += "- 📌 **趋势延续**: 大周期趋势明确,等待回调/反弹入场\n"
|
|
||||||
prompt += "- 📌 **反转布局**: 价格接近关键转折点,等待突破确认\n\n"
|
|
||||||
prompt += "埋伏位置示例:\n"
|
|
||||||
prompt += "- 做多埋伏: 等待回调到周线/日线支撑位 (例: 价格90500,埋伏88900)\n"
|
|
||||||
prompt += "- 做空埋伏: 等待反弹到周线/日线压力位 (例: 价格90500,埋伏93000)\n"
|
|
||||||
prompt += "- 突破埋伏: 等待突破关键位后回踩 (例: 突破91000后回踩90800)\n\n"
|
|
||||||
prompt += "埋伏策略:\n"
|
|
||||||
prompt += "- 基于: 日线/周线的关键支撑压力位\n"
|
|
||||||
prompt += "- 触发: 价格到达埋伏位 + 短周期(1h/4h)出现反转信号\n"
|
|
||||||
prompt += "- 止损: 埋伏位下方/上方1-2个ATR\n"
|
|
||||||
prompt += "- 止盈: 下一个日线/周线关键位\n\n"
|
|
||||||
|
|
||||||
prompt += "**5️⃣ 观望情况** - recommendations_by_timeframe中标注\n"
|
prompt += "```\n\n"
|
||||||
prompt += "- ❌ 某周期趋势不明确或震荡\n"
|
|
||||||
prompt += "- ❌ 量化评分接近0 (无明确方向)\n"
|
|
||||||
prompt += "- ❌ 多个周期趋势严重分歧\n"
|
|
||||||
prompt += "- ❌ 成交量萎缩,市场缺乏动能\n"
|
|
||||||
prompt += "- ❌ 价格在关键位之间震荡\n\n"
|
|
||||||
|
|
||||||
prompt += "#### 🎯 关键分析要点\n"
|
# Add analysis guidelines
|
||||||
prompt += "1. **平等对待各周期** - 周线、日线、小时级别都重要,根据持仓时间选择\n"
|
prompt += """
|
||||||
prompt += "2. **利用量化评分** - 每个周期都有量化综合得分,优先参考这个数值\n"
|
## 支撑压力位识别方法
|
||||||
prompt += "3. **分级别独立分析** - 短期、中期、长期可以有不同甚至相反的建议\n"
|
|
||||||
prompt += "4. **趋势共振**: 同级别内多周期一致时,信号最强\n"
|
1. **短期支撑压力 (5m/15m/1h)**
|
||||||
prompt += "5. **分歧利用**: 短期看多+长期看空 = 日内做多但不持仓过夜\n"
|
- 近1天内的明显高低点
|
||||||
prompt += "6. **必须填写所有级别建议** - recommendations_by_timeframe三个字段都要填\n\n"
|
- 多次触及但未突破的价格
|
||||||
|
- 整数关口 (如 91000, 92000)
|
||||||
|
|
||||||
|
2. **中期支撑压力 (4h/1d)**
|
||||||
|
- 近几天的重要高低点
|
||||||
|
- 趋势线位置
|
||||||
|
- 前期成交密集区
|
||||||
|
|
||||||
|
3. **长期支撑压力 (1d/1w)**
|
||||||
|
- 周线/月线级别的高低点
|
||||||
|
- 历史重要价格区间
|
||||||
|
- 大周期趋势线
|
||||||
|
|
||||||
|
## 止盈止损设置
|
||||||
|
|
||||||
|
- 短期: 止损 0.3%-0.5%, 止盈 ≥1%
|
||||||
|
- 中期: 止损 1%-2%, 止盈 ≥2%
|
||||||
|
- 长期: 止损 2%-4%, 止盈 ≥4%
|
||||||
|
|
||||||
|
只有当 (take_profit - entry) / entry ≥ 1% 时才给出具体建议!
|
||||||
|
"""
|
||||||
|
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
@ -454,6 +404,28 @@ ${current_price:,.2f}
|
|||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
# Helper function to calculate profit percentage
|
||||||
|
def calc_profit_pct(entry, take_profit, direction):
|
||||||
|
"""Calculate profit percentage for a trade"""
|
||||||
|
if not entry or not take_profit or entry <= 0:
|
||||||
|
return 0
|
||||||
|
if direction == 'LONG':
|
||||||
|
return (take_profit - entry) / entry * 100
|
||||||
|
elif direction == 'SHORT':
|
||||||
|
return (entry - take_profit) / entry * 100
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Helper function to check if opportunity meets minimum profit threshold
|
||||||
|
def meets_profit_threshold(opp, min_profit_pct=1.0):
|
||||||
|
"""Check if opportunity has at least min_profit_pct profit potential"""
|
||||||
|
if not opp.get('exists'):
|
||||||
|
return False
|
||||||
|
entry = safe_float(opp.get('entry_price'), 0)
|
||||||
|
tp = safe_float(opp.get('take_profit'), 0)
|
||||||
|
direction = opp.get('direction')
|
||||||
|
profit_pct = calc_profit_pct(entry, tp, direction)
|
||||||
|
return profit_pct >= min_profit_pct
|
||||||
|
|
||||||
# Parse opportunities structure (support both old and new format)
|
# Parse opportunities structure (support both old and new format)
|
||||||
opportunities = llm_decision.get('opportunities', {})
|
opportunities = llm_decision.get('opportunities', {})
|
||||||
|
|
||||||
@ -472,7 +444,43 @@ ${current_price:,.2f}
|
|||||||
medium_term = swing
|
medium_term = swing
|
||||||
long_term = {}
|
long_term = {}
|
||||||
|
|
||||||
# Determine primary levels (priority: short > medium > long)
|
# Apply minimum profit filter to all opportunities
|
||||||
|
MIN_PROFIT_PCT = settings.MIN_PROFIT_PCT
|
||||||
|
|
||||||
|
# Filter short_term
|
||||||
|
short_term_valid = meets_profit_threshold(short_term, MIN_PROFIT_PCT)
|
||||||
|
if short_term.get('exists') and not short_term_valid:
|
||||||
|
profit_pct = calc_profit_pct(
|
||||||
|
safe_float(short_term.get('entry_price'), 0),
|
||||||
|
safe_float(short_term.get('take_profit'), 0),
|
||||||
|
short_term.get('direction')
|
||||||
|
)
|
||||||
|
logger.info(f"短期机会被过滤: 盈利空间 {profit_pct:.2f}% < {MIN_PROFIT_PCT}%")
|
||||||
|
short_term = {'exists': False, 'reasoning': f'盈利空间不足1% (仅{profit_pct:.2f}%),建议观望'}
|
||||||
|
|
||||||
|
# Filter medium_term
|
||||||
|
medium_term_valid = meets_profit_threshold(medium_term, MIN_PROFIT_PCT)
|
||||||
|
if medium_term.get('exists') and not medium_term_valid:
|
||||||
|
profit_pct = calc_profit_pct(
|
||||||
|
safe_float(medium_term.get('entry_price'), 0),
|
||||||
|
safe_float(medium_term.get('take_profit'), 0),
|
||||||
|
medium_term.get('direction')
|
||||||
|
)
|
||||||
|
logger.info(f"中期机会被过滤: 盈利空间 {profit_pct:.2f}% < {MIN_PROFIT_PCT}%")
|
||||||
|
medium_term = {'exists': False, 'reasoning': f'盈利空间不足1% (仅{profit_pct:.2f}%),建议观望'}
|
||||||
|
|
||||||
|
# Filter long_term
|
||||||
|
long_term_valid = meets_profit_threshold(long_term, MIN_PROFIT_PCT)
|
||||||
|
if long_term.get('exists') and not long_term_valid:
|
||||||
|
profit_pct = calc_profit_pct(
|
||||||
|
safe_float(long_term.get('entry_price'), 0),
|
||||||
|
safe_float(long_term.get('take_profit'), 0),
|
||||||
|
long_term.get('direction')
|
||||||
|
)
|
||||||
|
logger.info(f"长期机会被过滤: 盈利空间 {profit_pct:.2f}% < {MIN_PROFIT_PCT}%")
|
||||||
|
long_term = {'exists': False, 'reasoning': f'盈利空间不足1% (仅{profit_pct:.2f}%),建议观望'}
|
||||||
|
|
||||||
|
# Determine primary levels (priority: short > medium > long) - 优先日内短线
|
||||||
entry = market_context.get('current_price', 0)
|
entry = market_context.get('current_price', 0)
|
||||||
stop_loss = 0
|
stop_loss = 0
|
||||||
take_profit = 0
|
take_profit = 0
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import logging
|
|||||||
from typing import Dict, Any, List, Optional
|
from typing import Dict, Any, List, Optional
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from config.settings import settings
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +73,24 @@ class QuantitativeSignalGenerator:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Build signal
|
# Build signal
|
||||||
|
# Calculate profit percentage
|
||||||
|
if signal_type == 'BUY' and entry_level > 0:
|
||||||
|
profit_pct = (take_profit_levels[0] - entry_level) / entry_level * 100
|
||||||
|
elif signal_type == 'SELL' and entry_level > 0:
|
||||||
|
profit_pct = (entry_level - take_profit_levels[0]) / entry_level * 100
|
||||||
|
else:
|
||||||
|
profit_pct = 0
|
||||||
|
|
||||||
|
# Apply minimum profit filter - 盈利空间不足时建议观望
|
||||||
|
MIN_PROFIT_PCT = settings.MIN_PROFIT_PCT
|
||||||
|
original_signal_type = signal_type
|
||||||
|
filtered_reason = ""
|
||||||
|
if signal_type != 'HOLD' and profit_pct < MIN_PROFIT_PCT:
|
||||||
|
logger.info(f"量化信号被过滤: {signal_type} 盈利空间 {profit_pct:.2f}% < {MIN_PROFIT_PCT}%,改为 HOLD")
|
||||||
|
filtered_reason = f" (原{original_signal_type}信号盈利空间不足{MIN_PROFIT_PCT}%,仅{profit_pct:.2f}%)"
|
||||||
|
signal_type = 'HOLD'
|
||||||
|
signal_strength = 0
|
||||||
|
|
||||||
signal = {
|
signal = {
|
||||||
'timestamp': datetime.now().isoformat(),
|
'timestamp': datetime.now().isoformat(),
|
||||||
'signal_type': signal_type, # 'BUY', 'SELL', 'HOLD'
|
'signal_type': signal_type, # 'BUY', 'SELL', 'HOLD'
|
||||||
@ -80,6 +100,7 @@ class QuantitativeSignalGenerator:
|
|||||||
trend, momentum, orderflow
|
trend, momentum, orderflow
|
||||||
),
|
),
|
||||||
'consensus_score': round(consensus_score, 2), # 共识得分 (关键指标)
|
'consensus_score': round(consensus_score, 2), # 共识得分 (关键指标)
|
||||||
|
'profit_pct': round(profit_pct, 2), # 预期盈利空间百分比
|
||||||
'scores': {
|
'scores': {
|
||||||
'trend': round(trend_score, 1),
|
'trend': round(trend_score, 1),
|
||||||
'momentum': round(momentum_score, 1),
|
'momentum': round(momentum_score, 1),
|
||||||
@ -98,8 +119,8 @@ class QuantitativeSignalGenerator:
|
|||||||
entry_level, stop_loss, take_profit_levels[0]
|
entry_level, stop_loss, take_profit_levels[0]
|
||||||
),
|
),
|
||||||
'reasoning': QuantitativeSignalGenerator._generate_reasoning(
|
'reasoning': QuantitativeSignalGenerator._generate_reasoning(
|
||||||
signal_type, trend, momentum, orderflow, breakout
|
original_signal_type, trend, momentum, orderflow, breakout
|
||||||
),
|
) + filtered_reason,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user