Upload folder using huggingface_hub
Browse files- Dockerfile +3 -0
- README.md +1 -1
- src/market-analyst/Dockerfile +3 -0
- src/market-analyst/README.md +1 -1
- src/market-analyst/aagents/__init__.py +0 -0
- src/market-analyst/aagents/market_analyst.py +35 -0
- src/market-analyst/aagents/risk_manager.py +25 -0
- src/market-analyst/aagents/sentiment_analyst.py +28 -0
- src/market-analyst/aagents/strategy_advisor.py +40 -0
- src/market-analyst/teams/team.py +15 -8
Dockerfile
CHANGED
|
@@ -28,6 +28,9 @@ COPY src/market-analyst/ ./src/market-analyst/
|
|
| 28 |
RUN uv sync --frozen --no-dev && \
|
| 29 |
uv pip install -e . --system
|
| 30 |
|
|
|
|
|
|
|
|
|
|
| 31 |
# Copy entry point
|
| 32 |
COPY run.py .
|
| 33 |
|
|
|
|
| 28 |
RUN uv sync --frozen --no-dev && \
|
| 29 |
uv pip install -e . --system
|
| 30 |
|
| 31 |
+
# Preload FinBERT model into standard cache directory
|
| 32 |
+
RUN python -c "from transformers import pipeline; pipeline('sentiment-analysis', model='ProsusAI/finbert')"
|
| 33 |
+
|
| 34 |
# Copy entry point
|
| 35 |
COPY run.py .
|
| 36 |
|
README.md
CHANGED
|
@@ -33,7 +33,7 @@ A sophisticated **Multi-Agent System** that performs real-time technical and sen
|
|
| 33 |
```
|
| 34 |
src/market-analyst/
|
| 35 |
├── app.py # Streamlit UI (Orchestrator)
|
| 36 |
-
├──
|
| 37 |
│ ├── market_analyst.py # Technical Analysis Agent
|
| 38 |
│ ├── sentiment_analyst.py# FinBERT Agent
|
| 39 |
│ ├── strategy_advisor.py # Option Strategist
|
|
|
|
| 33 |
```
|
| 34 |
src/market-analyst/
|
| 35 |
├── app.py # Streamlit UI (Orchestrator)
|
| 36 |
+
├── aagents/ # Agent Definitions
|
| 37 |
│ ├── market_analyst.py # Technical Analysis Agent
|
| 38 |
│ ├── sentiment_analyst.py# FinBERT Agent
|
| 39 |
│ ├── strategy_advisor.py # Option Strategist
|
src/market-analyst/Dockerfile
CHANGED
|
@@ -28,6 +28,9 @@ COPY src/market-analyst/ ./src/market-analyst/
|
|
| 28 |
RUN uv sync --frozen --no-dev && \
|
| 29 |
uv pip install -e . --system
|
| 30 |
|
|
|
|
|
|
|
|
|
|
| 31 |
# Copy entry point
|
| 32 |
COPY run.py .
|
| 33 |
|
|
|
|
| 28 |
RUN uv sync --frozen --no-dev && \
|
| 29 |
uv pip install -e . --system
|
| 30 |
|
| 31 |
+
# Preload FinBERT model into standard cache directory
|
| 32 |
+
RUN python -c "from transformers import pipeline; pipeline('sentiment-analysis', model='ProsusAI/finbert')"
|
| 33 |
+
|
| 34 |
# Copy entry point
|
| 35 |
COPY run.py .
|
| 36 |
|
src/market-analyst/README.md
CHANGED
|
@@ -33,7 +33,7 @@ A sophisticated **Multi-Agent System** that performs real-time technical and sen
|
|
| 33 |
```
|
| 34 |
src/market-analyst/
|
| 35 |
├── app.py # Streamlit UI (Orchestrator)
|
| 36 |
-
├──
|
| 37 |
│ ├── market_analyst.py # Technical Analysis Agent
|
| 38 |
│ ├── sentiment_analyst.py# FinBERT Agent
|
| 39 |
│ ├── strategy_advisor.py # Option Strategist
|
|
|
|
| 33 |
```
|
| 34 |
src/market-analyst/
|
| 35 |
├── app.py # Streamlit UI (Orchestrator)
|
| 36 |
+
├── aagents/ # Agent Definitions
|
| 37 |
│ ├── market_analyst.py # Technical Analysis Agent
|
| 38 |
│ ├── sentiment_analyst.py# FinBERT Agent
|
| 39 |
│ ├── strategy_advisor.py # Option Strategist
|
src/market-analyst/aagents/__init__.py
ADDED
|
File without changes
|
src/market-analyst/aagents/market_analyst.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from autogen_agentchat.agents import AssistantAgent
|
| 2 |
+
from autogen_core.tools import FunctionTool
|
| 3 |
+
from tools.market_data import get_current_price, get_historical_volatility, get_option_chain_snapshot, get_technical_indicators
|
| 4 |
+
|
| 5 |
+
def get_market_analyst(model_client):
|
| 6 |
+
|
| 7 |
+
# Wrap tools
|
| 8 |
+
price_tool = FunctionTool(get_current_price, description="Get current price of a stock.")
|
| 9 |
+
vol_tool = FunctionTool(get_historical_volatility, description="Get historical volatility and VIX context.")
|
| 10 |
+
chain_tool = FunctionTool(get_option_chain_snapshot, description="Get option chain snapshot for near-term expiry.")
|
| 11 |
+
tech_tool = FunctionTool(get_technical_indicators, description="Calculate SMA (20/50/200) and RSI (14) technical indicators.")
|
| 12 |
+
|
| 13 |
+
return AssistantAgent(
|
| 14 |
+
name="MarketAnalyst",
|
| 15 |
+
model_client=model_client,
|
| 16 |
+
tools=[price_tool, vol_tool, chain_tool, tech_tool],
|
| 17 |
+
system_message="""
|
| 18 |
+
You are a Market Technician.
|
| 19 |
+
1. Fetch Price, Volatility, Option Chain, AND Technical Indicators (SMA, RSI) for the ticker.
|
| 20 |
+
2. Analyze the Trend (Bullish/Bearish/Neutral) based on price action and SMA alignment (Price vs SMA200).
|
| 21 |
+
3. Analyze the Volatility Regime (Low/Normal/High) using HV and VIX.
|
| 22 |
+
4. Analyze Momentum: Check RSI levels (Overbought > 70 / Oversold < 30).
|
| 23 |
+
5. Output a JSON similar to:
|
| 24 |
+
{
|
| 25 |
+
"ticker": "...",
|
| 26 |
+
"price": ...,
|
| 27 |
+
"trend": "...",
|
| 28 |
+
"volatility": "...",
|
| 29 |
+
"rsi_status": "Overbought/Neutral/Oversold",
|
| 30 |
+
"liquidity_check": "Pass/Fail based on option chain availability",
|
| 31 |
+
"notes": "..."
|
| 32 |
+
}
|
| 33 |
+
Do NOT recommend a trade yet. Just analyze the context.
|
| 34 |
+
"""
|
| 35 |
+
)
|
src/market-analyst/aagents/risk_manager.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from autogen_agentchat.agents import AssistantAgent
|
| 2 |
+
|
| 3 |
+
def get_risk_manager(model_client):
|
| 4 |
+
|
| 5 |
+
return AssistantAgent(
|
| 6 |
+
name="RiskManager",
|
| 7 |
+
model_client=model_client,
|
| 8 |
+
system_message="""
|
| 9 |
+
You are the Chief Risk Officer.
|
| 10 |
+
1. Review the proposed strategy and confidence score.
|
| 11 |
+
2. STRICT RULE: If confidence < 70, reject the trade and recommend "WAIT".
|
| 12 |
+
3. Validate the score calculation against the Rubric (Start 50 + Trend/Vol/Sentiment addons).
|
| 13 |
+
4. Event Risk Check: If Earnings/CPI imminent, override and recommend "WAIT".
|
| 14 |
+
|
| 15 |
+
Output final JSON:
|
| 16 |
+
{
|
| 17 |
+
"final_decision": "TRADE | WAIT",
|
| 18 |
+
"confidence": ..., // The final validated score
|
| 19 |
+
"actionable_recommendation": "Execute Bull Call Spread... / Stay in Cash",
|
| 20 |
+
"entry_signal": "Net Credit | Net Debit",
|
| 21 |
+
"entry_price": 1.50,
|
| 22 |
+
"risk_warning": "..."
|
| 23 |
+
}
|
| 24 |
+
"""
|
| 25 |
+
)
|
src/market-analyst/aagents/sentiment_analyst.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from autogen_agentchat.agents import AssistantAgent
|
| 2 |
+
from autogen_core.tools import FunctionTool
|
| 3 |
+
from tools.news_data import search_news
|
| 4 |
+
|
| 5 |
+
def get_sentiment_analyst(model_client):
|
| 6 |
+
|
| 7 |
+
news_tool = FunctionTool(search_news, description="Search for recent news about the ticker.")
|
| 8 |
+
|
| 9 |
+
return AssistantAgent(
|
| 10 |
+
name="SentimentAnalyst",
|
| 11 |
+
model_client=model_client,
|
| 12 |
+
tools=[news_tool],
|
| 13 |
+
system_message="""
|
| 14 |
+
You are a Sentiment Analyst.
|
| 15 |
+
1. Search for recent news. The results now include **FinBERT Sentiment Scores** (e.g. [FinBERT: positive (0.95)]).
|
| 16 |
+
2. Aggregate these FinBERT scores to determine the overall sentiment (Bullish/Bearish/Neutral).
|
| 17 |
+
3. Assign a 'Sentiment Confidence' score based on the FinBERT probability scores.
|
| 18 |
+
- If multiple articles have >0.90 positive/negative, confidence is HIGH.
|
| 19 |
+
- If signals are mixed or low probability, confidence is LOW/MEDIUM.
|
| 20 |
+
4. Output JSON:
|
| 21 |
+
{
|
| 22 |
+
"sentiment": "...",
|
| 23 |
+
"confidence": "...",
|
| 24 |
+
"key_events": ["..."],
|
| 25 |
+
"risk_factors": ["..."]
|
| 26 |
+
}
|
| 27 |
+
"""
|
| 28 |
+
)
|
src/market-analyst/aagents/strategy_advisor.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from autogen_agentchat.agents import AssistantAgent
|
| 2 |
+
|
| 3 |
+
def get_strategy_advisor(model_client):
|
| 4 |
+
|
| 5 |
+
return AssistantAgent(
|
| 6 |
+
name="StrategyAdvisor",
|
| 7 |
+
model_client=model_client,
|
| 8 |
+
system_message="""
|
| 9 |
+
You are an Option Strategist.
|
| 10 |
+
1. Review the Market Analysis (Trend, Volatility, Option Chain) and Sentiment Analysis.
|
| 11 |
+
2. Select a specific strategy with EXPLICIT STRIKES and EXPIRY from the provided option chain.
|
| 12 |
+
|
| 13 |
+
RULES:
|
| 14 |
+
- HIGH Volatility + Range Bound -> Iron Condor (Credit)
|
| 15 |
+
- HIGH Volatility + Directional -> Credit Spread (Bull Put / Bear Call)
|
| 16 |
+
- LOW Volatility + Directional -> Debit Spread (Bull Call / Bear Put)
|
| 17 |
+
- LOW Volatility + Range Bound -> Calendar Spread (or WAIT)
|
| 18 |
+
|
| 19 |
+
CONFIDENCE SCORE RUBRIC (Start at 50):
|
| 20 |
+
1. Technical Trend Aligns with Strategy (Price vs SMA200): +20
|
| 21 |
+
2. Volatility Regime Aligns (e.g. High Vol/VIX > 20 for Credit): +10
|
| 22 |
+
3. Sentiment Analysis is Confirming (Same direction): +10
|
| 23 |
+
4. Technical Momentum Confluence (RSI isn't fighting the trade): +10
|
| 24 |
+
5. Option Liquidity is Sufficient: +10
|
| 25 |
+
6. Conflicting Signals (Trend vs Sentiment mismatch): -20
|
| 26 |
+
|
| 27 |
+
CALCULATE the score explicitly based on this rubric.
|
| 28 |
+
- Target > 70% confidence for a trade recommendation.
|
| 29 |
+
|
| 30 |
+
Output JSON:
|
| 31 |
+
{
|
| 32 |
+
"strategy": "Bull Call Spread | Iron Condor | WAIT",
|
| 33 |
+
"confidence_score": 95, // Integer 0-100
|
| 34 |
+
"reasoning": "...",
|
| 35 |
+
"proposed_legs": "Buy 100 Call, Sell 105 Call (Exp: 2024-XX-XX)", // MUST use actual strikes from chain
|
| 36 |
+
"entry_signal": "Net Credit | Net Debit",
|
| 37 |
+
"estimated_entry_price": 1.50 // Midpoint estimate of the spread
|
| 38 |
+
}
|
| 39 |
+
"""
|
| 40 |
+
)
|
src/market-analyst/teams/team.py
CHANGED
|
@@ -16,16 +16,23 @@ from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermi
|
|
| 16 |
# Import agents
|
| 17 |
# Adjust imports to work whether called from here or app.py
|
| 18 |
try:
|
| 19 |
-
from ..
|
| 20 |
-
from ..
|
| 21 |
-
from ..
|
| 22 |
-
from ..
|
| 23 |
except ImportError:
|
| 24 |
# Fallback if running from proper package context
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
def get_trading_team(model_client):
|
| 31 |
"""
|
|
|
|
| 16 |
# Import agents
|
| 17 |
# Adjust imports to work whether called from here or app.py
|
| 18 |
try:
|
| 19 |
+
from ..aagents.market_analyst import get_market_analyst
|
| 20 |
+
from ..aagents.sentiment_analyst import get_sentiment_analyst
|
| 21 |
+
from ..aagents.strategy_advisor import get_strategy_advisor
|
| 22 |
+
from ..aagents.risk_manager import get_risk_manager
|
| 23 |
except ImportError:
|
| 24 |
# Fallback if running from proper package context
|
| 25 |
+
try:
|
| 26 |
+
from aagents.market_analyst import get_market_analyst
|
| 27 |
+
from aagents.sentiment_analyst import get_sentiment_analyst
|
| 28 |
+
from aagents.strategy_advisor import get_strategy_advisor
|
| 29 |
+
from aagents.risk_manager import get_risk_manager
|
| 30 |
+
except ImportError:
|
| 31 |
+
# Try absolute (if market-analyst is in path but not as package)
|
| 32 |
+
from src.market_analyst.aagents.market_analyst import get_market_analyst
|
| 33 |
+
from src.market_analyst.aagents.sentiment_analyst import get_sentiment_analyst
|
| 34 |
+
from src.market_analyst.aagents.strategy_advisor import get_strategy_advisor
|
| 35 |
+
from src.market_analyst.aagents.risk_manager import get_risk_manager
|
| 36 |
|
| 37 |
def get_trading_team(model_client):
|
| 38 |
"""
|