FenixAI employs a multi-agent architecture where specialized AI agents collaborate to analyze cryptocurrency markets. Each agent is an expert in a specific domain, and their outputs are combined through a weighted consensus mechanism.
┌─────────────────────────────┐
│ LangGraph Orchestrator │
│ (State Machine) │
└─────────────┬───────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Technical │ │ Visual │ │ Sentiment │
│ Agent │ │ Agent │ │ Agent │
│ (30% weight) │ │ (25% weight) │ │ (15% weight) │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
┌───────────▼───────────┐
│ QABBA Agent │
│ (30% weight) │
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ Decision Agent │
│ (Weighted Consensus) │
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ Risk Manager │
│ (Final Approval) │
└───────────────────────┘
File: src/agents/enhanced_technical_analyst.py
Analyzes market structure, technical indicators, and price patterns to generate trading signals.
- Indicator Analysis: RSI, MACD, ADX, ATR, Bollinger Bands
- Market Structure: Trend detection, support/resistance levels
- Multi-timeframe: Analyzes multiple timeframes for confluence
- Validation: Checks indicator consistency before signaling
{
"kline_data": {"open": [...], "high": [...], "low": [...], "close": [...], "volume": [...]},
"indicators": {"rsi": 45.2, "macd": {...}, "adx": 28.5, ...},
"mtf_context": {"15m": {...}, "1h": {...}, "4h": {...}}
}{
"signal": "BUY" | "SELL" | "HOLD",
"confidence": 0.75, # 0.0 - 1.0
"reasoning": "RSI showing oversold conditions with bullish divergence...",
"confluence_score": 0.68,
"entry_price": 42150.0,
"stop_loss": 41800.0,
"take_profit": 43200.0,
"risk_reward_ratio": 2.5
}# config/fenix.yaml
agents:
technical_weight: 0.30
enable_technical: trueFile: src/agents/visual_analyst_enhanced.py
Analyzes TradingView chart screenshots to identify visual patterns that may not be captured by numerical indicators.
- Pattern Recognition: Head & Shoulders, triangles, flags, wedges
- Candlestick Analysis: Doji, engulfing, hammer, shooting star
- Trend Analysis: Visual trend lines, channels
- Indicator Reading: Interprets SuperTrend, SAR points from chart
- Security: Validates chart paths to prevent stale data analysis
{
"chart_path": "/path/to/BTCUSDT_15m_chart.png",
"symbol": "BTCUSDT",
"timeframe": "15m"
}{
"action": "BUY" | "SELL" | "HOLD",
"confidence": 0.72,
"reason": "Bullish engulfing pattern at key support level...",
"key_candlestick_patterns": ["bullish_engulfing", "morning_star"],
"chart_patterns": ["ascending_triangle"],
"trend_analysis": {"direction": "BULLISH", "strength": 0.7},
"support_resistance_levels": {"support": [41500, 41000], "resistance": [43000, 44500]},
"next_candle_prediction": {"direction": "UP", "probability": 0.65}
}- Vision-capable LLM (qwen3-vl:8b or similar)
- TradingView chart screenshots via Playwright
File: src/agents/sentiment_enhanced.py
Analyzes news articles, social media, and market sentiment to gauge market psychology.
- News Analysis: Crypto news from multiple sources
- Social Sentiment: Twitter/X, Reddit analysis
- Fear & Greed: Interprets market sentiment indices
- Event Detection: Identifies market-moving events
{
"news_data": [
{"title": "Bitcoin ETF sees record inflows", "source": "coindesk", "sentiment": "positive"},
...
],
"social_data": {"twitter": {...}, "reddit": {...}},
"fear_greed_index": 65
}{
"sentiment": "POSITIVE" | "NEGATIVE" | "NEUTRAL",
"confidence": 0.68,
"reasoning": "Multiple positive news about ETF inflows...",
"key_events": ["ETF inflows record", "whale accumulation"],
"social_sentiment_score": 0.72
}File: src/agents/enhanced_qabba_agent.py
Specialized quantitative agent focusing on Bollinger Bands, volatility analysis, and squeeze detection.
- Bollinger Band Analysis: Position, width, squeeze
- Volatility Assessment: ATR-based volatility scoring
- Breakout Probability: Predicts potential breakouts
- Quality Assurance: Validates other agents' outputs
{
"qabba_signal": "BUY_QABBA" | "SELL_QABBA" | "HOLD_QABBA" | "NEUTRAL_QABBA",
"qabba_confidence": 0.78,
"bb_position": "lower" | "middle" | "upper",
"squeeze_detection": true,
"breakout_probability": 0.65,
"volatility_state": "LOW" | "MEDIUM" | "HIGH"
}File: src/agents/decision.py
Aggregates all agent outputs using dynamic weighting to make the final trading decision.
Weights are adjusted based on:
- Historical Performance: Agents with higher accuracy get more weight
- Market Conditions: Different weights for trending vs. ranging markets
- Confidence Scores: Higher confidence increases influence
# Default weights
weights = {
'technical': 0.30,
'qabba': 0.30,
'visual': 0.25,
'sentiment': 0.15
}
# Market condition adjustments
market_adjustments = {
'high_volatility': {'sentiment': 0.8, 'technical': 1.2, 'visual': 1.1},
'trending': {'sentiment': 0.9, 'technical': 1.3, 'visual': 1.2},
'ranging': {'sentiment': 1.1, 'technical': 0.9, 'qabba': 1.2}
}{
"final_action": "BUY" | "SELL" | "HOLD",
"final_confidence": 0.72,
"weighted_scores": {"BUY": 0.65, "SELL": 0.15, "HOLD": 0.20},
"agent_contributions": {
"technical": {"action": "BUY", "weight": 0.30, "confidence": 0.75},
"visual": {"action": "BUY", "weight": 0.25, "confidence": 0.70},
...
},
"consensus_reasoning": "Strong bullish signals across multiple agents..."
}FenixAI supports multiple provider profiles configured in config/llm_providers.yaml. To use the Groq free profile set the environment variable or the active_profile to groq_free.
Recommended free Groq models (examples):
llama-3.3-70b-versatile— High-throughput Llama 3 model for text reasoning.meta-llama/llama-4-scout-17b-16e-instruct— Current Groq multimodal (vision) option.mixtral-8x7b-32768— Efficient model available in some Groq tiers.
TIP: To use the groq_free profile set the GROQ_API_KEY environment variable and restart the API.
Example .env entries:
GROQ_API_KEY=gsk_...
LLM_PROFILE=groq_free
Fallback behavior: If a specific provider package (e.g., langchain_groq) is missing on the machine, the loader will attempt to fall back to the configured fallback_provider_type (e.g., ollama_local). If fallback fails too and LLM_ALLOW_NOOP_STUB=1 (development), the system initializes a no-op stub LLM to keep the graph alive for testing.
File: src/agents/risk.py
Final gatekeeper that can veto any trade that exceeds risk parameters.
| Control | Description |
|---|---|
| Max Risk per Trade | Maximum 2% of portfolio per trade |
| Max Total Exposure | Maximum 5% total open positions |
| Circuit Breaker | Stops trading after X consecutive losses |
| Daily Loss Limit | Halts trading if daily loss exceeds threshold |
| Position Sizing | Dynamic sizing based on volatility |
{
"approved": true | false,
"risk_score": 0.35, # 0.0 (safe) - 1.0 (max risk)
"position_size": 0.01, # BTC
"stop_loss": 41800.0,
"take_profit": 43200.0,
"rejection_reason": null | "Exceeds max daily loss"
}File: src/inference/reasoning_judge.py
After each decision, an LLM evaluates the quality of the reasoning:
{
"verdict": "SOUND" | "QUESTIONABLE" | "POOR",
"score": 0.82,
"confidence": 0.75,
"critique": "Decision well-supported by technical confluence...",
"risks": ["High leverage in volatile market"],
"improvements": ["Consider adding volume confirmation"]
}All agents can be enabled/disabled and weighted via config/fenix.yaml:
agents:
# Enable/disable agents
enable_technical: true
enable_qabba: true
enable_visual: false # Requires vision model
enable_sentiment: false # Requires news APIs
# Agent weights (must sum to 1.0)
technical_weight: 0.30
qabba_weight: 0.30
visual_weight: 0.25
sentiment_weight: 0.15
# Decision thresholds
consensus_threshold: 0.65
min_confidence_to_trade: MEDIUMTo add a new agent:
- Create agent file in
src/agents/:
class CustomAgent(EnhancedBaseLLMAgent, LLMProviderMixin):
name = "CustomAgent"
role = "Custom Analysis Specialist"
async def analyze(self, data: dict) -> CustomOutput:
# Implement analysis logic
pass- Register in
src/core/langgraph_orchestrator.py:
# Add node to graph
graph.add_node("custom_agent", self._custom_agent_node)
graph.add_edge("previous_node", "custom_agent")- Add configuration in
config/fenix.yaml:
agents:
enable_custom: true
custom_weight: 0.20See also:
- ARCHITECTURE.md - System architecture
- API.md - REST API reference