diff --git a/requirements.txt b/requirements.txt index 6f16e08..5fbc4bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ fastapi uvicorn pandas python-multipart +yfinance diff --git a/src/metadata/__pycache__/fetcher.cpython-313.pyc b/src/metadata/__pycache__/fetcher.cpython-313.pyc new file mode 100644 index 0000000..7f0d388 Binary files /dev/null and b/src/metadata/__pycache__/fetcher.cpython-313.pyc differ diff --git a/src/metadata/fetcher.py b/src/metadata/fetcher.py index 0258602..0b0eda0 100644 --- a/src/metadata/fetcher.py +++ b/src/metadata/fetcher.py @@ -35,7 +35,38 @@ def get_processed_isins(): return [] return [] + from bs4 import BeautifulSoup +import yfinance as yf + +def fetch_ticker_from_openfigi(isin): + """Use OpenFIGI API to map ISIN to ticker symbol""" + try: + headers = {'Content-Type': 'application/json'} + payload = [{'idType': 'ID_ISIN', 'idValue': isin}] + response = requests.post('https://api.openfigi.com/v3/mapping', + json=payload, headers=headers, timeout=10) + if response.status_code == 200: + data = response.json() + if data and len(data) > 0 and 'data' in data[0]: + # Get the first result's ticker + for item in data[0]['data']: + if 'ticker' in item: + return item['ticker'] + except Exception as e: + logger.error(f"OpenFIGI error for {isin}: {e}") + return None + +def fetch_sector_from_yfinance(ticker): + """Use yfinance to get sector information from ticker symbol""" + try: + stock = yf.Ticker(ticker) + info = stock.info + if info and 'sector' in info: + return info['sector'] + except Exception as e: + logger.error(f"yfinance error for {ticker}: {e}") + return None def fetch_metadata(isin): logger.info(f"Fetching metadata for ISIN: {isin}") @@ -65,19 +96,17 @@ def fetch_metadata(isin): except Exception as e: logger.error(f"GLEIF error for {isin}: {e}") - # 2. Yahoo Finance for Sector + # 2. Sector from OpenFIGI + yfinance try: - # We use the lookup URL as discussed - yahoo_url = f"https://finance.yahoo.com/lookup/?s={isin}" - res = requests.get(yahoo_url, headers=headers, timeout=10) - if res.status_code == 200: - soup = BeautifulSoup(res.text, 'html.parser') - # Look for the sector link in the results table - sector_link = soup.find('a', href=lambda x: x and '/sector/' in x) - if sector_link: - metadata['sector'] = sector_link.text.strip() + ticker = fetch_ticker_from_openfigi(isin) + if ticker: + logger.info(f"Found ticker {ticker} for ISIN {isin}") + sector = fetch_sector_from_yfinance(ticker) + if sector: + metadata['sector'] = sector + logger.info(f"Found sector {sector} for {isin}") except Exception as e: - logger.error(f"Yahoo sector error for {isin}: {e}") + logger.error(f"Sector fetching error for {isin}: {e}") # 3. Continent mapping from Country Code if metadata['country'] != 'Unknown': diff --git a/test_sector_fetch.py b/test_sector_fetch.py new file mode 100644 index 0000000..0f59ae9 --- /dev/null +++ b/test_sector_fetch.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +"""Test script to verify the improved sector metadata fetching""" + +import sys +sys.path.insert(0, '/Users/melchiorreimers/.gemini/antigravity/scratch/trading_daemon/src') + +from metadata.fetcher import fetch_ticker_from_openfigi, fetch_sector_from_yfinance, fetch_metadata + +# Test ISINs from different regions and sectors +test_isins = [ + 'US69553P1003', # PagerDuty (US, Technology) + 'DE000LS1LUS9', # German security + 'US0378331005', # Apple (US, Technology) +] + +print("Testing improved sector metadata fetching...\n") + +for isin in test_isins: + print(f"Testing ISIN: {isin}") + + # Test ticker lookup + ticker = fetch_ticker_from_openfigi(isin) + print(f" Ticker: {ticker}") + + # Test sector lookup if ticker found + if ticker: + sector = fetch_sector_from_yfinance(ticker) + print(f" Sector: {sector}") + + print() + +print("\nFull metadata test for US69553P1003:") +metadata = fetch_metadata('US69553P1003') +for key, value in metadata.items(): + print(f" {key}: {value}")