spb/vquant Public MIT
VibeQuant — AI-powered institutional-grade financial intelligence platform.
TypeScript 84.3%
Python 11.7%
JavaScript 1.6%
CSS 1.5%
HTML 0.7%
1#!/usr/bin/env python32# =============================================================================3# VibeQuant (vquant) — AI-Powered Financial Intelligence Platform4# -----------------------------------------------------------------------------5# File: server/services/fmpClient.py6#7# Author: Simon-Pierre Boucher8# Contact: contact@spboucher.ai9# Website: https://www.spboucher.ai10# Demo: https://www.vquant.ai11# License: MIT (see LICENSE)12#13# Copyright © 2026 Simon-Pierre Boucher. All rights reserved.14# =============================================================================1516"""17FMP API Client for Python Services18Fetches financial data directly from Financial Modeling Prep API19"""2021import os22import requests23from typing import List, Dict, Any, Optional24import sys2526# Get API key from environment27FMP_API_KEY = os.environ.get('FMP_API_KEY')28FMP_BASE_URL = 'https://financialmodelingprep.com/stable'2930def get_historical_prices(symbol: str, from_date: Optional[str] = None, to_date: Optional[str] = None) -> Dict[str, Any]:31 """32 Fetch historical stock prices from FMP API3334 Args:35 symbol: Stock ticker symbol (e.g., 'AAPL')36 from_date: Start date in YYYY-MM-DD format (optional)37 to_date: End date in YYYY-MM-DD format (optional)3839 Returns:40 Dictionary with symbol and historical price data41 """42 if not FMP_API_KEY:43 raise ValueError("FMP_API_KEY environment variable not set")4445 url = f"{FMP_BASE_URL}/historical-price-eod/full"46 params = {'apikey': FMP_API_KEY, 'symbol': symbol}4748 if from_date:49 params['from'] = from_date50 if to_date:51 params['to'] = to_date5253 try:54 response = requests.get(url, params=params, timeout=15)55 response.raise_for_status()56 data = response.json()5758 # Stable API returns flat array; wrap to match legacy format59 if isinstance(data, list):60 historical = data61 else:62 historical = data.get('historical', [])6364 # Limit to 504 most recent data points (2 years) for performance65 if len(historical) > 504:66 historical = historical[:504]6768 return {'symbol': symbol, 'historical': historical}69 except requests.exceptions.RequestException as e:70 raise Exception(f"Failed to fetch data from FMP API: {str(e)}")717273def get_stock_quote(symbol: str) -> Dict[str, Any]:74 """75 Fetch current stock quote from FMP API7677 Args:78 symbol: Stock ticker symbol (e.g., 'AAPL')7980 Returns:81 Dictionary with current stock quote data82 """83 if not FMP_API_KEY:84 raise ValueError("FMP_API_KEY environment variable not set")8586 url = f"{FMP_BASE_URL}/quote"87 params = {'apikey': FMP_API_KEY, 'symbol': symbol}8889 try:90 response = requests.get(url, params=params, timeout=15)91 response.raise_for_status()92 data = response.json()9394 if not data or len(data) == 0:95 raise ValueError(f"No quote data found for symbol {symbol}")9697 return data[0] # Return first item98 except requests.exceptions.RequestException as e:99 raise Exception(f"Failed to fetch quote from FMP API: {str(e)}")100101102def calculate_historical_volatility(prices: List[float], annualize: bool = True) -> float:103 """104 Calculate historical volatility from price data105106 Args:107 prices: List of historical prices108 annualize: Whether to annualize the volatility (default: True, uses 252 trading days)109110 Returns:111 Annualized volatility as a decimal (e.g., 0.25 for 25%)112 """113 import numpy as np114115 if len(prices) < 2:116 raise ValueError("Need at least 2 prices to calculate volatility")117118 # Calculate daily returns119 prices_array = np.array(prices)120 returns = np.diff(prices_array) / prices_array[:-1]121122 # Calculate standard deviation of returns123 volatility = np.std(returns)124125 # Annualize if requested (252 trading days per year)126 if annualize:127 volatility = volatility * np.sqrt(252)128129 return float(volatility)130131132if __name__ == "__main__":133 # Test the module134 try:135 print("Testing FMP Client...")136137 # Test historical prices138 print("\n1. Testing get_historical_prices('AAPL')...")139 hist_data = get_historical_prices('AAPL')140 print(f" ✓ Fetched {len(hist_data['historical'])} historical records")141142 # Test stock quote143 print("\n2. Testing get_stock_quote('AAPL')...")144 quote = get_stock_quote('AAPL')145 print(f" ✓ Current price: ${quote['price']}")146147 # Test volatility calculation148 print("\n3. Testing calculate_historical_volatility()...")149 prices = [h['close'] for h in hist_data['historical'][:30]] # Last 30 days150 vol = calculate_historical_volatility(prices)151 print(f" ✓ 30-day volatility: {vol*100:.2f}%")152153 print("\n✓ All tests passed!")154155 except Exception as e:156 print(f"\n✗ Error: {e}", file=sys.stderr)157 sys.exit(1)158