Skip to main content

A Python library for Value at Risk (VaR) calculations and other financial aplications

Project description

VaR Calculation Library

Overview

This Python library provides functions to calculate the Value at Risk (VaR) and Conditional Value at Risk (cVaR) for financial portfolios, including stock and forex portfolios. These risk measures help in understanding potential losses under given confidence levels. It also allows you to conveniently download price data from Yahoo Finance and perform portfolio optimization using multiple strategies.

Features

  • Download stock price data.
  • Calculate VaR and cVaR for a stock portfolio.
  • Calculate VaR and cVaR for a forex portfolio.
  • Supports both long and short positions.
  • Outputs results in both percentage and cash value.
  • Rebalance a stock portfolio.
  • Portfolio optimization for multiple strategies.

Installation

Ensure you have the required dependencies installed:

pip install scipy
pip install numpy 
pip install pandas
pip install yfinance
pip install matplotlib

Then

pip install vartools

Also run

pip install --upgrade vartools

To get the latest version.

Functions

get_data(stocks, start_date, end_date, type)

Parameters

  • stocks (list): List of stock tickers to download.
  • start_date (str): Start date in the format YYYY-MM-DD.
  • end_date (str): End date in the format YYYY-MM-DD.
  • type (str): Type of price to retrieve (e.g., "Adj Close", "Close").

Returns

  • pd.DataFrame: A DataFrame containing the selected price type for the specified stocks.

Note: If you prefer to directly download the data from yfinance it is encouraged a format like this:

stocks = ["AAPL", "TSLA", "AMD", "LMT", "JPM"]
data=yf.download(stocks, start="2020-01-01", end="2023-01-01")['Close'][stocks]

Also if you get the data from an excel or csv file create the list stocks or currencieswith the name of the columns in your file for correct functioning. Also make sure to establish yor Datecolumn as index.

var_stocks(data, n_stocks, conf, long, stocks)

Calculates the VaR and cVaR for a stock portfolio.

Parameters:

  • data (pd.DataFrame): DataFrame containing stock prices.
  • stocks (list): List of stock tickers.
  • n_stocks (list): Number of stocks per ticker.
  • conf (float): Confidence level (e.g., 95 for 95%).
  • long (bool): True for long position, False for short position.

Returns:

A DataFrame with the following columns:

  • Métrica: "VaR" and "cVaR".
  • Porcentaje: The percentage value of risk.
  • Cash: The risk in monetary terms.

Note: Utilize this function when you have the number of shares of each stock instead of the weights.

var_forex(data, positions, conf, long, currencies)

Calculates the VaR and cVaR for a forex portfolio.

Parameters:

  • data (pd.DataFrame): DataFrame containing forex currency pair prices.
  • currencies (list): List of currency pairs.
  • positions (list): Number of units per currency pair.
  • conf (float): Confidence level (e.g., 95 for 95%).
  • long (bool): True for long position, False for short position.

Returns:

A DataFrame with the following columns:

  • Métrica: "VaR" and "cVaR".
  • Porcentual: The percentage value of risk.
  • Cash: The risk in monetary terms.

rebalance_stocks(w_original, target_weights, data, stocks, portfolio_value)

Calculates the number of shres to buy/sell to rebalance a stock portfolio..

Parameters:

  • w_original: list of floats representing the original weights of each asset in the portfolio.
  • target_weights: list of floats representing the target weights of each asset in the portfolio.
  • data: pd.DataFrame with historical stock prices, where columns represent different stocks.
  • stocks: list of stock tickers (column names in the data DataFrame).
  • portfolio_value: float representing the total value of the portfolio.

Returns:

  • A pd.DataFrame showing the original weights, target weights, and the number of shares to buy or sell for each asset to rebalance the portfolio.

var_weights(data, weights, conf)

Parameters

  • data (pd.DataFrame): DataFrame containing historical stock prices.
  • weights (list or np.array): Portfolio weights corresponding to each stock.
  • conf (float): Confidence level (e.g., 95 for 95%).

Returns

  • var (float): The Value at Risk (VaR) at the given confidence level.

Note: It only works for long positions, and the weights must add up to 1.

cvar_weights(data, weights, conf)

Parameters

  • data (pd.DataFrame): DataFrame containing historical stock prices.
  • weights (list or np.array): Portfolio weights corresponding to each stock.
  • conf (float): Confidence level (e.g., 95 for 95%).

Returns

  • cvar_pct (float): The Conditional Value at Risk (CVaR), representing the expected loss beyond VaR.

Note: It only works for long positions, and the weights must add up to 1.

opt_sharpe(returns, rf)

Parameters

  • returns (pd.DataFrame): DataFrame containing the daily returns of the stock prices.
  • rf: One-year risk-free rate

Returns

It returns a vector with the optimal weight for each stock.

min_variance(returns, rf)

Parameters

  • returns (pd.DataFrame): DataFrame containing the daily returns of the stock prices.

Returns

It returns a vector with the optimal weight for each stock.

