50939212be
Signed-off-by: TIANHE <TIANHE@GMAIL.COM>
205 lines
7.9 KiB
Python
205 lines
7.9 KiB
Python
"""
|
|
Researcher agents.
|
|
Includes: bull researcher and bear researcher.
|
|
"""
|
|
import json
|
|
from typing import Dict, Any
|
|
from .base_agent import BaseAgent
|
|
from app.services.llm import LLMService
|
|
|
|
logger = __import__('app.utils.logger', fromlist=['get_logger']).get_logger(__name__)
|
|
|
|
|
|
class BullResearcher(BaseAgent):
|
|
"""Bullish researcher."""
|
|
|
|
def __init__(self, memory=None):
|
|
super().__init__("BullResearcher", memory)
|
|
self.llm_service = LLMService()
|
|
|
|
def analyze(self, context: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Construct the bull case."""
|
|
market = context.get('market')
|
|
symbol = context.get('symbol')
|
|
language = context.get('language', 'zh-CN')
|
|
model = context.get('model')
|
|
|
|
# Inputs
|
|
market_report = context.get('market_report', {})
|
|
fundamental_report = context.get('fundamental_report', {})
|
|
news_report = context.get('news_report', {})
|
|
sentiment_report = context.get('sentiment_report', {})
|
|
|
|
# Memory
|
|
situation = f"{market}:{symbol} bull case"
|
|
memory_meta = {
|
|
"market": market,
|
|
"symbol": symbol,
|
|
"timeframe": context.get("timeframe"),
|
|
"features": context.get("memory_features") or {},
|
|
}
|
|
memories = self.get_memories(situation, n_matches=None, metadata=memory_meta)
|
|
memory_prompt = self.format_memories_for_prompt(memories)
|
|
|
|
lang_instruction = self._get_language_instruction(language)
|
|
system_prompt = f"""You are a Bullish Analyst, constructing a bullish argument for an investment decision. Your tasks are:
|
|
{lang_instruction}
|
|
1. Highlight growth potential, competitive advantages, and positive market indicators.
|
|
2. Use the provided research and data to build a strong argument.
|
|
3. Effectively address/counter bearish viewpoints.
|
|
4. Learn from historical experience: {memory_prompt}
|
|
5. **Confidence Score**: Evaluate your confidence in the bullish case (0-100). Be realistic. If the data is mixed or weak, lower your confidence. Do NOT default to 75.
|
|
|
|
Please return in JSON format as follows:
|
|
{{
|
|
"argument": "Detailed bullish argument...",
|
|
"key_points": ["Point 1", "Point 2", "Point 3"],
|
|
"confidence": 75
|
|
}}"""
|
|
|
|
user_prompt = f"""Based on the following analysis reports, construct a bullish argument for {symbol} in {market} market:
|
|
|
|
**Market Technical Analysis:**
|
|
{json.dumps(market_report.get('data', {}), ensure_ascii=False, indent=2) if market_report else 'No Data'}
|
|
|
|
**Fundamental Analysis:**
|
|
{json.dumps(fundamental_report.get('data', {}), ensure_ascii=False, indent=2) if fundamental_report else 'No Data'}
|
|
|
|
**News Analysis:**
|
|
{json.dumps(news_report.get('data', {}), ensure_ascii=False, indent=2) if news_report else 'No Data'}
|
|
|
|
**Sentiment Analysis:**
|
|
{json.dumps(sentiment_report.get('data', {}), ensure_ascii=False, indent=2) if sentiment_report else 'No Data'}
|
|
|
|
Please construct a strong bullish argument, emphasizing growth potential, competitive advantages, and positive indicators."""
|
|
|
|
result = self.llm_service.safe_call_llm(
|
|
system_prompt,
|
|
user_prompt,
|
|
{"argument": "", "key_points": [], "confidence": 50},
|
|
model=model
|
|
)
|
|
|
|
return {
|
|
"type": "bull",
|
|
"data": result
|
|
}
|
|
|
|
def _get_language_instruction(self, language: str) -> str:
|
|
language_map = {
|
|
'zh-CN': 'Answer in Simplified Chinese.',
|
|
'zh-TW': 'Answer in Traditional Chinese.',
|
|
'en-US': 'Answer in English.',
|
|
'ja-JP': 'Answer in Japanese.',
|
|
'ko-KR': 'Answer in Korean.',
|
|
'vi-VN': 'Answer in Vietnamese.',
|
|
'th-TH': 'Answer in Thai.',
|
|
'ar-SA': 'Answer in Arabic.',
|
|
'fr-FR': 'Answer in French.',
|
|
'de-DE': 'Answer in German.'
|
|
}
|
|
return language_map.get(language, 'Answer in English.')
|
|
|
|
|
|
class BearResearcher(BaseAgent):
|
|
"""Bearish researcher."""
|
|
|
|
def __init__(self, memory=None):
|
|
super().__init__("BearResearcher", memory)
|
|
self.llm_service = LLMService()
|
|
|
|
def analyze(self, context: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Construct the bear case."""
|
|
market = context.get('market')
|
|
symbol = context.get('symbol')
|
|
language = context.get('language', 'zh-CN')
|
|
model = context.get('model')
|
|
|
|
# Inputs
|
|
market_report = context.get('market_report', {})
|
|
fundamental_report = context.get('fundamental_report', {})
|
|
news_report = context.get('news_report', {})
|
|
sentiment_report = context.get('sentiment_report', {})
|
|
risk_report = context.get('risk_report', {})
|
|
|
|
# Bull argument (if present)
|
|
bull_argument = context.get('bull_argument', '')
|
|
|
|
# Memory
|
|
situation = f"{market}:{symbol} bear case"
|
|
memory_meta = {
|
|
"market": market,
|
|
"symbol": symbol,
|
|
"timeframe": context.get("timeframe"),
|
|
"features": context.get("memory_features") or {},
|
|
}
|
|
memories = self.get_memories(situation, n_matches=None, metadata=memory_meta)
|
|
memory_prompt = self.format_memories_for_prompt(memories)
|
|
|
|
lang_instruction = self._get_language_instruction(language)
|
|
system_prompt = f"""You are a Bearish Analyst, constructing a bearish argument for an investment decision. Your tasks are:
|
|
{lang_instruction}
|
|
1. Identify risks, challenges, and negative indicators.
|
|
2. Use the provided research and data to build a strong argument.
|
|
3. Effectively address/counter bullish viewpoints.
|
|
4. Learn from historical experience: {memory_prompt}
|
|
5. **Confidence Score**: Evaluate your confidence in the bearish case (0-100). Be realistic. If the data is mixed or weak, lower your confidence. Do NOT default to 75.
|
|
|
|
Please return in JSON format as follows:
|
|
{{
|
|
"argument": "Detailed bearish argument...",
|
|
"key_points": ["Point 1", "Point 2", "Point 3"],
|
|
"confidence": 75
|
|
}}"""
|
|
|
|
# Bull argument section (avoid backslashes in f-string expression)
|
|
bull_argument_section = f"**Bullish Argument (Needs Rebuttal):**\n{bull_argument}" if bull_argument else ""
|
|
|
|
user_prompt = f"""Based on the following analysis reports, construct a bearish argument for {symbol} in {market} market:
|
|
|
|
**Market Technical Analysis:**
|
|
{json.dumps(market_report.get('data', {}), ensure_ascii=False, indent=2) if market_report else 'No Data'}
|
|
|
|
**Fundamental Analysis:**
|
|
{json.dumps(fundamental_report.get('data', {}), ensure_ascii=False, indent=2) if fundamental_report else 'No Data'}
|
|
|
|
**News Analysis:**
|
|
{json.dumps(news_report.get('data', {}), ensure_ascii=False, indent=2) if news_report else 'No Data'}
|
|
|
|
**Sentiment Analysis:**
|
|
{json.dumps(sentiment_report.get('data', {}), ensure_ascii=False, indent=2) if sentiment_report else 'No Data'}
|
|
|
|
**Risk Analysis:**
|
|
{json.dumps(risk_report.get('data', {}), ensure_ascii=False, indent=2) if risk_report else 'No Data'}
|
|
|
|
{bull_argument_section}
|
|
|
|
Please construct a strong bearish argument, emphasizing risks, challenges, and negative indicators."""
|
|
|
|
result = self.llm_service.safe_call_llm(
|
|
system_prompt,
|
|
user_prompt,
|
|
{"argument": "", "key_points": [], "confidence": 50},
|
|
model=model
|
|
)
|
|
|
|
return {
|
|
"type": "bear",
|
|
"data": result
|
|
}
|
|
|
|
def _get_language_instruction(self, language: str) -> str:
|
|
language_map = {
|
|
'zh-CN': 'Answer in Simplified Chinese.',
|
|
'zh-TW': 'Answer in Traditional Chinese.',
|
|
'en-US': 'Answer in English.',
|
|
'ja-JP': 'Answer in Japanese.',
|
|
'ko-KR': 'Answer in Korean.',
|
|
'vi-VN': 'Answer in Vietnamese.',
|
|
'th-TH': 'Answer in Thai.',
|
|
'ar-SA': 'Answer in Arabic.',
|
|
'fr-FR': 'Answer in French.',
|
|
'de-DE': 'Answer in German.'
|
|
}
|
|
return language_map.get(language, 'Answer in English.')
|