Signed-off-by: TIANHE <TIANHE@GMAIL.COM>
This commit is contained in:
TIANHE
2026-01-31 02:59:49 +08:00
parent 2853e83885
commit 0b37aa4a67
58 changed files with 11231 additions and 8698 deletions
@@ -13,7 +13,7 @@ from typing import Any, Dict, List, Optional
from app.utils.db import get_db_connection
from app.utils.logger import get_logger
from app.services.analysis import AnalysisService
from app.services.fast_analysis import get_fast_analysis_service
from app.services.signal_notifier import SignalNotifier
from app.services.kline import KlineService
@@ -156,14 +156,17 @@ def _get_positions_for_monitor(position_ids: List[int] = None, user_id: int = No
def _run_ai_analysis(positions: List[Dict[str, Any]], config: Dict[str, Any]) -> Dict[str, Any]:
"""
Run full multi-agent AI analysis on positions.
Uses the same 13-agent analysis flow as the AI Analysis page.
Run fast AI analysis on positions.
Uses the new FastAnalysisService (single LLM call, faster and more stable).
"""
try:
language = config.get('language', 'en-US')
custom_prompt = config.get('prompt', '')
# Analyze each position using the full agent analysis flow
# Get the fast analysis service
service = get_fast_analysis_service()
# Analyze each position
position_analyses = []
for pos in positions:
@@ -176,21 +179,24 @@ def _run_ai_analysis(positions: List[Dict[str, Any]], config: Dict[str, Any]) ->
continue
try:
logger.info(f"Running multi-agent analysis for {market}:{symbol}")
logger.info(f"Running fast AI analysis for {market}:{symbol}")
# Use the full AnalysisService (13-agent flow)
analysis_result = AnalysisService().analyze(
# Use the new FastAnalysisService (single LLM call)
analysis_result = service.analyze(
market=market,
symbol=symbol,
language=language,
timeframe='1D'
)
# Extract key information from the analysis
final_decision = analysis_result.get('final_decision', {})
trader_decision = analysis_result.get('trader_decision', {})
overview = analysis_result.get('overview', {})
risk_report = analysis_result.get('risk', {})
# Extract information from the new format
detailed = analysis_result.get('detailed_analysis', {})
trading_plan = analysis_result.get('trading_plan', {})
scores = analysis_result.get('scores', {})
# Build risk report from risks list
risks = analysis_result.get('risks', [])
risk_report = '\n'.join([f"{r}" for r in risks]) if risks else ''
position_analysis = {
'market': market,
@@ -198,24 +204,35 @@ def _run_ai_analysis(positions: List[Dict[str, Any]], config: Dict[str, Any]) ->
'name': name,
'group_name': group_name,
'entry_price': pos.get('entry_price'),
'current_price': pos.get('current_price'),
'current_price': pos.get('current_price') or analysis_result.get('market_data', {}).get('current_price'),
'pnl': pos.get('pnl'),
'pnl_percent': pos.get('pnl_percent'),
'quantity': pos.get('quantity'),
'side': pos.get('side'),
# Multi-agent analysis results
'final_decision': final_decision.get('decision', 'HOLD'),
'confidence': final_decision.get('confidence', 50),
'reasoning': final_decision.get('reasoning', ''),
'trader_decision': trader_decision.get('decision', 'HOLD'),
'trader_reasoning': trader_decision.get('reasoning', ''),
'overview_report': overview.get('report', ''),
'risk_report': risk_report.get('report', ''),
# New fast analysis results
'final_decision': analysis_result.get('decision', 'HOLD'),
'confidence': analysis_result.get('confidence', 50),
'reasoning': analysis_result.get('summary', ''),
'trader_decision': analysis_result.get('decision', 'HOLD'), # Same as final for fast analysis
'trader_reasoning': analysis_result.get('summary', ''),
'overview_report': detailed.get('technical', ''),
'fundamental_report': detailed.get('fundamental', ''),
'sentiment_report': detailed.get('sentiment', ''),
'risk_report': risk_report,
# Trading plan
'suggested_entry': trading_plan.get('entry_price'),
'suggested_stop_loss': trading_plan.get('stop_loss'),
'suggested_take_profit': trading_plan.get('take_profit'),
# Scores
'technical_score': scores.get('technical', 50),
'fundamental_score': scores.get('fundamental', 50),
'sentiment_score': scores.get('sentiment', 50),
'key_reasons': analysis_result.get('reasons', []),
'error': analysis_result.get('error')
}
position_analyses.append(position_analysis)
logger.info(f"Analysis completed for {market}:{symbol}: {final_decision.get('decision', 'N/A')}")
logger.info(f"Fast analysis completed for {market}:{symbol}: {analysis_result.get('decision', 'N/A')}")
except Exception as e:
logger.error(f"Failed to analyze {market}:{symbol}: {e}")
@@ -283,7 +300,7 @@ def _build_html_report(
# Text translations
texts = {
'title': '投资组合AI分析报告' if is_zh else 'Portfolio AI Analysis Report',
'subtitle': '由 QuantDinger 多智能体分析系统生成' if is_zh else 'Generated by QuantDinger Multi-Agent Analysis System',
'subtitle': '由 QuantDinger AI 快速分析引擎生成' if is_zh else 'Generated by QuantDinger Fast AI Analysis Engine',
'overview': '组合概览' if is_zh else 'Portfolio Overview',
'positions': '持仓数量' if is_zh else 'Positions',
'total_value': '总市值' if is_zh else 'Total Value',