Koopman Operators and DMD: Do Market Modes Survive Out-of-Sample?
Dinamik Mod Ayrıştırma size bir spektrum sunar: her biri bir büyüme oranına ve frekansa sahip olan ve her biri varlık kesitiniz üzerinde bir mekansal moda bağlı olan bir avuç karmaşık özdeğer. Yapıya benziyor. Bütün soru, bunun bir yapı mı olduğu yoksa bir gürültü penceresini görev bilinciyle ezberleyen doğrusal bir operatör mü olduğudur.
Bu sorunun test edilebilir iki yarısı vardır ve bu makale bunların etrafında oluşturulmuştur:
- Mod kalıcılığı. DMD'yi pencereye yerleştirin ve pencerede . Baskın modlar aynı altuzayı mı kapsıyor yoksa her yeniden düzenlemede yeniden mi karıştırılıyor? Eğer değişiklik yaparlarsa, DMD örnek içi bir ayrıştırmadır ve başka bir şey değildir - ve bunu açıkça söylemek başka bir eğitimden daha faydalıdır.
- Öncü gösterge olarak spektral yarıçap. En büyük özdeğer modülü takılan dinamiklerin ne kadar patlayıcı olduğunu özetleyen tek bir skalerdir. Gerçekleşmiş oynaklığa öncülük ediyor mu, geciktiriyor mu, yoksa sadece yeniden ifade ediyor mu? Her iki yanıt da yayınlanabilir; yalnızca ilki takas edilebilir.
Piyasaların burada durağan olmayan doğrusal olmayan sistemler olduğu varsayılıyor, tartışılmıyor - blog bunu zaten algotrading'deki çekiciler'deki faz-uzay geometrisi ve HMM'lerle rejim tespiti'de rejim başına ölçülen BTC istatistikleriyle tartışmıştı. Aşağıda, durağan olmamanın uygun bir Koopman operatörüne ne yaptığı ve bunun nasıl ölçüleceğine ilişkin daha dar bir soru yer almaktadır.
1. Temel Fikir: Doğrusal Olmayan Dinamikleri Doğrusallaştırmak

Durum uzayında ayrık zamanlı bir dinamik sistemi düşünün :
Neresi muhtemelen doğrusal olmayan bir haritadır. Piyasalar için, zaman adımındaki varlık getirilerinin, oynaklıkların veya emir defteri dengesizliklerinin bir vektörüdür .
Koopman operatörü devlete bağlı olmayan hareketler doğrudan, ancak skaler değerli gözlemlenebilir fonksiyonlarda :
Anahtar özellik: doğrusaldır, şu durumlarda bile değil. Fiyat boyutluluktur — sonsuz boyutlu bir fonksiyon uzayına etki eder. İyi bir sonlu boyutlu yaklaşım, size doğrusal cebirin izlenebilirliğiyle birlikte doğrusal olmayan dinamiklerin ifade gücünü satın alır: tahmin, matris üssü haline gelir ve her mod, ağ ağırlıklarına gömülmek yerine denetlenebilir.
2. Koopman Operatörünün Spektral Ayrışımı

Eğer özdeğerleri var ve özfonksiyonlar , Daha sonra ve gözlemlenebilir herhangi bir bu özfonksiyonların aralığında şu şekilde ayrışır:
Neresi Koopman modları — her bir özfonksiyonun tam gözlemlenebilir vektöre nasıl katkıda bulunduğunu açıklayan vektör değerli katsayılardır.
Her bir özdeğer bir büyüme veya bozulma oranını kodlar () ve bir salınım frekansı ():
| Bileşen | Özdeğer özelliği | Finansal yorumlama |
|---|---|---|
| Eğilim | , | Yavaş sürüklenme, momentum |
| Döngüler | , | Salınımlar, mevsimsellik |
| Geçiciler | Çürüyen şoklar, kısa ömürlü hamleler | |
| Kararsız modlar | Büyüyen, patlayıcı dinamikler |
Bu tablo vaattir. Bölüm 4, sözün verilere göre kontrol edildiği yerdir.
3. Dinamik Mod Ayrışımı (DMD)

