(Acest articol a fost publicat pentru prima dată pe DataGeeekși cu amabilitate a contribuit la R-bloggeri). (Puteți raporta problema legată de conținutul acestei pagini aici)
Doriți să vă distribuiți conținutul pe R-bloggeri? dați clic aici dacă aveți un blog, sau aici dacă nu aveți.
În lucrarea lor „Un sistem purtabil multi-IMU sincronizat pentru urmărirea unghiurilor articulare în analiza mișcării sportive” (arXiv:2607.26027v1), Samarasekera și colegii și-au propus să rezolve o problemă foarte practică: cum să măsurați în mod fiabil unghiurile articulațiilor în mișcările sportive dinamice folosind IMU-uri portabile. Scopul lor a fost să proiecteze o conductă sincronizată care să filtreze zgomotul, să corecteze deriva și să normalizeze intervalele, astfel încât semnalele biomecanice să poată fi de încredere în condițiile lumii reale.
Scopul nostru este diferit, dar este paralel conceptual: să se aplice aceeași logică în pipeline datelor financiare din seria temporală. În loc de unghiurile de flexie a genunchiului, analizăm dinamica comparativă a Aurului și Bitcoin. Provocarea este similară – randamentele financiare sunt zgomotoase, predispuse la derive și dificil de comparat direct. Prin adaptarea conductei lor, ne propunem să extragem tendințe latente, să atenuăm deriva, să normalizăm intervalele și să evidențiem divergența relativă între active.
Conducta constă din patru etape succesive:
- Filtrare Kalman indirectă (IKF) – extragerea tendințelor latente din returnările jurnalelor zgomotoase.
- IKF separă semnalul de zgomot, cu şi învăţat prin probabilitate maximă.
- Atenuarea derivei prin filtrare High-Pass – eliminarea polarizării de joasă frecvență.
- Acest lucru asigură că deriva pe termen lung nu domină dinamica pe termen scurt.
- Normalizarea intervalului – maparea valorilor filtrate la o scară comparabilă.
- Acest lucru permite compararea aurului și a Bitcoinului pe aceeași scară de la 0 la 100.
- Notație relativă (divergență direcțională) – evidențierea când activele se mișcă în direcții opuse.
- Dacă este adevărat, regiunile umbrite arată divergență; dacă este fals, aliniere.
De ce contează asta
- Pentru cercetătorii în biomecanică, conducta însemna urmărire de încredere a unghiului articulației.
- Pentru noi, aceeași arhitectură înseamnă analiză comparativă de încredere a tendințelor între activele financiare.
- În ambele cazuri, puterea conductei constă în modularitatea sa: IKF pentru extracția semnalului latent, filtrarea trece-înaltă pentru controlul derivei, normalizarea pentru comparabilitate și notația relativă pentru detectarea divergenței.
✦ Pachetele R în conducta noastră
Pentru a face această conductă reproductibilă și transparentă, ne bazăm pe un set de pachete R. Fiecare pachet joacă un rol specific în arhitectură:
- tidyverse
- Scop: manipularea datelor și dispute.
- Functii:
mutate,rename,inner_join,drop_na. - De ce: oferă o gramatică curată pentru transformarea datelor financiare brute în serii cronologice structurate.
- tidyquant
- Scop: Achiziția și transformarea datelor financiare.
- Functii:
tq_get(descărcați prețurile activelor),tq_transmute(calculați jurnalul de întoarcere). - De ce: Unește întreținerea cu API-urile financiare, permițând conducte reproductibile de date de piață.
- KFAS
- Scop: modelare în spațiul de stat și filtrare Kalman.
- Functii:
SSModel(definiți modelul spațiului de stare),fitSSM(estimarea parametrului MLE),KFS(Netezirea Kalman). - De ce: implementează coloana vertebrală matematică a IKF, separând tendințele latente de zgomot.
- grădină zoologică
- Scop: operațiuni cu ferestre rulante.
- Functii:
rollmean. - De ce: Folosit pentru filtrarea trece-înaltă prin scăderea mediilor mobile, atenuând derapajul.
- cântare
- Scop: Normalizare și redimensionare.
- Functii:
rescale. - De ce: Maps a filtrat tendințele într-un interval de la 0 la 100, permițând comparabilitatea între elemente.
- ggbraid
- Scop: vizualizarea divergenței.
- Functii:
geom_braid. - De ce: evidențiază perioadele de divergență dintre Aur și Bitcoin cu regiuni umbrite.
- ggplot2 (prin tidyverse)
- Scop: vizualizare.
- Functii:
geom_line,labs,theme_classic. - De ce: oferă cadrul de graficare pentru prezentarea tendințelor Kalman de trecere înaltă normalizate.
library(tidyverse)
library(tidyquant)
library(KFAS)
library(ggbraid)
# --- Step 1: Log returns ---
gold <- tq_get("GC=F", from = "2024-01-01") %>%
tq_transmute(select = close,
mutate_fun = periodReturn,
period = "daily",
type = "log")
btc <- tq_get("BTC-USD", from = "2024-01-01") %>%
tq_transmute(select = close,
mutate_fun = periodReturn,
period = "daily",
type = "log")
df <- gold %>%
rename(ret_gold = daily.returns) %>%
inner_join(btc %>% rename(ret_btc = daily.returns), by="date") %>%
drop_na()
# --- Step 2: IKF (Kalman filter) ---
model_gold <- SSModel(df$ret_gold ~ SSMtrend(1, Q = list(NA)), H = NA)
model_btc <- SSModel(df$ret_btc ~ SSMtrend(1, Q = list(NA)), H = NA)
fit_gold <- fitSSM(model_gold, inits = c(log(var(df$ret_gold)), log(var(df$ret_gold))))
fit_btc <- fitSSM(model_btc, inits = c(log(var(df$ret_btc)), log(var(df$ret_btc))))
kf_gold <- KFS(fit_gold$model, smoothing = c("state"))
kf_btc <- KFS(fit_btc$model, smoothing = c("state"))
trend_gold <- as.numeric(kf_gold$alphahat)
trend_btc <- as.numeric(kf_btc$alphahat)
# --- Step 3: High-pass filter (remove low-frequency drift) ---
hp_gold <- trend_gold - zoo::rollmean(trend_gold, k=30, fill=NA, align="right")
hp_btc <- trend_btc - zoo::rollmean(trend_btc, k=30, fill=NA, align="right")
# --- Step 4: Range normalization ---
gold_norm <- scales::rescale(hp_gold, to=c(0,100))
btc_norm <- scales::rescale(hp_btc, to=c(0,100))
# --- Step 5: Relative notation (directional divergence) ---
df_norm <- df %>%
mutate(
gold_norm = gold_norm,
btc_norm = btc_norm,
sign_gold = sign(ret_gold),
sign_btc = sign(ret_btc),
divergence = sign_gold != sign_btc
)
# --- Plot ---
ggplot(df_norm, aes(x=date)) +
geom_line(aes(y=gold_norm, color="Gold"), linewidth=1.2) +
geom_line(aes(y=btc_norm, color="Bitcoin"), linewidth=1.2) +
geom_braid(aes(ymin=gold_norm, ymax=btc_norm, fill=divergence), alpha=0.3) +
scale_color_manual(values=c("Gold"="#FFD700", "Bitcoin"="#1E3A8A"),
name = "") +
scale_fill_manual(values=c("TRUE"="#FF4C4C", "FALSE"="#87CEFA"),
name = "Divergence") +
scale_y_continuous(limits=c(0,100)) +
labs(title="Gold vs Bitcoin: Kalman-Filtered High-Pass Trends",
subtitle="Directional divergence highlighted with shaded regions",
x="", y="Normalized High-Pass Kalman Trend") +
theme_classic(base_family = "Roboto Slab") +
theme(
legend.position="bottom",
legend.title=element_text(size=12, face="bold"),
legend.text=element_text(size=10),
plot.title=element_text(size=16, face="bold"),
plot.subtitle=element_text(size=12),
axis.title=element_text(size=12, face="bold"),
axis.text=element_text(size=10),
panel.grid.minor=element_blank()
)


Concluzie
Adaptând conducta IKF din lucrarea de biomecanică sportivă, demonstrăm cum filtrare în spațiul de stareatenuarea derivei și normalizarea pot dezvălui dinamica comparativă între activele financiare. Această abordare modulară este reproductibilă și extensibilă la alte domenii în care tendințele latente și divergențele contează.
