import re import json import csv import sys import requests from bs4 import BeautifulSoup FX_CACHE = {} def get_fx_rate(currency): if currency in FX_CACHE: return FX_CACHE[currency] if currency == "GBP": return 1.0 url = f"https://open.er-api.com/v6/latest/{currency}" r = requests.get(url, timeout=20) rate = r.json()["rates"]["GBP"] FX_CACHE[currency] = rate return rate def get_price(market, ticker): url = f"https://web.freetrade.io/universe/{market}/{ticker}" response = requests.get(url, headers={ "User-Agent": "Mozilla/5.0" }, timeout=20) text = BeautifulSoup(response.text, "html.parser").get_text(" ", strip=True) m = re.search(r"Latest price\s*:\s*[£$€]([0-9,.]+)", text) if m: return float(m.group(1).replace(",", "")) return None def get_currency(market): return {"GB": "GBP", "US": "USD"}.get(market, "GBP") holdings_file = sys.argv[1] if len(sys.argv) > 1 else "holdings.csv" results = [] with open(holdings_file) as f: reader = csv.reader(f) for row in reader: ticker, market, shares = row[0].strip(), row[1].strip(), float(row[2].strip()) currency = get_currency(market) price = get_price(market, ticker) if price is None: results.append({ "ticker": ticker, "market": market, "currency": currency, "shares": shares, "price": None, "fx_rate": None, "total_value_gbp": None }) continue fx = get_fx_rate(currency) total_gbp = round(price * shares * fx, 2) results.append({ "ticker": ticker, "market": market, "currency": currency, "shares": shares, "price": price, "fx_rate": fx, "total_value_gbp": total_gbp }) print(json.dumps(results, indent=2))