my net house
WAHEGURU….!
Vanila Implementation of Financial Risk modeling in Python!
August 28, 2020
Posted by on For most of .
 Use historical data of stocks to Calculate historical Portfolio Variance.
 Use Factor Analysis Model to Calculate historical Portfolio Variance.
 Setup Scenario using Factor Analysis model.(Stress Testing!)
 Calculate Worst Case Scenario from Historical Data and Scenarios.
 Compare VaR(Value at Risk) for these cases.
What is Six Step Approach for Scenario Based Risk Model?
 Create a Basket of Financial Assests. (Each assest has uncertain “Returns”)
 Calculate the Standard Deviation of That Bucket of Financial Assests.
 Find out Systematic and ideoSyncractic risk on Each asset of the portfolio.
 Study those risk Factors and also compare with Historical Data.
 Generate Scenarios. Findout how Assest may perform in Future.
 Calculate WorstCase outcomes.
Scrap Data from Yahoo Finance for Mulitple Stock Symbols.
Assest Symbols are as follows:
["AAPL","ADBE","CVX","GOOG","IBM","MDLZ","MSFT","NFLX","ORCL","SBUX","^GSPC","VOOG"]
Find out code to Download Stock’s Data and Save to CSV files individually.
def download_csv_data(symbol_names=[],dir_path=''): for symbol in symbol_names: data_url="https://query1.finance.yahoo.com/v7/finance/download/{symbol}? period1=1283040000&period2=1598659200&interval=1d&events=history".format(symbol=symbol) data = requests.get(dataurl) with open(dir_path+symbol+".csv", 'w') as f: for line in data.iter_lines(): f.write(line.decode('utf8')+ '\n') return
Now combine all CSV files into into one DataFrame.
def combine_data(dir_path =""): data_frames=[] files = os.listdir(dir_path) for file in files: data_frame = pd.read_csv(file) data_frame = pd.DataFrame(data_frame["Adj Close"].values,columns [file.split(".")[0]]) data_frames.append(data_frame) result = pd.concat(data_frames, axis=1, sort=False) return result
Now we have DataFrame which Looks something like this
Now Portfolio assemble part is done.
Let’s calcuate Historical Risk, Understand carefully folllwing two lists. We have stock names on which we want to calculate Historical risk, and FactorNames based on which factors we want to calcuate the Historical Risk.
stockNames = ["AAPL","ADBE","CVX","GOOG","IBM","MDLZ","MSFT","NFLX","ORCL","SBUX"] factorNames = ["^GSPC","VOOG","Intercept"]
Let’s Calculate StockReturns and FactorReturns. Why?
Because that’s all we need to Callculate to find Historical risk on Financial assests.
Look for following mathematical expression to calcualte historical Risk .
Now calcuations!
stockReturns = returns[stockNames] factorReturns = returns[factorNames] weights = np.array([1.0/len(stockNames)] * len(stockNames)) historicalTotalRisk = np.dot(np.dot(weights,stockReturns.cov()),weights.T)
Now we have calculated the historical variance of our portfolio next step is to “Perform Factor Analysis” Systematic and Ideosyntractic.
Factor based model:
Decompose our model into Systemic and ideosyncractic Risks, Use this understanding for StressTesting Scenarios.
That would be our ScenarioBased model.
Systemic Risk:
IdeoSyncractic Risk:
Now we have chosen three RiskFactors,
1. S&P500 – Spread across the market –> Systemic Risk
2. VFISX – Could effect across indiviual Stocks –>>Ideosyncratic Risk
Here assumption is if Interest Rates are going UP Stock investment willl go Low.
so S&P500 and VFISX are somewhat oposite to each other interms of Risk Factors.
Total Var = SystematicVar(p)+IdesyncracticVar(p)
Risk Factor Analysis: Now let’s Express “returns on Every stock” w.r.t “FactorReturns” in terms
of regression Equation.
**This regression equation will tell us how much change in the RiskFactor wi effect the Returns of
each stock.
Residual = Observed value – predicted value
e = y – ŷ
Alpha = Stock Specific out Performance
Beta_ on factorF1
Beta_ on FactorF2
import statsmodels.api as sm xData = factorReturns modelCoeffs = [] for oneStockName in stockNames: yData = stockReturns[oneStockName] model = sm.OLS(yData, xData) result = model .fit() modelCoeffRow = list(result.params) modelCoeffRow.append(np.std(result.resid,ddof=1)) modelCoeffs.append(modelCoeffRow) print(result.summary())
we have calculates ResidualCofficents for each stock individually , using that let’s calculate Systematic and Ideosyncratic risk on Each stock.
SystematicRisk = Weignt*Factor(S)Beta Matrix* FactorsCovarianceMatrix*Transpose_BetaMatric*Tranpose_WeightMatrix
idiosyncraticRisk = sum(modelCoeffs[“ResidVol”] * modelCoeffs[“ResidVol”]* weights * weights)
factorModelTotalRisk = systemicRisk + idiosyncraticRisk
Systematic and Ideosyncractic Variance calculations
factorCov = factorReturns[["VOOG","^GSPC"]].cov() reconstructedCov = np.dot(np.dot(modelCoeffs[["B_FVX","B_SP"]], factorCov),modelCoeffs[["B_FVX","B_SP"]].T) systemicRisk = np.dot(np.dot(weights,reconstructedCov),weights.T) idiosyncraticRisk = sum(modelCoeffs["ResidVol"] * modelCoeffs["ResidVol"]* weights * weights) factorModelTotalRisk = systemicRisk + idiosyncraticRisk
We have calcualted RiskFactors on each model as well. Let’s move on to generate Scenarios for each stock.
Scenario baed Model:
Let’s conside two scenarios:
 S&P500 is at lowest point (Systemic Scenario)
 FVX is at lowest point point. (ideosyncractic scenario)
we are assuming that 5% stp change for S&P500 and 2% for FVX each day.
Let’s use Python to generate FVX scenarios and Spscenarios, wich indicate that how high and how low S&p500 and FVX could go in Future.
<span id="mce_SELREST_start" style="overflow:hidden;lineheight:0;"></span> fvxScenarios = np.arange(min(returns["FVX"]),max(returns["FVX"]),0.05) spScenarios = np.arange(min(returns["^GSPC"]),max(returns["^GSPC"]),0.02)
Let’s Test Scenarios with Each individual Stock.
scenarios = [] for oneFVXValue in fvxScenarios: for oneSPValue in spScenarios: oneScenario = [oneFVXValue,oneSPValue] for oneStockName in stockNames: alpha = float(modelCoeffs[modelCoeffs["Names"] == oneStockName]["Alpha"]) beta_sp = float(modelCoeffs[modelCoeffs["Names"] == oneStockName]["B_SP"]) beta_fvx = float(modelCoeffs[modelCoeffs["Names"] == oneStockName]["B_FVX"]) oneStockPredictedReturn = alpha + beta_sp * oneSPValue + beta_fvx * oneFVXValue oneScenario.append(oneStockPredictedReturn) scenarios.append(oneScenario)
We have obtained Hitorical Risk, Factor based Model risk, this time we will calculate Scenario based risk
scenarios = pd.DataFrame(scenarios) scenarios.columns = ["FVX","SP500","AAPL","ADBE","CVX","GOOG","IBM","MDLZ","MSFT","NFLX","ORCL","SBUX"] scenariosCov = scenarios[stockNames].cov() scenarioTotalRisk = np.dot(np.dot(weights,scenariosCov ),weights.T) So what we have done. <ol> <li>Calculated Historical Relationship</li> <li>Calculated Risk using Factor based models.</li> <li>Using factor Based models we generated ScenarioBased models.</li> </ol> <img class="alignnone sizefull wpimage2483" src="https://arshpreetsingh.files.wordpress.com/2020/08/didall.png?w=680" alt="didall" width="1344" height="759" /> Calculating VAR: P = Our amont invested in the Stocks sigma = Variance of Returns from (historical/Riskfactor/ScenarioStressTest baed model) Z = How much %age of loss we can bear in which is "Number of Standard Deviation" away from mean. <img class="alignnone sizefull wpimage2486" src="https://arshpreetsingh.files.wordpress.com/2020/08/thisone.png?w=680" alt="thisone" width="1343" height="758" /> Best way to Express VaR is as follows: <img class="alignnone sizefull wpimage2487" src="https://arshpreetsingh.files.wordpress.com/2020/08/bestway.png?w=680" alt="bestway" width="1361" height="787" /> <span id="mce_SELREST_start" style="overflow:hidden;lineheight:0;"></span> <strong> Calculations of VaR using Python </strong> from scipy.stats import norm import math confLevel = 0.95 principal = 1 numMonths = 1 def calculateVaR(risk,confLevel,principal = 1,numMonths = 1): vol = math.sqrt(risk) return abs(principal*norm.ppf(1confLevel,0,1)*vol*math.sqrt(numMonths)) print (calculateVaR(scenarioTotalRisk,0.99)) print (calculateVaR(historicalTotalRisk,0.99)) print (calculateVaR(factorModelTotalRisk,0.99))
Thing that Matters most is Eastimation of Volitility, Which is Sigma.
MultiPeriod Var = VaR x Sqrt(number of trading Periods)
Advantages of VaR:
 Helpful to modeling worst Case outcomes.
 Sanctioned in regulations and risk accords.
 Even understood by NonFinance people.
 Measured and Reported objectively.
 easy to aggregate across assests to create End to end Risk matric
DisAdvantages of VaR:


 For short time assumptions

 Multiperiod VaR assumes that Loss will be same in Each Trading Period, which is ver bad assumption to make. Stick to Single period VaR whereever possible.
 VaR depends on Standard Deviation only.
 Skewness and Curtosis are ignored.
 VaR is only as Good as Variance Plugged into it.