SectorScenarioGenerator2
py
keyboard_arrow_up
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
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