TRADER_SYSTEM = """You are a professional crypto trading agent. Your job is to analyze market data and make a single trading decision. Rules: - You MUST respond with ONLY a JSON object, no markdown, no explanation outside the JSON. - action must be exactly one of: BUY, SELL, HOLD - size is the fraction of available capital to use (0.0 to 1.0) - confidence is your confidence level (0.0 to 1.0) - reason is a brief explanation (max 100 words) Response format (strict JSON): {"action": "BUY|SELL|HOLD", "size": 0.5, "confidence": 0.7, "reason": "..."}""" TECHNICAL_ANALYST_SYSTEM = """You are a technical analysis expert for crypto markets. Analyze the provided OHLCV data and technical indicators. Provide a structured technical analysis in JSON format: {"signal": "BULLISH|BEARISH|NEUTRAL", "strength": 0.0, "key_levels": {"support": 0.0, "resistance": 0.0}, "summary": "..."} Respond ONLY with the JSON object.""" NEWS_ANALYST_SYSTEM = """You are a crypto news sentiment analyst. Analyze the provided news headlines and assess market sentiment. Respond ONLY with a JSON object: {"sentiment": "POSITIVE|NEGATIVE|NEUTRAL", "score": 0.0, "key_themes": ["theme1"], "summary": "..."} score ranges from -1.0 (very negative) to 1.0 (very positive).""" SENTIMENT_ANALYST_SYSTEM = """You are a crypto market sentiment analyst specializing in on-chain data and market psychology. Analyze the provided Fear & Greed index, funding rates, and other sentiment indicators. Respond ONLY with a JSON object: {"sentiment": "EXTREME_FEAR|FEAR|NEUTRAL|GREED|EXTREME_GREED", "score": 0.0, "funding_bias": "LONG|SHORT|NEUTRAL", "summary": "..."}""" RESEARCHER_SYSTEM = """You are a senior crypto research analyst moderating a bull vs bear debate. You receive analyses from multiple analysts and must synthesize them into a final research note. Consider both bullish and bearish arguments objectively. Identify the strongest signals. Respond ONLY with a JSON object: {"verdict": "BULLISH|BEARISH|NEUTRAL", "conviction": 0.0, "bull_points": ["..."], "bear_points": ["..."], "synthesis": "..."} conviction ranges from 0.0 to 1.0.""" RISK_MANAGER_SYSTEM = """You are a crypto portfolio risk manager. You receive a trading recommendation and must validate it against risk constraints. Risk rules: - Max position size: 80% of capital - If drawdown > 20%, reduce position sizes by 50% - Do not override HOLD decisions with BUY unless conviction > 0.6 Respond ONLY with a JSON object: {"approved": true, "adjusted_action": "BUY|SELL|HOLD", "adjusted_size": 0.5, "risk_note": "..."}""" def build_trader_prompt_A(market_data: dict) -> str: """Benchmark A: single agent sees price + indicators directly.""" asset = market_data.get("asset", "BTC/USDT") price = market_data.get("current_price", 0) ohlcv = market_data.get("recent_ohlcv", []) indicators = market_data.get("indicators", {}) portfolio = market_data.get("portfolio", {}) ohlcv_text = "" if ohlcv: ohlcv_text = "\nRecent OHLCV (last 7 days):\n" for row in ohlcv[-7:]: ohlcv_text += f" {row['date']}: O={row['open']:.2f} H={row['high']:.2f} L={row['low']:.2f} C={row['close']:.2f} V={row['volume']:.0f}\n" ind_text = "" if indicators: ind_text = f""" Technical Indicators: RSI(14): {indicators.get('rsi', 'N/A')} MA(20): {indicators.get('ma20', 'N/A')} MA(50): {indicators.get('ma50', 'N/A')} MACD: {indicators.get('macd', 'N/A')} MACD Signal: {indicators.get('macd_signal', 'N/A')} MACD Hist: {indicators.get('macd_hist', 'N/A')} Bollinger Upper: {indicators.get('bb_upper', 'N/A')} Bollinger Lower: {indicators.get('bb_lower', 'N/A')}""" port_text = f""" Portfolio Status: Cash: ${portfolio.get('cash', 0):.2f} Position: {portfolio.get('position', 0):.6f} {asset.split('/')[0]} Total Value: ${portfolio.get('total_value', 0):.2f}""" return f"""Asset: {asset} Current Price: ${price:.2f} {ohlcv_text}{ind_text}{port_text} Based on this data, make your trading decision.""" def build_technical_analyst_prompt(market_data: dict) -> str: asset = market_data.get("asset", "BTC/USDT") price = market_data.get("current_price", 0) ohlcv = market_data.get("recent_ohlcv", []) indicators = market_data.get("indicators", {}) ohlcv_text = "" if ohlcv: ohlcv_text = "\nRecent OHLCV (last 14 days):\n" for row in ohlcv[-14:]: ohlcv_text += f" {row['date']}: O={row['open']:.2f} H={row['high']:.2f} L={row['low']:.2f} C={row['close']:.2f} V={row['volume']:.0f}\n" ind_text = f""" Indicators: RSI(14): {indicators.get('rsi', 'N/A')} MA(20): {indicators.get('ma20', 'N/A')} | MA(50): {indicators.get('ma50', 'N/A')} MACD: {indicators.get('macd', 'N/A')} | Signal: {indicators.get('macd_signal', 'N/A')} BB Upper: {indicators.get('bb_upper', 'N/A')} | BB Lower: {indicators.get('bb_lower', 'N/A')}""" return f"Asset: {asset}\nCurrent Price: ${price:.2f}\n{ohlcv_text}{ind_text}\n\nProvide your technical analysis." def build_news_analyst_prompt(news_items: list, asset: str) -> str: if not news_items: return f"No news available for {asset}. Respond with neutral sentiment." headlines = "\n".join(f"- {item.get('title', '')}" for item in news_items[:10]) return f"Asset: {asset}\n\nRecent news headlines:\n{headlines}\n\nAnalyze the sentiment." def build_sentiment_analyst_prompt(onchain_data: dict, asset: str) -> str: fng = onchain_data.get("fear_greed", {}) funding = onchain_data.get("funding_rate", None) return f"""Asset: {asset} Fear & Greed Index: {fng.get('value', 'N/A')} ({fng.get('label', 'N/A')}) Funding Rate: {f'{funding:.4f}%' if funding is not None else 'N/A'} Analyze the market sentiment.""" def build_researcher_prompt(tech_analysis: dict, news_analysis: dict, sentiment_analysis: dict, asset: str) -> str: return f"""Asset: {asset} Technical Analysis: {tech_analysis} News Analysis: {news_analysis} Sentiment Analysis: {sentiment_analysis} Synthesize these analyses into a final research verdict.""" def build_risk_manager_prompt(recommendation: dict, portfolio: dict) -> str: return f"""Trading Recommendation: {recommendation} Portfolio Status: Cash: ${portfolio.get('cash', 0):.2f} Position: {portfolio.get('position', 0):.6f} Total Value: ${portfolio.get('total_value', 0):.2f} Current Drawdown: {portfolio.get('drawdown', 0):.1%} Validate this recommendation against risk constraints.""" def build_trader_prompt_B(tech_analysis: dict, news_analysis: dict, portfolio: dict, asset: str, price: float) -> str: return f"""Asset: {asset} Current Price: ${price:.2f} Technical Analysis Summary: {tech_analysis.get('summary', 'N/A')} (Signal: {tech_analysis.get('signal', 'N/A')}) News Sentiment Summary: {news_analysis.get('summary', 'N/A')} (Sentiment: {news_analysis.get('sentiment', 'N/A')}, Score: {news_analysis.get('score', 0):.2f}) Portfolio: Cash: ${portfolio.get('cash', 0):.2f} Total Value: ${portfolio.get('total_value', 0):.2f} Make your trading decision based on the analyses above.""" def build_trader_prompt_C(research: dict, risk_decision: dict, portfolio: dict, asset: str, price: float) -> str: return f"""Asset: {asset} Current Price: ${price:.2f} Research Verdict: {research.get('verdict', 'N/A')} (Conviction: {research.get('conviction', 0):.2f}) Research Synthesis: {research.get('synthesis', 'N/A')} Risk Manager Assessment: {risk_decision.get('risk_note', 'N/A')} Risk-Adjusted Action: {risk_decision.get('adjusted_action', 'HOLD')} (size: {risk_decision.get('adjusted_size', 0)}) Portfolio: Cash: ${portfolio.get('cash', 0):.2f} Total Value: ${portfolio.get('total_value', 0):.2f} Make your final trading decision."""