min_cvar(returns, alpha)

Parameters:

  • returns (pd.DataFrame): DataFrame containing historical asset returns.
  • alpha (float): Significance level for CVaR (example: 0.05 for 95% confidence level).

Returns:

It returns a vector with the optimal weight for each stock.

Note: It is required to write alpha in decimal notation, also this portfolio strategy only works for long positions.

mcc_portfolio(returns, alpha)

Parameters:

  • returns (pd.DataFrame): DataFrame containing historical asset returns.
  • alpha (float): Significance level for CVaR (example: 0.05 for 95% confidence level).

Returns:

It returns a vector with the optimal weight for each stock.

Note: It is required to write alpha in decimal notation, also this portfolio strategy only works for long positions.

def cvar_contributions(weights, returns, alpha)

Parameters:

  • weights: An array with the weights for each asset in the portfolio.
  • returns (pd.DataFrame): DataFrame containing historical asset returns.
  • alpha (float): Significance level for CVaR (example: 0.05 for 95% confidence level).

Returns:

It returns an array with the individual contribution of each asset to the cvar of the portfolio.

Note: It is required to write alpha in decimal notation, also this portfolio strategy only works for long positions, so the weights must add up to 1.

plot_weights(df)

Parameters

  • df (pd.DataFrame): DataFrame with the weights for each stock.

Returns

It creates a pie chart with the weights of the portfolio.

Note: It works with the DataFrames generated by the optimization modules of the package.

BlackScholes

Parameters:

  • S: Current stock price
  • k: Strike price
  • r: Risk-free rate
  • sigma: Volatility of the asset
  • T: Time to expiration (in years)

Returns

The value of the delta of a call or put option.

Note: It also has function to determine how much of the underlying asset (in monetary unit) should be bought to delta hedge.

Usage Example

import numpy as np
import pandas as pd
import yfinance as yf
import vartools as vt
import matplotlib.pyplot as plt
from scipy.optimize import minimize

get_data

stocks = ["AAPL", "TSLA", "AMD", "LMT", "JPM"]
start_date = "2020-01-01"
end_date = "2023-01-01"
type = 'Close' # 'Close', select the type of price you want to download

data = vt.get_data(stocks, start_date, end_date, type)

var_stocks

stocks = ["AAPL", "TSLA", "AMD", "LMT", "JPM"]
start_date = "2020-01-01"
end_date = "2023-01-01"
type = 'Close' # 'Close', select the type of price you want to download

data = vt.get_data(stocks, start_date, end_date, type)
n_stocks =[2193, 1211, 3221, 761, 1231]
conf = 95
long = True

var_df = vt.var_stocks(data, n_stocks, conf, long, stocks)

var_forex

currencies = ['CHFMXN=X', 'MXN=X']
start_date = "2020-01-01"
end_date = "2024-12-02"
type = 'Close'

data = vt.get_data(currencies, start_date, end_date, type)
positions = [7100000, 5300000] # How much you have in each currency. Must match the order in currencies.
conf = 99 # Nivel de confianza
long = True

var_forex_df = vt.var_forex(data, positions, conf, long, currencies)

rebalance_stocks

stocks = ["AAPL", "TSLA", "AMD", "LMT", "JPM"]
start_date = "2020-01-01"
end_date = "2023-01-01"
type = 'Close' # 'Close', select the type of price you want to download

data = vt.get_data(stocks, start_date, end_date, type)

rt = data.pct_change().dropna()
stock_value = n_stocks * data.iloc[-1]
portfolio_value = stock_value.sum()
w_original = stock_value / portfolio_value
w_opt = [0.33, 0.15, 0.06, 0.46, 0.00]

rebalance_df = vt.rebalance_stocks(w_original, w_opt, data, stocks, portfolio_value)

var_weights

stocks = ["AAPL", "TSLA", "AMD", "LMT", "JPM"]
start_date = "2020-01-01"
end_date = "2023-01-01"
type = 'Close' # 'Close', select the type of price you want to download

data = vt.get_data(stocks, start_date, end_date, type)

weights = [0.2457, 0.1301, 0.1820, 0.3064, 0.1358]
conf = 95
var_pct = vt.var_weights(data, weights, conf)

cvar_weights

stocks = ["AAPL", "TSLA", "AMD", "LMT", "JPM"]
start_date = "2020-01-01"
end_date = "2023-01-01"
type = 'Close' # 'Close', select the type of price you want to download

data = vt.get_data(stocks, start_date, end_date, type)

weights = [0.2457, 0.1301, 0.1820, 0.3064, 0.1358]
conf = 95
cvar_pct = vt.cvar_weights(data, weights, conf)

opt_sharpe

stocks=['WMT','AAPL','GOOGL','PG','XOM','KO','CMG','F']
start_date='2020-01-01'
end_date='2024-11-24'
type='Close'

data = vt.get_data(stocks, start_date, end_date, type)
returns = data.pct_change().dropna()
rf = 0.04413

opt_sharpe_weights = vt.opt_sharpe(returns, rf)

