SectorScenarioGenerator2

py

School

Northwestern University *

*We aren’t endorsed by this school

Course

401

Subject

Industrial Engineering

Date

Dec 6, 2023

Type

py

Pages

2

Uploaded by DeaconCaribou828

Report
import pandas as pd import numpy as np from scipy.stats import chi2 from numpy.random import multivariate_normal # Step 1: Loading the Data file_path = r"C:\Users\rbenn\OneDrive\Desktop\SP500TogetherAllDays(copy).csv" df = pd.read_csv(file_path) # Step 2: Deriving Sector Weights sector_weights = df.groupby("GICS CODE")["INDEX WEIGHT"].sum().reset_index() # Step 3: Weighted Sector Returns df["WEIGHTED RETURN"] = df["DAILY PRICE RETURN"] * df["INDEX WEIGHT"] sector_returns = df.groupby(["Date", "GICS CODE"])["WEIGHTED RETURN"].sum().reset_index() # Step 4: Log of Daily Sector Returns sector_returns["LOG RETURN"] = np.log(1 + sector_returns["WEIGHTED RETURN"]) # Step 5: Compute Mahalanobis Distances pivot_data = sector_returns.pivot(index="Date", columns="GICS CODE", values="LOG RETURN") mean_vector = pivot_data.mean().values cov_matrix = pivot_data.cov() def mahalanobis(x): diff = x - mean_vector inv_cov_matrix = np.linalg.inv(cov_matrix) return np.dot(diff, np.dot(inv_cov_matrix, diff.T)) mahalanobis_distances_all = pivot_data.apply(mahalanobis, axis=1) # Step 6: Simulate Sector Shocks user_z_score_range = (0.5,2) # User-defined range for the average z-score num_simulations = 10000 # Number of scenarios you want to generate degree_of_freedom = len(sector_returns["GICS CODE"].unique()) confidence_interval = chi2.ppf([(1 + user_z_score_range[0])/2, (1 + user_z_score_range[1])/2], degree_of_freedom) scenario_significance = [] # List to store scenario significance for scenario_idx in range(num_simulations): z_scores = [] # List to store z-scores for shocks within this scenario for sector_idx in range(len(pivot_data.columns)): sample = multivariate_normal(mean_vector, cov_matrix) mahalanobis_dist = mahalanobis(sample) # Calculate the z-score for this shock z_score = (mahalanobis_dist - np.mean(mahalanobis_distances_all)) / np.std(mahalanobis_distances_all) z_scores.append(z_score) # Calculate the average z-score for shocks within this scenario average_z_score = np.mean(z_scores) # Assess the significance of the scenario based on the user-defined range
if user_z_score_range[0] <= average_z_score <= user_z_score_range[1]: scenario_significance.append("Significant") # Print shocks for this significant scenario print(f"Scenario {scenario_idx + 1} - Shocks to Sectors:") for sector_idx, shock_value in enumerate(z_scores): print(f" Sector {sector_idx + 1}: {shock_value:.4f}") from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler # Standardize the data scaler = StandardScaler() pivot_data_standardized = scaler.fit_transform(pivot_data) # Calculate the covariance matrix based on the standardized data cov_matrix = np.cov(pivot_data_standardized, rowvar=False) # Fit PCA to standardized data pca = PCA(n_components = 3) pca.fit(pivot_data_standardized) # User inputs a shock for a given sector user_input_sector = 20 # Replace with the desired sector ID user_shock_value = -10.0 # Replace with the desired shock value # Create a vector for the user's input shock user_input_shock = np.zeros(len(pivot_data.columns)) user_input_shock[pivot_data.columns.get_loc(user_input_sector)] = user_shock_value # Transform the user's input using PCA components user_input_transformed = pca.transform(user_input_shock.reshape(1, -1)) # Inverse transform to get shocks to other sectors shocks_to_other_sectors = np.dot(user_input_transformed, pca.components_) print(f"User's Shock to Sector {user_input_sector}: {user_shock_value:.4f}") print("Estimated Shocks to Other Sectors:") for sector_id, shock_value in zip(pivot_data.columns, shocks_to_other_sectors[0]): if sector_id != user_input_sector: print(f" Sector {sector_id}: {shock_value:.4f}") # Explained variance ratio for each component explained_variance_ratio = pca.explained_variance_ratio_ print("\nExplained Variance Ratio for Each Component:") for component_idx, explained_variance in enumerate(explained_variance_ratio): print(f"Component {component_idx + 1}: {explained_variance:.4f}")
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help