Implement Risk Metrics: Value At Risk
Expected Behavior
Portfolio Statistics include Value at Risk (VaR)
Actual Behavior
Not supported
Checklist
- [x] I have completely filled out this template
- [x] I have confirmed that this issue exists on the current
masterbranch - [x] I have confirmed that this is not a duplicate issue by searching issues
- [x] I have provided detailed steps to reproduce the issue
Hi @AlexCatarino - please could I pick up this issue?
Hi @wtindall1 , thank you! I suggest adding your thoughts about this problem before working on it. VaR is a statistical metric, an "indicator" (see guidance on GitHub issues for Indicators), so we must create a unit test that compares the calculation with an external source.
When you say VaR should be an "indicator", do you mean that the scope of the issue is an implementation of IIndicator? Rather than a property of PortfolioStatistics (as I had assumed from the Expected Behaviour)
If VaR can be an IIndicator and a property of PortfolioStatistics, the better, right? :-)
For example, see Sharpe and Sortino ratios.
If not, yes, it should be property of PortfolioStatistics. The point I was trying to make is that it should be validated like an indicator (external data file generated with third-party software, you need to tell us how it was created).
Makes sense - thank you. I will have a look into this and comment back here
@AlexCatarino - proposed script for generating the test data, based on: https://blog.quantinsti.com/calculating-value-at-risk-in-excel-python/ spy_var.csv
#https://blog.quantinsti.com/calculating-value-at-risk-in-excel-python/
import pandas as pd
from scipy.stats import norm
spy = pd.read_csv("https://github.com/QuantConnect/Lean/raw/master/Data/equity/usa/daily/spy.zip",
index_col=0, names=["open", "high", "low", "close", "volume"])
spy_close = spy[["close"]]
spy["returns"] = spy_close.close.pct_change()
window_length = 252
min_periods = 2
spy["mean"] = spy["returns"].rolling(window_length, min_periods).mean()
spy["stdev"] = spy["returns"].rolling(window_length, min_periods).std()
spy["VaR_99"] = norm.ppf(0.01, spy["mean"], spy["stdev"])
spy["VaR_95"] = norm.ppf(0.05, spy["mean"], spy["stdev"])
spy["VaR_90"] = norm.ppf(0.1, spy["mean"], spy["stdev"])
columns_to_export = ["open", "high", "low", "close", "volume", "returns", "VaR_99", "VaR_95", "VaR_90"]
spy[columns_to_export].to_csv("spy_valueatrisk.csv", index_label="date")