Spaces:
Paused
Paused
| """ | |
| Gate.io Public API Integration | |
| Fetch candle data for USDT perpetual futures | |
| """ | |
| import aiohttp | |
| import pandas as pd | |
| from typing import List, Dict, Optional | |
| from datetime import datetime, timedelta | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| class GateIOClient: | |
| """Gate.io public API client for candle data""" | |
| def __init__(self, base_url: str = "https://api.gateio.ws/api/v4"): | |
| self.base_url = base_url | |
| self.session = None | |
| async def __aenter__(self): | |
| self.session = aiohttp.ClientSession() | |
| return self | |
| async def __aexit__(self, exc_type, exc_val, exc_tb): | |
| if self.session: | |
| await self.session.close() | |
| async def get_usdt_perpetuals(self) -> List[Dict]: | |
| """Get list of USDT perpetual futures""" | |
| url = f"{self.base_url}/futures/usdt/contracts" | |
| async with self.session.get(url) as response: | |
| data = await response.json() | |
| # Filter for USDT-settled perpetuals | |
| perpetuals = [ | |
| { | |
| 'symbol': c['name'], | |
| 'name': c.get('name', ''), | |
| 'quanto_multiplier': c.get('quanto_multiplier', 1), | |
| 'tick_size': c.get('order_price_round', 1e-8), | |
| 'position_size': c.get('position_size', 1) | |
| } | |
| for c in data | |
| if c.get('name', '').endswith('_USDT') and c.get('quanto_multiplier') is not None | |
| ] | |
| return perpetuals | |
| async def get_candles( | |
| self, | |
| symbol: str, | |
| interval: str = '1h', | |
| limit: int = 1000, | |
| from_: Optional[int] = None, | |
| to: Optional[int] = None | |
| ) -> List[Dict]: | |
| """Get candle data for a symbol""" | |
| url = f"{self.base_url}/futures/usdt/candlesticks" | |
| params = { | |
| 'contract': symbol, | |
| 'interval': interval, | |
| 'limit': limit | |
| } | |
| if from_: | |
| params['from'] = from_ | |
| if to: | |
| params['to'] = to | |
| async with self.session.get(url, params=params) as response: | |
| data = await response.json() | |
| # Gate.io returns data in reverse chronological order | |
| candles = [ | |
| { | |
| 'timestamp': datetime.fromtimestamp(int(c[0])), | |
| 'volume': float(c[1]), | |
| 'close': float(c[2]), | |
| 'high': float(c[3]), | |
| 'low': float(c[4]), | |
| 'open': float(c[5]), | |
| 'quote_volume': float(c[1]) * float(c[2]) # Approximate | |
| } | |
| for c in reversed(data) | |
| ] | |
| return candles | |
| async def get_ticker(self, symbol: str) -> Dict: | |
| """Get current ticker data""" | |
| url = f"{self.base_url}/futures/usdt/ticker" | |
| params = {'contract': symbol} | |
| async with self.session.get(url, params=params) as response: | |
| data = await response.json() | |
| if isinstance(data, list) and len(data) > 0: | |
| return { | |
| 'symbol': symbol, | |
| 'last_price': float(data[0].get('last', 0)), | |
| 'volume_24h': float(data[0].get('volume_24h', 0)), | |
| 'quote_volume_24h': float(data[0].get('volume_24h_quote', 0)), | |
| 'high_24h': float(data[0].get('high_24h', 0)), | |
| 'low_24h': float(data[0].get('low_24h', 0)) | |
| } | |
| return {} | |
| async def filter_symbols( | |
| self, | |
| min_price: float = 0.10, | |
| min_volume_24h: float = 50000.0 | |
| ) -> List[Dict]: | |
| """Filter symbols by price and volume criteria""" | |
| perpetuals = await self.get_usdt_perpetuals() | |
| filtered = [] | |
| for contract in perpetuals: | |
| symbol = contract['symbol'] | |
| ticker = await self.get_ticker(symbol) | |
| if ticker: | |
| last_price = ticker.get('last_price', 0) | |
| volume_24h = ticker.get('volume_24h', 0) | |
| if last_price > 0 and last_price < min_price and volume_24h >= min_volume_24h: | |
| filtered.append({ | |
| **contract, | |
| **ticker | |
| }) | |
| return filtered | |
| async def backfill_candles( | |
| self, | |
| symbol: str, | |
| days: int = 30, | |
| interval: str = '1h' | |
| ) -> pd.DataFrame: | |
| """Backfill historical candle data""" | |
| to_time = int(datetime.now().timestamp()) | |
| from_time = int((datetime.now() - timedelta(days=days)).timestamp()) | |
| candles = await self.get_candles( | |
| symbol, | |
| interval=interval, | |
| from_=from_time, | |
| to=to_time | |
| ) | |
| df = pd.DataFrame(candles) | |
| if not df.empty: | |
| df = df.sort_values('timestamp') | |
| return df | |