DMD, yaklaşıklaştırma için güçlü bir algoritmadır verilerden. Matrisler halinde düzenlenmiş anlık görüntüler:
DMD en uygun doğrusal operatörü arıyor ile :
- SVD'yi hesaplayın:
- Proje:
- Özoluşturma:
- Tam alan modlarını kurtarın:
Sütunları DMD modları; köşegeni DMD özdeğerlerini tutar.
import numpy as np
from numpy.linalg import svd, eig, lstsq
def dmd(X: np.ndarray, rank: int | None = None) -> tuple:
"""
Dynamic Mode Decomposition.
Parameters
----------
X : np.ndarray, shape (n_features, n_snapshots)
Data matrix where each column is a state snapshot.
rank : int or None
Truncation rank for the SVD. None = no truncation.
Returns
-------
eigenvalues : np.ndarray, shape (r,)
DMD eigenvalues (approximating Koopman eigenvalues).
modes : np.ndarray, shape (n_features, r)
DMD modes (columns), L2-normalised.
amplitudes : np.ndarray, shape (r,)
Mode amplitudes fitted to the FINAL snapshot, so that a one-step
forecast is simply modes @ (eigenvalues * amplitudes).
"""
X0 = X[:, :-1]
X1 = X[:, 1:]
U, S, Vh = svd(X0, full_matrices=False)
if rank is not None:
U = U[:, :rank]
S = S[:rank]
Vh = Vh[:rank, :]
S_inv = np.diag(1.0 / S)
A_tilde = U.conj().T @ X1 @ Vh.conj().T @ S_inv
eigenvalues, W = eig(A_tilde)
modes = X1 @ Vh.conj().T @ S_inv @ W
norms = np.linalg.norm(modes, axis=0)
norms[norms == 0] = 1.0
modes = modes / norms
amplitudes = lstsq(modes, X[:, -1].astype(complex), rcond=None)[0]
return eigenvalues, modes, amplitudes
Burada iki kasıtlı seçim var. Modlar L2-normalize edilmiştir, çünkü bölüm 4.2 pencerelerdeki mod altuzaylarını karşılaştırmaktadır ve normalleştirilmemiş genlikler karşılaştırmayı gölgede bırakacaktır. Genlikler, ilki yerine son anlık görüntüye uyarlanır; bu, bir tahminin hiçbir zaman bir özdeğeri büyük bir güce yükseltmediği anlamına gelir; bu, saf DMD sinyallerinin kayan nokta taşması olduklarında dinamik gibi görünmesini sağlayan sayısal patlamanın kaynağıdır.
4. Ölçüm

