From 669af683372914dc165975551a0c4e15868517c9 Mon Sep 17 00:00:00 2001 From: Tomortec Date: Wed, 2 Jul 2025 15:52:47 +0800 Subject: [PATCH] feat: fetch news from coinstats --- .../agents/analysts/fundamentals_analyst.py | 1 + tradingagents/agents/analysts/news_analyst.py | 1 + .../agents/analysts/social_media_analyst.py | 1 + tradingagents/agents/utils/agent_utils.py | 22 ++++++++ tradingagents/dataflows/__init__.py | 4 ++ tradingagents/dataflows/coinstats_utils.py | 55 +++++++++++++++++++ tradingagents/dataflows/interface.py | 26 +++++++++ tradingagents/graph/trading_graph.py | 3 + 8 files changed, 113 insertions(+) create mode 100644 tradingagents/dataflows/coinstats_utils.py diff --git a/tradingagents/agents/analysts/fundamentals_analyst.py b/tradingagents/agents/analysts/fundamentals_analyst.py index 2bf0315d..3fa5df50 100644 --- a/tradingagents/agents/analysts/fundamentals_analyst.py +++ b/tradingagents/agents/analysts/fundamentals_analyst.py @@ -12,6 +12,7 @@ def create_fundamentals_analyst(llm, toolkit): tools = [ toolkit.get_binance_ohlcv, + toolkit.get_coinstats_btc_dominance, toolkit.get_fundamentals_openai ] diff --git a/tradingagents/agents/analysts/news_analyst.py b/tradingagents/agents/analysts/news_analyst.py index 9b8cafb4..8d89c57c 100644 --- a/tradingagents/agents/analysts/news_analyst.py +++ b/tradingagents/agents/analysts/news_analyst.py @@ -16,6 +16,7 @@ def create_news_analyst(llm, toolkit): # toolkit.get_reddit_news, toolkit.get_blockbeats_news, toolkit.get_coindesk_news, + toolkit.get_coinstats_news, toolkit.get_fear_and_greed_index ] diff --git a/tradingagents/agents/analysts/social_media_analyst.py b/tradingagents/agents/analysts/social_media_analyst.py index 88700d38..2fc94c3c 100644 --- a/tradingagents/agents/analysts/social_media_analyst.py +++ b/tradingagents/agents/analysts/social_media_analyst.py @@ -13,6 +13,7 @@ def create_social_media_analyst(llm, toolkit): tools = [ toolkit.get_binance_ohlcv, toolkit.get_fear_and_greed_index, + toolkit.get_coinstats_btc_dominance # toolkit.get_stock_news_openai, # toolkit.get_reddit_stock_info ] diff --git a/tradingagents/agents/utils/agent_utils.py b/tradingagents/agents/utils/agent_utils.py index ecd8e9de..184885f3 100644 --- a/tradingagents/agents/utils/agent_utils.py +++ b/tradingagents/agents/utils/agent_utils.py @@ -83,6 +83,17 @@ class Toolkit: coindesk_news_result = interface.get_coindesk_news(tickers, count) return coindesk_news_result + @staticmethod + @tool + def get_coinstats_news() -> str: + """ + Retrieve the latest news from CoinStats. + Returns: + str: A formatted string containing the latest news from CoinStats. + """ + coinstats_news_result = interface.get_coinstats_news() + return coinstats_news_result + @staticmethod @tool def get_binance_ohlcv( @@ -103,6 +114,17 @@ class Toolkit: binance_ohlcv_result = interface.get_binance_ohlcv(symbol, interval) return binance_ohlcv_result + @staticmethod + @tool + def get_coinstats_btc_dominance() -> str: + """ + Retrieve the current Bitcoin dominance percentage from CoinStats. + Returns: + str: A formatted string containing the last daily and weekly Bitcoin dominance percentage. + """ + btc_dominance_result = interface.get_coinstats_btc_dominance() + return btc_dominance_result + @staticmethod @tool def get_binance_data( diff --git a/tradingagents/dataflows/__init__.py b/tradingagents/dataflows/__init__.py index 24f2c85c..df50cb3d 100644 --- a/tradingagents/dataflows/__init__.py +++ b/tradingagents/dataflows/__init__.py @@ -2,9 +2,11 @@ from .interface import ( # Universal functions get_binance_ohlcv, + get_coinstats_btc_dominance, # News and sentiment functions get_blockbeats_news, get_coindesk_news, + get_coinstats_news, get_google_news, get_fear_and_greed_index, get_reddit_global_news, @@ -19,9 +21,11 @@ from .interface import ( __all__ = [ "get_binance_ohlcv", + "get_coinstats_btc_dominance", # News and sentiment functions "get_blockbeats_news", "get_coindesk_news", + "get_coinstats_news", "get_google_news", "get_fear_and_greed_index", "get_reddit_global_news", diff --git a/tradingagents/dataflows/coinstats_utils.py b/tradingagents/dataflows/coinstats_utils.py new file mode 100644 index 00000000..59226f76 --- /dev/null +++ b/tradingagents/dataflows/coinstats_utils.py @@ -0,0 +1,55 @@ + +import os +import requests + +def fetch_btc_dominance_from_coinstats(): + """ + Fetches the current Bitcoin dominance percentage from CoinStats API. + + Returns: + dict: A dictionary containing Bitcoin dominance for 24 hours and 1 week. {"24h": value, "1w": value} + """ + url_24h = "https://openapiv1.coinstats.app/insights/btc-dominance?type=24h" + url_1w = "https://openapiv1.coinstats.app/insights/btc-dominance?type=1w" + + headers = { + "accept": "application/json", + "X-API-KEY": "Sk4n/ND4vD5w6KXs3PUAaQmFfa9dqzcaBEbB1eh9j+g="#os.getenv("COINSTATS_API_KEY") + } + + response_24h = requests.get(url_24h, headers=headers) + response_1w = requests.get(url_1w, headers=headers) + + if response_24h.status_code == 200 and response_1w.status_code == 200: + data_24h = response_24h.json() + data_1w = response_1w.json() + + if "data" in data_24h and "data" in data_1w and \ + isinstance(data_24h["data"], list) and isinstance(data_1w["data"], list): + btc_dominance_24h = data_24h["data"][-1][1] + btc_dominance_1w = data_1w["data"][-1][1] + return {"24h": btc_dominance_24h, "1w": btc_dominance_1w} + +def fetch_news_from_coinstats(): + """ + Fetches the latest news from CoinStats API. + + Returns: + list: A list of dictionaries containing news articles with keys: "title", "source", "description" + """ + url = "https://openapiv1.coinstats.app/news/type/latest?page=1&limit=20" + headers = { + "accept": "application/json", + "X-API-KEY": "Sk4n/ND4vD5w6KXs3PUAaQmFfa9dqzcaBEbB1eh9j+g="#os.getenv("COINSTATS_API_KEY") + } + response = requests.get(url, headers=headers) + if response.status_code == 200: + data = response.json() + if isinstance(data, list): + return [ + { + "title": article.get("title", ""), + "description": article.get("description", ""), + "source": article.get("source", "") + } for article in data + ] \ No newline at end of file diff --git a/tradingagents/dataflows/interface.py b/tradingagents/dataflows/interface.py index e000f21f..9b6f170b 100644 --- a/tradingagents/dataflows/interface.py +++ b/tradingagents/dataflows/interface.py @@ -1,6 +1,7 @@ from typing import Annotated, Dict from .blockbeats_utils import fetch_news_from_blockbeats from .coindesk_utils import fetch_news_from_coindesk +from .coinstats_utils import * from .reddit_utils import fetch_top_from_category from .googlenews_utils import * from .binance_utils import * @@ -73,6 +74,16 @@ def get_fear_and_greed_index() -> str: fng = fetch_fear_and_greed_from_alternativeme() return f"""## Fear and Greed Index: {fng[0]}\n0 means \"Extreme Fear\", while 100 means \"Extreme Greed\"\nPrevious daily FnG: {','.join(fng[1:])}""" +def get_coinstats_btc_dominance() -> str: + """ + Fetch the current Bitcoin dominance percentage from CoinStats API. + + Returns: + str: A formatted string containing Bitcoin dominance for 24 hours and 1 week. + """ + btc_dominance = fetch_btc_dominance_from_coinstats() + return f"## Bitcoin Dominance:\n24h: {btc_dominance['24h']}%, 1week: {btc_dominance['1w']}%" + def get_taapi_single_indicator( symbol: Annotated[str, "ticker symbol of the asset"], indicator: Annotated[ @@ -116,6 +127,21 @@ def get_taapi_bulk_indicators( return f"## {symbol} Trend and Momentum Indicators at {interval}:\n{trend_momentum}\n\n" + \ f"## {symbol} Volatility and Pattern Indicators at {interval}:\n{volatility_structure}\n" +def get_coinstats_news() -> str: + """ + Fetch the latest news from CoinStats API. + + Returns: + str: A formatted string containing the latest news articles and meta information. + """ + news = fetch_news_from_coinstats() + if len(news) == 0: + return "" + news_str = "" + for article in news: + news_str += f"### {article['title']} (source: {article['source']})\n{article['description']}\n\n" + return f"## CoinStats News:\n{news_str}" + def get_google_news( query: Annotated[str, "Query to search with"], curr_date: Annotated[str, "Curr date in yyyy-mm-dd format"], diff --git a/tradingagents/graph/trading_graph.py b/tradingagents/graph/trading_graph.py index fcdf3645..adf40304 100644 --- a/tradingagents/graph/trading_graph.py +++ b/tradingagents/graph/trading_graph.py @@ -125,6 +125,7 @@ class TradingAgentsGraph: [ self.toolkit.get_binance_ohlcv, self.toolkit.get_fear_and_greed_index, + self.toolkit.get_coinstats_btc_dominance, # self.toolkit.get_stock_news_openai, # self.toolkit.get_reddit_stock_info, ] @@ -132,6 +133,7 @@ class TradingAgentsGraph: "news": ToolNode( [ self.toolkit.get_binance_ohlcv, + self.toolkit.get_coinstats_news, # self.toolkit.get_global_news_openai, # self.toolkit.get_google_news, self.toolkit.get_blockbeats_news, @@ -142,6 +144,7 @@ class TradingAgentsGraph: "fundamentals": ToolNode( [ self.toolkit.get_binance_ohlcv, + self.toolkit.get_coinstats_btc_dominance, self.toolkit.get_fundamentals_openai ] ),