σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
SciPy skill›Module 3 · Matrices, signals and structure›Topic 3.3·~50 minIntermediate

Signal filtering and spectra

Skill positionModule 3 of 3 · Topic 3 of 5
3.3 Signal filtering and spectra
—Lab score— / 100Total XP—Streak—

Smoothing a noisy series and finding its rhythm

A filter turns one series into another by mixing each value with its neighbours. A moving average of NNN days is the simplest filter: each output is the average of the last NNN inputs, so noise shrinks but the output also lags behind. An exponential moving average (EMA) gives recent days more weight: yt=αxt+(1−α)yt−1y_t=\alpha x_t+(1-\alpha)y_{t-1}yt​=αxt​+(1−α)yt−1​, where α=2/(N+1)\alpha=2/(N+1)α=2/(N+1) is the smoothing weight. signal.lfilter(b, a, x) runs any such filter on a series, using only past and present values. The average delay of an EMA is (1−α)/α(1-\alpha)/\alpha(1−α)/α days, and that of an NNN-day moving average is (N−1)/2(N-1)/2(N−1)/2 days, so a 19-day average and an EMA with α=0.1\alpha=0.1α=0.1 both lag by about 9 days.

The second job is finding cycles. signal.periodogram(x) splits the variance of a series into frequencies, measured in cycles per day. A peak at frequency fff means a repeating pattern with period 1/f1/f1/f days. With one observation per day you can see frequencies only up to 0.50.50.5 cycles per day, the Nyquist limit, because a faster cycle cannot be told apart from a slower one. One warning matters a great deal in trading. signal.filtfilt runs the filter forward and then backward, which removes the lag, but each output then uses future values. A signal built with filtfilt looks perfect in a backtest and cannot be traded, because tomorrow's data is not available today. Use only causal filters such as lfilter for anything you plan to trade.

yt=αxt+(1−α)yt−1,α=2N+1,lag=1−αα  (moving average: N−12),period=1fy_t=\alpha x_t+(1-\alpha)y_{t-1},\quad \alpha=\frac{2}{N+1},\quad \text{lag}=\frac{1-\alpha}{\alpha}\ \ \Big(\text{moving average: }\frac{N-1}{2}\Big),\qquad \text{period}=\frac1fyt​=αxt​+(1−α)yt−1​,α=N+12​,lag=α1−α​  (moving average: 2N−1​),period=f1​(1)
Three numbers and a cycleTake the series 10,12,1110,12,1110,12,11 with α=0.5\alpha=0.5α=0.5 and start the EMA at the first value. Then y0=10y_0=10y0​=10, y1=0.5⋅12+0.5⋅10=11y_1=0.5\cdot12+0.5\cdot10=11y1​=0.5⋅12+0.5⋅10=11 and y2=0.5⋅11+0.5⋅11=11y_2=0.5\cdot11+0.5\cdot11=11y2​=0.5⋅11+0.5⋅11=11. A 3-day moving average of 10,12,11,1310,12,11,1310,12,11,13 gives 111111 and then 121212. A 19-day window means α=2/20=0.1\alpha=2/20=0.1α=2/20=0.1 and a lag of (1−0.1)/0.1=9(1-0.1)/0.1=9(1−0.1)/0.1=9 days. A pure cycle that repeats 0.050.050.05 times per day has a period of 1/0.05=201/0.05=201/0.05=20 days, and the periodogram peaks exactly there. On real data, SPY's daily returns have a lag-1 autocorrelation of only −0.10-0.10−0.10, but their squares have 0.270.270.27 at lag 1 and 0.300.300.30 at lag 5: big days follow big days, which is volatility clustering. An EMA of squared returns with weight α=0.06\alpha=0.06α=0.06 (RiskMetrics λ=0.94\lambda=0.94λ=0.94) reached 0.75%0.75\%0.75% a day on 21 August 2026 (11.9%11.9\%11.9% a year), well below the full-sample 1.20%1.20\%1.20%. That is exactly what a slow-moving average of the past can tell you without looking ahead.
  • Smoothing costs lag: a longer window or a smaller α\alphaα removes more noise and delays the signal more.
  • Periods from peaks: a periodogram peak at frequency fff means a cycle of 1/f1/f1/f days, up to a limit of 0.5 cycles a day.
  • Only causal filters for trading: filtfilt uses the future, so it is for analysis, never for a live signal.

Lab · what's graded

  • An EMA step10 pts
  • A moving average10 pts
  • The weight for a window10 pts
  • A period from a frequency10 pts
  • The lag of an EMA10 pts
  • What each routine does15 pts
  • Why filtfilt cannot be traded35 pts
0/ 7 answered
Tasks
1Numeric answer10 ptsNot answered

With α=0.5\alpha=0.5α=0.5, y0=10y_0=10y0​=10 and the next value x1=12x_1=12x1​=12, what is y1=αx1+(1−α)y0y_1=\alpha x_1+(1-\alpha)y_0y1​=αx1​+(1−α)y0​?

y=y =y=accepted: ± 0.01
2Numeric answer10 ptsNot answered

The series is 10, 12, 11, 1310,\ 12,\ 11,\ 1310, 12, 11, 13. What is the 3-day moving average at the last day?

m=m =m=accepted: ± 0.01
3Numeric answer10 ptsNot answered

An EMA should resemble a N=19N=19N=19 day average. What is α=2/(N+1)\alpha=2/(N+1)α=2/(N+1)?

a=a =a=accepted: ± 0.002
4Numeric answer10 ptsNot answered

The periodogram of a daily series peaks at f=0.05f=0.05f=0.05 cycles per day. How many days long is one cycle?

p=p =p=accepted: ± 0.1
5Numeric answer10 ptsNot answered

An EMA has α=0.1\alpha=0.1α=0.1. Its average delay is (1−α)/α(1-\alpha)/\alpha(1−α)/α days. How many days?

l=l =l=accepted: ± 0.05
6Match15 ptsNot answered

Match each scipy.signal routine with what it does.

Pick the partner of each item on the left.

lfilter
filtfilt
periodogram
detrend
7Explain in words35 ptsNot answered

A signal made with filtfilt has no lag and gives a wonderful backtest. In one or two sentences, explain why it cannot be traded.

Math modeKeyboard or LaTeX inputTask 1 of 7 · Ctrl ⏎ to check

Log in to run your code.

Every lecture is free to read. Create an account or log in to run code, run tests and submit this lab.

  • In-browser IDE with a bash terminal — nothing to install
  • Instant grading, XP and your place on the skill
Create an accountLog in
OR
Continue with GitHub