Bu makalenin ders kitabı olmayan kısmıdır. Yukarıdaki her şey uygun bir prosedürdür; Aşağıda uygunluğun bir anlam ifade edip etmediğini bulmaya yönelik protokol bulunmaktadır.
Veriler. Hisse senedi ETF'lerinin günlük olarak indirilmesi yerine, tutarlı bir dakika veya işaret tablosu üzerinde BTC, ETH ve likit altcoinlerin bir kesiti olan projenin kendi değişim verilerini kullanın. Blog kripto önceliklidir ve mikro yapı argümanı aktarılmaz. İnşa etmek satırlarda varlıklar ve sütunlarda zaman, günlük getirilerinde, her pencerede varlık başına küçültülmüş.
4.1 Özdeğer spektrumu
Temsili bir pencere için rapor: kaç tane özdeğerler birim çemberin toleransı dahilinde yer alır; her biri saat cinsinden (periyod) hangi salınım periyoduna karşılık gelir? çubuklar, dönüştürülmüş) ve dönüş varyansının ne kadarı en üstte modlar yeniden yapılandırılır.
def spectrum_report(eigenvalues: np.ndarray, bar_minutes: float,
tol: float = 0.05) -> list[dict]:
"""
Turn a DMD spectrum into human-readable rows: modulus, period in hours,
and whether the eigenvalue sits on the unit circle within `tol`.
"""
rows = []
for lam in eigenvalues:
modulus = float(np.abs(lam))
omega = float(np.angle(lam))
period_hours = (2 * np.pi / abs(omega)) * bar_minutes / 60 if omega else np.inf
rows.append({
"modulus": modulus,
"period_hours": period_hours,
"on_unit_circle": abs(modulus - 1.0) < tol,
"regime": "unstable" if modulus > 1 + tol
else "persistent" if abs(modulus - 1.0) <= tol
else "decaying",
})
return sorted(rows, key=lambda r: -r["modulus"])
def reconstruction_r2(X: np.ndarray, modes: np.ndarray,
eigenvalues: np.ndarray, amplitudes: np.ndarray) -> float:
"""Fraction of in-window return variance captured by the truncated modes."""
n_steps = X.shape[1]
powers = eigenvalues[:, None] ** np.arange(-(n_steps - 1), 1)
X_hat = (modes @ (amplitudes[:, None] * powers)).real
resid = np.var(X - X_hat)
return 1.0 - resid / np.var(X)
Dürüst bir spektrum raporu zaten makaleye değer. Birim çemberin yakınında hiçbir şey yoksa, ticaret için kalıcı döngüler yoktur ve hisse senedi literatüründeki "yıllık mevsimsellik" hikayesi, 7/24 kriptoya aktarılmaz.
4.2 Bitişik pencerelerde mod kararlılığı
Belirleyici test. DMD'yi pencereye sığdır , ardından pencerede ve baskın mod alt uzayının ne kadarının hayatta kaldığını ölçün. Doğru istatistik, mod vektörlerinin basit bir korelasyonu değil (mod sıralaması ve karmaşık faz keyfidir), iki altuzay arasındaki ana açılardır.
def subspace_stability(modes_a: np.ndarray, modes_b: np.ndarray,
k: int = 3) -> float:
"""
Overlap between the leading-k DMD mode subspaces of two adjacent windows.
Returns the mean cosine of the principal angles: 1.0 = identical subspace,
0.0 = orthogonal. Immune to mode reordering and complex phase, both of
which are arbitrary in a DMD fit.
"""
Qa, _ = np.linalg.qr(modes_a[:, :k])
Qb, _ = np.linalg.qr(modes_b[:, :k])
sing = np.linalg.svd(Qa.conj().T @ Qb, compute_uv=False)
return float(np.mean(np.clip(sing, 0.0, 1.0)))
def stability_curve(returns: np.ndarray, window: int, step: int,
rank: int, k: int = 3) -> np.ndarray:
"""Subspace overlap between every pair of adjacent windows."""
fits = []
for t_end in range(window, returns.shape[1], step):
evals, modes, _ = dmd(returns[:, t_end - window:t_end], rank=rank)
order = np.argsort(-np.abs(evals))
fits.append(modes[:, order])
return np.array([subspace_stability(fits[i], fits[i + 1], k=k)
for i in range(len(fits) - 1)])
Bu örtüşmenin dağılımını rapor edin ve bunu boş bir değere göre rapor edin: aynı getirilerin faz-rastgeleleştirilmiş ikameleri üzerinde hesaplanan aynı istatistik. Yüksek olan ancak yedek sıfırdan daha yüksek olmayan örtüşme, modların dinamikleri değil kovaryans yapısını takip ettiği anlamına gelir.
4.3 Gerçekleşen oynaklığa karşı dönen spektral yarıçap
Test etme iddiası: Dönen pencerelerde yeniden hesaplanan , volatilite gerçekleşmeden önce hareket eder. Skaler mekanik olarak yenidir - blog daha önce geometrik skalerleri gerçek zamanlı olarak izlemişti, özellikle de algoritmik ticaret için karmaşık manifoldlar'deki Kobayashi eğriliği - ancak Koopman özdeğer modülü, farklı bir hata moduna sahip farklı bir miktardır ve miras alınan bir adım yerine kendi ön-gecikme testini hak eder.
def rolling_spectral_radius(returns: np.ndarray, window: int = 1440,
step: int = 60, rank: int = 5) -> dict:
"""
Rolling DMD spectrum for regime monitoring.
returns : np.ndarray, shape (n_assets, n_timesteps)
window : rolling window length in bars
step : bars between refits
"""
idx, radii, dom_freq = [], [], []
for t_end in range(window, returns.shape[1], step):
X_win = returns[:, t_end - window:t_end]
try:
evals, _, _ = dmd(X_win, rank=rank)
except np.linalg.LinAlgError:
continue
idx.append(t_end)
radii.append(float(np.max(np.abs(evals))))
on_circle = np.abs(np.abs(evals) - 1.0) < 0.1
if on_circle.any():
sel = evals[on_circle]
dom_freq.append(float(np.abs(np.angle(sel[np.argmax(np.abs(sel))])) / (2 * np.pi)))
else:
dom_freq.append(0.0)
return {"index": np.array(idx),
"spectral_radius": np.array(radii),
"dominant_frequency": np.array(dom_freq)}
def lead_lag(signal: np.ndarray, target: np.ndarray, max_lag: int = 24) -> dict:
"""
Cross-correlation of `signal` against `target` over +/- max_lag steps.
A peak at negative lag means the signal LEADS the target.
"""
s = (signal - signal.mean()) / (signal.std() + 1e-12)
y = (target - target.mean()) / (target.std() + 1e-12)
lags = np.arange(-max_lag, max_lag + 1)
corrs = []
for L in lags:
if L < 0:
corrs.append(float(np.corrcoef(s[:L], y[-L:])[0, 1]))
elif L > 0:
corrs.append(float(np.corrcoef(s[L:], y[:-L])[0, 1]))
else:
corrs.append(float(np.corrcoef(s, y)[0, 1]))
corrs = np.array(corrs)
return {"lags": lags, "corr": corrs, "peak_lag": int(lags[np.argmax(np.abs(corrs))])}
Hizala spectral_radius aynı tablo üzerinde hesaplanan ve okunan gerçekleşen volatiliteye peak_lag. 0 gecikmede bir zirve şu anlama gelir: ekstra adımlarla volatilitenin yeniden ifade edilmesidir. Örneklem ve sıralamalar arasında istikrarlı olan negatif gecikmedeki zirve, bu makalenin içinde takas edilebilir bir iddia bulunan tek versiyonudur.
Olumlu bir sonuçtan sonra ne olacağına dair bir not
Eğer liderlik ediyorsa, bir sonraki bariz hamle kesitsel yapıdır: varlıkları DMD tarafından tahmin edilen bir sonraki adım getirisine göre sıralayın, tahmin edilen kazananlara uzun gidin ve tahmin edilen kaybedenlere kısa tutun. Bu yapı burada yeni değil; faktör-artık ticareti, halihazırda istatistiksel arbitraj ve kriptoda çift ticareti ve vektörler ve matrislerle karmaşık arbitraj bölümünün 4. bölümünde ele alınmıştır; Koopman'a özgü tek gerçek değişiklik, özportföylerin statik PCA yüklemeleri yerine zamanla değişen özdeğerler taşımasıdır.
Strateji bölümü bu makalede kasıtlı olarak yer almamaktadır çünkü burada ücretler ve kaymalar açısından tekrar test edilmemiştir. Öyle olduğunda, blogun kendi çıtasını aşması gerekir: Dürüst negatifin geçerli karşı örneğine karşı Sönük Sharpe Oranı ve çoklu testte anlamlılık testi. DMD spektrum grafiği bir sonuç değildir.
Tek adımlı tahminin kendisi için, doğru uygulama, bir özdeğeri pencere uzunluğunun kuvvetine yaymak yerine son anlık görüntüden tahmin yapar:
def dmd_one_step(returns: np.ndarray, rank: int = 4) -> np.ndarray:
"""
One-step-ahead prediction from the final snapshot of the window.
Never raise eigenvalues to the window length: any |lambda| != 1 then
overflows or underflows and the "signal" becomes numerical garbage.
"""
evals, modes, amplitudes = dmd(returns, rank=rank)
return (modes @ (evals * amplitudes)).real
5. Genişletilmiş DMD (EDMD): Doğrusal Olmayan Gözlemlenebilirler

