Files
profitable-expert-advisor/polymarket/api/gamma_client.py
T
zhutoutoutousan 98a87a69ca Update
2026-02-13 08:03:25 +01:00

178 lines
5.4 KiB
Python

"""
Polymarket Gamma API Client
Provides market discovery, metadata, and event data.
API Documentation: https://docs.polymarket.com/developers/gamma-markets-api/overview
"""
import requests
from typing import List, Dict, Optional, Any
from datetime import datetime
import time
class GammaClient:
"""Client for Polymarket Gamma API - Market discovery and metadata"""
BASE_URL = "https://gamma-api.polymarket.com"
def __init__(self, timeout: int = 30):
"""
Initialize Gamma API client.
Args:
timeout: Request timeout in seconds
"""
self.timeout = timeout
self.session = requests.Session()
self.session.headers.update({
'Accept': 'application/json',
'User-Agent': 'Polymarket-Trading-Framework/1.0'
})
def _get(self, endpoint: str, params: Optional[Dict] = None) -> Dict:
"""Make GET request with error handling"""
url = f"{self.BASE_URL}{endpoint}"
try:
response = self.session.get(url, params=params, timeout=self.timeout)
response.raise_for_status()
data = response.json()
# According to docs, /events returns an array directly
# But handle both array and dict responses
return data
except requests.exceptions.RequestException as e:
raise Exception(f"Gamma API error: {e}")
def get_events(self,
active: bool = True,
closed: bool = False,
limit: int = 100,
tag_id: Optional[int] = None,
series_id: Optional[int] = None,
order: Optional[str] = None,
ascending: bool = True) -> List[Dict]:
"""
Fetch active events/markets.
Args:
active: Filter for active events
closed: Filter for closed events
limit: Maximum number of results
tag_id: Filter by tag/category ID
series_id: Filter by series ID (for sports)
order: Sort order (e.g., 'startTime')
ascending: Sort ascending or descending
Returns:
List of event dictionaries
"""
params = {
'active': str(active).lower(),
'closed': str(closed).lower(),
'limit': limit
}
if tag_id:
params['tag_id'] = tag_id
if series_id:
params['series_id'] = series_id
if order:
params['order'] = order
params['ascending'] = str(ascending).lower()
return self._get('/events', params=params)
def get_event_by_slug(self, slug: str) -> Optional[Dict]:
"""
Get event details by slug.
Args:
slug: Event slug (e.g., 'will-bitcoin-reach-100k-by-2025')
Returns:
Event dictionary or None if not found
"""
events = self.get_events(limit=1)
for event in events:
if event.get('slug') == slug:
return event
return None
def get_market_by_slug(self, slug: str) -> Optional[Dict]:
"""
Get market details by slug.
Args:
slug: Market slug
Returns:
Market dictionary with clobTokenIds, outcomes, prices
"""
params = {'slug': slug}
markets = self._get('/markets', params=params)
return markets[0] if markets else None
def get_tags(self, limit: int = 100) -> List[Dict]:
"""
Get all available tags/categories.
Args:
limit: Maximum number of tags to return
Returns:
List of tag dictionaries
"""
params = {'limit': limit}
return self._get('/tags', params=params)
def get_sports(self) -> List[Dict]:
"""
Get all supported sports leagues.
Returns:
List of sports league dictionaries
"""
return self._get('/sports')
def get_market_prices(self, market: Dict) -> Dict[str, float]:
"""
Extract current prices from market data.
Args:
market: Market dictionary with outcomes and outcomePrices
Returns:
Dictionary mapping outcome to price (probability)
"""
import json
outcomes = json.loads(market.get('outcomes', '[]'))
prices = json.loads(market.get('outcomePrices', '[]'))
return {outcome: float(price) for outcome, price in zip(outcomes, prices)}
def search_events(self, query: str, limit: int = 20) -> List[Dict]:
"""
Search events by title/keywords.
Args:
query: Search query
limit: Maximum results
Returns:
List of matching events
"""
# Note: This is a simplified search - actual API may have different endpoint
all_events = self.get_events(limit=1000)
query_lower = query.lower()
matches = []
for event in all_events:
title = event.get('title', '').lower()
if query_lower in title:
matches.append(event)
if len(matches) >= limit:
break
return matches