Skip to content

Quantitative Finance

FinanceLib includes a comprehensive quant module with academic-grade financial mathematics for risk analysis, portfolio optimization, and statistical testing.

Return Analysis

from financelib import Stock
from financelib.quant.returns import (
    simple_returns, log_returns, cumulative_returns,
    annualized_return, annualized_volatility,
    rolling_volatility, rolling_sharpe,
)

stock = Stock("THYAO.IS")
df = stock.get_historical_data(period="1y")
prices = df["Close"]

# Calculate returns
ret = simple_returns(prices)
log_ret = log_returns(prices)
cum_ret = cumulative_returns(ret)

print(f"Annualized Return: {annualized_return(ret):.2%}")
print(f"Annualized Volatility: {annualized_volatility(ret):.2%}")

Risk Metrics

from financelib.quant.risk_metrics import (
    sharpe_ratio, sortino_ratio, max_drawdown,
    value_at_risk, conditional_var,
)

sr = sharpe_ratio(ret, risk_free_rate=0.45)  # TCMB rate
sortino = sortino_ratio(ret, risk_free_rate=0.45)
mdd = max_drawdown(prices)
var_95 = value_at_risk(ret, confidence=0.95)
cvar_95 = conditional_var(ret, confidence=0.95)

print(f"Sharpe Ratio: {sr:.2f}")
print(f"Sortino Ratio: {sortino:.2f}")
print(f"Max Drawdown: {mdd:.2%}")
print(f"VaR (95%): {var_95:.4f}")
print(f"CVaR (95%): {cvar_95:.4f}")

CAPM: Alpha & Beta

from financelib.quant.risk_metrics import beta, alpha

# Compare THYAO against XU100 (BIST-100 index)
thyao = Stock("THYAO.IS")
xu100 = Stock("XU100.IS")

thyao_ret = simple_returns(thyao.get_historical_data(period="1y")["Close"])
xu100_ret = simple_returns(xu100.get_historical_data(period="1y")["Close"])

b = beta(thyao_ret, xu100_ret)
a = alpha(thyao_ret, xu100_ret, risk_free_rate=0.45)

print(f"Beta: {b:.2f}")
print(f"Alpha: {a:.2%}")

Portfolio Optimization

import numpy as np
from financelib.quant.portfolio import (
    minimum_variance_weights, portfolio_return,
    portfolio_volatility, portfolio_sharpe,
    covariance_matrix,
)

# Multi-asset portfolio
symbols = ["THYAO.IS", "GARAN.IS", "ASELS.IS"]
returns_df = pd.DataFrame()
for sym in symbols:
    s = Stock(sym)
    df = s.get_historical_data(period="1y")
    returns_df[sym] = simple_returns(df["Close"])

# Minimum variance portfolio
weights = minimum_variance_weights(returns_df.dropna())
print(f"Optimal weights: {dict(zip(symbols, weights.round(3)))}")
print(f"Portfolio Sharpe: {portfolio_sharpe(weights, returns_df.dropna()):.2f}")

Statistical Tests

from financelib.quant.statistics import (
    skewness, kurtosis, jarque_bera_test,
    hurst_exponent, half_life, autocorrelation,
)

print(f"Skewness: {skewness(ret):.3f}")
print(f"Excess Kurtosis: {kurtosis(ret):.3f}")

jb_stat, p_value = jarque_bera_test(ret)
print(f"Jarque-Bera: {jb_stat:.2f} (p={p_value:.4f})")

h = hurst_exponent(prices)
print(f"Hurst Exponent: {h:.3f}")
if h < 0.5:
    print("  → Mean-reverting")
elif h > 0.5:
    print("  → Trending")
else:
    print("  → Random walk")

hl = half_life(prices)
print(f"Half-life: {hl:.1f} periods")

ac = autocorrelation(ret, lag=1)
print(f"Autocorrelation (lag=1): {ac:.3f}")

Available Functions

Category Functions
Returns simple_returns, log_returns, cumulative_returns, annualized_return, annualized_volatility, rolling_volatility, rolling_sharpe, rolling_beta
Risk sharpe_ratio, sortino_ratio, max_drawdown, calmar_ratio, value_at_risk, conditional_var, beta, alpha, information_ratio, treynor_ratio
Portfolio portfolio_return, portfolio_volatility, portfolio_sharpe, minimum_variance_weights, equal_weight_portfolio, covariance_matrix, correlation_matrix
Statistics skewness, kurtosis, jarque_bera_test, hurst_exponent, half_life, z_score, rolling_z_score, autocorrelation