Financial functions for Python providing performance analysis, risk metrics, portfolio optimization, and data retrieval for quantitative finance
—
Financial data downloading with Yahoo Finance integration, CSV support, and flexible data provider architecture. Provides seamless access to financial time series data for analysis and backtesting.
Primary interface for downloading financial data with flexible provider support and data processing options.
def get(tickers, provider=None, common_dates=True, forward_fill=False, clean_tickers=True, column_names=None, ticker_field_sep=":", mrefresh=False, existing=None, **kwargs):
"""
Download financial data and return as DataFrame.
Parameters:
- tickers (str, list): Ticker symbols to download (can be CSV string, list, or individual ticker)
- provider (function): Data provider function (default: yf - Yahoo Finance)
- common_dates (bool): Keep only dates common across all tickers (default: True)
- forward_fill (bool): Forward fill missing values (default: False)
- clean_tickers (bool): Clean ticker names using utils.clean_ticker (default: True)
- column_names (list): Custom column names for DataFrame (default: None)
- ticker_field_sep (str): Separator for ticker:field specification (default: ":")
- mrefresh (bool): Ignore memoization cache and refresh data (default: False)
- existing (pd.DataFrame): Existing DataFrame to append new data to (default: None)
- **kwargs: Additional arguments passed to the provider function
Returns:
pd.DataFrame: Financial data with tickers as columns and dates as index
"""Default data provider using yfinance library for stock, ETF, and index data.
def yf(ticker, field, start=None, end=None, mrefresh=False):
"""
Yahoo Finance data provider using yfinance library.
Parameters:
- ticker (str): Stock ticker symbol (e.g., 'AAPL', 'SPY')
- field (str): Data field to retrieve (default: 'Adj Close')
Available fields: 'Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume'
- start (str, datetime): Start date for data (default: None for all available)
- end (str, datetime): End date for data (default: None for most recent)
- mrefresh (bool): Ignore memoization cache (default: False)
Returns:
pd.Series: Time series data for the specified ticker and field
"""Local CSV file data provider with pandas integration.
def csv(ticker, path="data.csv", field="", mrefresh=False, **kwargs):
"""
CSV file data provider with pandas read_csv wrapper.
Parameters:
- ticker (str): Column name in CSV file to extract
- path (str): Path to CSV file (default: "data.csv")
- field (str): Additional field specification (default: "")
- mrefresh (bool): Ignore memoization cache (default: False)
- **kwargs: Additional arguments passed to pandas.read_csv()
Returns:
pd.Series: Time series data from CSV file
"""def web(ticker, field=None, start=None, end=None, mrefresh=False, source="yahoo"):
"""
Legacy web data provider (DEPRECATED - use yf() instead).
Parameters:
- ticker (str): Ticker symbol
- field (str): Data field (default: None)
- start: Start date (default: None)
- end: End date (default: None)
- mrefresh (bool): Ignore cache (default: False)
- source (str): Data source (default: "yahoo")
Returns:
pd.Series: Time series data
Note: This function is deprecated. Use yf() for Yahoo Finance data.
"""DEFAULT_PROVIDER = yf # Default data provider set to Yahoo Financeimport ffn
# Download single stock
aapl = ffn.get('AAPL', start='2020-01-01')
print(f"AAPL data shape: {aapl.shape}")
print(f"Date range: {aapl.index[0]} to {aapl.index[-1]}")
# Download multiple stocks
stocks = ffn.get('AAPL,MSFT,GOOGL', start='2020-01-01', end='2023-01-01')
print(f"Multi-stock data shape: {stocks.shape}")
print(f"Columns: {stocks.columns.tolist()}")
# Download with list format
tech_stocks = ffn.get(['AAPL', 'MSFT', 'GOOGL', 'AMZN'], start='2020-01-01')
print(f"Tech stocks: {tech_stocks.columns.tolist()}")import ffn
# Download with forward fill for missing data
data_ff = ffn.get('AAPL,BND', start='2020-01-01', forward_fill=True)
print(f"Forward filled data gaps: {data_ff.isnull().sum().sum()}")
# Download without common dates (keep all available data)
data_all = ffn.get('AAPL,VTI', start='2020-01-01', common_dates=False)
print(f"All dates shape: {data_all.shape}")
# Custom column names
custom_data = ffn.get('AAPL,MSFT', start='2020-01-01',
column_names=['Apple', 'Microsoft'])
print(f"Custom columns: {custom_data.columns.tolist()}")
# Refresh cached data
fresh_data = ffn.get('AAPL', start='2023-01-01', mrefresh=True)
print("Data refreshed from source")import ffn
# Download different price fields using ticker:field syntax
price_data = ffn.get('AAPL:Open,AAPL:High,AAPL:Low,AAPL:Close', start='2023-01-01')
print(f"OHLC data columns: {price_data.columns.tolist()}")
# Volume data
volume_data = ffn.get('AAPL:Volume,MSFT:Volume', start='2023-01-01')
print(f"Volume data shape: {volume_data.shape}")
# Direct provider usage for specific fields
ohlcv_data = {}
for field in ['Open', 'High', 'Low', 'Close', 'Volume']:
ohlcv_data[field] = ffn.yf('AAPL', field=field, start='2023-01-01')
import pandas as pd
ohlcv_df = pd.DataFrame(ohlcv_data)
print(f"OHLCV DataFrame shape: {ohlcv_df.shape}")import ffn
import pandas as pd
# Create sample CSV data
sample_data = pd.DataFrame({
'Date': pd.date_range('2020-01-01', periods=100, freq='D'),
'Custom_Asset_1': (1 + 0.001 * np.random.randn(100)).cumprod() * 100,
'Custom_Asset_2': (1 + 0.0015 * np.random.randn(100)).cumprod() * 100
})
sample_data.set_index('Date').to_csv('sample_data.csv')
# Load CSV data using ffn
csv_data = ffn.get('Custom_Asset_1,Custom_Asset_2', provider=ffn.csv,
path='sample_data.csv')
print(f"CSV data shape: {csv_data.shape}")
# Combine CSV and web data
combined = ffn.get('AAPL', start='2020-01-01', end='2020-04-09') # 100 days
combined = ffn.get('Custom_Asset_1,Custom_Asset_2', provider=ffn.csv,
path='sample_data.csv', existing=combined)
print(f"Combined data columns: {combined.columns.tolist()}")import ffn
# Multi-asset data pipeline
def build_portfolio_data(tickers, start_date, benchmark='SPY'):
"""Build complete dataset for portfolio analysis."""
# Download core assets
assets = ffn.get(tickers, start=start_date, forward_fill=True)
# Add benchmark
benchmark_data = ffn.get(benchmark, start=start_date)
benchmark_data.columns = ['Benchmark']
# Combine datasets
full_data = pd.concat([assets, benchmark_data], axis=1)
# Remove any remaining NaN values
full_data = full_data.dropna()
return full_data
# Usage
portfolio_data = build_portfolio_data(
['AAPL', 'MSFT', 'GOOGL', 'AMZN'],
start_date='2020-01-01',
benchmark='QQQ'
)
print(f"Portfolio dataset shape: {portfolio_data.shape}")
print(f"Date range: {portfolio_data.index[0]} to {portfolio_data.index[-1]}")
# Quick analysis
returns = ffn.to_returns(portfolio_data).dropna()
correlations = returns.corr()
print(f"\nCorrelation with benchmark:")
print(correlations['Benchmark'].drop('Benchmark').round(3))import ffn
# Handle invalid tickers gracefully
tickers = ['AAPL', 'INVALID_TICKER', 'MSFT']
try:
data = ffn.get(tickers, start='2020-01-01')
print(f"Successfully downloaded: {data.columns.tolist()}")
except Exception as e:
print(f"Error downloading some tickers: {e}")
# Download valid tickers individually
valid_data = {}
for ticker in ['AAPL', 'MSFT']: # Skip invalid
try:
valid_data[ticker] = ffn.get(ticker, start='2020-01-01')[ticker]
except:
continue
data = pd.DataFrame(valid_data)
print(f"Recovered data: {data.columns.tolist()}")
# Data quality checks
print(f"Missing values: {data.isnull().sum().sum()}")
print(f"Data range: {data.index[0]} to {data.index[-1]}")
print(f"Business days in range: {len(data)}")
# Clean and prepare for analysis
clean_data = (data
.dropna() # Remove missing values
.asfreq('D') # Ensure daily frequency
.forward_fill() # Fill weekend gaps
)
print(f"Cleaned data shape: {clean_data.shape}")Install with Tessl CLI
npx tessl i tessl/pypi-ffn