Standart DMD ham durum vektörü üzerinde çalışır. EDMD, verileri öncelikle doğrusal olmayan temel işlevler sözlüğü aracılığıyla kaldırır.
Bir sözlük verildi skaler fonksiyonların , kaldırılmış durumu tanımlayın:
EDMD arıyor ile . Aşağıdaki kodun kullandığı kuralda sütunlar olarak belirtilir, sol tarafta hareket ederek:
| Sözlük türü | İşlevler | Yakalamalar |
|---|---|---|
| Polinom | Doğrusal olmayan çapraz varlık etkileşimleri | |
| Radyal temel (RBF) | Yerel benzerlik, rejim kümelenmesi | |
| Zaman gecikmeli yerleştirme | Bellek / otoregresif yapı | |
| Fourier | Bilinen periyodiklikler (gün içi, haftalık) | |
| Volatilite özellikleri | Değişken varyans, hacim kümeleme |
Sözlük, alan bilgisinin devreye girdiği yerdir ve zaman gecikmesi satırı, gecikme koordinatlarını önemsemenin Koopman'a özgü nedenidir: bunlar cıvatalanmış ayrı bir teknik değildir, kaldırma haritasının bir bloğu dahadır. Gömmenin kendisi – gecikme seçimi , gömme boyutu ve bunun arkasındaki yeniden yapılandırma teoremi — algoritmik ticaret için karmaşık manifoldlar bölümünde zaten tanıtılmış ve kodlanmıştır; gecikme vektörlerini oradan alın ve doğrudan içine besleyin build_financial_dictionary ekstra satırlar olarak.
import numpy as np
from itertools import combinations_with_replacement
def build_financial_dictionary(X: np.ndarray, max_poly_degree: int = 2,
include_volatility: bool = True,
delay_steps: int = 0) -> np.ndarray:
"""
Build a dictionary of nonlinear observables for EDMD.
X : np.ndarray, shape (n_features, n_snapshots)
Returns Z of shape (n_dict, n_snapshots - delay_steps).
"""
n_features, n_snapshots = X.shape
offset = max(delay_steps, 0)
X_eff = X[:, offset:]
n_eff = X_eff.shape[1]
lifted = [X_eff] # degree-1 terms (identity)
if max_poly_degree >= 2:
for deg in range(2, max_poly_degree + 1):
for combo in combinations_with_replacement(range(n_features), deg):
term = np.ones(n_eff)
for idx in combo:
term *= X_eff[idx]
lifted.append(term.reshape(1, -1))
if include_volatility:
lifted.append(np.abs(X_eff)) # absolute returns
lifted.append(X_eff ** 2) # squared returns
for d in range(1, delay_steps + 1):
lifted.append(X[:, offset - d : n_snapshots - d])
return np.vstack(lifted)
def edmd(X: np.ndarray, dictionary_fn=None, reg: float = 1e-8,
**dict_kwargs) -> tuple:
"""
Extended Dynamic Mode Decomposition.
Solves Z1 ~= K @ Z0 in the least-squares sense. Uses a least-squares
solve rather than an explicit Gram inverse: `inv` on a near-singular
dictionary Gram matrix is how EDMD spectra get silently corrupted.
"""
if dictionary_fn is None:
dictionary_fn = lambda x: build_financial_dictionary(x, **dict_kwargs)
Z = dictionary_fn(X)
Z0, Z1 = Z[:, :-1], Z[:, 1:]
p = Z0.shape[0]
G = Z0 @ Z0.T + reg * np.eye(p) # regularised Gram matrix
A = Z1 @ Z0.T
K = np.linalg.solve(G, A.T).T
eigenvalues, eigenvectors = np.linalg.eig(K)
return K, eigenvalues, eigenvectors
6. Derin Koopman Ağları