min_variance

stocks=['WMT','AAPL','GOOGL','PG','XOM','KO','CMG','F']
start_date='2020-01-01'
end_date='2024-11-24'
type='Close'

data = vt.get_data(stocks, start_date, end_date, type)
returns = data.pct_change().dropna()

min_var_weights = vt.min_variance(returns)

min_cvar

# bonds, commodities, equities and real estate
stocks = ['VBTLX', 'GSG', 'VTI', 'VNQ']
start_date = '2019-01-01'
end_date = '2024-01-01'
type = 'Close'

data = vt.get_data(stocks, start_date, end_date, type)
returns = data.pct_change().dropna()
alpha = 0.05

min_cvar = vt.min_cvar(returns, alpha)

mcc_portfolio

# bonds, commodities, equities and real estate
stocks = ['VBTLX', 'GSG', 'VTI', 'VNQ']
start_date = '2019-01-01'
end_date = '2024-01-01'
type = 'Close'

data = vt.get_data(stocks, start_date, end_date, type)
returns = data.pct_change().dropna()
alpha = 0.05

mcc_weights = vt.mcc_portfolio(returns, alpha)

cvar_contributions

# bonds, commodities, equities and real estate
stocks = ['VBTLX', 'GSG', 'VTI', 'VNQ']
start_date = '2019-01-01'
end_date = '2024-01-01'
type = 'Close'

data = vt.get_data(stocks, start_date, end_date, type)
returns = data.pct_change().dropna()
alpha = 0.05

mcc_weights = vt.mcc_portfolio(returns, alpha)

cvar_contributions = vt.cvar_contributions(mcc_weights, returns, alpha)

plot_weights

stocks=['WMT','AAPL','GOOGL','PG','XOM','KO','CMG','F']
start_date='2020-01-01'
end_date='2024-11-24'
type='Close'

data = vt.get_data(stocks, start_date, end_date, type)
returns = data.pct_change().dropna()
rf = 0.04413

opt_sharpe = vt.opt_sharpe(returns, rf)

vt.plot_weights(stocks, opt_sharpe)

call_delta and put_delta

S_call = 20.3
K_call = 20.43
r_call = 0.0425
sigma_call = 0.102
T_call = 1/12

S_put = 20.3
K_put = 20.2
r_put = 0.0425
sigma_put = 0.156
T_put = 1/12

delta_call = vt.BlackScholes().call_delta(S_call, K_call, r_call, sigma_call, T_call)
delta_put = vt.BlackScholes().put_delta(S_put, K_put, r_put, sigma_put, T_put)

delta_call, delta_put
# Write in order S, K, r, sigma, T

call = [20.3, 20.43, 0.0425, 0.102, 1/12]
put = [20.3, 20.2, 0.0425, 0.156, 1/12]

delta_call = vt.BlackScholes().call_delta(*call)
delta_put = vt.BlackScholes().put_delta(*put)

delta_call, delta_put

delta_hedge

# Write in order S, K, r, sigma, T, N (money invested in each option)

info_call = [[20.3, 20.43, 0.0425, 0.102, 1/12, 23],
            [20.3, 20.52, 0.0425, 0.111, 1/12, 25],
            [20.3, 20.43, 0.0421, 0.297, 6/12, 17],
            [20.3, 20.52, 0.0421, 0.289, 6/12, 32]]

info_put = [[20.3, 20.2, 0.0425, 0.156, 1/12, 12],
            [20.3, 20, 0.0425, 0.153, 1/12, 16],
            [20.3, 20.2, 0.0421, 0.348, 6/12, 11],
            [20.3, 20, 0.0421, 0.378, 6/12, 17]]

# If N is in millions of dollar, then
hedge = vt.BlackScholes().delta_hedge(info_call, info_put)
print(f'Buy {hedge} millions of dollars of the underlying asset')

License

This project is licensed under the GPL-3.0 license.

Author

Luis Fernando Márquez Bañuelos

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vartools-0.1.7.tar.gz (53.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vartools-0.1.7-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file vartools-0.1.7.tar.gz.

File metadata

  • Download URL: vartools-0.1.7.tar.gz
  • Upload date:
  • Size: 53.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for vartools-0.1.7.tar.gz
Algorithm Hash digest
SHA256 86bfd22a7eb39f96cbf226edda7b76f710725acb6464eb078b4cec1b72feaba0
MD5 72aa7bce92365404f523c79c5209de2a
BLAKE2b-256 c63b2fe28ce59776b025363bc7045c8c36ef8c096d5bbefd4286063b3c7607c5

See more details on using hashes here.

File details

Details for the file vartools-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: vartools-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 20.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for vartools-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 64bb07d559015893fdcb940f107f4da911c2f6b27ea12a0cd1f3a94d52d41950
MD5 cd6a25216117f63a48208282742a9914
BLAKE2b-256 5904625f1ba7ea6f202c1b88ef26b4eafef84d6bfa21c8aec2c89b3171bd13f7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page