erlangshen 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/equity-agent.md +26 -0
- package/.claude/agents/macro-agent.md +25 -0
- package/.claude/commands/analyze.md +40 -0
- package/.claude/commands/macro.md +29 -0
- package/.claude/settings.json +12 -0
- package/CODEX_GOAL.md +46 -0
- package/README.md +206 -0
- package/bin/cli.js +67 -0
- package/bin/erlangshen +2 -0
- package/bin/xiaoergod +2 -0
- package/frontend/index.html +700 -0
- package/knowledge/crypto_guide.md +147 -0
- package/knowledge/economic_indicators.md +125 -0
- package/knowledge/financial_glossary.md +148 -0
- package/knowledge/first_principles.md +50 -0
- package/knowledge/first_principles_deep.md +115 -0
- package/knowledge/global_markets.md +173 -0
- package/knowledge/insights.md +141 -0
- package/knowledge/market_basics.md +116 -0
- package/knowledge/memos/session_20260513_003616.json +6 -0
- package/knowledge/memos/session_20260513_003822.json +6 -0
- package/knowledge/risk_management.md +151 -0
- package/knowledge/team_context.md +42 -0
- package/knowledge/trading_strategies.md +114 -0
- package/package.json +42 -0
- package/requirements.txt +14 -0
- package/scripts/postinstall.js +188 -0
- package/scripts/preuninstall.js +22 -0
- package/src/__init__.py +4 -0
- package/src/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/agents/__init__.py +3 -0
- package/src/agents/base.py +103 -0
- package/src/agents/base_agent.py +86 -0
- package/src/agents/equity.py +136 -0
- package/src/agents/equity_agent.py +91 -0
- package/src/agents/erlang.py +165 -0
- package/src/agents/macro.py +137 -0
- package/src/agents/macro_agent.py +81 -0
- package/src/agents/multi_asset.py +147 -0
- package/src/agents/multi_asset_agent.py +87 -0
- package/src/api/__init__.py +1 -0
- package/src/api/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/api/__pycache__/server.cpython-313.pyc +0 -0
- package/src/api/cli.py +435 -0
- package/src/api/cli_enhanced.py +537 -0
- package/src/api/server.py +266 -0
- package/src/brain.py +200 -0
- package/src/cli.py +153 -0
- package/src/commands/__init__.py +3 -0
- package/src/commands/analyze.py +131 -0
- package/src/commands/macro.py +100 -0
- package/src/commands/memo.py +216 -0
- package/src/commands/portfolio.py +154 -0
- package/src/commands/report.py +228 -0
- package/src/commands/risk.py +183 -0
- package/src/commands/search.py +183 -0
- package/src/commands/stock.py +124 -0
- package/src/config.py +327 -0
- package/src/core/__init__.py +1 -0
- package/src/core/brain.py +645 -0
- package/src/core/cerebellum.py +175 -0
- package/src/core/investment_universe.py +423 -0
- package/src/core/knowledge.py +207 -0
- package/src/core/memory.py +115 -0
- package/src/hooks/__init__.py +3 -0
- package/src/hooks/session_end.py +57 -0
- package/src/hooks/session_start.py +75 -0
- package/src/knowledge/__init__.py +1 -0
- package/src/mcp/__init__.py +3 -0
- package/src/mcp/feishu.py +331 -0
- package/src/mcp/fund_tools.py +323 -0
- package/src/mcp/macro.py +452 -0
- package/src/mcp/market.py +331 -0
- package/src/mcp/registry.py +168 -0
- package/src/network/__init__.py +15 -0
- package/src/network/detector.py +125 -0
- package/src/network/proxy.py +199 -0
- package/src/network/router.py +103 -0
- package/src/prompts/__init__.py +1 -0
- package/src/prompts/analysis_framework.md +164 -0
- package/src/prompts/persona.md +65 -0
- package/src/prompts/report_template.md +144 -0
- package/src/skills/__init__.py +3 -0
- package/src/skills/framework.py +105 -0
- package/src/skills/templates.py +342 -0
- package/src/tools/__init__.py +1 -0
- package/src/tools/file_tools.py +209 -0
- package/src/tools/macro_tools.py +152 -0
- package/src/tools/market_tools.py +1172 -0
- package/src/tools/registry.py +398 -0
- package/src/tools/search_tools.py +777 -0
- package/tests/__init__.py +1 -0
- package/tests/test_erlangshen.py +140 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
股票分析师 Agent
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, Dict, Any, List
|
|
6
|
+
from src.agents.base import BaseAgent
|
|
7
|
+
from src.brain import Brain
|
|
8
|
+
from src.mcp.registry import MCPRegistry
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EquityAgent(BaseAgent):
|
|
12
|
+
"""
|
|
13
|
+
股票分析师
|
|
14
|
+
|
|
15
|
+
专注于A股、港股、美股的基本面和技术面分析
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, brain: Brain, mcp: MCPRegistry):
|
|
19
|
+
super().__init__(brain, mcp)
|
|
20
|
+
self.role = "股票分析师"
|
|
21
|
+
|
|
22
|
+
def _build_system_prompt(self) -> str:
|
|
23
|
+
return """你是一位资深股票分析师,专注于:
|
|
24
|
+
- A股、港股、美股基本面分析
|
|
25
|
+
- 公司财务分析 (营收、利润、现金流)
|
|
26
|
+
- 行业研究和竞争格局分析
|
|
27
|
+
- 估值分析 (PE, PB, DCF)
|
|
28
|
+
- 技术分析 (趋势、支撑阻力、量价关系)
|
|
29
|
+
- 个股和行业配置建议
|
|
30
|
+
|
|
31
|
+
分析原则:
|
|
32
|
+
1. 价值投资:注重企业内在价值和长期回报
|
|
33
|
+
2. 风险收益:平衡收益预期和风险控制
|
|
34
|
+
3. 基本面为本:技术面作为辅助参考
|
|
35
|
+
4. 分散配置:避免过度集中单一标的
|
|
36
|
+
|
|
37
|
+
输出格式:
|
|
38
|
+
## 核心观点
|
|
39
|
+
(1-2句话概括投资逻辑)
|
|
40
|
+
|
|
41
|
+
## 基本面分析
|
|
42
|
+
(公司概况、竞争优势、财务数据)
|
|
43
|
+
|
|
44
|
+
## 估值分析
|
|
45
|
+
(当前估值、历史分位、合理区间)
|
|
46
|
+
|
|
47
|
+
## 技术面
|
|
48
|
+
(近期走势、关键价位、量价配合)
|
|
49
|
+
|
|
50
|
+
## 风险因素
|
|
51
|
+
(主要风险点)
|
|
52
|
+
|
|
53
|
+
## 投资建议
|
|
54
|
+
(买入/持有/卖出建议,目标价位)
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
async def process(self, query: str, **kwargs) -> str:
|
|
58
|
+
"""
|
|
59
|
+
处理股票分析查询
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
query: 分析查询
|
|
63
|
+
**kwargs: 其他参数 (symbol, symbols等)
|
|
64
|
+
"""
|
|
65
|
+
symbol = kwargs.get("symbol")
|
|
66
|
+
symbols = kwargs.get("symbols", [])
|
|
67
|
+
days = kwargs.get("days", 30)
|
|
68
|
+
|
|
69
|
+
data = {}
|
|
70
|
+
|
|
71
|
+
# 获取股票数据
|
|
72
|
+
if symbol:
|
|
73
|
+
symbols = [symbol]
|
|
74
|
+
|
|
75
|
+
if symbols:
|
|
76
|
+
quotes = await self.call_mcp_tool("get_realtime_quotes", symbols=symbols)
|
|
77
|
+
if isinstance(quotes, list):
|
|
78
|
+
for quote in quotes:
|
|
79
|
+
symbol = quote.get("symbol")
|
|
80
|
+
if symbol:
|
|
81
|
+
data[symbol] = quote
|
|
82
|
+
# 获取历史数据
|
|
83
|
+
history = await self.call_mcp_tool(
|
|
84
|
+
"get_stock_history",
|
|
85
|
+
symbol=symbol,
|
|
86
|
+
days=days
|
|
87
|
+
)
|
|
88
|
+
if isinstance(history, list):
|
|
89
|
+
data[f"{symbol}_history"] = history[-5:] # 最近5天
|
|
90
|
+
|
|
91
|
+
# 执行分析
|
|
92
|
+
return await self.analyze(query, data=data)
|
|
93
|
+
|
|
94
|
+
async def analyze_stock(self, symbol: str, angle: str = "综合") -> str:
|
|
95
|
+
"""
|
|
96
|
+
分析单只股票
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
symbol: 股票代码
|
|
100
|
+
angle: 分析角度 (综合/基本面/技术面/估值)
|
|
101
|
+
"""
|
|
102
|
+
# 获取数据
|
|
103
|
+
quote = await self.call_mcp_tool("get_stock_price", symbol=symbol)
|
|
104
|
+
history = await self.call_mcp_tool("get_stock_history", symbol=symbol, days=60)
|
|
105
|
+
|
|
106
|
+
data = {
|
|
107
|
+
"quote": quote,
|
|
108
|
+
"history": history[-10:] if isinstance(history, list) else []
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
prompt = f"请从{angle}角度分析股票 {symbol}"
|
|
112
|
+
return await self.analyze(prompt, data=data)
|
|
113
|
+
|
|
114
|
+
async def compare_stocks(self, symbols: List[str]) -> str:
|
|
115
|
+
"""
|
|
116
|
+
比较股票
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
symbols: 股票代码列表
|
|
120
|
+
"""
|
|
121
|
+
quotes = await self.call_mcp_tool("get_realtime_quotes", symbols=symbols)
|
|
122
|
+
|
|
123
|
+
data = {"quotes": quotes}
|
|
124
|
+
|
|
125
|
+
prompt = f"请比较以下股票:{', '.join(symbols)}"
|
|
126
|
+
return await self.analyze(prompt, framework="比较分析", data=data)
|
|
127
|
+
|
|
128
|
+
async def analyze_sector(self, sector: str) -> str:
|
|
129
|
+
"""
|
|
130
|
+
分析行业板块
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
sector: 行业名称
|
|
134
|
+
"""
|
|
135
|
+
prompt = f"请分析{sector}行业的:\n1. 当前景气度\n2. 竞争格局\n3. 龙头公司\n4. 投资机会"
|
|
136
|
+
return await self.think(prompt)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Equity Agent - 股票分析师
|
|
3
|
+
专注于个股分析、行业研究、财务建模
|
|
4
|
+
"""
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
from .base_agent import BaseAgent
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EquityAgent(BaseAgent):
|
|
12
|
+
"""
|
|
13
|
+
股票分析师智能体
|
|
14
|
+
|
|
15
|
+
能力:
|
|
16
|
+
- 个股基本面分析
|
|
17
|
+
- 行业研究
|
|
18
|
+
- 财务建模
|
|
19
|
+
- 估值分析
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, tools: Optional[dict] = None):
|
|
23
|
+
super().__init__(
|
|
24
|
+
name="股票分析师",
|
|
25
|
+
description="专注于个股基本面分析和行业研究",
|
|
26
|
+
tools=tools,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
async def process(self, query: str, context: Optional[dict] = None) -> dict:
|
|
30
|
+
"""
|
|
31
|
+
处理股票分析查询
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
query: 分析问题
|
|
35
|
+
context: 上下文
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
dict 包含分析结论
|
|
39
|
+
"""
|
|
40
|
+
logger.info(f"EquityAgent processing: {query[:80]}")
|
|
41
|
+
context = context or {}
|
|
42
|
+
|
|
43
|
+
# 1. 提取股票代码
|
|
44
|
+
symbol = context.get("symbol", self._extract_symbol(query))
|
|
45
|
+
|
|
46
|
+
# 2. 分类分析类型
|
|
47
|
+
analysis_type = self._classify_query(query)
|
|
48
|
+
|
|
49
|
+
# 3. 获取数据
|
|
50
|
+
data = {}
|
|
51
|
+
if symbol:
|
|
52
|
+
if "market_tools" in self.tools:
|
|
53
|
+
data["price"] = await self.call_tool("market_tools.get_stock_price", symbol=symbol)
|
|
54
|
+
if "search_tools" in self.tools:
|
|
55
|
+
data["news"] = await self.call_tool("search_tools.get_company_info", ticker=symbol)
|
|
56
|
+
|
|
57
|
+
# 4. 生成分析
|
|
58
|
+
analysis = {
|
|
59
|
+
"query": query,
|
|
60
|
+
"symbol": symbol,
|
|
61
|
+
"type": analysis_type,
|
|
62
|
+
"data": data,
|
|
63
|
+
"conclusion": f"基于{query}的分析结论",
|
|
64
|
+
"valuation": "估值:合理/偏高/偏低",
|
|
65
|
+
"recommendation": "建议:买入/持有/卖出",
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return analysis
|
|
69
|
+
|
|
70
|
+
def _extract_symbol(self, query: str) -> str:
|
|
71
|
+
"""从查询中提取股票代码"""
|
|
72
|
+
# 简单的代码提取逻辑
|
|
73
|
+
import re
|
|
74
|
+
match = re.search(r'\b\d{6}\b', query)
|
|
75
|
+
if match:
|
|
76
|
+
return match.group(0)
|
|
77
|
+
return ""
|
|
78
|
+
|
|
79
|
+
def _classify_query(self, query: str) -> str:
|
|
80
|
+
"""分类查询类型"""
|
|
81
|
+
q = query.lower()
|
|
82
|
+
if any(k in q for k in ["估值", "价值", "贵", "便宜"]):
|
|
83
|
+
return "valuation"
|
|
84
|
+
elif any(k in q for k in ["业绩", "利润", "收入", "财报"]):
|
|
85
|
+
return "financial"
|
|
86
|
+
elif any(k in q for k in ["行业", "竞争", "市场份额"]):
|
|
87
|
+
return "industry"
|
|
88
|
+
elif any(k in q for k in ["技术", "走势", "趋势", "k线"]):
|
|
89
|
+
return "technical"
|
|
90
|
+
else:
|
|
91
|
+
return "general"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""
|
|
2
|
+
二郎神 - 二郎神主智能体
|
|
3
|
+
全知全能的投资智能体,整合所有能力
|
|
4
|
+
"""
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
from .base_agent import BaseAgent
|
|
9
|
+
from .macro_agent import MacroAgent
|
|
10
|
+
from .equity_agent import EquityAgent
|
|
11
|
+
from .multi_asset_agent import MultiAssetAgent
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class 二郎神(BaseAgent):
|
|
15
|
+
"""
|
|
16
|
+
二郎神 - 主智能体
|
|
17
|
+
|
|
18
|
+
整合所有分析师能力,提供全品类、全方位的投资分析
|
|
19
|
+
|
|
20
|
+
架构:
|
|
21
|
+
- Brain: LLM大脑
|
|
22
|
+
- Cerebellum: 认知调度
|
|
23
|
+
- Agents: 专业分析师团队
|
|
24
|
+
- Tools: 工具集
|
|
25
|
+
- Memory: 记忆系统
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
brain=None,
|
|
31
|
+
memory=None,
|
|
32
|
+
knowledge=None,
|
|
33
|
+
tools: Optional[dict] = None,
|
|
34
|
+
):
|
|
35
|
+
super().__init__(
|
|
36
|
+
name="二郎神",
|
|
37
|
+
description="全知全能的投资智能体,具有天眼般全方位洞察能力",
|
|
38
|
+
tools=tools,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
self.brain = brain
|
|
42
|
+
self.memory = memory
|
|
43
|
+
self.knowledge = knowledge
|
|
44
|
+
|
|
45
|
+
# 初始化专业分析师团队
|
|
46
|
+
self.macro_agent = MacroAgent(tools=tools)
|
|
47
|
+
self.equity_agent = EquityAgent(tools=tools)
|
|
48
|
+
self.multi_asset_agent = MultiAssetAgent(tools=tools)
|
|
49
|
+
|
|
50
|
+
logger.info("二郎神 (二郎神) fully initialized")
|
|
51
|
+
|
|
52
|
+
async def process(self, query: str, context: Optional[dict] = None) -> dict:
|
|
53
|
+
"""
|
|
54
|
+
处理用户查询
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
query: 用户查询
|
|
58
|
+
context: 上下文
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
dict 包含完整分析结果
|
|
62
|
+
"""
|
|
63
|
+
logger.info(f"二郎神 processing: {query[:100]}")
|
|
64
|
+
context = context or {}
|
|
65
|
+
|
|
66
|
+
# 1. 确定查询类型
|
|
67
|
+
query_type = self._classify_query(query)
|
|
68
|
+
|
|
69
|
+
# 2. 路由到对应分析师
|
|
70
|
+
result = {}
|
|
71
|
+
if query_type == "macro":
|
|
72
|
+
result = await self.macro_agent.process(query, context)
|
|
73
|
+
elif query_type == "equity":
|
|
74
|
+
result = await self.equity_agent.process(query, context)
|
|
75
|
+
elif query_type == "multi_asset":
|
|
76
|
+
result = await self.multi_asset_agent.process(query, context)
|
|
77
|
+
else:
|
|
78
|
+
# 综合分析
|
|
79
|
+
result = await self._comprehensive_analysis(query, context)
|
|
80
|
+
|
|
81
|
+
# 3. 添加二郎神特色结论
|
|
82
|
+
result["erlangshen_insight"] = self._generate_insight(query, result)
|
|
83
|
+
|
|
84
|
+
# 4. 记录到记忆
|
|
85
|
+
if self.memory:
|
|
86
|
+
await self.memory.add_interaction(query, str(result.get("conclusion", "")))
|
|
87
|
+
|
|
88
|
+
# 5. 沉淀到知识库
|
|
89
|
+
if self.knowledge and result.get("conclusion"):
|
|
90
|
+
await self.knowledge.append_insight(
|
|
91
|
+
result["conclusion"],
|
|
92
|
+
tags=["analysis", query_type],
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
return result
|
|
96
|
+
|
|
97
|
+
async def _comprehensive_analysis(self, query: str, context: dict) -> dict:
|
|
98
|
+
"""综合分析 - 多维度分析"""
|
|
99
|
+
logger.info("Running comprehensive analysis")
|
|
100
|
+
|
|
101
|
+
# 并行调用多个分析师
|
|
102
|
+
import asyncio
|
|
103
|
+
try:
|
|
104
|
+
results = await asyncio.gather(
|
|
105
|
+
self.macro_agent.process(query, context),
|
|
106
|
+
self.equity_agent.process(query, context),
|
|
107
|
+
self.multi_asset_agent.process(query, context),
|
|
108
|
+
return_exceptions=True,
|
|
109
|
+
)
|
|
110
|
+
except Exception:
|
|
111
|
+
results = []
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
"query": query,
|
|
115
|
+
"type": "comprehensive",
|
|
116
|
+
"macro_analysis": results[0] if len(results) > 0 else {},
|
|
117
|
+
"equity_analysis": results[1] if len(results) > 1 else {},
|
|
118
|
+
"multi_asset_analysis": results[2] if len(results) > 2 else {},
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
def _classify_query(self, query: str) -> str:
|
|
122
|
+
"""分类查询类型"""
|
|
123
|
+
q = query.lower()
|
|
124
|
+
if any(k in q for k in ["宏观", "经济", "gdp", "通胀", "利率", "政策"]):
|
|
125
|
+
return "macro"
|
|
126
|
+
elif any(k in q for k in ["股票", "个股", "茅台", "估值", "行业"]):
|
|
127
|
+
return "equity"
|
|
128
|
+
elif any(k in q for k in ["配置", "资产", "组合", "多资产", "黄金", "债券"]):
|
|
129
|
+
return "multi_asset"
|
|
130
|
+
else:
|
|
131
|
+
return "comprehensive"
|
|
132
|
+
|
|
133
|
+
def _generate_insight(self, query: str, result: dict) -> str:
|
|
134
|
+
"""生成二郎神洞察"""
|
|
135
|
+
return (
|
|
136
|
+
"【二郎神天眼观察】"
|
|
137
|
+
f"针对「{query[:30]}...」的分析已完成。"
|
|
138
|
+
"建议结合宏观周期、资产配置和个人风险偏好综合决策。"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
async def analyze_market(self, market: str = "A股") -> dict:
|
|
142
|
+
"""分析市场整体状况"""
|
|
143
|
+
logger.info(f"Analyzing {market}")
|
|
144
|
+
return await self.process(f"分析当前{market}市场走势和投资机会")
|
|
145
|
+
|
|
146
|
+
async def analyze_stock(self, symbol: str) -> dict:
|
|
147
|
+
"""分析个股"""
|
|
148
|
+
logger.info(f"Analyzing stock {symbol}")
|
|
149
|
+
return await self.process(f"分析股票{symbol}的投资价值", {"symbol": symbol})
|
|
150
|
+
|
|
151
|
+
async def analyze_macro(self, topic: str) -> dict:
|
|
152
|
+
"""分析宏观经济"""
|
|
153
|
+
logger.info(f"Analyzing macro: {topic}")
|
|
154
|
+
return await self.process(f"分析{topic}对投资的影响")
|
|
155
|
+
|
|
156
|
+
async def generate_report(
|
|
157
|
+
self,
|
|
158
|
+
title: str,
|
|
159
|
+
content: str,
|
|
160
|
+
) -> dict:
|
|
161
|
+
"""生成报告并沉淀到知识库"""
|
|
162
|
+
if self.knowledge:
|
|
163
|
+
filepath = await self.knowledge.write_report(content, title)
|
|
164
|
+
return {"status": "success", "path": filepath}
|
|
165
|
+
return {"status": "skipped", "reason": "knowledge not available"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""
|
|
2
|
+
宏观分析师 Agent
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, Dict, Any
|
|
6
|
+
from src.agents.base import BaseAgent
|
|
7
|
+
from src.brain import Brain
|
|
8
|
+
from src.mcp.registry import MCPRegistry
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MacroAgent(BaseAgent):
|
|
12
|
+
"""
|
|
13
|
+
宏观分析师
|
|
14
|
+
|
|
15
|
+
专注于宏观经济分析、政策解读、大类资产配置
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, brain: Brain, mcp: MCPRegistry):
|
|
19
|
+
super().__init__(brain, mcp)
|
|
20
|
+
self.role = "宏观分析师"
|
|
21
|
+
|
|
22
|
+
def _build_system_prompt(self) -> str:
|
|
23
|
+
return """你是一位资深宏观经济分析师,专注于:
|
|
24
|
+
- 宏观经济指标分析 (GDP, CPI, PPI, PMI等)
|
|
25
|
+
- 货币政策解读 (利率、存款准备金率、LPR等)
|
|
26
|
+
- 财政政策分析
|
|
27
|
+
- 大类资产配置建议
|
|
28
|
+
- 汇率走势分析
|
|
29
|
+
- 全球经济联动
|
|
30
|
+
|
|
31
|
+
分析原则:
|
|
32
|
+
1. 数据驱动:基于宏观经济数据进行客观分析
|
|
33
|
+
2. 政策导向:关注央行、财政部政策动向
|
|
34
|
+
3. 全球视野:关注海外主要经济体动态
|
|
35
|
+
4. 风险提示:明确指出潜在风险
|
|
36
|
+
|
|
37
|
+
输出格式:
|
|
38
|
+
## 核心观点
|
|
39
|
+
(1-2句话概括)
|
|
40
|
+
|
|
41
|
+
## 宏观环境
|
|
42
|
+
(当前经济周期、货币财政政策)
|
|
43
|
+
|
|
44
|
+
## 数据解读
|
|
45
|
+
(关键指标数据及含义)
|
|
46
|
+
|
|
47
|
+
## 资产配置建议
|
|
48
|
+
(股票、债券、商品、外汇等)
|
|
49
|
+
|
|
50
|
+
## 风险提示
|
|
51
|
+
(主要风险点)
|
|
52
|
+
|
|
53
|
+
## 近期关注
|
|
54
|
+
(即将发布的重要数据、政策事件)
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
async def process(self, query: str, **kwargs) -> str:
|
|
58
|
+
"""
|
|
59
|
+
处理宏观分析查询
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
query: 分析查询
|
|
63
|
+
**kwargs: 其他参数 (framework, indicators等)
|
|
64
|
+
"""
|
|
65
|
+
framework = kwargs.get("framework")
|
|
66
|
+
indicators = kwargs.get("indicators", [])
|
|
67
|
+
|
|
68
|
+
# 收集相关数据
|
|
69
|
+
data = {}
|
|
70
|
+
|
|
71
|
+
# 获取请求的宏观指标
|
|
72
|
+
if indicators:
|
|
73
|
+
for indicator in indicators:
|
|
74
|
+
result = await self.call_mcp_tool("get_macro_indicator", indicator_code=indicator)
|
|
75
|
+
if isinstance(result, dict):
|
|
76
|
+
data[indicator] = result
|
|
77
|
+
else:
|
|
78
|
+
# 默认获取主要指标
|
|
79
|
+
for indicator in ["GDP", "CPI", "PMI"]:
|
|
80
|
+
result = await self.call_mcp_tool("get_macro_indicator", indicator_code=indicator)
|
|
81
|
+
if isinstance(result, dict):
|
|
82
|
+
data[indicator] = result
|
|
83
|
+
|
|
84
|
+
# 获取利率数据
|
|
85
|
+
lpr_result = await self.call_mcp_tool("get_interest_rates", rate_type="LPR")
|
|
86
|
+
if isinstance(lpr_result, dict):
|
|
87
|
+
data["LPR"] = lpr_result
|
|
88
|
+
|
|
89
|
+
# 获取汇率数据
|
|
90
|
+
currency_result = await self.call_mcp_tool("get_currency_rates", base="USD")
|
|
91
|
+
if isinstance(currency_result, dict):
|
|
92
|
+
data["USD_CNY"] = currency_result
|
|
93
|
+
|
|
94
|
+
# 执行分析
|
|
95
|
+
if data:
|
|
96
|
+
return await self.analyze(query, framework=framework, data=data)
|
|
97
|
+
else:
|
|
98
|
+
return await self.analyze(query, framework=framework)
|
|
99
|
+
|
|
100
|
+
async def analyze_policy(self, policy_type: str) -> str:
|
|
101
|
+
"""
|
|
102
|
+
分析特定政策
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
policy_type: 政策类型 (货币政策/财政政策/产业政策)
|
|
106
|
+
"""
|
|
107
|
+
prompt = f"请详细分析当前{policy_type}的取向、力度和潜在影响"
|
|
108
|
+
return await self.think(prompt)
|
|
109
|
+
|
|
110
|
+
async def compare_economies(
|
|
111
|
+
self,
|
|
112
|
+
countries: list,
|
|
113
|
+
indicators: list
|
|
114
|
+
) -> str:
|
|
115
|
+
"""
|
|
116
|
+
比较多国经济
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
countries: 国家列表
|
|
120
|
+
indicators: 指标列表
|
|
121
|
+
"""
|
|
122
|
+
data = {}
|
|
123
|
+
|
|
124
|
+
for country in countries:
|
|
125
|
+
country_data = {}
|
|
126
|
+
for indicator in indicators:
|
|
127
|
+
result = await self.call_mcp_tool(
|
|
128
|
+
"get_macro_indicator",
|
|
129
|
+
indicator_code=indicator,
|
|
130
|
+
country=country
|
|
131
|
+
)
|
|
132
|
+
if isinstance(result, dict):
|
|
133
|
+
country_data[indicator] = result
|
|
134
|
+
data[country] = country_data
|
|
135
|
+
|
|
136
|
+
prompt = f"请比较多国经济状况:{countries}"
|
|
137
|
+
return await self.analyze(prompt, framework="跨国比较", data=data)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Macro Agent - 宏观分析师
|
|
3
|
+
专注于宏观经济分析、政策解读、大类资产配置
|
|
4
|
+
"""
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
from .base_agent import BaseAgent
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MacroAgent(BaseAgent):
|
|
12
|
+
"""
|
|
13
|
+
宏观分析师智能体
|
|
14
|
+
|
|
15
|
+
能力:
|
|
16
|
+
- 宏观经济指标分析
|
|
17
|
+
- 货币政策解读
|
|
18
|
+
- 大类资产配置建议
|
|
19
|
+
- 宏观风险识别
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, tools: Optional[dict] = None):
|
|
23
|
+
super().__init__(
|
|
24
|
+
name="宏观分析师",
|
|
25
|
+
description="专注于宏观经济分析、政策解读和大类资产配置",
|
|
26
|
+
tools=tools,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
async def process(self, query: str, context: Optional[dict] = None) -> dict:
|
|
30
|
+
"""
|
|
31
|
+
处理宏观分析查询
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
query: 分析问题
|
|
35
|
+
context: 上下文
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
dict 包含分析结论和建议
|
|
39
|
+
"""
|
|
40
|
+
logger.info(f"MacroAgent processing: {query[:80]}")
|
|
41
|
+
context = context or {}
|
|
42
|
+
|
|
43
|
+
# 1. 解析分析类型
|
|
44
|
+
analysis_type = self._classify_query(query)
|
|
45
|
+
|
|
46
|
+
# 2. 获取相关数据
|
|
47
|
+
data = {}
|
|
48
|
+
if "indicator" in analysis_type:
|
|
49
|
+
# 获取宏观指标
|
|
50
|
+
indicator = context.get("indicator", "CPI")
|
|
51
|
+
if "macro_tools" in self.tools:
|
|
52
|
+
data["macro"] = await self.call_tool("macro_tools.get_macro_indicator", code=indicator)
|
|
53
|
+
if "search_tools" in self.tools:
|
|
54
|
+
data["news"] = await self.call_tool("search_tools.news_search", query=f"{indicator} 宏观 经济")
|
|
55
|
+
|
|
56
|
+
# 3. 生成分析
|
|
57
|
+
analysis = {
|
|
58
|
+
"query": query,
|
|
59
|
+
"type": analysis_type,
|
|
60
|
+
"data": data,
|
|
61
|
+
"conclusion": f"基于{query}的分析结论",
|
|
62
|
+
"recommendation": "建议配置...",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return analysis
|
|
66
|
+
|
|
67
|
+
def _classify_query(self, query: str) -> str:
|
|
68
|
+
"""分类查询类型"""
|
|
69
|
+
q = query.lower()
|
|
70
|
+
if any(k in q for k in ["gdp", "增长", "经济"]):
|
|
71
|
+
return "economic_growth"
|
|
72
|
+
elif any(k in q for k in ["通胀", "cpi", "ppi", "物价"]):
|
|
73
|
+
return "inflation"
|
|
74
|
+
elif any(k in q for k in ["利率", "美联储", "央行", "货币政策"]):
|
|
75
|
+
return "monetary_policy"
|
|
76
|
+
elif any(k in q for k in ["汇率", "外汇", "人民币", "美元"]):
|
|
77
|
+
return "fx_rate"
|
|
78
|
+
elif any(k in q for k in ["配置", "资产"]):
|
|
79
|
+
return "asset_allocation"
|
|
80
|
+
else:
|
|
81
|
+
return "general_macro"
|