EDMD sözlüğü el yapımıdır ve bu, Koopman'la değişmez alt uzayın bilinmediği durumlarda gerçek bir sınırlamadır. Deep Koopman ağları kaldırma işlemini ve operatörü birlikte öğrenir.
Mimari bir otomatik kodlayıcıdır (kodlayıcı, gizli kod, kod çözücü, yeniden yapılandırma kaybı, hepsi algotrading'de anormallik tespiti bölümünde tanıtıldığı gibi - bölümün asıl amacı olan bir eklemeyle: gizli dinamikleri tek bir öğrenilmiş matris yoluyla zorlayan bir doğrusallık kaybı .
x_k --> [Encoder φ] --> z_k --> [Linear K] --> z_{k+1} --> [Decoder ψ] --> x̂_{k+1}
| |
+--- Linearity loss: ‖z_{k+1} - K z_k‖ ---+
olmadan terimde, gizli alanını bir matris çarpımı takip eden sıradan bir otomatik kodlayıcınız var. Bununla birlikte ağ, evrimi doğrusal olmayan herhangi bir gizli temsil için cezalandırılır; bu da öğrenilmiş olanı yapar. Bölüm 4'teki DMD spektrumuyla karşılaştırılabilir bir Koopman yaklaşımı ve özdeğerleri.
import torch
import torch.nn as nn
class DeepKoopman(nn.Module):
"""Deep Koopman autoencoder: learned lifting + linear latent dynamics."""
def __init__(self, input_dim: int, latent_dim: int, hidden_dim: int = 128):
super().__init__()
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim), nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
nn.Linear(hidden_dim, latent_dim),
)
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim), nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
)
self.K = nn.Linear(latent_dim, latent_dim, bias=False)
def encode(self, x: torch.Tensor) -> torch.Tensor:
return self.encoder(x)
def decode(self, z: torch.Tensor) -> torch.Tensor:
return self.decoder(z)
def forward(self, x_k: torch.Tensor) -> dict:
z_k = self.encode(x_k)
z_k1_pred = self.K(z_k)
return {
"z_k": z_k,
"z_k1_pred": z_k1_pred,
"x_k1_pred": self.decode(z_k1_pred),
"x_k_recon": self.decode(z_k),
}
def multi_step_predict(self, x_0: torch.Tensor, n_steps: int) -> torch.Tensor:
"""Roll out by repeated application of the linear operator."""
z = self.encode(x_0)
preds = []
for _ in range(n_steps):
z = self.K(z)
preds.append(self.decode(z))
return torch.stack(preds, dim=1)
def latent_spectrum(self) -> np.ndarray:
"""Eigenvalues of the learned K — directly comparable to DMD's."""
return np.linalg.eigvals(self.K.weight.detach().cpu().numpy())
def koopman_loss(model: DeepKoopman, x_k: torch.Tensor, x_k1: torch.Tensor,
alpha: float = 1.0, beta: float = 0.5) -> torch.Tensor:
out = model(x_k)
z_k1_true = model.encode(x_k1)
prediction = nn.functional.mse_loss(out["x_k1_pred"], x_k1)
linearity = nn.functional.mse_loss(out["z_k1_pred"], z_k1_true)
reconstruction = nn.functional.mse_loss(out["x_k_recon"], x_k)
return prediction + alpha * linearity + beta * reconstruction
latent_spectrum Bunu bir dizi modeline ulaşmaktan ziyade eğitime değer kılan şey budur: öğrenilen operatör hala bir matristir, dolayısıyla bölüm 4.2 stabilite testi ve bölüm 4.3 ileri-gecikme testi derin bir modele değiştirilmeden uygulanır.
7. Pratik Hususlar ve Tuzaklar

