diff --git a/src/talos/prompts/yield_management_prompt.json b/src/talos/prompts/yield_management_prompt.json index 1273cd46..cda04aa1 100644 --- a/src/talos/prompts/yield_management_prompt.json +++ b/src/talos/prompts/yield_management_prompt.json @@ -1,6 +1,6 @@ { "name": "yield_management", "description": "A prompt for managing the Talos yield.", - "template": "You are an AI-powered treasury manager for the Talos protocol. Your goal is to determine the optimal staking APR to ensure the long-term success of the protocol. You should consider the following data:\n\n* **Price:** {price}\n* **24-hour Change:** {change}\n* **24-hour Volume:** {volume}\n* **Twitter Sentiment:** {sentiment}\n* **Staked Supply Percentage:** {staked_supply_percentage}\n* **OHLCV Data:** {ohlcv_data}\n\nBased on this data, what should the new staking APR be? Please provide your answer as a JSON object with the following structure:\n\n```json\n{{\n \"apr\": ,\n \"explanation\": \"\"\n}}\n```\n\nThe APR should be a value between 0.01 and 0.2. The explanation should be a brief summary of why you chose that APR.", - "input_variables": ["price", "change", "volume", "sentiment", "staked_supply_percentage", "ohlcv_data"] + "template": "You are an AI-powered treasury manager for the Talos protocol. Your goal is to determine the optimal staking APR to ensure the long-term success of the protocol. You should consider the following data:\n\n* **Price:** {price}\n* **24-hour Change:** {change}\n* **24-hour Volume:** {volume}\n* **Relative Performance (T vs ARB):** {relative_performance}%\n* **Twitter Sentiment:** {sentiment}\n* **Staked Supply Percentage:** {staked_supply_percentage}\n* **OHLCV Data:** {ohlcv_data}\n\nBased on this data, what should the new staking APR be? Please provide your answer as a JSON object with the following structure:\n\n```json\n{{\n \"apr\": ,\n \"explanation\": \"\"\n}}\n```\n\nThe APR should be a value between 0.01 and 0.2. The explanation should be a brief summary of why you chose that APR.", + "input_variables": ["price", "change", "volume", "relative_performance", "sentiment", "staked_supply_percentage", "ohlcv_data"] } diff --git a/src/talos/services/implementations/yield_manager.py b/src/talos/services/implementations/yield_manager.py index 5ddd6fde..20813d0d 100644 --- a/src/talos/services/implementations/yield_manager.py +++ b/src/talos/services/implementations/yield_manager.py @@ -29,6 +29,11 @@ def update_staking_apr(self, sentiment: float, sentiment_report: str) -> float: dexscreener_data = self.dexscreener_client.get_talos_data() logging.info(f"Dexscreener data: {dexscreener_data}") + arb_data = self.dexscreener_client.get_arb_data() + logging.info(f"ARB data: {arb_data}") + relative_t_arb_change = round(dexscreener_data.price_change_h24 - arb_data.price_change_h24, 2) + logging.info(f"Relative TALOS to ARB change: {relative_t_arb_change}") + logging.info(f"Social media sentiment: {sentiment}") logging.info(f"Sentiment report: {sentiment_report}") @@ -45,6 +50,7 @@ def update_staking_apr(self, sentiment: float, sentiment_report: str) -> float: price=dexscreener_data.price_usd, change=dexscreener_data.price_change_h24, volume=dexscreener_data.volume_h24, + relative_performance=relative_t_arb_change, sentiment=sentiment, staked_supply_percentage=staked_supply_percentage, ohlcv_data=ohlcv_data.model_dump_json(), diff --git a/src/talos/utils/dexscreener.py b/src/talos/utils/dexscreener.py index 99c5c795..6eb899fb 100644 --- a/src/talos/utils/dexscreener.py +++ b/src/talos/utils/dexscreener.py @@ -5,7 +5,11 @@ class DexscreenerClient: def __init__(self, pair_address: str = "0xdaae914e4bae2aae4f536006c353117b90fb37e3"): + # $T pair address on arbitrum self.pair_address = pair_address + + # ARB pair address on arbitrum + self.arb_pair_address = "0xC6F780497A95e246EB9449f5e4770916DCd6396A" def get_talos_data(self) -> DexscreenerData: """Gets the OHLCV data for a token from dexscreener.com""" @@ -13,7 +17,45 @@ def get_talos_data(self) -> DexscreenerData: response = requests.get(url) response.raise_for_status() data = response.json() - return DexscreenerData.model_validate(data.get("pair", {})) + + # Handle the nested data structure + pair_data = data.get("pair", {}) + + # Extract 24h values from the nested structure + price_change_24h = pair_data.get("priceChange", {}).get("h24", 0.0) + volume_24h = pair_data.get("volume", {}).get("h24", 0.0) + + # Create a modified data structure that matches DexscreenerData + talos_data = { + "priceUsd": pair_data.get("priceUsd", 0.0), + "priceChange": price_change_24h, + "volume": volume_24h + } + + return DexscreenerData.model_validate(talos_data) + + def get_arb_data(self) -> DexscreenerData: + """Gets ETH price data from dexscreener.com""" + url = f"https://api.dexscreener.com/latest/dex/pairs/arbitrum/{self.arb_pair_address}" + response = requests.get(url) + response.raise_for_status() + data = response.json() + + # Handle the different data structure for ARB pair + pair_data = data.get("pair", {}) + + # Extract 24h values from the nested structure + price_change_24h = pair_data.get("priceChange", {}).get("h24", 0.0) + volume_24h = pair_data.get("volume", {}).get("h24", 0.0) + + # Create a modified data structure that matches DexscreenerData + arb_data = { + "priceUsd": pair_data.get("priceUsd", 0.0), + "priceChange": price_change_24h, + "volume": volume_24h + } + + return DexscreenerData.model_validate(arb_data) def get_ohlcv_data(pair_address: str) -> DexscreenerData: diff --git a/tests/test_dexscreener_price_data.py b/tests/test_dexscreener_price_data.py new file mode 100644 index 00000000..eaac9f71 --- /dev/null +++ b/tests/test_dexscreener_price_data.py @@ -0,0 +1,60 @@ +import requests +from talos.utils.dexscreener import DexscreenerClient +from talos.models.dexscreener import DexscreenerData + +def test_arb_data(): + client = DexscreenerClient() + + print("Testing ARB data fetch...") + try: + arb_data = client.get_arb_data() + print(f"✅ ARB Price: ${arb_data.price_usd}") + print(f"✅ ARB 24h Change: {arb_data.price_change_h24}%") + print(f"✅ ARB 24h Volume: ${arb_data.volume_h24:,.0f}") + return arb_data + except Exception as e: + print(f"❌ Error fetching ARB data: {e}") + return None + +def test_talos_data(): + client = DexscreenerClient() + + print("\nTesting TALOS data fetch...") + try: + talos_data = client.get_talos_data() + print(f"✅ TALOS Price: ${talos_data.price_usd}") + print(f"✅ TALOS 24h Change: {talos_data.price_change_h24}%") + print(f"✅ TALOS 24h Volume: ${talos_data.volume_h24:,.0f}") + return talos_data + except Exception as e: + print(f"❌ Error fetching TALOS data: {e}") + return None + +def test_relative_performance(): + client = DexscreenerClient() + + print("\nTesting relative performance calculation...") + try: + talos_data = client.get_talos_data() + arb_data = client.get_arb_data() + + relative_performance = round(talos_data.price_change_h24 - arb_data.price_change_h24, 2) + + print(f"✅ TALOS 24h Change: {talos_data.price_change_h24}%") + print(f"✅ ARB 24h Change: {arb_data.price_change_h24}%") + print(f"✅ Relative Performance (T vs ARB): {relative_performance}%") + + if relative_performance > 0: + print(f"✅ TALOS is outperforming ARB by {relative_performance}%") + else: + print(f"✅ TALOS is underperforming ARB by {abs(relative_performance)}%") + + return relative_performance + except Exception as e: + print(f"❌ Error calculating relative performance: {e}") + return None + +if __name__ == "__main__": + test_arb_data() + test_talos_data() + test_relative_performance() \ No newline at end of file diff --git a/tests/test_prompt_formatting.py b/tests/test_prompt_formatting.py new file mode 100644 index 00000000..8f6bad57 --- /dev/null +++ b/tests/test_prompt_formatting.py @@ -0,0 +1,60 @@ +def test_prompt_formatting(): + print("Testing prompt formatting with real Dexscreener data...") + try: + # Import the prompt manager and get the prompt + from talos.prompts.prompt_managers.file_prompt_manager import FilePromptManager + from talos.utils.dexscreener import DexscreenerClient + + prompt_manager = FilePromptManager("src/talos/prompts") + prompt = prompt_manager.get_prompt("yield_management") + + if not prompt: + print("❌ Prompt not found") + return False + + # Get real data from Dexscreener + client = DexscreenerClient() + talos_data = client.get_talos_data() + arb_data = client.get_arb_data() + + # Calculate relative performance + relative_performance = round(talos_data.price_change_h24 - arb_data.price_change_h24, 2) + + print(f"✅ TALOS Price: ${talos_data.price_usd}") + print(f"✅ TALOS 24h Change: {talos_data.price_change_h24}%") + print(f"✅ ARB 24h Change: {arb_data.price_change_h24}%") + print(f"✅ Relative Performance: {relative_performance}%") + + # Real data for testing + test_data = { + "price": talos_data.price_usd, + "change": talos_data.price_change_h24, + "volume": talos_data.volume_h24, + "relative_performance": relative_performance, + "sentiment": 75.0, # Mock sentiment for testing + "staked_supply_percentage": 0.5, # Mock staked supply for testing + "ohlcv_data": '{"test": "data"}' # Mock OHLCV for testing + } + + # Format the prompt + formatted_prompt = prompt.format(**test_data) + + print("\n✅ Prompt formatted successfully!") + print("\n--- Formatted Prompt Preview ---") + print(formatted_prompt[:800] + "..." if len(formatted_prompt) > 800 else formatted_prompt) + print("--- End Preview ---") + + # Check if relative performance is included + if "Relative Performance (T vs ARB):" in formatted_prompt: + print("✅ Relative performance data correctly included in prompt") + else: + print("❌ Relative performance data not found in prompt") + + return True + + except Exception as e: + print(f"❌ Error testing prompt formatting: {e}") + return False + +if __name__ == "__main__": + test_prompt_formatting() \ No newline at end of file