115 lines
4.2 KiB
Python
115 lines
4.2 KiB
Python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
from typing import Callable
|
|
|
|
|
|
def create_screening_agent(llm: Callable) -> Callable:
|
|
"""
|
|
Creates a screening agent node for the trading graph.
|
|
Identifies potential stocks to analyze using market-wide screening techniques.
|
|
|
|
Args:
|
|
llm: Language model to use for analysis
|
|
|
|
Returns:
|
|
Callable agent node function that processes AgentState
|
|
"""
|
|
|
|
def screening_agent_node(state: dict) -> dict:
|
|
"""
|
|
Screening agent node.
|
|
Scans the market for interesting stock candidates.
|
|
|
|
Args:
|
|
state: Current agent state containing:
|
|
- messages: Conversation history
|
|
- trade_date: Current trading date
|
|
|
|
Returns:
|
|
Updated state with screening recommendations
|
|
"""
|
|
from tradingagents.agents.utils.agent_utils import (
|
|
get_market_movers,
|
|
get_earnings_calendar,
|
|
get_insider_transactions,
|
|
get_indicators,
|
|
get_trending_social,
|
|
)
|
|
|
|
# Tools available to the screening agent
|
|
tools = [
|
|
get_market_movers,
|
|
get_earnings_calendar,
|
|
get_insider_transactions,
|
|
get_indicators,
|
|
get_trending_social,
|
|
]
|
|
|
|
trade_date = state.get("trade_date", "")
|
|
|
|
system_message = (
|
|
f"You are a Market Screening Agent analyzing markets on {trade_date}. "
|
|
"Your goal is to identify 'Hidden Gem' stocks before they make a massive move."
|
|
"\n\n"
|
|
"**Screening Strategy:**"
|
|
"\n"
|
|
"1. **Scan**: Use `get_market_movers` to find 'Most Active' or 'Top Losers' (potential reversals)"
|
|
"\n"
|
|
"2. **Social**: Use `get_trending_social` to find stocks buzzing on social platforms"
|
|
"\n"
|
|
"3. **Catalyst**: Use `get_earnings_calendar` to find upcoming catalysts"
|
|
"\n"
|
|
"4. **Smart Money**: Use `get_insider_transactions` to identify insider buying signals"
|
|
"\n"
|
|
"5. **Technicals**: Use `get_indicators` (RSI, MACD) to check for oversold conditions"
|
|
"\n\n"
|
|
"**Analysis Criteria:**"
|
|
"\n"
|
|
"Look for stocks that are:"
|
|
"\n"
|
|
"- Active but haven't spiked yet"
|
|
"\n"
|
|
"- Beaten down (in losers) with insider buying"
|
|
"\n"
|
|
"- Oversold (RSI < 30) for reversal potential"
|
|
"\n"
|
|
"- With upcoming catalysts (earnings, events)"
|
|
"\n"
|
|
"- With high social media buzz"
|
|
"\n\n"
|
|
"**Deliverable:**"
|
|
"\n"
|
|
"Analyze the market and recommend 1-3 ticker candidates for deeper analysis. "
|
|
"Return candidates as a comma-separated list in the final line (e.g., 'NVDA, TSLA, AAPL')."
|
|
)
|
|
|
|
prompt = ChatPromptTemplate.from_messages(
|
|
[
|
|
(
|
|
"system",
|
|
"You are a helpful AI assistant specialized in market analysis. "
|
|
"You have access to the following tools: {tool_names}.\n{system_message}",
|
|
),
|
|
MessagesPlaceholder(variable_name="messages"),
|
|
]
|
|
)
|
|
|
|
prompt = prompt.partial(system_message=system_message)
|
|
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
|
|
|
|
# Bind tools to the LLM
|
|
chain = prompt | llm.bind_tools(tools)
|
|
|
|
# Initialize messages if needed
|
|
if not state.get("messages"):
|
|
state["messages"] = [("user", "Please screen the market and find interesting stock candidates to analyze.")]
|
|
|
|
# Invoke the chain
|
|
result = chain.invoke(state)
|
|
|
|
# Add screening analysis to state
|
|
return {
|
|
"messages": state["messages"] + [result],
|
|
"screening_report": result.content if hasattr(result, 'content') else str(result),
|
|
}
|
|
|
|
return screening_agent_node |