Sıra seçimi. Kesme sırası önyargılı bir kadrandır - çok düşük dinamikleri kaçırır, çok yüksek gürültüye uyar. Tekil değerli bir dirseğe göz atmayın; blog, vektörler ve matrislerle karmaşık arbitraj'te Rastgele Matris Teorisinden yola çıkan Marchenko-Pastur ile "gürültüyü yerleştirmeden önce kaç bileşen" sorusunu zaten doğru bir şekilde yanıtlıyor. Tekil değerleri Marchenko-Pastur kenarını aşan bileşenleri pencere şekliniz için tutun ve sonucu belirtin. yayınladığınız her spektrumun yanında açıkça.
Pencere uzunluğu. Koopman teorisi sabit bir pencere uzunluğunu varsayar ; Piyasalar bir tane tedarik etmiyor. Sürekli yenilemeler zorunludur ve bölüm 4.2'nin stabilite eğrisi, seçilen pencerenin tahmin için yeterince uzun ve bir rejim içinde kalacak kadar kısa olup olmadığının tam olarak teşhisidir.
Gürültü duyarlılığı. Finansal verilerin sinyal-gürültü oranı düşüktür ve standart DMD, gürültüye karşı önyargılıdır. . Modların kararsız olduğu sonucuna varmadan önce denemeye değer çözümler:
- Toplam DMD (TDMD) — her ikisini de tedavi eder Ve toplam en küçük kareler yoluyla gürültülü.
- Optimize edilmiş DMD — özdeğer modu ayrıştırmasını artık Frobenius normuna göre doğrudan optimize eder.
- Çekirdek EDMD — sözlüğü oluşturmadan yüksek boyutlu bir özellik alanında örtülü olarak çalışır.
TDMD altında mod kararlılığı önemli ölçüde artarsa, kararsızlık ölçüm gürültüsüdür. Değilse, pazardı.
8. DMD'nin Olduğu Yer

