Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
37-tool crypto derivatives data suite: funding rates, open interest, liquidations, Hyperliquid whale tracking, and ETF flows.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
coinglass.py
1"""2Coinglass Tool Wrappers34Wraps tools from /tools/coinglass/ for use in Agent framework.5Provides derivatives data: funding rates, open interest, liquidations, long/short ratios.6"""7import asyncio8import logging9from typing import Optional1011from core.tool import BaseTool, ToolContext, ToolResult1213logger = logging.getLogger(__name__)1415# Import original tools from local tools directory16try:17from .tools.funding_rate import get_funding_rates, get_symbol_funding_rate18from .tools.long_short_ratio import get_long_short_ratio19from .tools.long_short_advanced import (20get_global_account_ratio,21get_top_account_ratio,22get_top_position_ratio,23get_taker_buysell_exchanges,24get_net_position25)26from .tools.open_interest import get_open_interest27from .tools.liquidations import get_liquidations, get_liquidation_aggregated28from .tools.liquidations_advanced import (29get_coin_liquidation_history,30get_pair_liquidation_history,31get_liquidation_coin_list,32get_liquidation_orders33)34from .tools.hyperliquid import (35get_whale_alerts,36get_whale_positions,37get_positions_by_coin,38get_position_distribution39)40from .tools.futures_market import (41get_supported_coins,42get_supported_exchanges,43get_coins_data,44get_pair_data,45get_ohlc_history46)47from .tools.volume_flow import (48get_taker_volume_history,49get_aggregated_taker_volume,50get_cumulative_volume_delta,51get_coin_netflow52)53from .tools.whale_transfer import get_whale_transfers54from .tools._api import CoinglassError55from .tools.bitcoin_etf import (56get_btc_etf_flows,57get_btc_etf_premium_discount,58get_btc_etf_history,59get_btc_etf_list,60get_hk_btc_etf_flows61)62from .tools.other_etfs import (63get_eth_etf_flows,64get_eth_etf_list,65get_sol_etf_flows,66get_xrp_etf_flows67)68COINGLASS_AVAILABLE = True69except ImportError as e:70logger.warning(f"Coinglass tools not available: {e}")71COINGLASS_AVAILABLE = False727374class FundingRateTool(BaseTool):75"""76Get perpetual futures funding rates across exchanges.7778Funding rates indicate market sentiment:79- Positive rates: Longs pay shorts (bullish bias)80- Negative rates: Shorts pay longs (bearish bias)81- Extreme rates often precede reversals82"""8384@property85def name(self) -> str:86return "funding_rate"8788@property89def description(self) -> str:90return """Get perpetual futures funding rates across exchanges.9192Positive rates = longs pay shorts (bullish sentiment)93Negative rates = shorts pay longs (bearish sentiment)94Extreme funding often signals reversal risk.9596Examples:97- Get BTC funding rates: funding_rate(symbol="BTC")98- Get ETH funding on Binance: funding_rate(symbol="ETH", exchange="Binance")"""99100@property101def parameters(self) -> dict:102return {103"type": "object",104"properties": {105"symbol": {106"type": "string",107"description": "Symbol (BTC, ETH, SOL, etc.)"108},109"exchange": {110"type": "string",111"description": "Optional: specific exchange (Binance, OKX, Bybit, etc.)"112}113},114"required": ["symbol"]115}116117async def execute(118self,119ctx: ToolContext,120symbol: str,121exchange: Optional[str] = None122) -> ToolResult:123if not COINGLASS_AVAILABLE:124return ToolResult(125success=False,126output=None,127error="Coinglass tools not available."128)129130try:131if exchange:132result = await asyncio.to_thread(get_symbol_funding_rate, symbol=symbol, exchange=exchange)133else:134result = await asyncio.to_thread(get_funding_rates, symbol=symbol)135136if result is None:137return ToolResult(138success=False,139output=None,140error="No data returned. The API returned an empty result."141)142143return ToolResult(success=True, output=result)144except CoinglassError as e:145msg = f"Coinglass: {e}"146if e.suggestion:147msg += f" ({e.suggestion})"148return ToolResult(149success=False, output=None, error=msg)150except Exception as e:151return ToolResult(152success=False, output=None,153error=f"Coinglass: {type(e).__name__}: {e}")154155156class LongShortRatioTool(BaseTool):157"""158Get long/short ratio for a cryptocurrency.159160Shows the ratio of long vs short positions across exchanges.161Useful for sentiment analysis.162"""163164@property165def name(self) -> str:166return "long_short_ratio"167168@property169def description(self) -> str:170return """Get long/short position ratio across exchanges.171172Ratio > 1: More longs than shorts173Ratio < 1: More shorts than longs174Extreme ratios often signal crowded trades.175176Examples:177- Get BTC L/S ratio: long_short_ratio(symbol="BTC")178- Get ETH L/S ratio with timeframe: long_short_ratio(symbol="ETH", interval="h4")"""179180@property181def parameters(self) -> dict:182return {183"type": "object",184"properties": {185"symbol": {186"type": "string",187"description": "Symbol (BTC, ETH, SOL, etc.)"188},189"interval": {190"type": "string",191"description": "Time interval: h1, h4, h12, h24",192"default": "h4"193}194},195"required": ["symbol"]196}197198async def execute(199self,200ctx: ToolContext,201symbol: str,202interval: str = "h4"203) -> ToolResult:204if not COINGLASS_AVAILABLE:205return ToolResult(206success=False,207output=None,208error="Coinglass tools not available."209)210211try:212result = await asyncio.to_thread(get_long_short_ratio, symbol=symbol, time_type=interval)213214if result is None:215return ToolResult(216success=False,217output=None,218error="No data returned. The API returned an empty result."219)220221return ToolResult(success=True, output=result)222except CoinglassError as e:223msg = f"Coinglass: {e}"224if e.suggestion:225msg += f" ({e.suggestion})"226return ToolResult(227success=False, output=None, error=msg)228except Exception as e:229return ToolResult(230success=False, output=None,231error=f"Coinglass: {type(e).__name__}: {e}")232233234# ==================== Advanced Long/Short Ratio Tools ====================235236class GlobalAccountRatioTool(BaseTool):237"""Get global long/short account ratio history."""238239@property240def name(self) -> str:241return "cg_global_account_ratio"242243@property244def description(self) -> str:245return """Get global long/short account ratio history for a trading pair.246247Shows the percentage of accounts holding long vs short positions over time.248249Examples:250- Get BTC global ratio: cg_global_account_ratio(symbol="BTC", exchange="Binance")251- Get ETH with 4h interval: cg_global_account_ratio(symbol="ETH", exchange="OKX", interval="4h")"""252253@property254def parameters(self) -> dict:255return {256"type": "object",257"properties": {258"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},259"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},260"interval": {"type": "string", "description": "Time interval: 1m, 5m, 15m, 30m, 1h, 4h, 12h, 1d, 1w", "default": "1h"},261"limit": {"type": "integer", "description": "Number of results (default: 100)", "default": 100}262},263"required": ["symbol", "exchange"]264}265266async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 100) -> ToolResult:267if not COINGLASS_AVAILABLE:268return ToolResult(success=False, output=None, error="Coinglass tools not available.")269270try:271result = await asyncio.to_thread(get_global_account_ratio, symbol, exchange, interval, limit)272if result is None:273return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")274return ToolResult(success=True, output=result)275except CoinglassError as e:276msg = f"Coinglass: {e}"277if e.suggestion:278msg += f" ({e.suggestion})"279return ToolResult(280success=False, output=None, error=msg)281except Exception as e:282return ToolResult(283success=False, output=None,284error=f"Coinglass: {type(e).__name__}: {e}")285286287class TopAccountRatioTool(BaseTool):288"""Get top traders long/short account ratio."""289290@property291def name(self) -> str:292return "cg_top_account_ratio"293294@property295def description(self) -> str:296return """Get long/short account ratio for top traders only.297298Shows what the most successful traders are doing. More reliable than global ratios.299300Examples:301- Get BTC top trader ratio: cg_top_account_ratio(symbol="BTC", exchange="Binance")302- Get ETH 4h: cg_top_account_ratio(symbol="ETH", exchange="OKX", interval="4h")"""303304@property305def parameters(self) -> dict:306return {307"type": "object",308"properties": {309"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},310"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},311"interval": {"type": "string", "description": "Time interval: 1m, 5m, 15m, 30m, 1h, 4h, 12h, 1d, 1w", "default": "1h"},312"limit": {"type": "integer", "description": "Number of results (default: 100)", "default": 100}313},314"required": ["symbol", "exchange"]315}316317async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 100) -> ToolResult:318if not COINGLASS_AVAILABLE:319return ToolResult(success=False, output=None, error="Coinglass tools not available.")320321try:322result = await asyncio.to_thread(get_top_account_ratio, symbol, exchange, interval, limit)323if result is None:324return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")325return ToolResult(success=True, output=result)326except CoinglassError as e:327msg = f"Coinglass: {e}"328if e.suggestion:329msg += f" ({e.suggestion})"330return ToolResult(331success=False, output=None, error=msg)332except Exception as e:333return ToolResult(334success=False, output=None,335error=f"Coinglass: {type(e).__name__}: {e}")336337338class TopPositionRatioTool(BaseTool):339"""Get top traders long/short position ratio."""340341@property342def name(self) -> str:343return "cg_top_position_ratio"344345@property346def description(self) -> str:347return """Get long/short position ratio for top traders (by position size, not account count).348349Shows the actual $ amount split between longs and shorts for top traders.350351Examples:352- Get BTC top position ratio: cg_top_position_ratio(symbol="BTC", exchange="Binance")353- Get ETH 4h: cg_top_position_ratio(symbol="ETH", exchange="OKX", interval="4h")"""354355@property356def parameters(self) -> dict:357return {358"type": "object",359"properties": {360"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},361"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},362"interval": {"type": "string", "description": "Time interval: 1m, 5m, 15m, 30m, 1h, 4h, 12h, 1d, 1w", "default": "1h"},363"limit": {"type": "integer", "description": "Number of results (default: 100)", "default": 100}364},365"required": ["symbol", "exchange"]366}367368async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 100) -> ToolResult:369if not COINGLASS_AVAILABLE:370return ToolResult(success=False, output=None, error="Coinglass tools not available.")371372try:373result = await asyncio.to_thread(get_top_position_ratio, symbol, exchange, interval, limit)374if result is None:375return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")376return ToolResult(success=True, output=result)377except CoinglassError as e:378msg = f"Coinglass: {e}"379if e.suggestion:380msg += f" ({e.suggestion})"381return ToolResult(382success=False, output=None, error=msg)383except Exception as e:384return ToolResult(385success=False, output=None,386error=f"Coinglass: {type(e).__name__}: {e}")387388389class TakerBuySellExchangesTool(BaseTool):390"""Get exchanges with taker buy/sell volume data."""391392@property393def name(self) -> str:394return "cg_taker_exchanges"395396@property397def description(self) -> str:398return """Get list of exchanges with taker buy/sell volume data available.399400Shows which exchanges provide taker volume metrics and their current ratios.401402Examples:403- Get BTC exchanges (1h): cg_taker_exchanges(symbol="BTC")404- Get ETH exchanges (24h): cg_taker_exchanges(symbol="ETH", range="24h")"""405406@property407def parameters(self) -> dict:408return {409"type": "object",410"properties": {411"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},412"range": {"type": "string", "description": "Time range: 1h, 4h, 12h, 24h (default: 1h)", "default": "1h"}413},414"required": ["symbol"]415}416417async def execute(self, ctx: ToolContext, symbol: str, range: str = "1h") -> ToolResult:418if not COINGLASS_AVAILABLE:419return ToolResult(success=False, output=None, error="Coinglass tools not available.")420421try:422result = await asyncio.to_thread(get_taker_buysell_exchanges, symbol, range)423if result is None:424return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")425return ToolResult(success=True, output=result)426except CoinglassError as e:427msg = f"Coinglass: {e}"428if e.suggestion:429msg += f" ({e.suggestion})"430return ToolResult(431success=False, output=None, error=msg)432except Exception as e:433return ToolResult(434success=False, output=None,435error=f"Coinglass: {type(e).__name__}: {e}")436437438class NetPositionTool(BaseTool):439"""Get net position changes (net long/short delta)."""440441@property442def name(self) -> str:443return "cg_net_position"444445@property446def description(self) -> str:447return """Get historical net position data showing net long/short changes.448449Net position = difference between long and short positions opened.450Useful for tracking institutional positioning.451452Examples:453- Get BTC net position: cg_net_position(symbol="BTC", exchange="Binance")454- Get ETH 4h: cg_net_position(symbol="ETH", exchange="OKX", interval="4h")"""455456@property457def parameters(self) -> dict:458return {459"type": "object",460"properties": {461"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},462"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},463"interval": {"type": "string", "description": "Time interval: 1m, 5m, 15m, 30m, 1h, 4h, 12h, 1d, 1w", "default": "1h"},464"limit": {"type": "integer", "description": "Number of results (default: 100)", "default": 100}465},466"required": ["symbol", "exchange"]467}468469async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 100) -> ToolResult:470if not COINGLASS_AVAILABLE:471return ToolResult(success=False, output=None, error="Coinglass tools not available.")472473try:474result = await asyncio.to_thread(get_net_position, symbol, exchange, interval, limit)475if result is None:476return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")477return ToolResult(success=True, output=result)478except CoinglassError as e:479msg = f"Coinglass: {e}"480if e.suggestion:481msg += f" ({e.suggestion})"482return ToolResult(483success=False, output=None, error=msg)484except Exception as e:485return ToolResult(486success=False, output=None,487error=f"Coinglass: {type(e).__name__}: {e}")488489490# ==================== Open Interest Tools ====================491492class OpenInterestTool(BaseTool):493"""494Get aggregate open interest across exchanges.495"""496497@property498def name(self) -> str:499return "cg_open_interest"500501@property502def description(self) -> str:503return """Get aggregate open interest across exchanges for a symbol.504505Open interest = total outstanding derivative contracts.506Rising OI + rising price = new money entering (bullish)507Rising OI + falling price = new shorts opening (bearish)508Falling OI = positions closing (trend weakening)509510Examples:511- Get BTC open interest: cg_open_interest(symbol="BTC")512- Get ETH open interest: cg_open_interest(symbol="ETH")"""513514@property515def parameters(self) -> dict:516return {517"type": "object",518"properties": {519"symbol": {520"type": "string",521"description": "Symbol (BTC, ETH, SOL, etc.)"522}523},524"required": ["symbol"]525}526527async def execute(528self,529ctx: ToolContext,530symbol: str531) -> ToolResult:532if not COINGLASS_AVAILABLE:533return ToolResult(534success=False,535output=None,536error="Coinglass tools not available."537)538539try:540result = await asyncio.to_thread(get_open_interest, symbol)541542if result is None:543return ToolResult(544success=False,545output=None,546error="No data returned. The API returned an empty result."547)548549return ToolResult(success=True, output=result)550except CoinglassError as e:551msg = f"Coinglass: {e}"552if e.suggestion:553msg += f" ({e.suggestion})"554return ToolResult(555success=False, output=None, error=msg)556except Exception as e:557return ToolResult(558success=False, output=None,559error=f"Coinglass: {type(e).__name__}: {e}")560561562# ==================== Liquidation Tools ====================563564class LiquidationsTool(BaseTool):565"""566Get recent liquidation data.567"""568569@property570def name(self) -> str:571return "cg_liquidations"572573@property574def description(self) -> str:575return """Get recent liquidation data across exchanges.576577Liquidations = forced position closures due to insufficient margin.578More long liquidations = bearish pressure (longs being squeezed)579More short liquidations = bullish pressure (shorts being squeezed)580581Examples:582- Get BTC liquidations (24h): cg_liquidations(symbol="BTC")583- Get ETH liquidations (4h): cg_liquidations(symbol="ETH", time_type="h4")"""584585@property586def parameters(self) -> dict:587return {588"type": "object",589"properties": {590"symbol": {591"type": "string",592"description": "Symbol (BTC, ETH, SOL, etc.)"593},594"time_type": {595"type": "string",596"description": "Time window: h1, h4, h12, h24",597"default": "h24"598}599},600"required": ["symbol"]601}602603async def execute(604self,605ctx: ToolContext,606symbol: str,607time_type: str = "h24"608) -> ToolResult:609if not COINGLASS_AVAILABLE:610return ToolResult(611success=False,612output=None,613error="Coinglass tools not available."614)615616try:617result = await asyncio.to_thread(get_liquidations, symbol, time_type)618619if result is None:620return ToolResult(621success=False,622output=None,623error="No data returned. The API returned an empty result."624)625626return ToolResult(success=True, output=result)627except CoinglassError as e:628msg = f"Coinglass: {e}"629if e.suggestion:630msg += f" ({e.suggestion})"631return ToolResult(632success=False, output=None, error=msg)633except Exception as e:634return ToolResult(635success=False, output=None,636error=f"Coinglass: {type(e).__name__}: {e}")637638639class LiquidationAnalysisTool(BaseTool):640"""641Get liquidation data with sentiment analysis.642"""643644@property645def name(self) -> str:646return "cg_liquidation_analysis"647648@property649def description(self) -> str:650return """Get liquidation data with market sentiment analysis.651652Includes interpretation of liquidation imbalances.653654Examples:655- Analyze BTC liquidations: cg_liquidation_analysis(symbol="BTC")656- Analyze ETH (4h): cg_liquidation_analysis(symbol="ETH", time_type="h4")"""657658@property659def parameters(self) -> dict:660return {661"type": "object",662"properties": {663"symbol": {664"type": "string",665"description": "Symbol (BTC, ETH, SOL, etc.)"666},667"time_type": {668"type": "string",669"description": "Time window: h1, h4, h12, h24",670"default": "h24"671}672},673"required": ["symbol"]674}675676async def execute(677self,678ctx: ToolContext,679symbol: str,680time_type: str = "h24"681) -> ToolResult:682if not COINGLASS_AVAILABLE:683return ToolResult(684success=False,685output=None,686error="Coinglass tools not available."687)688689try:690result = await asyncio.to_thread(get_liquidation_aggregated, symbol, time_type)691692if result is None:693return ToolResult(694success=False,695output=None,696error="No data returned. The API returned an empty result."697)698699return ToolResult(success=True, output=result)700except CoinglassError as e:701msg = f"Coinglass: {e}"702if e.suggestion:703msg += f" ({e.suggestion})"704return ToolResult(705success=False, output=None, error=msg)706except Exception as e:707return ToolResult(708success=False, output=None,709error=f"Coinglass: {type(e).__name__}: {e}")710711712# ==================== Advanced Liquidation Tools ====================713714class CoinLiquidationHistoryTool(BaseTool):715"""Get aggregated liquidation history for a coin across all exchanges."""716717@property718def name(self) -> str:719return "cg_coin_liquidation_history"720721@property722def description(self) -> str:723return """Get aggregated liquidation history across all exchanges for a coin.724725Shows total long/short liquidations over time, aggregated across all exchanges.726727Examples:728- Get BTC liquidation history: cg_coin_liquidation_history(symbol="BTC", interval="1h", limit=100)729- Get ETH 4h intervals: cg_coin_liquidation_history(symbol="ETH", interval="4h", limit=50)"""730731@property732def parameters(self) -> dict:733return {734"type": "object",735"properties": {736"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},737"exchange_list": {"type": "string", "description": "Comma-separated exchange list (e.g. 'Binance,OKX,Bybit')"},738"interval": {"type": "string", "description": "Time interval: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 6h, 8h, 12h, 1d, 1w", "default": "1h"},739"limit": {"type": "integer", "description": "Number of results (default: 1000, max: 4500)", "default": 1000},740"start_time": {"type": "integer", "description": "Start timestamp in milliseconds"},741"end_time": {"type": "integer", "description": "End timestamp in milliseconds"}742},743"required": ["symbol", "exchange_list"]744}745746async def execute(self, ctx: ToolContext, symbol: str, exchange_list: str, interval: str = "1h", limit: int = 1000,747start_time: Optional[int] = None, end_time: Optional[int] = None) -> ToolResult:748if not COINGLASS_AVAILABLE:749return ToolResult(success=False, output=None, error="Coinglass tools not available.")750751try:752result = await asyncio.to_thread(get_coin_liquidation_history, symbol, exchange_list, interval, limit, start_time, end_time)753if result is None:754return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")755return ToolResult(success=True, output=result)756except CoinglassError as e:757msg = f"Coinglass: {e}"758if e.suggestion:759msg += f" ({e.suggestion})"760return ToolResult(761success=False, output=None, error=msg)762except Exception as e:763return ToolResult(764success=False, output=None,765error=f"Coinglass: {type(e).__name__}: {e}")766767768class PairLiquidationHistoryTool(BaseTool):769"""Get liquidation history for a specific trading pair on an exchange."""770771@property772def name(self) -> str:773return "cg_pair_liquidation_history"774775@property776def description(self) -> str:777return """Get liquidation history for a specific pair on a specific exchange.778779Shows long/short liquidations over time for exchange-specific pairs.780781Examples:782- Get BTC/USDT on Binance: cg_pair_liquidation_history(symbol="BTC", exchange="Binance", interval="1h")783- Get ETH/USDT on OKX: cg_pair_liquidation_history(symbol="ETH", exchange="OKX", interval="4h")"""784785@property786def parameters(self) -> dict:787return {788"type": "object",789"properties": {790"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},791"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},792"interval": {"type": "string", "description": "Time interval: 1h, 4h, 12h, 24h", "default": "1h"},793"limit": {"type": "integer", "description": "Number of results (default: 1000, max: 4500)", "default": 1000},794"start_time": {"type": "integer", "description": "Start timestamp in seconds"},795"end_time": {"type": "integer", "description": "End timestamp in seconds"}796},797"required": ["symbol", "exchange"]798}799800async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 1000,801start_time: Optional[int] = None, end_time: Optional[int] = None) -> ToolResult:802if not COINGLASS_AVAILABLE:803return ToolResult(success=False, output=None, error="Coinglass tools not available.")804805try:806result = await asyncio.to_thread(get_pair_liquidation_history, symbol, exchange, interval, limit, start_time, end_time)807if result is None:808return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")809return ToolResult(success=True, output=result)810except CoinglassError as e:811msg = f"Coinglass: {e}"812if e.suggestion:813msg += f" ({e.suggestion})"814return ToolResult(815success=False, output=None, error=msg)816except Exception as e:817return ToolResult(818success=False, output=None,819error=f"Coinglass: {type(e).__name__}: {e}")820821822class LiquidationCoinListTool(BaseTool):823"""Get liquidation data for all coins on a specific exchange."""824825@property826def name(self) -> str:827return "cg_liquidation_coin_list"828829@property830def description(self) -> str:831return """Get liquidation data for all coins on a specific exchange.832833Shows liquidation amounts across multiple timeframes (1h, 4h, 12h, 24h) for all coins on an exchange.834835Examples:836- Get all Binance liquidations: cg_liquidation_coin_list(exchange="Binance")837- Get all OKX liquidations: cg_liquidation_coin_list(exchange="OKX")"""838839@property840def parameters(self) -> dict:841return {842"type": "object",843"properties": {844"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"}845},846"required": ["exchange"]847}848849async def execute(self, ctx: ToolContext, exchange: str) -> ToolResult:850if not COINGLASS_AVAILABLE:851return ToolResult(success=False, output=None, error="Coinglass tools not available.")852853try:854result = await asyncio.to_thread(get_liquidation_coin_list, exchange)855if result is None:856return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")857return ToolResult(success=True, output=result)858except CoinglassError as e:859msg = f"Coinglass: {e}"860if e.suggestion:861msg += f" ({e.suggestion})"862return ToolResult(863success=False, output=None, error=msg)864except Exception as e:865return ToolResult(866success=False, output=None,867error=f"Coinglass: {type(e).__name__}: {e}")868869870class LiquidationOrdersTool(BaseTool):871"""Get individual liquidation orders (past 7 days)."""872873@property874def name(self) -> str:875return "cg_liquidation_orders"876877@property878def description(self) -> str:879return """Get individual liquidation orders with price, side, and USD value (past 7 days only).880881Shows actual liquidation events. Max 200 records per request.882883Examples:884- Get BTC liquidations on Binance (min $10K): cg_liquidation_orders(symbol="BTC", exchange="Binance", min_liquidation_amount="10000")885- Get ETH liquidations on OKX (min $5K): cg_liquidation_orders(symbol="ETH", exchange="OKX", min_liquidation_amount="5000")"""886887@property888def parameters(self) -> dict:889return {890"type": "object",891"properties": {892"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},893"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},894"min_liquidation_amount": {"type": "string", "description": "Minimum threshold for liquidation events (USD)"},895"start_time": {"type": "integer", "description": "Start timestamp in milliseconds"},896"end_time": {"type": "integer", "description": "End timestamp in milliseconds"}897},898"required": ["symbol", "exchange", "min_liquidation_amount"]899}900901async def execute(self, ctx: ToolContext, symbol: str, exchange: str, min_liquidation_amount: str,902start_time: Optional[int] = None, end_time: Optional[int] = None) -> ToolResult:903if not COINGLASS_AVAILABLE:904return ToolResult(success=False, output=None, error="Coinglass tools not available.")905906try:907result = await asyncio.to_thread(get_liquidation_orders, symbol, exchange, min_liquidation_amount, start_time, end_time)908if result is None:909return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")910return ToolResult(success=True, output=result)911except CoinglassError as e:912msg = f"Coinglass: {e}"913if e.suggestion:914msg += f" ({e.suggestion})"915return ToolResult(916success=False, output=None, error=msg)917except Exception as e:918return ToolResult(919success=False, output=None,920error=f"Coinglass: {type(e).__name__}: {e}")921922923# ==================== Futures Market Data Tools (V4 API) ====================924925class SupportedCoinsTool(BaseTool):926"""Get list of all supported coins for futures trading."""927928@property929def name(self) -> str:930return "cg_supported_coins"931932@property933def description(self) -> str:934return """Get list of all supported coins for futures trading on Coinglass.935936Returns array of coin symbols (BTC, ETH, SOL, XRP, HYPE, DOGE, etc.)937938Use this for:939- Market discovery940- Checking if a coin has futures markets941- Finding new trading opportunities942943Examples:944- Get all supported coins: cg_supported_coins()"""945946@property947def parameters(self) -> dict:948return {"type": "object", "properties": {}, "required": []}949950async def execute(self, ctx: ToolContext) -> ToolResult:951if not COINGLASS_AVAILABLE:952return ToolResult(success=False, output=None, error="Coinglass tools not available.")953954try:955result = await asyncio.to_thread(get_supported_coins)956if result is None:957return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")958return ToolResult(success=True, output=result)959except CoinglassError as e:960msg = f"Coinglass: {e}"961if e.suggestion:962msg += f" ({e.suggestion})"963return ToolResult(964success=False, output=None, error=msg)965except Exception as e:966return ToolResult(967success=False, output=None,968error=f"Coinglass: {type(e).__name__}: {e}")969970971class SupportedExchangesTool(BaseTool):972"""Get all supported exchanges with their trading pairs."""973974@property975def name(self) -> str:976return "cg_supported_exchanges"977978@property979def description(self) -> str:980return """Get all supported exchanges with trading pairs and specs.981982Returns dictionary with exchange pairs including leverage limits, funding intervals, tick sizes.983984Examples:985- Get all exchanges: cg_supported_exchanges()"""986987@property988def parameters(self) -> dict:989return {"type": "object", "properties": {}, "required": []}990991async def execute(self, ctx: ToolContext) -> ToolResult:992if not COINGLASS_AVAILABLE:993return ToolResult(success=False, output=None, error="Coinglass tools not available.")994995try:996result = await asyncio.to_thread(get_supported_exchanges)997if result is None:998return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")999return ToolResult(success=True, output=result)1000except CoinglassError as e:1001msg = f"Coinglass: {e}"1002if e.suggestion:1003msg += f" ({e.suggestion})"1004return ToolResult(1005success=False, output=None, error=msg)1006except Exception as e:1007return ToolResult(1008success=False, output=None,1009error=f"Coinglass: {type(e).__name__}: {e}")101010111012class CoinsMarketDataTool(BaseTool):1013"""Get comprehensive market data for ALL coins in one request."""10141015@property1016def name(self) -> str:1017return "cg_coins_market_data"10181019@property1020def description(self) -> str:1021return """Get market data for ALL coins in ONE request.10221023Returns: price, funding rates, OI, volume, long/short ratios, liquidations for 100+ coins.10241025Use this for market screening and bulk analysis. MUCH more efficient than individual calls.10261027Examples:1028- Get all coins data: cg_coins_market_data()"""10291030@property1031def parameters(self) -> dict:1032return {"type": "object", "properties": {}, "required": []}10331034async def execute(self, ctx: ToolContext) -> ToolResult:1035if not COINGLASS_AVAILABLE:1036return ToolResult(success=False, output=None, error="Coinglass tools not available.")10371038try:1039result = await asyncio.to_thread(get_coins_data)1040if result is None:1041return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1042return ToolResult(success=True, output=result)1043except CoinglassError as e:1044msg = f"Coinglass: {e}"1045if e.suggestion:1046msg += f" ({e.suggestion})"1047return ToolResult(1048success=False, output=None, error=msg)1049except Exception as e:1050return ToolResult(1051success=False, output=None,1052error=f"Coinglass: {type(e).__name__}: {e}")105310541055class PairMarketDataTool(BaseTool):1056"""Get detailed market data for a specific trading pair."""10571058@property1059def name(self) -> str:1060return "cg_pair_market_data"10611062@property1063def description(self) -> str:1064return """Get detailed market data for a specific pair on an exchange.10651066Returns: price, volume, OI, funding rate, liquidations, long/short volumes.10671068Examples:1069- Get BTC/USDT on Binance: cg_pair_market_data(symbol="BTC", exchange="Binance")1070- Get ETH/USDT on OKX: cg_pair_market_data(symbol="ETH", exchange="OKX")"""10711072@property1073def parameters(self) -> dict:1074return {1075"type": "object",1076"properties": {1077"symbol": {"type": "string", "description": "Coin symbol (BTC, ETH, SOL, etc.)"},1078"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, Gate, etc.)"}1079},1080"required": ["symbol", "exchange"]1081}10821083async def execute(self, ctx: ToolContext, symbol: str, exchange: str) -> ToolResult:1084if not COINGLASS_AVAILABLE:1085return ToolResult(success=False, output=None, error="Coinglass tools not available.")10861087try:1088result = await asyncio.to_thread(get_pair_data, symbol, exchange)1089if result is None:1090return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1091return ToolResult(success=True, output=result)1092except CoinglassError as e:1093msg = f"Coinglass: {e}"1094if e.suggestion:1095msg += f" ({e.suggestion})"1096return ToolResult(1097success=False, output=None, error=msg)1098except Exception as e:1099return ToolResult(1100success=False, output=None,1101error=f"Coinglass: {type(e).__name__}: {e}")110211031104class OHLCHistoryTool(BaseTool):1105"""Get OHLC price history for a trading pair."""11061107@property1108def name(self) -> str:1109return "cg_ohlc_history"11101111@property1112def description(self) -> str:1113return """Get OHLC candlestick data for price analysis.11141115Returns array of candles with: timestamp, open, high, low, close.11161117Examples:1118- Get BTC 1h candles: cg_ohlc_history(symbol="BTC", exchange="Binance", interval="h1", limit=100)1119- Get ETH daily: cg_ohlc_history(symbol="ETH", exchange="OKX", interval="d1", limit=30)"""11201121@property1122def parameters(self) -> dict:1123return {1124"type": "object",1125"properties": {1126"symbol": {"type": "string", "description": "Coin symbol (BTC, ETH, SOL, etc.)"},1127"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},1128"interval": {"type": "string", "description": "Time interval: m1, m5, m15, m30, h1, h4, h12, d1", "default": "h1"},1129"limit": {"type": "integer", "description": "Number of candles (default: 100)", "default": 100}1130},1131"required": ["symbol", "exchange"]1132}11331134async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "h1", limit: int = 100) -> ToolResult:1135if not COINGLASS_AVAILABLE:1136return ToolResult(success=False, output=None, error="Coinglass tools not available.")11371138try:1139result = await asyncio.to_thread(get_ohlc_history, symbol, exchange, interval, limit)1140if result is None:1141return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1142return ToolResult(success=True, output=result)1143except CoinglassError as e:1144msg = f"Coinglass: {e}"1145if e.suggestion:1146msg += f" ({e.suggestion})"1147return ToolResult(1148success=False, output=None, error=msg)1149except Exception as e:1150return ToolResult(1151success=False, output=None,1152error=f"Coinglass: {type(e).__name__}: {e}")115311541155# ==================== Hyperliquid Tools ====================11561157class HyperliquidWhaleAlertsTool(BaseTool):1158"""Get recent whale alerts on Hyperliquid (positions > $1M)."""11591160@property1161def name(self) -> str:1162return "cg_hyperliquid_whale_alerts"11631164@property1165def description(self) -> str:1166return """Get recent whale alerts on Hyperliquid (positions > $1M).11671168Returns approximately 200 most recent large position opens/closes.11691170Examples:1171- Get whale alerts: cg_hyperliquid_whale_alerts()"""11721173@property1174def parameters(self) -> dict:1175return {"type": "object", "properties": {}, "required": []}11761177async def execute(self, ctx: ToolContext) -> ToolResult:1178if not COINGLASS_AVAILABLE:1179return ToolResult(success=False, output=None, error="Coinglass tools not available.")11801181try:1182result = await asyncio.to_thread(get_whale_alerts)1183if result is None:1184return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1185return ToolResult(success=True, output=result)1186except CoinglassError as e:1187msg = f"Coinglass: {e}"1188if e.suggestion:1189msg += f" ({e.suggestion})"1190return ToolResult(1191success=False, output=None, error=msg)1192except Exception as e:1193return ToolResult(1194success=False, output=None,1195error=f"Coinglass: {type(e).__name__}: {e}")119611971198class HyperliquidWhalePositionsTool(BaseTool):1199"""Get current whale positions on Hyperliquid."""12001201@property1202def name(self) -> str:1203return "cg_hyperliquid_whale_positions"12041205@property1206def description(self) -> str:1207return """Get current whale positions on Hyperliquid.12081209Shows large active positions with entry price, PnL, leverage, and margin data.12101211Examples:1212- Get whale positions: cg_hyperliquid_whale_positions()"""12131214@property1215def parameters(self) -> dict:1216return {"type": "object", "properties": {}, "required": []}12171218async def execute(self, ctx: ToolContext) -> ToolResult:1219if not COINGLASS_AVAILABLE:1220return ToolResult(success=False, output=None, error="Coinglass tools not available.")12211222try:1223result = await asyncio.to_thread(get_whale_positions)1224if result is None:1225return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1226return ToolResult(success=True, output=result)1227except CoinglassError as e:1228msg = f"Coinglass: {e}"1229if e.suggestion:1230msg += f" ({e.suggestion})"1231return ToolResult(1232success=False, output=None, error=msg)1233except Exception as e:1234return ToolResult(1235success=False, output=None,1236error=f"Coinglass: {type(e).__name__}: {e}")123712381239class HyperliquidPositionsByCoinTool(BaseTool):1240"""Get wallet positions organized by coin on Hyperliquid."""12411242@property1243def name(self) -> str:1244return "cg_hyperliquid_positions_by_coin"12451246@property1247def description(self) -> str:1248return """Get real-time wallet positions for a specific coin on Hyperliquid.12491250Shows all open positions for the specified cryptocurrency.12511252Examples:1253- Get BTC positions: cg_hyperliquid_positions_by_coin(symbol="BTC")1254- Get ETH positions: cg_hyperliquid_positions_by_coin(symbol="ETH")"""12551256@property1257def parameters(self) -> dict:1258return {1259"type": "object",1260"properties": {1261"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"}1262},1263"required": ["symbol"]1264}12651266async def execute(self, ctx: ToolContext, symbol: str) -> ToolResult:1267if not COINGLASS_AVAILABLE:1268return ToolResult(success=False, output=None, error="Coinglass tools not available.")12691270try:1271result = await asyncio.to_thread(get_positions_by_coin, symbol)1272if result is None:1273return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1274return ToolResult(success=True, output=result)1275except CoinglassError as e:1276msg = f"Coinglass: {e}"1277if e.suggestion:1278msg += f" ({e.suggestion})"1279return ToolResult(1280success=False, output=None, error=msg)1281except Exception as e:1282return ToolResult(1283success=False, output=None,1284error=f"Coinglass: {type(e).__name__}: {e}")128512861287class HyperliquidPositionDistributionTool(BaseTool):1288"""Get wallet position distribution on Hyperliquid."""12891290@property1291def name(self) -> str:1292return "cg_hyperliquid_position_distribution"12931294@property1295def description(self) -> str:1296return """Get wallet position distribution on Hyperliquid.12971298Shows distribution by size tiers including address counts, long/short values, sentiment, and P/L distribution.12991300Examples:1301- Get position distribution: cg_hyperliquid_position_distribution()"""13021303@property1304def parameters(self) -> dict:1305return {"type": "object", "properties": {}, "required": []}13061307async def execute(self, ctx: ToolContext) -> ToolResult:1308if not COINGLASS_AVAILABLE:1309return ToolResult(success=False, output=None, error="Coinglass tools not available.")13101311try:1312result = await asyncio.to_thread(get_position_distribution)1313if result is None:1314return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1315return ToolResult(success=True, output=result)1316except CoinglassError as e:1317msg = f"Coinglass: {e}"1318if e.suggestion:1319msg += f" ({e.suggestion})"1320return ToolResult(1321success=False, output=None, error=msg)1322except Exception as e:1323return ToolResult(1324success=False, output=None,1325error=f"Coinglass: {type(e).__name__}: {e}")13261327# ==================== Volume & Flow Tools ====================13281329class TakerVolumeHistoryTool(BaseTool):1330"""Get taker buy/sell volume history for a specific trading pair."""13311332@property1333def name(self) -> str:1334return "cg_taker_volume_history"13351336@property1337def description(self) -> str:1338return """Get historical taker buy/sell volume data for a specific trading pair.13391340Taker volume = aggressive market orders (vs passive limit orders).1341Higher taker buy volume = bullish pressure.1342Higher taker sell volume = bearish pressure.13431344Examples:1345- Get BTC taker volume on Binance: cg_taker_volume_history(symbol="BTC", exchange="Binance", interval="1h")1346- Get ETH 4h intervals: cg_taker_volume_history(symbol="ETH", exchange="OKX", interval="4h", limit=50)"""13471348@property1349def parameters(self) -> dict:1350return {1351"type": "object",1352"properties": {1353"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},1354"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},1355"interval": {"type": "string", "description": "Time interval: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 6h, 8h, 12h, 1d, 1w", "default": "1h"},1356"limit": {"type": "integer", "description": "Number of results (default: 1000, max: 4500)", "default": 1000},1357"start_time": {"type": "integer", "description": "Start timestamp in seconds"},1358"end_time": {"type": "integer", "description": "End timestamp in seconds"}1359},1360"required": ["symbol", "exchange"]1361}13621363async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 1000,1364start_time: Optional[int] = None, end_time: Optional[int] = None) -> ToolResult:1365if not COINGLASS_AVAILABLE:1366return ToolResult(success=False, output=None, error="Coinglass tools not available.")13671368try:1369result = await asyncio.to_thread(get_taker_volume_history, symbol, exchange, interval, limit, start_time, end_time)1370if result is None:1371return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1372return ToolResult(success=True, output=result)1373except CoinglassError as e:1374msg = f"Coinglass: {e}"1375if e.suggestion:1376msg += f" ({e.suggestion})"1377return ToolResult(1378success=False, output=None, error=msg)1379except Exception as e:1380return ToolResult(1381success=False, output=None,1382error=f"Coinglass: {type(e).__name__}: {e}")138313841385class AggregatedTakerVolumeTool(BaseTool):1386"""Get aggregated taker buy/sell volume across all exchanges."""13871388@property1389def name(self) -> str:1390return "cg_aggregated_taker_volume"13911392@property1393def description(self) -> str:1394return """Get aggregated taker buy/sell volume across all exchanges for a coin.13951396Shows total market pressure across all major exchanges.1397More comprehensive than single-exchange data.13981399Examples:1400- Get BTC aggregated volume: cg_aggregated_taker_volume(symbol="BTC", interval="1h")1401- Get ETH 4h: cg_aggregated_taker_volume(symbol="ETH", interval="4h", limit=100)"""14021403@property1404def parameters(self) -> dict:1405return {1406"type": "object",1407"properties": {1408"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},1409"exchange_list": {"type": "string", "description": "Comma-separated exchange list (e.g. 'Binance,OKX,Bybit')"},1410"interval": {"type": "string", "description": "Time interval: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 6h, 8h, 12h, 1d, 1w", "default": "1h"},1411"limit": {"type": "integer", "description": "Number of results (default: 1000, max: 4500)", "default": 1000},1412"start_time": {"type": "integer", "description": "Start timestamp in seconds"},1413"end_time": {"type": "integer", "description": "End timestamp in seconds"}1414},1415"required": ["symbol", "exchange_list"]1416}14171418async def execute(self, ctx: ToolContext, symbol: str, exchange_list: str, interval: str = "1h", limit: int = 1000,1419start_time: Optional[int] = None, end_time: Optional[int] = None) -> ToolResult:1420if not COINGLASS_AVAILABLE:1421return ToolResult(success=False, output=None, error="Coinglass tools not available.")14221423try:1424result = await asyncio.to_thread(get_aggregated_taker_volume, symbol, exchange_list, interval, limit, start_time, end_time)1425if result is None:1426return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1427return ToolResult(success=True, output=result)1428except CoinglassError as e:1429msg = f"Coinglass: {e}"1430if e.suggestion:1431msg += f" ({e.suggestion})"1432return ToolResult(1433success=False, output=None, error=msg)1434except Exception as e:1435return ToolResult(1436success=False, output=None,1437error=f"Coinglass: {type(e).__name__}: {e}")143814391440class CumulativeVolumeDeltaTool(BaseTool):1441"""Get Cumulative Volume Delta (CVD) for trend analysis."""14421443@property1444def name(self) -> str:1445return "cg_cumulative_volume_delta"14461447@property1448def description(self) -> str:1449return """Get Cumulative Volume Delta (CVD) history for a trading pair.14501451CVD = Running total of (taker buy volume - taker sell volume).1452Rising CVD = accumulation (bullish).1453Falling CVD = distribution (bearish).1454Divergences between price and CVD signal trend weakness.14551456Examples:1457- Get BTC CVD on Binance: cg_cumulative_volume_delta(symbol="BTC", exchange="Binance", interval="1h")1458- Get ETH CVD: cg_cumulative_volume_delta(symbol="ETH", exchange="OKX", interval="4h", limit=100)"""14591460@property1461def parameters(self) -> dict:1462return {1463"type": "object",1464"properties": {1465"symbol": {"type": "string", "description": "Trading coin (BTC, ETH, SOL, etc.)"},1466"exchange": {"type": "string", "description": "Exchange name (Binance, OKX, Bybit, etc.)"},1467"interval": {"type": "string", "description": "Time interval: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 6h, 8h, 12h, 1d, 1w", "default": "1h"},1468"limit": {"type": "integer", "description": "Number of results (default: 1000, max: 4500)", "default": 1000},1469"start_time": {"type": "integer", "description": "Start timestamp in seconds"},1470"end_time": {"type": "integer", "description": "End timestamp in seconds"}1471},1472"required": ["symbol", "exchange"]1473}14741475async def execute(self, ctx: ToolContext, symbol: str, exchange: str, interval: str = "1h", limit: int = 1000,1476start_time: Optional[int] = None, end_time: Optional[int] = None) -> ToolResult:1477if not COINGLASS_AVAILABLE:1478return ToolResult(success=False, output=None, error="Coinglass tools not available.")14791480try:1481result = await asyncio.to_thread(get_cumulative_volume_delta, symbol, exchange, interval, limit, start_time, end_time)1482if result is None:1483return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1484return ToolResult(success=True, output=result)1485except CoinglassError as e:1486msg = f"Coinglass: {e}"1487if e.suggestion:1488msg += f" ({e.suggestion})"1489return ToolResult(1490success=False, output=None, error=msg)1491except Exception as e:1492return ToolResult(1493success=False, output=None,1494error=f"Coinglass: {type(e).__name__}: {e}")149514961497class CoinNetflowTool(BaseTool):1498"""Get netflow data for all futures coins."""14991500@property1501def name(self) -> str:1502return "cg_coin_netflow"15031504@property1505def description(self) -> str:1506return """Get coin netflow data for all futures coins.15071508Netflow = Capital flowing into/out of a coin across exchanges.1509Positive netflow = accumulation (bullish signal).1510Negative netflow = distribution (bearish signal).15111512Use for identifying which coins are seeing the strongest capital inflows.15131514Examples:1515- Get all coin netflows: cg_coin_netflow()"""15161517@property1518def parameters(self) -> dict:1519return {"type": "object", "properties": {}, "required": []}15201521async def execute(self, ctx: ToolContext) -> ToolResult:1522if not COINGLASS_AVAILABLE:1523return ToolResult(success=False, output=None, error="Coinglass tools not available.")15241525try:1526result = await asyncio.to_thread(get_coin_netflow)1527if result is None:1528return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1529return ToolResult(success=True, output=result)1530except CoinglassError as e:1531msg = f"Coinglass: {e}"1532if e.suggestion:1533msg += f" ({e.suggestion})"1534return ToolResult(1535success=False, output=None, error=msg)1536except Exception as e:1537return ToolResult(1538success=False, output=None,1539error=f"Coinglass: {type(e).__name__}: {e}")154015411542# ==================== Whale Transfer Tools ====================15431544class WhaleTransferTool(BaseTool):1545"""Get large on-chain transfers (minimum $10M) across major blockchains."""15461547@property1548def name(self) -> str:1549return "cg_whale_transfers"15501551@property1552def description(self) -> str:1553return """Get large on-chain whale transfers (minimum $10M) within the past 6 months.15541555Covers major blockchains: Bitcoin, Ethereum, Tron, Ripple, Dogecoin, Litecoin, Polygon, Algorand, Bitcoin Cash, Solana.15561557Shows transaction hash, asset, amount, exchanges involved, and transfer direction.1558Useful for tracking institutional movements and market impact events.15591560Transfer types:1561- 1 = Inflow (to exchange)1562- 2 = Outflow (from exchange)1563- 3 = Internal (between exchange wallets)15641565Examples:1566- Get recent whale transfers: cg_whale_transfers()"""15671568@property1569def parameters(self) -> dict:1570return {"type": "object", "properties": {}, "required": []}15711572async def execute(self, ctx: ToolContext) -> ToolResult:1573if not COINGLASS_AVAILABLE:1574return ToolResult(success=False, output=None, error="Coinglass tools not available.")15751576try:1577result = await asyncio.to_thread(get_whale_transfers)1578if result is None:1579return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1580return ToolResult(success=True, output=result)1581except CoinglassError as e:1582msg = f"Coinglass: {e}"1583if e.suggestion:1584msg += f" ({e.suggestion})"1585return ToolResult(1586success=False, output=None, error=msg)1587except Exception as e:1588return ToolResult(1589success=False, output=None,1590error=f"Coinglass: {type(e).__name__}: {e}")159115921593# ==================== Bitcoin ETF Tools ====================15941595class BTCETFFlowsTool(BaseTool):1596"""Get Bitcoin ETF flow history (inflows/outflows)."""15971598@property1599def name(self) -> str:1600return "cg_btc_etf_flows"16011602@property1603def description(self) -> str:1604return """Get Bitcoin ETF flow history including daily net inflows and outflows.16051606Shows institutional money movement into/out of Bitcoin through ETFs.1607Large inflows = institutional accumulation (bullish).1608Large outflows = institutional distribution (bearish).16091610Examples:1611- Get BTC ETF flows: cg_btc_etf_flows()"""16121613@property1614def parameters(self) -> dict:1615return {"type": "object", "properties": {}, "required": []}16161617async def execute(self, ctx: ToolContext) -> ToolResult:1618if not COINGLASS_AVAILABLE:1619return ToolResult(success=False, output=None, error="Coinglass tools not available.")16201621try:1622result = await asyncio.to_thread(get_btc_etf_flows)1623if result is None:1624return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1625return ToolResult(success=True, output=result)1626except CoinglassError as e:1627msg = f"Coinglass: {e}"1628if e.suggestion:1629msg += f" ({e.suggestion})"1630return ToolResult(1631success=False, output=None, error=msg)1632except Exception as e:1633return ToolResult(1634success=False, output=None,1635error=f"Coinglass: {type(e).__name__}: {e}")163616371638class BTCETFPremiumDiscountTool(BaseTool):1639"""Get Bitcoin ETF premium/discount rates."""16401641@property1642def name(self) -> str:1643return "cg_btc_etf_premium_discount"16441645@property1646def description(self) -> str:1647return """Get Bitcoin ETF premium/discount rates.16481649Shows how ETF market prices compare to their net asset value (NAV).1650Premium (positive) = trading above NAV (high demand).1651Discount (negative) = trading below NAV (low demand).16521653Examples:1654- Get BTC ETF premium/discount: cg_btc_etf_premium_discount()"""16551656@property1657def parameters(self) -> dict:1658return {"type": "object", "properties": {}, "required": []}16591660async def execute(self, ctx: ToolContext) -> ToolResult:1661if not COINGLASS_AVAILABLE:1662return ToolResult(success=False, output=None, error="Coinglass tools not available.")16631664try:1665result = await asyncio.to_thread(get_btc_etf_premium_discount)1666if result is None:1667return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1668return ToolResult(success=True, output=result)1669except CoinglassError as e:1670msg = f"Coinglass: {e}"1671if e.suggestion:1672msg += f" ({e.suggestion})"1673return ToolResult(1674success=False, output=None, error=msg)1675except Exception as e:1676return ToolResult(1677success=False, output=None,1678error=f"Coinglass: {type(e).__name__}: {e}")167916801681class BTCETFHistoryTool(BaseTool):1682"""Get comprehensive Bitcoin ETF history."""16831684@property1685def name(self) -> str:1686return "cg_btc_etf_history"16871688@property1689def description(self) -> str:1690return """Get comprehensive Bitcoin ETF history.16911692Includes market price, NAV, premium/discount %, shares outstanding, and net assets.16931694Examples:1695- Get IBIT history: cg_btc_etf_history(ticker="IBIT")1696- Get FBTC history: cg_btc_etf_history(ticker="FBTC")"""16971698@property1699def parameters(self) -> dict:1700return {1701"type": "object",1702"properties": {1703"ticker": {"type": "string", "description": "ETF ticker symbol (e.g. IBIT, FBTC, GBTC)"}1704},1705"required": ["ticker"]1706}17071708async def execute(self, ctx: ToolContext, ticker: str) -> ToolResult:1709if not COINGLASS_AVAILABLE:1710return ToolResult(success=False, output=None, error="Coinglass tools not available.")17111712try:1713result = await asyncio.to_thread(get_btc_etf_history, ticker)1714if result is None:1715return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1716return ToolResult(success=True, output=result)1717except CoinglassError as e:1718msg = f"Coinglass: {e}"1719if e.suggestion:1720msg += f" ({e.suggestion})"1721return ToolResult(1722success=False, output=None, error=msg)1723except Exception as e:1724return ToolResult(1725success=False, output=None,1726error=f"Coinglass: {type(e).__name__}: {e}")172717281729class BTCETFListTool(BaseTool):1730"""Get list of Bitcoin ETFs."""17311732@property1733def name(self) -> str:1734return "cg_btc_etf_list"17351736@property1737def description(self) -> str:1738return """Get list of Bitcoin ETFs with key status information.17391740Returns ticker symbols, names, inception dates, and other ETF metadata.17411742Examples:1743- Get BTC ETF list: cg_btc_etf_list()"""17441745@property1746def parameters(self) -> dict:1747return {"type": "object", "properties": {}, "required": []}17481749async def execute(self, ctx: ToolContext) -> ToolResult:1750if not COINGLASS_AVAILABLE:1751return ToolResult(success=False, output=None, error="Coinglass tools not available.")17521753try:1754result = await asyncio.to_thread(get_btc_etf_list)1755if result is None:1756return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1757return ToolResult(success=True, output=result)1758except CoinglassError as e:1759msg = f"Coinglass: {e}"1760if e.suggestion:1761msg += f" ({e.suggestion})"1762return ToolResult(1763success=False, output=None, error=msg)1764except Exception as e:1765return ToolResult(1766success=False, output=None,1767error=f"Coinglass: {type(e).__name__}: {e}")176817691770class HKBTCETFFlowsTool(BaseTool):1771"""Get Hong Kong Bitcoin ETF flow history."""17721773@property1774def name(self) -> str:1775return "cg_hk_btc_etf_flows"17761777@property1778def description(self) -> str:1779return """Get Hong Kong Bitcoin ETF flow history.17801781Shows ETF flow activity for Bitcoin ETFs in the Hong Kong market.1782Useful for tracking Asian institutional demand.17831784Examples:1785- Get HK BTC ETF flows: cg_hk_btc_etf_flows()"""17861787@property1788def parameters(self) -> dict:1789return {"type": "object", "properties": {}, "required": []}17901791async def execute(self, ctx: ToolContext) -> ToolResult:1792if not COINGLASS_AVAILABLE:1793return ToolResult(success=False, output=None, error="Coinglass tools not available.")17941795try:1796result = await asyncio.to_thread(get_hk_btc_etf_flows)1797if result is None:1798return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1799return ToolResult(success=True, output=result)1800except CoinglassError as e:1801msg = f"Coinglass: {e}"1802if e.suggestion:1803msg += f" ({e.suggestion})"1804return ToolResult(1805success=False, output=None, error=msg)1806except Exception as e:1807return ToolResult(1808success=False, output=None,1809error=f"Coinglass: {type(e).__name__}: {e}")181018111812# ==================== Ethereum & Other ETF Tools ====================18131814class ETHETFFlowsTool(BaseTool):1815"""Get Ethereum ETF flow history."""18161817@property1818def name(self) -> str:1819return "cg_eth_etf_flows"18201821@property1822def description(self) -> str:1823return """Get Ethereum ETF flow history including daily net inflows and outflows.18241825Shows institutional money movement into/out of Ethereum through ETFs.18261827Examples:1828- Get ETH ETF flows: cg_eth_etf_flows()"""18291830@property1831def parameters(self) -> dict:1832return {"type": "object", "properties": {}, "required": []}18331834async def execute(self, ctx: ToolContext) -> ToolResult:1835if not COINGLASS_AVAILABLE:1836return ToolResult(success=False, output=None, error="Coinglass tools not available.")18371838try:1839result = await asyncio.to_thread(get_eth_etf_flows)1840if result is None:1841return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1842return ToolResult(success=True, output=result)1843except CoinglassError as e:1844msg = f"Coinglass: {e}"1845if e.suggestion:1846msg += f" ({e.suggestion})"1847return ToolResult(1848success=False, output=None, error=msg)1849except Exception as e:1850return ToolResult(1851success=False, output=None,1852error=f"Coinglass: {type(e).__name__}: {e}")185318541855class ETHETFListTool(BaseTool):1856"""Get list of Ethereum ETFs."""18571858@property1859def name(self) -> str:1860return "cg_eth_etf_list"18611862@property1863def description(self) -> str:1864return """Get list of Ethereum ETFs with key status information.18651866Examples:1867- Get ETH ETF list: cg_eth_etf_list()"""18681869@property1870def parameters(self) -> dict:1871return {"type": "object", "properties": {}, "required": []}18721873async def execute(self, ctx: ToolContext) -> ToolResult:1874if not COINGLASS_AVAILABLE:1875return ToolResult(success=False, output=None, error="Coinglass tools not available.")18761877try:1878result = await asyncio.to_thread(get_eth_etf_list)1879if result is None:1880return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1881return ToolResult(success=True, output=result)1882except CoinglassError as e:1883msg = f"Coinglass: {e}"1884if e.suggestion:1885msg += f" ({e.suggestion})"1886return ToolResult(1887success=False, output=None, error=msg)1888except Exception as e:1889return ToolResult(1890success=False, output=None,1891error=f"Coinglass: {type(e).__name__}: {e}")189218931894class SOLETFFlowsTool(BaseTool):1895"""Get Solana ETF flow history."""18961897@property1898def name(self) -> str:1899return "cg_sol_etf_flows"19001901@property1902def description(self) -> str:1903return """Get Solana ETF flow history including daily net inflows and outflows.19041905Examples:1906- Get SOL ETF flows: cg_sol_etf_flows()"""19071908@property1909def parameters(self) -> dict:1910return {"type": "object", "properties": {}, "required": []}19111912async def execute(self, ctx: ToolContext) -> ToolResult:1913if not COINGLASS_AVAILABLE:1914return ToolResult(success=False, output=None, error="Coinglass tools not available.")19151916try:1917result = await asyncio.to_thread(get_sol_etf_flows)1918if result is None:1919return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1920return ToolResult(success=True, output=result)1921except CoinglassError as e:1922msg = f"Coinglass: {e}"1923if e.suggestion:1924msg += f" ({e.suggestion})"1925return ToolResult(1926success=False, output=None, error=msg)1927except Exception as e:1928return ToolResult(1929success=False, output=None,1930error=f"Coinglass: {type(e).__name__}: {e}")193119321933class XRPETFFlowsTool(BaseTool):1934"""Get XRP ETF flow history."""19351936@property1937def name(self) -> str:1938return "cg_xrp_etf_flows"19391940@property1941def description(self) -> str:1942return """Get XRP ETF flow history including daily net inflows and outflows.19431944Examples:1945- Get XRP ETF flows: cg_xrp_etf_flows()"""19461947@property1948def parameters(self) -> dict:1949return {"type": "object", "properties": {}, "required": []}19501951async def execute(self, ctx: ToolContext) -> ToolResult:1952if not COINGLASS_AVAILABLE:1953return ToolResult(success=False, output=None, error="Coinglass tools not available.")19541955try:1956result = await asyncio.to_thread(get_xrp_etf_flows)1957if result is None:1958return ToolResult(success=False, output=None, error="No data returned. The API returned an empty result.")1959return ToolResult(success=True, output=result)1960except CoinglassError as e:1961msg = f"Coinglass: {e}"1962if e.suggestion:1963msg += f" ({e.suggestion})"1964return ToolResult(1965success=False, output=None, error=msg)1966except Exception as e:1967return ToolResult(1968success=False, output=None,1969error=f"Coinglass: {type(e).__name__}: {e}")197019711972