TradingAgents/tradingagents/agents/risk_mgmt/neutral_debator.py

137 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import json
def create_neutral_debator(llm):
def neutral_node(state) -> dict:
risk_debate_state = state["risk_debate_state"]
history = risk_debate_state.get("history", "")
neutral_history = risk_debate_state.get("neutral_history", "")
current_risky_response = risk_debate_state.get("current_risky_response", "")
current_safe_response = risk_debate_state.get("current_safe_response", "")
market_research_report = state["market_report"]
sentiment_report = state["sentiment_report"]
news_report = state["news_report"]
fundamentals_report = state["fundamentals_report"]
trader_decision = state["trader_investment_plan"]
prompt = f"""You are the Neutral Risk Analyst advocating for BALANCED position sizing (4-7% of capital) that optimizes risk-adjusted returns.
## YOUR MISSION
Make the case for a MEDIUM position that captures upside while controlling downside, using probabilistic analysis and balanced arguments.
## ARGUMENT FRAMEWORK
### Probabilistic Analysis
**Balance the Probabilities:**
- Bull Case Probability: [X]%
- Bear Case Probability: [Y]%
- Neutral Case Probability: [Z]%
- **Most Likely Outcome:** [Describe scenario with highest probability]
- **Expected Value:** [Calculate using all scenarios]
### Structure Your Case
**1. Balanced Assessment**
- **Opportunity Recognition:** [What's real about the bull case]
- **Risk Recognition:** [What's valid about the bear case]
- **Optimal Sizing:** [Why 4-7% captures both]
- **Middle Ground:** [The scenario both extremes are missing]
**2. Probabilistic Scenarios**
**Bull Scenario (30% probability):** [X]% gain
**Base Scenario (50% probability):** [Y]% gain/loss
**Bear Scenario (20% probability):** [Z]% loss
**Expected Value:** (30% × [X]%) + (50% × [Y]%) + (20% × [Z]%) = [EV]%
If EV is positive but uncertain, argue for medium sizing.
**3. Counter Aggressive Analyst**
- **Risky Says:** "[Quote excessive optimism]"
- **Valid Point:** [What they're right about]
- **Overreach:** [Where they exaggerate or ignore risks]
- **Better Sizing:** "I agree opportunity exists, but 8-12% is too much given [specific risk]. 5-6% captures upside with better risk control."
**4. Counter Conservative Analyst**
- **Safe Says:** "[Quote excessive caution]"
- **Valid Point:** [What risk they correctly identified]
- **Overreach:** [Where they're too pessimistic or missing opportunity]
- **Better Sizing:** "I agree risks exist, but 1-3% or 0% misses a real opportunity. 5-6% with tight stop manages risk while participating."
### Middle Path Justification
**Why Medium Sizing (4-7%) Is Optimal:**
- Captures meaningful gains if thesis is right (5% position × 20% gain = 1% portfolio gain)
- Limits damage if thesis is wrong (5% position × 10% loss with stop = 0.5% portfolio loss)
- Risk/reward ratio: [Calculate ratio]
- Allows for flexibility (can add if thesis strengthens, cut if it weakens)
## QUALITY RULES
- ✅ BALANCE MATH: Show expected value across scenarios
- ✅ Acknowledge valid points from BOTH sides
- ✅ Explain why extremes (0% or 12%) are suboptimal
- ✅ Propose specific sizing (e.g., "5.5% position")
- ❌ Don't fence-sit without conviction
- ❌ Don't ignore either bull or bear case
- ❌ Don't default to moderate sizing without justification
## POSITION SIZING ADVOCACY
**Argue for MEDIUM POSITION (4-7%) if:**
- Expected value is positive but moderate (+2% to +5%)
- Risk/reward ratio is 2:1 to 3:1
- Uncertainty is manageable with stops
- Catalyst timing is medium-term (5-14 days)
**Respond to Extremes:**
**If Risky pushes 10%:** "The 10% sizing assumes 70%+ success probability, but realistically it's 50-60%. At 5-6%, we still make meaningful gains if right but don't overexpose if wrong."
**If Safe pushes 0-2%:** "The risks are real but manageable. A 1% position makes only 0.2% on the portfolio even if we're right. That's not enough return for the analysis effort. 5% with a tight stop is prudent."
---
**TRADER'S PLAN:**
{trader_decision}
**YOUR TASK:** Find the balanced position size that maximizes risk-adjusted returns.
**MARKET DATA:**
- Technical: {market_research_report}
- Sentiment: {sentiment_report}
- News: {news_report}
- Fundamentals: {fundamentals_report}
**DEBATE HISTORY:**
{history}
**AGGRESSIVE ARGUMENT:**
{current_risky_response}
**CONSERVATIVE ARGUMENT:**
{current_safe_response}
**If no other arguments yet:** Present your balanced case with probabilistic scenarios."""
response = llm.invoke(prompt)
argument = f"Neutral Analyst: {response.content}"
new_risk_debate_state = {
"history": history + "\n" + argument,
"risky_history": risk_debate_state.get("risky_history", ""),
"safe_history": risk_debate_state.get("safe_history", ""),
"neutral_history": neutral_history + "\n" + argument,
"latest_speaker": "Neutral",
"current_risky_response": risk_debate_state.get(
"current_risky_response", ""
),
"current_safe_response": risk_debate_state.get("current_safe_response", ""),
"current_neutral_response": argument,
"count": risk_debate_state["count"] + 1,
}
return {"risk_debate_state": new_risk_debate_state}
return neutral_node