| Yöntem | Doğrusallık | Yorumlanabilir | Çok adımlı tahmin |
|---|---|---|---|
| DMD | Durum uzayında doğrusal | Evet (modlar + özdeğerler) | Kararlı (matris gücü) |
| EDMD | Kaldırılmış uzayda doğrusal | Evet, sözlük göz önüne alındığında | Kararlı (matris gücü) |
| Derin Koopman | Öğrenilmiş uzayda doğrusal | Orta (gizli K'yi inceleyin) | Kararlı (matris gücü) |
Volatiliteye özgü tahminler için karşılaştırma noktası GARCH ailesidir — bkz. Kripto için GARCH volatilite tahmini. Tamamen doğrusal olmayan dizi modelleri ve bunların taşıdıkları yorumlanabilirlik ve hata birikimi dengelemeleri için, bkz. Ticaretteki Geçici Füzyon Transformatörü.
DMD'nin kapladığı alan dar ama gerçektir: her modun denetlenebildiği, otoregresif dağıtım yerine tek bir matris gücüyle oluşturulan çok adımlı tahminler. Bu nişin alfa içerip içermediği bu tablonun değil, 4. bölümün sorusudur.
Sonuç

Koopman teorisi, pazar dinamiklerine bakmanın gerçekten zarif bir yoludur ve zarafet, tam da mevcut en zorlu teste ihtiyaç duymasının nedenidir. Paket servisler:
- DMD'yi takın, ardından hemen uyumu test edin. Bitişik pencereler arasındaki altuzay örtüşmesi, faz-rastgeleleştirilmiş bir boşluğa göre ölçülür, size bir öğleden sonra yapıyı mı bulduğunuzu yoksa bir pencereyi ezberleyip ezberlemediğinizi söyler.
- Dönme spektral yarıçapı izlenmeye değer tek skalerdir ve değeri tamamen ilerleme-gecikme sonucuna bağlıdır. 0 gecikmesinde bu bir volatilite göstergesidir; negatif gecikmede bu bir rejim uyarısıdır.
- Genlikleri son anlık görüntüye sabitleyin ve özdeğerleri hiçbir zaman pencere uzunluğuna yükseltmeyin. Doğadaki DMD "sinyallerinin" büyük bir kısmı kayan nokta yapaylıklarıdır.
- Sırayı gözünü dikerek değil, Marchenko-Pastur'a göre seçin ve sıralamayı her spektrumla birlikte yayınlayın.
- Bir spektrum grafiği bir sonuç değildir. Bunun üzerine inşa edilen herhangi bir stratejinin, geçerli olmadan önce ücretlerden, kaymalardan ve söndürülmüş bir Sharpe testinden sağ çıkması gerekir.
Bunların ötesindeki uygulamalar için, PyDMD kütüphanesi DMD varyantlarını kapsamlı bir şekilde kapsar ve Mallen ve arkadaşlarının referans kodu derin Koopman tarafını kapsar.
Piyasalar dağınık, durağan olmayan ve kısmen gözlemlenmeye devam edecek. Koopman teorisi, bu karmaşadan yapıyı çıkarmak için ilkeli bir bakış açısı sunuyor; tabii yapının önümüzdeki hafta da orada olup olmadığını kontrol etmeniz şartıyla.
Referanslar ve daha fazla okuma:- B. O. Koopman, "Hamilton Sistemleri ve Hilbert Uzayında Dönüşüm" Ulusal Bilimler Akademisi Bildirileri, 1931.
- J. H. Tu ve diğerleri, "Dinamik Mod Ayrışımı Üzerine: Teori ve Uygulamalar" Journal of Computational Dynamics, 2014.
- M. O. Williams, I. G. Kevrekidis, C. W. Rowley, "A Data-Driven Approximation of the Koopman Operator: Extending Dynamic Mode Decomposition" Journal of Nonlinear Science, 2015.
- B. Lusch, J. N. Kutz, S. L. Brunton, "Doğrusal Olmayan Dinamiklerin Evrensel Doğrusal Yerleştirmeleri için Derin Öğrenme," Nature Communications, 2018.
- J. Mann ve J. N. Kutz, "Finansal Ticaret Stratejileri için Dinamik Mod Ayrışımı", Kantitatif Finans, 2016.
- A. Mallen ve diğerleri, "Zamansal Dağılım Kaymaları Olan Zaman Serileri için Koopman Nöral Tahminci" ICML, 2023.
- E. Gonzalez ve M. Generelo, "Koopman operatörleri, EDMD, Takens teoremi ve Makine Öğrenimi aracılığıyla kaotik ekonomik modellerin analizi", Finans ve Ekonomide Veri Bilimi, 2022.
Yazarlar
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.