Skip to content

Instantly share code, notes, and snippets.

@rafaelquintanilha
Last active January 24, 2025 13:26
Show Gist options
  • Save rafaelquintanilha/34e421a5419bf305e10105cfa80d27fb to your computer and use it in GitHub Desktop.
Save rafaelquintanilha/34e421a5419bf305e10105cfa80d27fb to your computer and use it in GitHub Desktop.
Correlation vs Trend
import numpy as np
import matplotlib.pyplot as plt
# Set seed for reproducibility
np.random.seed(42)
# Configuration (Balanced Parameters)
n_periods = 100 # Trading days
mu = 0.001 # Daily drift (0.1%)
noise_std = 0.0005 # Daily volatility (0.05%)
initial_price = 100
# Generate perfectly mirrored noise
epsilon = np.random.normal(0, noise_std, n_periods-1)
# Create returns series with zero first day
returns_B = np.zeros(n_periods)
returns_C = np.zeros(n_periods)
# Apply trends and variations from day 1 onward
returns_B[1:] = mu + epsilon # Bullish asset
returns_C[1:] = mu - epsilon # Bearish asset
# Calculate price paths with compounding
price_B = initial_price * np.cumprod(1 + returns_B)
price_C = initial_price * np.cumprod(1 + returns_C)
# Compute theoretical trend
trend_line = initial_price * (1 + mu) ** np.arange(n_periods)
# Create visualization
plt.figure(figsize=(8, 5))
plt.plot(price_B, color='#49CE8B', linewidth=1.8, label='Asset B')
plt.plot(price_C, color='#CE4949', linewidth=1.8, label='Asset C')
plt.plot(trend_line, '--', color='#666666', linewidth=1.2,
label='Theoretical Trend (μ={:.2%} daily)'.format(mu))
# Formatting
plt.xlabel('Trading Days')
plt.ylabel('Price')
plt.legend()
plt.grid(alpha=0.2)
plt.tight_layout()
plt.show()
# Correlation is -1
print(f"Correlation coefficient: {np.corrcoef(returns_B[1:], returns_C[1:])[0,1]:.8f}")
# Now for perfect correlated yet in opposite trends
# Generate identical noise for days 1-100 (exclude day 0)
epsilon = np.random.normal(0, noise_std, n_periods-1)
# Create returns series with zero first day
returns_B = np.zeros(n_periods)
returns_C = np.zeros(n_periods)
# Apply trends and variations from day 1 onward
returns_B[1:] = mu + epsilon # Bullish asset
returns_C[1:] = -mu + epsilon # Bearish asset
# Calculate price paths with compounding
price_B = initial_price * np.cumprod(1 + returns_B)
price_C = initial_price * np.cumprod(1 + returns_C)
# Compute theoretical trends (now aligned with actual start)
trend_B = initial_price * (1 + mu) ** np.arange(n_periods)
trend_C = initial_price * (1 - mu) ** np.arange(n_periods)
# Create visualization
plt.figure(figsize=(8, 5))
# Plot price paths with markers
plt.plot(price_B, color='#49CE8B', linewidth=1.8, alpha=0.8, label='Asset B')
plt.plot(price_C, color='#CE4949', linewidth=1.8, alpha=0.8, label='Asset C')
# Plot trend lines
plt.plot(trend_B, '--', color='#49CE8B', alpha=0.5, linewidth=1.2,
label='Bullish Trend (μ=+{:.2%} daily)'.format(mu))
plt.plot(trend_C, '--', color='#CE4949', alpha=0.5, linewidth=1.2,
label='Bearish Trend (μ=-{:.2%} daily)'.format(mu))
# Formatting
plt.xlabel('Trading Days')
plt.ylabel('Price')
plt.legend()
plt.grid(alpha=0.2)
plt.tight_layout()
plt.show()
# Correlation is 1
print(f"Correlation coefficient: {np.corrcoef(returns_B[1:], returns_C[1:])[0,1]:.8f}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment