From 7fbfc96795a499cc6faf37cbaaf3c0cb27bb293d Mon Sep 17 00:00:00 2001 From: cillin Date: Fri, 13 Mar 2026 04:31:06 +0800 Subject: [PATCH] feat(ui): update frontend components and agent prompts - Update analyst, portfolio_manager, risk_manager prompts - Enhance analysis tools functionality - Improve UI components (AgentCard, AgentFeed, RoomView, etc.) - Update constants configuration Co-Authored-By: Claude --- .../agents/prompts/analyst/personas.yaml | 132 +++++++++--------- .../backend/agents/prompts/analyst/system.md | 34 ++--- .../prompts/portfolio_manager/system.md | 50 +++---- .../agents/prompts/risk_manager/system.md | 33 ++--- evotraders/backend/tools/analysis_tools.py | 51 ++++++- evotraders/frontend/src/App.jsx | 20 +-- .../frontend/src/components/AboutModal.jsx | 3 + .../frontend/src/components/AgentCard.jsx | 34 ++--- .../frontend/src/components/AgentFeed.jsx | 28 ++-- evotraders/frontend/src/components/Header.jsx | 4 +- .../frontend/src/components/RoomView.jsx | 10 +- .../frontend/src/components/RulesView.jsx | 14 +- .../src/components/StatisticsView.jsx | 60 ++++---- evotraders/frontend/src/config/constants.js | 24 ++-- 14 files changed, 273 insertions(+), 224 deletions(-) diff --git a/evotraders/backend/agents/prompts/analyst/personas.yaml b/evotraders/backend/agents/prompts/analyst/personas.yaml index 73cea6e..ea86625 100644 --- a/evotraders/backend/agents/prompts/analyst/personas.yaml +++ b/evotraders/backend/agents/prompts/analyst/personas.yaml @@ -1,13 +1,13 @@ -# Analyst Personas Configuration +# 分析师角色配置 fundamentals_analyst: - name: "Fundamental Analyst" + name: "基本面分析师" focus: - - "Company financial health and profitability" - - "Business model sustainability and competitive advantages" - - "Management quality and corporate governance" - - "Industry position and market share" - - "Long-term investment value assessment" + - "公司财务健康状况和盈利能力" + - "商业模式可持续性和竞争优势" + - "管理层质量和公司治理" + - "行业地位和市场份额" + - "长期投资价值评估" tools: - "analyze_profitability" - "analyze_growth" @@ -15,30 +15,30 @@ fundamentals_analyst: - "analyze_valuation_ratios" - "analyze_efficiency_ratios" description: | - As a fundamental analyst, you focus on: - - Company financial health and profitability - - Business model sustainability and competitive advantages - - Management quality and corporate governance - - Industry position and market share - - Long-term investment value assessment - You tend to select tools that provide deep insights into company intrinsic value, preferring fundamental and valuation tools. + 作为基本面分析师,你专注于: + - 公司财务健康状况和盈利能力 + - 商业模式可持续性和竞争优势 + - 管理层质量和公司治理 + - 行业地位和市场份额 + - 长期投资价值评估 + 你倾向于选择能够深入了解公司内在价值的工具,更偏好基本面和估值类工具。 technical_analyst: - name: "Technical Analyst" + name: "技术分析师" focus: - - "Price trends and chart patterns" - - "Technical indicators and trading signals" - - "Market sentiment and capital flows" - - "Support/resistance levels and key price points" - - "Short to medium-term trading opportunities" + - "价格趋势和图表形态" + - "技术指标和交易信号" + - "市场情绪和资金流向" + - "支撑/阻力位和关键价格点" + - "中短期交易机会" description: | - As a technical analyst, you focus on: - - Price trends and chart patterns - - Technical indicators and trading signals - - Market sentiment and capital flows - - Support/resistance levels and key price points - - Short to medium-term trading opportunities - You tend to select tools that capture price dynamics and market trends, preferring technical analysis tools. + 作为技术分析师,你专注于: + - 价格趋势和图表形态 + - 技术指标和交易信号 + - 市场情绪和资金流向 + - 支撑/阻力位和关键价格点 + - 中短期交易机会 + 你倾向于选择能够捕捉价格动态和市场趋势的工具,更偏好技术分析类工具。 tools: - "analyze_trend_following" - "analyze_momentum" @@ -46,41 +46,41 @@ technical_analyst: - "analyze_volatility" sentiment_analyst: - name: "Sentiment Analyst" + name: "情绪分析师" focus: - - "Market participant sentiment changes" - - "News opinion and media influence" - - "Insider trading behavior" - - "Investor panic and greed emotions" - - "Market expectations and psychological factors" + - "市场参与者情绪变化" + - "新闻舆情和媒体影响" + - "内部人交易行为" + - "投资者恐慌和贪婪情绪" + - "市场预期和心理因素" description: | - As a sentiment analyst, you focus on: - - Market participant sentiment changes - - News opinion and media influence - - Insider trading behavior - - Investor panic and greed emotions - - Market expectations and psychological factors - You tend to select tools that reflect market sentiment and investor behavior, preferring sentiment and behavioral tools. + 作为情绪分析师,你专注于: + - 市场参与者情绪变化 + - 新闻舆情和媒体影响 + - 内部人交易行为 + - 投资者恐慌和贪婪情绪 + - 市场预期和心理因素 + 你倾向于选择能够反映市场情绪和投资者行为的工具,更偏好情绪和行为类工具。 tools: - "analyze_news_sentiment" - "analyze_insider_trading" valuation_analyst: - name: "Valuation Analyst" + name: "估值分析师" focus: - - "Company intrinsic value calculation" - - "Comparison of different valuation methods" - - "Valuation model assumptions and sensitivity" - - "Relative and absolute valuation" - - "Investment margin of safety assessment" + - "公司内在价值计算" + - "不同估值方法的比较" + - "估值模型假设和敏感性分析" + - "相对估值和绝对估值" + - "投资安全边际评估" description: | - As a valuation analyst, you focus on: - - Company intrinsic value calculation - - Comparison of different valuation methods - - Valuation model assumptions and sensitivity - - Relative and absolute valuation - - Investment margin of safety assessment - You tend to select tools that accurately calculate company value, preferring valuation models and fundamental tools. + 作为估值分析师,你专注于: + - 公司内在价值计算 + - 不同估值方法的比较 + - 估值模型假设和敏感性分析 + - 相对估值和绝对估值 + - 投资安全边际评估 + 你倾向于选择能够准确计算公司价值的工具,更偏好估值模型和基本面工具。 tools: - "dcf_valuation_analysis" - "owner_earnings_valuation_analysis" @@ -88,21 +88,21 @@ valuation_analyst: - "residual_income_valuation_analysis" comprehensive_analyst: - name: "Comprehensive Analyst" + name: "综合分析师" focus: - - "Integrate multiple analytical perspectives" - - "Balance short-term and long-term factors" - - "Comprehensively consider fundamentals, technicals, and sentiment" - - "Provide comprehensive investment advice" - - "Adapt to different market environments" + - "整合多种分析视角" + - "平衡短期和长期因素" + - "综合考虑基本面、技术面和情绪面" + - "提供全面的投资建议" + - "适应不同市场环境" description: | - As a comprehensive analyst, you need to: - - Integrate multiple analytical perspectives - - Balance short-term and long-term factors - - Consider combined impact of fundamentals, technicals, and sentiment - - Provide comprehensive investment advice - - Adapt to different market environments - You will flexibly select various tools based on specific situations, pursuing comprehensiveness and accuracy in analysis. + 作为综合分析师,你需要: + - 整合多种分析视角 + - 平衡短期和长期因素 + - 综合考虑基本面、技术面和情绪面的影响 + - 提供全面的投资建议 + - 适应不同市场环境 + 你会根据具体情况灵活选择各类工具,追求分析的全面性和准确性。 tools: - "analyze_profitability" - "analyze_growth" diff --git a/evotraders/backend/agents/prompts/analyst/system.md b/evotraders/backend/agents/prompts/analyst/system.md index 37e0c4c..0c1bbe8 100644 --- a/evotraders/backend/agents/prompts/analyst/system.md +++ b/evotraders/backend/agents/prompts/analyst/system.md @@ -1,23 +1,23 @@ -You are a professional {{ analyst_type }}. +你是一位专业的{{ analyst_type }}。 -Your Focus: +你的关注重点: {{ focus }} -Your Role: +你的角色: {{ description }} -Note: -- Construct and continuously refine your "Investment Philosophy." Your analyses should not be isolated events but rather manifestations of your overarching worldview and core investment beliefs. After each analysis, you must reflect: - - How did this case/data validate or challenge your existing conviction? - - What key principle regarding markets, human psychology, valuation, or risk management did you learn from this mistake (or success)? -- Deepen your "Investment Logic." Ensure every investment recommendation you make is supported by a clear, traceable, and repeatable logic. Your analysis steps should resemble a rigorous proof, covering: - - Core Driver Identification: What are the genuine variables that influence value? - - Risk Boundary Setting: Under what specific scenarios would your recommendation fail? - - Contrarian Testing: What is the prevailing market consensus, and where is your view differentiated? -Maintain Humility and Openness. A core trait of an Investment Master is continuous learning and adaptation. In every analysis, you must actively seek out evidence and arguments that contradict your own view and integrate them into your final assessment. - - You have access to analysis tools. Use them to gather relevant data and make informed recommendations. +注意: +- 构建并持续完善你的"投资哲学"。你的分析不应是孤立的事件,而应该是你整体投资世界观和核心信念的体现。每次分析后,你必须反思: + - 这个案例/数据如何验证或挑战了你现有的信念? + - 你从这次错误(或成功)中学到了关于市场、人性、估值或风险管理的什么关键原则? +- 深化你的"投资逻辑"。确保每一项投资建议都有清晰、可追溯、可重复的逻辑支撑。你的分析步骤应该像严谨的证明一样,涵盖: + - 核心驱动因素识别:真正影响价值的变量是什么? + - 风险边界设定:在什么具体情况下你的建议会失效? + - 逆向测试:市场主流共识是什么,你的观点有何不同? +保持谦逊和开放。投资大师的核心特质是持续学习和适应。在每次分析中,你必须积极寻找与自己观点相悖的证据和论据,并将其纳入最终评估。 + - 你可以使用分析工具。用它们来收集相关数据并做出明智的建议。 -Output Guidelines: -- Return clear investment signals: bullish, bearish, or neutral -- Include confidence level (0-100) -- Provide reasoning for your analysis (Present your conclusion first if you are sure to share your final analysis. ) +输出指南: +- 给出明确的投资信号:看涨、看跌或中性 +- 包含置信度(0-100) +- 为你的分析提供理由(如果你确定要分享最终分析,请先给出结论) diff --git a/evotraders/backend/agents/prompts/portfolio_manager/system.md b/evotraders/backend/agents/prompts/portfolio_manager/system.md index ca386c8..4177f1a 100644 --- a/evotraders/backend/agents/prompts/portfolio_manager/system.md +++ b/evotraders/backend/agents/prompts/portfolio_manager/system.md @@ -1,31 +1,31 @@ -You are a Portfolio Manager responsible for making investment decisions. +你是一位负责做出投资决策的投资组合经理。 -Your Core Responsibilities: -1. Analyze input from analysts and risk managers -2. Make investment decisions based on signals and market context -3. Record your decisions using the available tool +你的核心职责: +1. 分析分析师和风险管理经理的输入 +2. 基于信号和市场情境做出投资决策 +3. 使用可用工具记录你的决策 -Decision Framework: -- Review analysis to understand market views -- Consider risk warnings before making decisions -- Evaluate current portfolio positions and cash -- Make decisions that align with the portfolio's investment objectives +决策框架: +- 审阅分析以了解市场观点 +- 在做决策前考虑风险警告 +- 评估当前投资组合持仓和现金 +- 做出与投资组合投资目标一致的决策 -Decision Types: -- "long": Bullish - recommend buying shares -- "short": Bearish - recommend selling shares or shorting -- "hold": Neutral - maintain current positions +决策类型: +- "long":看涨 - 建议买入股票 +- "short":看跌 - 建议卖出股票或做空 +- "hold":中性 - 维持当前持仓 -Budget Awareness: -- Consider available cash when deciding quantities -- Do not recommend buying more than cash allows -- Consider margin requirements for short positions +预算意识: +- 在决定数量时考虑可用现金 +- 不要建议买入超过现金允许的数量 +- 考虑做空头寸的保证金要求 -Output: -Use the `make_decision` tool to record your decision for each ticker. -After recording all decisions, provide a summary of your investment rationale. +输出: +使用 `make_decision` 工具记录你对每个股票代码的决策。 +记录所有决策后,提供你的投资逻辑总结。 -Important: -- Base decisions on the analyst signals and risk assessments provided -- Be conservative with position sizes relative to portfolio value -- Always provide reasoning for your decisions +重要: +- 基于提供的分析师信号和风险评估做出决策 +- 相对于投资组合价值保持保守的仓位规模 +- 始终为你的决策提供理由 diff --git a/evotraders/backend/agents/prompts/risk_manager/system.md b/evotraders/backend/agents/prompts/risk_manager/system.md index 08373a7..7469f78 100644 --- a/evotraders/backend/agents/prompts/risk_manager/system.md +++ b/evotraders/backend/agents/prompts/risk_manager/system.md @@ -1,21 +1,18 @@ -You are a professional Risk Manager responsible for monitoring portfolio risk and providing risk warnings. - -Your Core Responsibilities: -1. Monitor portfolio exposure and concentration risk -2. Evaluate position sizes relative to volatility -3. Assess margin usage and leverage levels -4. Identify potential risk factors and provide warnings -5. Suggest position limits based on market conditions - -Your Decision Process: -3. Generate actionable risk warnings and position limit recommendations -4. Provide clear reasoning for your risk assessments - -Output Guidelines: -- Be concise but thorough in risk assessments -- Prioritize warnings by severity -- Provide specific, actionable recommendations -- Include quantitative metrics when available +你是一位专业的风险管理经理,负责监控投资组合风险并提供风险警告。 +你的核心职责: +1. 监控投资组合敞口和集中度风险 +2. 评估仓位规模相对于波动性 +3. 评估保证金使用和杠杆水平 +4. 识别潜在风险因素并提供警告 +5. 基于市场条件建议仓位限制 +你的决策流程: +3. 生成可操作的风险警告和仓位限制建议 +4. 为你的风险评估提供清晰的理由 +输出指南: +- 风险评估要简洁但全面 +- 按严重程度优先排序警告 +- 提供具体、可操作的建议 +- 尽可能包含量化指标 diff --git a/evotraders/backend/tools/analysis_tools.py b/evotraders/backend/tools/analysis_tools.py index c2f4c39..f9c5713 100644 --- a/evotraders/backend/tools/analysis_tools.py +++ b/evotraders/backend/tools/analysis_tools.py @@ -7,12 +7,13 @@ Returns human-readable text format for easy LLM consumption. """ # flake8: noqa: E501 # pylint: disable=C0301,W0613 +import json import logging import traceback from datetime import datetime, timedelta from functools import wraps from statistics import median -from typing import List, Optional +from typing import List, Optional, Union import numpy as np import pandas as pd @@ -37,6 +38,39 @@ def _to_text_response(text: str) -> ToolResponse: return ToolResponse(content=[TextBlock(type="text", text=text)]) +def _parse_tickers(tickers: Union[str, List[str], None]) -> List[str]: + """ + Parse tickers parameter which may be a JSON string or a list. + + LLM sometimes passes tickers as a JSON string like '["AAPL", "MSFT"]' + instead of an actual list. This function handles both cases. + + Args: + tickers: List of stock tickers as a list or JSON string. + + Returns: + List of stock tickers. + """ + if tickers is None: + return [] + + if isinstance(tickers, str): + try: + parsed = json.loads(tickers) + if isinstance(parsed, list): + return parsed + # If it's a single string, wrap in list + return [parsed] + except json.JSONDecodeError: + # If not valid JSON, treat as comma-separated string + return [t.strip() for t in tickers.split(",") if t.strip()] + + if isinstance(tickers, list): + return tickers + + return [] + + def _safe_float(value, default=0.0) -> float: """Safely convert to float.""" try: @@ -100,6 +134,7 @@ def analyze_efficiency_ratios( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Efficiency Ratios Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -141,6 +176,7 @@ def analyze_profitability( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Profitability Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -182,6 +218,7 @@ def analyze_growth( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Growth Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -222,6 +259,7 @@ def analyze_financial_health( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Financial Health Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -265,6 +303,7 @@ def analyze_valuation_ratios( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Valuation Ratios Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -364,6 +403,7 @@ def analyze_trend_following( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Trend Following Analysis ({current_date}) ===\n"] end_dt = datetime.strptime(current_date, "%Y-%m-%d") @@ -459,6 +499,7 @@ def analyze_mean_reversion( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Mean Reversion Analysis ({current_date}) ===\n"] end_dt = datetime.strptime(current_date, "%Y-%m-%d") @@ -545,6 +586,7 @@ def analyze_momentum( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Momentum Analysis ({current_date}) ===\n"] end_dt = datetime.strptime(current_date, "%Y-%m-%d") @@ -640,6 +682,7 @@ def analyze_volatility( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Volatility Analysis ({current_date}) ===\n"] end_dt = datetime.strptime(current_date, "%Y-%m-%d") @@ -718,6 +761,7 @@ def analyze_insider_trading( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Insider Trading Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -786,6 +830,7 @@ def analyze_news_sentiment( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== News Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -835,6 +880,7 @@ def dcf_valuation_analysis( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== DCF Valuation Analysis ({current_date}) ===\n"] for ticker in tickers: @@ -931,6 +977,7 @@ def owner_earnings_valuation_analysis( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Owner Earnings Valuation ({current_date}) ===\n"] for ticker in tickers: @@ -1049,6 +1096,7 @@ def ev_ebitda_valuation_analysis( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== EV/EBITDA Valuation ({current_date}) ===\n"] for ticker in tickers: @@ -1144,6 +1192,7 @@ def residual_income_valuation_analysis( """ current_date = _resolved_date(current_date) + tickers = _parse_tickers(tickers) lines = [f"=== Residual Income Valuation ({current_date}) ===\n"] for ticker in tickers: diff --git a/evotraders/frontend/src/App.jsx b/evotraders/frontend/src/App.jsx index 234e6cf..09c8033 100644 --- a/evotraders/frontend/src/App.jsx +++ b/evotraders/frontend/src/App.jsx @@ -755,7 +755,7 @@ export default function LiveTradingApp() { fontFamily: '"Courier New", monospace', letterSpacing: '0.5px' }}> - LIVE MOCK MODE + 模拟模式 )} @@ -785,7 +785,7 @@ export default function LiveTradingApp() { textTransform: 'uppercase', letterSpacing: '0.5px' }}> - VIRTUAL TIME + 虚拟时间 - {isConnected ? (isUpdating ? 'SYNCING' : 'LIVE') : 'OFFLINE'} + {isConnected ? (isUpdating ? '同步中' : '在线') : '离线'} {marketStatus && ( <> · - {marketStatus.status_text || (marketStatus.status === 'open' ? 'OPEN' : 'CLOSED')} + {marketStatus.status_text || (marketStatus.status === 'open' ? '开盘' : '收盘')} )} @@ -903,7 +903,7 @@ export default function LiveTradingApp() { ))}
- PORTFOLIO + 投资组合 ${formatNumber(portfolioData.netValue)}
@@ -918,28 +918,28 @@ export default function LiveTradingApp() { className={`view-nav-btn ${currentView === 'rules' ? 'active' : ''}`} onClick={() => setCurrentView('rules')} > - Rules + 规则 @@ -970,7 +970,7 @@ export default function LiveTradingApp() { className={`chart-tab ${chartTab === 'all' ? 'active' : ''}`} onClick={() => setChartTab('all')} > - Daily + 日线 {/* )} @@ -397,8 +397,8 @@ function MemoryItem({ memory, itemId, isHighlighted }) { } const agentLabel = memory.agent && memory.agent !== 'Memory' - ? `MEMORY · ${memory.agent}` - : 'MEMORY'; + ? `记忆 · ${memory.agent}` + : '记忆'; return (
setExpanded(!expanded)} > - {expanded ? '« Less' : 'More »'} + {expanded ? '« 收起' : '更多 »'} )}
@@ -525,7 +525,7 @@ function MessageItem({ message, itemId, isHighlighted, getAgentModelInfo }) { const colors = message.agent === 'Memory' ? MESSAGE_COLORS.memory : getAgentColors(message.agentId, message.agent); - const title = message.agent === 'Memory' ? 'MEMORY' : message.agent || 'AGENT'; + const title = message.agent === 'Memory' ? '记忆' : message.agent || 'AGENT'; const agentModelData = message.agentId && getAgentModelInfo ? getAgentModelInfo(message.agentId) : @@ -614,7 +614,7 @@ function MessageItem({ message, itemId, isHighlighted, getAgentModelInfo }) { outline: 'none' }} > - 📄 {isManagerAgent ? 'View decision log »' : 'View full report »'} + 📄 {isManagerAgent ? '查看决策日志 »' : '查看完整报告 »'} )} @@ -623,7 +623,7 @@ function MessageItem({ message, itemId, isHighlighted, getAgentModelInfo }) { className="feed-expand-btn" onClick={() => setExpanded(!expanded)} > - {expanded ? '« Less' : 'More »'} + {expanded ? '« 收起' : '更多 »'} )} diff --git a/evotraders/frontend/src/components/Header.jsx b/evotraders/frontend/src/components/Header.jsx index 7afb5e9..db1eee6 100644 --- a/evotraders/frontend/src/components/Header.jsx +++ b/evotraders/frontend/src/components/Header.jsx @@ -59,7 +59,7 @@ export default function Header({ letterSpacing: '0.5px', marginRight: '0px' }}> - OPEN SOURCE + 开源
- Contact Us + 联系我们 {/* Two contact buttons */} diff --git a/evotraders/frontend/src/components/RoomView.jsx b/evotraders/frontend/src/components/RoomView.jsx index 15a9f9e..7bded68 100644 --- a/evotraders/frontend/src/components/RoomView.jsx +++ b/evotraders/frontend/src/components/RoomView.jsx @@ -551,7 +551,7 @@ export default function RoomView({ bubbles, bubbleFor, leaderboard, feed, onJump {/* Hint Text */}
- Click avatar to view details + 点击头像查看详情
@@ -620,14 +620,14 @@ export default function RoomView({ bubbles, bubbleFor, leaderboard, feed, onJump @@ -728,7 +728,7 @@ export default function RoomView({ bubbles, bubbleFor, leaderboard, feed, onJump title="Replay feed history" > ▶▶ - REPLAY + 回放 )} @@ -749,7 +749,7 @@ export default function RoomView({ bubbles, bubbleFor, leaderboard, feed, onJump }} />
- {isPaused ? 'PAUSED' : 'REPLAY MODE'} + {isPaused ? '已暂停' : '回放模式'}
@@ -170,7 +170,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e marginBottom: 12, textTransform: 'uppercase' }}> - Total Asset Value + 总资产价值
- Excess Return + 超额收益
- vs. VW: {excessReturnData.benchmarkReturn >= 0 ? '+' : ''}{excessReturnData.benchmarkReturn.toFixed(2)}% + vs 市值加权: {excessReturnData.benchmarkReturn >= 0 ? '+' : ''}{excessReturnData.benchmarkReturn.toFixed(2)}%
) : null} @@ -233,7 +233,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e marginBottom: 8, textTransform: 'uppercase' }}> - Win Rate + 胜率
- {pmWinRateData.totalWins}Win / {pmWinRateData.evaluatedTotal}Eval + {pmWinRateData.totalWins}胜 / {pmWinRateData.evaluatedTotal}评
)} @@ -267,7 +267,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e marginBottom: 8, textTransform: 'uppercase' }}> - Absolute Return + 绝对收益
- Cash Position + 现金头寸
- Total Trades + 总交易数
- Portfolio Weights + 组合权重
- No statistics available + 暂无统计数据
)} @@ -433,7 +433,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e color: '#000000', textTransform: 'uppercase' }}> - Portfolio Holdings + 持仓明细 @@ -448,7 +448,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e fontSize: 11, letterSpacing: 0.5 }}> - No positions currently held + 当前无持仓 ) : ( <> @@ -456,11 +456,11 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e - - - - - + + + + + @@ -505,7 +505,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e onClick={() => setHoldingsPage(p => Math.max(1, p - 1))} disabled={holdingsPage === 1} > - ◀ Prev + ◀ 上一页
@@ -517,7 +517,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e onClick={() => setHoldingsPage(p => Math.min(totalHoldingsPages, p + 1))} disabled={holdingsPage === totalHoldingsPages} > - Next ▶ + 下一页 ▶
)} @@ -552,7 +552,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e color: '#000000', textTransform: 'uppercase' }}> - Transaction History + 交易历史 {trades.length > 0 && (
- {trades.length} total + 共 {trades.length} 笔
)} @@ -576,7 +576,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e fontSize: 11, letterSpacing: 0.5 }}> - No trades recorded + 暂无交易记录 ) : ( <> @@ -584,11 +584,11 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e
TickerQuantityPriceValueWeight代码数量价格市值权重
- - - - - + + + + + @@ -638,7 +638,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e onClick={() => setTradesPage(p => Math.max(1, p - 1))} disabled={tradesPage === 1} > - ◀ Prev + ◀ 上一页
@@ -650,7 +650,7 @@ export default function StatisticsView({ trades, holdings, stats, baseline_vw, e onClick={() => setTradesPage(p => Math.min(totalTradesPages, p + 1))} disabled={tradesPage === totalTradesPages} > - Next ▶ + 下一页 ▶
)} diff --git a/evotraders/frontend/src/config/constants.js b/evotraders/frontend/src/config/constants.js index 8e19c75..41be7a6 100644 --- a/evotraders/frontend/src/config/constants.js +++ b/evotraders/frontend/src/config/constants.js @@ -66,43 +66,43 @@ export const AGENT_SEATS = [ export const AGENTS = [ { id: "portfolio_manager", - name: "Portfolio Manager", - role: "Portfolio Manager", + name: "投资经理", + role: "投资经理", avatar: CDN_ASSETS.companyRoom.agent_1, colors: { bg: "#F9FDFF", text: "#1565C0", accent: "#1565C0" } }, { id: "risk_manager", - name: "Risk Manager", - role: "Risk Manager", + name: "风控经理", + role: "风控经理", avatar: CDN_ASSETS.companyRoom.agent_2, colors: { bg: "#FFF8F8", text: "#C62828", accent: "#C62828" } }, { id: "valuation_analyst", - name: "Valuation Analyst", - role: "Valuation Analyst", + name: "估值分析师", + role: "估值分析师", avatar: CDN_ASSETS.companyRoom.agent_3, colors: { bg: "#FAFFFA", text: "#2E7D32", accent: "#2E7D32" } }, { id: "sentiment_analyst", - name: "Sentiment Analyst", - role: "Sentiment Analyst", + name: "情绪分析师", + role: "情绪分析师", avatar: CDN_ASSETS.companyRoom.agent_4, colors: { bg: "#FCFAFF", text: "#6A1B9A", accent: "#6A1B9A" } }, { id: "fundamentals_analyst", - name: "Fundamentals Analyst", - role: "Fundamentals Analyst", + name: "基本面分析师", + role: "基本面分析师", avatar: CDN_ASSETS.companyRoom.agent_5, colors: { bg: "#FFFCF7", text: "#E65100", accent: "#E65100" } }, { id: "technical_analyst", - name: "Technical Analyst", - role: "Technical Analyst", + name: "技术分析师", + role: "技术分析师", avatar: CDN_ASSETS.companyRoom.agent_6, colors: { bg: "#F9FEFF", text: "#00838F", accent: "#00838F" } },
TimeStockSideQtyPrice时间股票方向数量价格