File size: 7,773 Bytes
68025ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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."""