Last active
August 5, 2025 06:26
-
-
Save al6x/a769abfe18bcef427951e440f49f5d6e to your computer and use it in GitHub Desktop.
Overlap Bias
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Random, Distributions, Statistics, DataFrames, Plots | |
# parameters | |
Random.seed!(1) | |
mu = 0.005 # drift per 30d step | |
sigma = 0.08 # volatility per step | |
steps = 12 * 45 * 250 # number of 30d steps | |
S0 = 1.0 # initial price | |
ν = 3 # degrees of freedom for Student-t (ν > 2) | |
lps = cumsum(rand(TDist(ν), steps) .* sigma .+ mu) | |
lrs30 = [lps[i] - lps[i-1] for i in 2:length(lps)] | |
lrs360o = [lps[i] - lps[i-12] for i in 13:length(lps)] | |
lrs360 = [lps[i] - lps[i-12] for i in 13:12:length(lps)] | |
p_tail(x) = begin | |
tq, n = 0.01, length(x) # tail quantile | |
nq = floor(Int, n * tq) | |
x = sort(x) | |
rtail = x[end-nq+1:end] | |
rp = reverse((1:length(rtail)) ./ n) | |
rtail, rp | |
end | |
rtailo, rpo = p_tail(lrs360o) | |
rtail, rp = p_tail(lrs360) | |
plot( | |
rtail, rp; | |
# rtailc, rpc; | |
xscale = :log10, | |
yscale = :log10, | |
label = "Overlapping", | |
xlabel = "Return (log scale)", | |
ylabel = "P(X ≥ x) (log scale)", | |
legend = :topright, | |
seriestype = :scatter, | |
markersize = 4, | |
markerstrokewidth = 0 # ← smaller points | |
) | |
plot!( | |
rtailo, rpo; | |
label = "Non-overlapping", | |
seriestype = :scatter, | |
markersize = 2, | |
markerstrokewidth = 0 # ← same here | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import matplotlib.pyplot as plt | |
from scipy.stats import t | |
# Parameters | |
np.random.seed(1) | |
mu = 0.005 | |
sigma = 0.08 | |
steps = 10 * 12 * 45 * 250 # number of 30d steps | |
S0 = 1.0 | |
nu = 3 # degrees of freedom for Student-t | |
# Simulate log-price path from Student-t | |
lps = np.cumsum(t.rvs(df=nu, size=steps) * sigma + mu) | |
# Log returns | |
lrs30 = lps[1:] - lps[:-1] # 30d returns (no overlap) | |
lrs360o = lps[12:] - lps[:-12] # 360d overlapping | |
lrs360 = lps[12::12] - lps[:-12:12] # 360d non-overlapping | |
# Tail extraction function | |
def p_tail(x, tq=0.01): | |
x = np.sort(x) | |
n = len(x) | |
nq = int(np.floor(n * tq)) | |
rtail = x[-nq:] | |
rp = np.flip(np.arange(1, nq + 1) / n) | |
return rtail, rp | |
# Compute right tails | |
rtailo, rpo = p_tail(lrs360o) # overlapping | |
rtail, rp = p_tail(lrs360) # non-overlapping | |
# Log-log scatter plot | |
plt.figure(figsize=(7, 5)) | |
plt.scatter(rtail, rp, s=30, color="red", label='Non-overlapping', edgecolors='none') # larger markers | |
plt.scatter(rtailo, rpo, s=4, label='Overlapping', color="black", edgecolors='none') | |
plt.xscale('log') | |
plt.yscale('log') | |
plt.xlabel("log r (log scale)") | |
plt.ylabel("P(X ≥ x) (log scale)") | |
plt.legend(loc='upper right') | |
plt.grid(True, which='both', linestyle='--', linewidth=0.5) | |
plt.tight_layout() | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment