my net house

WAHEGURU….!

Vanila Implementation of Financial Risk modeling in Python!

For most of . 

  1. Use historical data of stocks to Calculate historical Portfolio Variance.
  2. Use Factor Analysis Model to Calculate historical Portfolio Variance.
  3. Setup Scenario using Factor Analysis model.(Stress Testing!)
  4. Calculate Worst Case Scenario from Historical Data and Scenarios.
  5. Compare VaR(Value at Risk) for these cases.

What is Six Step Approach for Scenario Based Risk Model?

  1. Create a Basket of Financial Assests. (Each assest has uncertain “Returns”)
  2. Calculate the Standard Deviation of That Bucket of Financial Assests.
  3. Find out Systematic and ideo-Syncractic risk on Each asset of the portfolio.
  4. Study those risk Factors and also compare with Historical Data.
  5. Generate Scenarios. Find-out how Assest may perform in Future.
  6. Calculate Worst-Case 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('utf-8')+ '\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

wp-upload

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 .

impo

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 Stress-Testing Scenarios.
That would be our Scenario-Based model.

Systemic Risk:
IdeoSyncractic Risk:

Now we have chosen three Risk-Factors,
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 “Factor-Returns” 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:

  1. S&P500 is at lowest point (Systemic Scenario)
  2. 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;line-height: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 Scenario-Based models.</li>
</ol>
<img class="alignnone size-full wp-image-2483" src="https://arshpreetsingh.files.wordpress.com/2020/08/did-all.png?w=680" alt="did-all" width="1344" height="759" />

Calculating VAR:

P = Our amont invested in the Stocks

sigma = Variance of Returns from (historical/Risk-factor/Scenario-Stress-Test baed model)

Z = How much %age of loss we can bear in which is "Number of Standard Deviation" away from mean.

<img class="alignnone size-full wp-image-2486" 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 size-full wp-image-2487" src="https://arshpreetsingh.files.wordpress.com/2020/08/best-way.png?w=680" alt="best-way" width="1361" height="787" />
<span id="mce_SELREST_start" style="overflow:hidden;line-height: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(1-confLevel,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:

  1. Helpful to modeling worst Case outcomes.
  2. Sanctioned in regulations and risk accords.
  3. Even understood by Non-Finance people.
  4. Measured and Reported objectively.
  5. easy to aggregate across assests to create End to end Risk matric

Dis-Advantages of VaR:

      1. For short time assumptions
  1. 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.
  2. VaR depends on Standard Deviation only.
  • Skewness and Curtosis are ignored.
  • VaR is only as Good as Variance Plugged into it.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: