Skip to content

Instantly share code, notes, and snippets.

@sitmo
Created October 25, 2024 16:18
Show Gist options
  • Save sitmo/4e23487d8610f2213edc3ef7d757b559 to your computer and use it in GitHub Desktop.
Save sitmo/4e23487d8610f2213edc3ef7d757b559 to your computer and use it in GitHub Desktop.
Squeezing Financial Noise: A Novel Approach to Covariance Matrix Estimation
import numpy as np
def calculate_iq_cov_matrix(returns, delta_params, eta_weights, tau, epsilon, gamma):
"""
Calculate the IQ-based covariance matrix.
Parameters:
- returns: Matrix of asset returns, shape (T, N), where T is time and N is assets.
- delta_params: Boundary parameters defining squeezing channels.
- eta_weights: Array of squeezing weights for each channel.
- tau: Lookback window duration.
- epsilon: Delay parameter for temporal discounting.
- gamma: Decay rate for temporal quality adjustment.
Returns:
- cov_matrix: IQ-adjusted covariance matrix.
"""
T, N = returns.shape
cov_matrix = np.zeros((N, N))
def temporal_discount(t, epsilon, gamma):
# Apply temporal discount based on delay and decay parameters
return np.exp(-gamma * max(0, t - epsilon))
def get_squeezing_weight(x_i, x_j, delta_params, eta_weights):
# Determine squeezing weight based on channel definition
# For simplicity, assume quadrant-based simple body, tail, and wing delineation
if abs(x_i) < delta_params['noise_exclusion'] or abs(x_j) < delta_params['noise_exclusion']:
return 0 # Exclude as noise if within exclusion zone
# Add more complex rules here for quadrant/channel categorization if needed
# For demonstration, return a generic weight
return eta_weights['body'] if x_i * x_j > 0 else eta_weights['tail']
for i in range(N):
for j in range(i, N):
if i == j:
cov_matrix[i, j] = 1 # Variance for diagonal elements
continue
weighted_sum = 0
normalization = 0
for t in range(T - tau, T):
x_i, x_j = returns[t, i], returns[t, j]
squeezing_weight = get_squeezing_weight(x_i, x_j, delta_params, eta_weights)
temporal_weight = temporal_discount(t, epsilon, gamma)
evidence = squeezing_weight * np.sign(x_i * x_j)
weighted_sum += evidence * temporal_weight
normalization += temporal_weight
cov_matrix[i, j] = cov_matrix[j, i] = weighted_sum / (np.sqrt(normalization) or 1)
return cov_matrix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment