← Tous les exercices
Normaliser dans la fenêtre et protéger la division
Partie 4 · ★★★
Comme le z-score du cours, on standardise le prix par rapport à son voisinage, mais avec une quantité disponible partout dans SQLite : la position dans l'amplitude de la fenêtre, (close - MIN) / NULLIF(MAX - MIN, 0). NULLIF(x, 0) renvoie NULL quand l'amplitude est nulle (fenêtre plate) au lieu de diviser par zéro. (Le cours utilise AVG et STDDEV ; SQLite n'a pas de STDDEV, d'où ce choix : exemple adapté.)
Pour l'actif C, fenêtre de 3 lignes (2 PRECEDING), renvoie date, pos trié par date.
import sqlite3 con = sqlite3.connect(":memory:") con.execute("CREATE TABLE prices(date TEXT, ticker TEXT, close REAL)") A = [100, 102, 101, 105, 107, 108] B = [50, 49, 51, 50, 52, 55] C = [80, 90, 83, 110, 79, 120] for i in range(6): d = f"2024-01-0{i + 1}" for t, s in (("A", A), ("B", B), ("C", C)): con.execute("INSERT INTO prices VALUES (?, ?, ?)", (d, t, s[i])) sql = """ SELECT date, (close - MIN(close) OVER w) / ___(MAX(close) OVER w - MIN(close) OVER w, 0) AS pos FROM prices WHERE ticker = 'C' WINDOW w AS (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) ORDER BY date """ rows = con.execute(sql).fetchall()
Ctrl/⌘+Entrée