Koopman Operators and DMD: Do Market Modes Survive Out-of-Sample?
Динамикалык модаларды ажыратуу сизге спектрди берет: өсүү ылдамдыгы жана жыштыгы бар бир нече комплекстүү өздүк маанилер, алардын ар бири активдердин кесилишиндеги мейкиндиктик модага байланышкан. Бул структурага окшош. Негизги суроо — бул чындап эле структурабы, же сызыктуу оператор ызы-чуунун бир гана терезесин жаттап алдыбы.
Бул суроонун эки сыналуучу жарымы бар жана бул макала алардын тегерегинде курулган:
- Модалардын туруктуулугу. DMDни терезесине жана терезесине үйрөтүңүз. Үстөмдүк кылган модалар бир эле ички мейкиндикти камтыйбы же ар бир кайра үйрөтүүдө өзгөрөбү? Эгер өзгөрсө, DMD тандоо ичиндеги ажыратуу гана болуп калат — муну ачык айтуу дагы бир окуу колдонмосунан пайдалуураак.
- Спектралдык радиус алдын ала көрсөткүч катары. Эң чоң өздүк маанинин модулу үйрөтүлгөн динамиканын канчалык жарылма экенин бир сан менен жыйынтыктайт. Ал ишке ашкан өзгөрмөлүүлүктү алдын ала көрсөтөбү, артынан ээрчийби же аны жөн гана кайталайбы? Кайсы жооп болбосун жарыялоого татыктуу; биринчи жооп гана соодалоого жарайт.
Рыноктор стационардык эмес сызыктуу системалар экени бул жерде далилденбейт, болжол катары кабыл алынат: блог муну фазалык мейкиндиктин геометриясы аркылуу алгоритмдик трейдингдеги аттракторлор жана ар бир режим боюнча өлчөнгөн BTC статистикасы аркылуу HMM менен режимди аныктоо макалаларында талкуулаган. Төмөндө стационардык эместик үйрөтүлгөн Koopman операторуна кандай таасир берерин жана аны кантип өлчөө керектиги каралат.
1. Негизги идея: Сызыктуу эмес динамикаларды сызыкташтыруу

абалдар мейкиндигиндеги дискреттик убакыт динамикалык системасын карайлы:
мында сызыктуу эмес болушу мүмкүн болгон чагылдыруу. Рынокто — убакыт кадамындагы активдердин кирешелеринин, өзгөрмөлүүлүгүнүн же буйрутмалар китебиндеги дисбаланстардын вектору.
Koopman оператору абал менен түз иштебестен, скаляр маанилүү байкоого боло турган функцияларга таасир этет:
Негизги касиети: сызыктуу, сызыктуу эмес болсо да. Баасы — өлчөмдүүлүк: чексиз өлчөмдүү функциялар мейкиндигинде иштейт. Жакшы чектүү өлчөмдүү жакындатуу сызыктуу эмес динамиканын мүмкүнчүлүгүн сызыктуу алгебранын башкарылуучулугу менен айкалыштырат: болжолдоо матрицаны даражага көтөрүүгө айланат, ал эми ар бир моданы нейрондук тармактын салмактарынан издеп отурбастан текшерүүгө болот.
2. Коопман операторунун спектралдык декомпозициясы

Эгер операторунун өздүк маанилери жана өздүк функциялары болсо, анда . Бул өздүк функциялардын сызыктуу кабыгындагы каалаган байкоого боло турган төмөнкүдөй ажыратылат:
мында — Koopman модалары, башкача айтканда, ар бир өздүк функциянын толук байкоо векторуна кошкон салымын сүрөттөгөн вектордук коэффициенттер.
Ар бир өздүк маани өсүү же басаңдоо ылдамдыгын () жана термелүү жыштыгын () коддойт:
| Компонент | Өздүк маанинин касиети | Финансылык чечмелөө |
|---|---|---|
| Тренд | , | Жай дрейф, импульс |
| Циклдер | , | Термелүүлөр, мезгилдүүлүк |
| Өткөөл процесстер | Басаңдаган соккулар, кыска кыймылдар | |
| Туруксуз модалар | Өсүүчү, жарылма динамика |
Бул үстөл убада болуп саналат. 4-бөлүмдө убада маалыматтарга каршы текшерилет.
3. Динамикалык режимдин декомпозициясы (DMD)

DMD — маалыматтардан операторун жакындаткан негизги алгоритм. Снимоктор төмөнкү матрицаларга тизилет: DMD эң ылайыктуу сызыктуу операторун издеп, шартын канааттандырат:
- SVD эсептөө: .
- Проекциялоо: .
- Өздүк ажыратуу: .
- Толук мейкиндиктеги модаларды калыбына келтирүү: .
матрицасынын мамычалары DMD модалары, ал эми диагоналы DMD өздүк маанилерин камтыйт.
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
Бул жерде эки атайын чечим кабыл алынган. Модалар L2 боюнча нормалдаштырылган, анткени 4.2-бөлүмдө ар башка терезелердеги мода ички мейкиндиктери салыштырылат, ал эми нормалдаштырылбаган амплитудалар салыштырууну бузмак. Амплитудалар биринчи эмес, акыркы снимокко ылайыкташтырылат. Ошондуктан болжолдоо өздүк маанини чоң даражага көтөрбөйт — дал ушул нерсе сандык жарылууга алып келип, жөнөкөй DMD сигналдарын калкыма чекиттин ашып кетүүсүн динамикадай көрсөтөт.
4. Өлчөө протоколу

Бул макаланын окуу китебине кирбеген бөлүгү. Жогорудагылардын баары — модель орнотуу процедурасы; төмөндө ошол орнотуунун мааниси бар-жогун аныктоочу протокол берилет.
Маалыматтар. Долбоордун өз биржа маалыматтарын колдонуңуз — BTC, ETH жана ликвиддүү альткоиндердин бирдиктүү минуталык же тиктик тордогу кесилиши. Акция ETFтеринин күнүмдүк жүктөмүн колдонбоңуз. Блог крипторынокко багытталган, ошондуктан микроструктура жөнүндөгү жүйө автоматтык түрдө көчүрүлбөйт. Ар бир терезеде активдер саптарда, убакыт мамычаларда турган матрицасын логарифмдик кирешелер менен түзүп, ар бир актив боюнча орточосун алып салыңыз.
4.1 Өздүк маани спектри
Өкүлчүлүктүү терезе үчүн төмөнкүлөрдү отчет кылыңыз: өздүк маанинин канчасы бирдик айланасына берилген толеранттуулукта жайгашат; ар бирине саат менен кайсы термелүү мезгили туура келет (мезгил бар менен эсептелип, андан кийин саатка которулат); жана эң жогорку мода кирешелер дисперсиясынын кайсы бөлүгүн кайра түзөт.
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)
Чынчыл спектр отчету өзү эле макаланы баалуу кылат. Эгер бирдик айланасына жакын эч нерсе жок болсо, соодалоого туруктуу циклдер жок, демек акциялар адабиятындагы "жылдык мезгилдүүлүк" жөнүндөгү окуя 24/7 иштеген крипторынокко көчпөйт.
4.2 Кошуна терезелер боюнча режимдин туруктуулугу
Бул чечүүчү тест. DMDни терезесине, андан кийин терезесине үйрөтүп, үстөмдүк кылган мода ички мейкиндигинин канчасы сакталганын өлчөңүз. Туура статистика — мода векторлорунун жөнөкөй корреляциясы эмес (модалардын тартиби жана комплекстүү фазасы эркин), эки ички мейкиндиктин ортосундагы башкы бурчтар.
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)])
Бул кабатташуунун бөлүштүрүлүшүн жана нөлдүк бөлүштүрүү менен салыштыруусун жарыялаңыз: ошол эле кирешелердин фазасы рандомизацияланган суррогаттарында эсептелген статистиканы колдонуңуз. Кабатташуу жогору болгону менен суррогаттык нөлдөн жогору болбосо, модалар динамиканы эмес, ковариация түзүмүн ээрчип жатканын билдирет.
4.3 Реализацияланган өзгөрмөлүүлүккө салыштырмалуу жылма спектралдык радиус
Текшериле турган доомат: жылма терезелерде кайра эсептелген реализацияланган өзгөрмөлүүлүктөн мурда кыймылдайбы же аны менен кошо гана өзгөрөбү? Бул скаляр таптакыр жаңы эмес — блог буга чейин реалдуу убакытта геометриялык скалярларды, анын ичинде алгоритмдик соода үчүн комплекстүү көп түрдүүлүктөр макаласындагы Кобаяши ийрилигин көзөмөлдөгөн. Бирок Koopman өздүк маанисинин модулу башка чоңдук жана башкача иштен чыгуу режими бар; ага өзүнчө алдыга-артка жылыш тестин жүргүзүү керек.
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))])}
spectral_radius маанисин ошол эле тордо эсептелген реализацияланган өзгөрмөлүүлүк менен теңдеп, peak_lag маанисин аныктаңыз. Лаг 0дөгү чоку өзгөрмөлүүлүктү кошумча кадамдар менен гана кайталап жатканын билдирет. Бүт тандоодо жана ар башка рангдарда туруктуу терс лагдагы чоку — бул макалада соодалоого жарамдуу доомат бар жалгыз вариант.
Оң натыйжадан кийин эмне болору жөнүндө эскертүү
Эгер чындап алдын ала көрсөткүч болсо, кийинки кадам — кесилиштик конструкция: активдерди DMD болжолдогон кийинки кадамдын кирешеси боюнча иреттеп, күтүлгөн жеңүүчүлөрдү сатып, утулгандарды кыска позицияга сатуу. Бул конструкция жаңы эмес — фактордук калдык соодасы криптодогу статистикалык арбитраж жана жуптук соода жана векторлор менен матрицалар аркылуу комплекстүү арбитраж материалдарында камтылган. Koopmanга гана тиешелүү бурулуш — өздүк портфелдер статикалык PCA жүктөмдөрүнүн ордуна убакыт боюнча өзгөргөн өздүк маанилерди алып жүрөт.
Стратегия бөлүмү атайын киргизилген жок, анткени бул жерде ал комиссиялар жана тайгалануу эске алынган тарыхый тесттен өткөн эмес. Тест жасалганда, стратегия блогдун өз талабына жооп бериши керек: дефляцияланган Sharpe коэффициенти жана көп жолку тестирлөө боюнча маанилүүлүк тестинен өтүп, туруктуу каршы мисал болгон чынчыл терс жыйынтык менен салыштырылышы керек. DMD спектринин графиги жыйынтык эмес.
Бир кадам алдыга болжолдоодо туура ишке ашыруу өздүк маанини терезенин узундугуна барабар даражага көтөрбөйт, акыркы снимоктон болжолдойт:
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. Кеңейтилген DMD (EDMD): сызыктуу эмес байкоолор

Стандарттык DMD баштапкы абал вектору менен иштейт. EDMD адегенде маалыматтарды сызыктуу эмес базистик функциялардын сөздүгү аркылуу көтөрөт.
Скалярдык функциялардын сөздүгү берилсин, мында . Көтөрүлгөн абалды аныктайбыз: EDMD операторун шартын канааттандыра тургандай издейт. Төмөнкү коддогу келишимде абалдар мамычалар катары берилет, ал эми сол жактан аракеттенет:
| Сөздүктүн түрү | Функциялар | Камтыган нерсе |
|---|---|---|
| Полином | Активдердин ортосундагы сызыктуу эмес өз ара аракеттенүүлөр | |
| Радиалдык базис (RBF) | Жергиликтүү окшоштук, режимдердин кластерлешүүсү | |
| Убакытты кечиктирүү киргизүү | Эс тутум/авторегрессивдүү структура | |
| Фурье | Белгилүү мезгилдүүлүк (бир күндүк, жумалык) | |
| Туруксуздуктун өзгөчөлүктөрү | Гетероскедастика, вол кластер |
Сөздүк — предметтик билим киргизилген жер. Убакыт кечигүүсү жөнүндөгү сап Koopman үчүн кечигүү координаттарына көңүл буруунун өзгөчө себебин көрсөтөт: алар кошумча техника эмес, көтөрүү чагылдыруусунун дагы бир блогу. Киргизүүнүн өзү — кечигүү тандоосу, киргизүү өлчөмү жана анын негизиндеги реконструкция теоремасы — буга чейин алгоритмдик соода үчүн комплекстүү көп түрдүүлүктөр макаласында киргизилип, коддолгон. Ал жактагы кечигүү векторлорун алып, кошумча саптар катары түз эле build_financial_dictionary функциясына бериңиз.
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. Deep Koopman тармактары

EDMD сөздүгү кол менен түзүлөт, ал эми Koopman инварианттуу ички мейкиндиги белгисиз болгондо бул олуттуу чектөө. Deep Koopman тармактары көтөрүү чагылдыруусун жана операторду бир убакта үйрөнөт.
Архитектура — алгоритмдик трейдингдеги аномалияларды аныктоо материалында киргизилгендей, коддоочу, жашыруун код, декодер жана реконструкция жоготуусу бар автокодер. Бул бөлүмдүн негизги кошумчасы — жашыруун динамиканы бир үйрөнүлгөн матрицасы аркылуу өткөрүүгө мажбурлаган сызыктуулук жоготуусу.
x_k --> [Encoder φ] --> z_k --> [Linear K] --> z_{k+1} --> [Decoder ψ] --> x̂_{k+1}
| |
+--- Linearity loss: ‖z_{k+1} - K z_k‖ ---+
мүчөсү жок болсо, жашыруун мейкиндигинен кийин матрица көбөйтүлгөн кадимки автокодер алынат. Бул мүчө кошулганда, жашыруун өкүлчүлүктүн эволюциясы сызыктуу эмес болсо, тармак жаза алат. Ошондуктан үйрөнүлгөн Koopman жакындатуусуна айланат, ал эми анын өздүк маанилерин 4-бөлүмдөгү DMD спектри менен салыштырууга болот.
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 функциясы бул моделди жөн гана ырааттуулук моделине алмаштырбай үйрөтүүгө негиз берет: үйрөнүлгөн оператор дагы эле матрица бойдон калат. Демек, 4.2-бөлүмдөгү туруктуулук тести жана 4.3-бөлүмдөгү алдыга-артка жылыш тести терең моделге өзгөрүүсүз колдонулат.
7. Практикалык кароолор жана тузактар

Рангды тандоо. Кыскартуу рангы смещение менен дисперсиянын ортосундагы жөнгө салгыч: өтө төмөн ранг динамиканы өткөрүп жиберет, өтө жогорку ранг ызы-чууну үйрөнөт. Сингулярдык маанилердин "чыканагын" көз менен тандабаңыз. Блог векторлор жана матрицалар менен комплекстүү арбитраж макаласында кокустук матрицалар теориясындагы Марченко — Пастур чеги аркылуу "ызы-чууну үйрөнүп баштаганга чейин канча компонент керек" деген суроого жооп берет. Терезеңиздин өлчөмү үчүн сингулярдык мааниси Марченко — Пастур чегинен ашкан компоненттерди калтырып, алынган маанисин жарыялаган ар бир спектр менен кошо көрсөтүңүз.
Терезенин узундугу. Koopman теориясы туруктуу операторун болжолдойт, бирок рынок мындай операторду бербейт. Жылма терезелерде кайра үйрөтүү милдеттүү, ал эми 4.2-бөлүмдөгү туруктуулук ийри сызыгы тандалган терезе баалоого жетиштүү узунбу жана бир режимдин ичинде калууга жетиштүү кыскабы деген диагностикалык көрсөткүч.
Ызы-чууга сезгичтик. Финансылык маалыматтарда сигнал/ызы-чуу катышы төмөн, ал эми стандарттык DMD ичиндеги ызы-чуудан кыйшаят. Модалар туруксуз деген жыйынтыкка келерден мурда төмөнкүлөрдү сынап көрүңүз:
- Total DMD (TDMD) — толук эң кичине квадраттар ыкмасы аркылуу жана матрицаларын тең ызы-чуу камтыган деп эсептейт.
- Оптимизацияланган DMD — өздүк маанилер-модалар ажыратуусун Фробениустун калдыгынын нормасына карата түз оптималдаштырат.
- Kernel EDMD — сөздүк курбастан, жогорку өлчөмдүү белгилер мейкиндигинде кыйыр иштейт.
Эгер TDMD колдонгондо мода туруктуулугу олуттуу өссө, туруксуздук өлчөө ызы-чуусунан келип чыккан. Өспөсө, себеп рыноктун өзү.
8. DMD кайсы жерде турат

| Ыкма | Сызыктуулук | Чечмелениши | Көп кадамдуу болжолдоо |
|---|---|---|---|
| DMD | Абалдар мейкиндигинде сызыктуу | Ооба (модалар + өздүк маанилер) | Туруктуу (матрицанын даражасы) |
| EDMD | Көтөрүлгөн мейкиндикте сызыктуу | Ооба, сөздүк берилсе | Туруктуу (матрицанын даражасы) |
| Deep Koopman | Үйрөнүлгөн мейкиндикте сызыктуу | Орточо (жашыруун Kни текшерүү керек) | Туруктуу (матрицанын даражасы) |
Өзгөрмөлүүлүктү болжолдоодо салыштыруу үчүн GARCH үй-бүлөсүн караңыз — крипто үчүн GARCH өзгөрмөлүүлүгүн болжолдоо. Толук сызыктуу эмес ырааттуулук моделдери жана алардын чечмелениш менен каталардын топтолушунун ортосундагы компромисстери үчүн соодадагы Temporal Fusion Transformer макаласын караңыз.
DMD ээлеген ниша тар, бирок чыныгы: авторегрессиялык жайылтуунун ордуна бир матрицанын даражасы түзгөн көп кадамдуу болжолдор, мында ар бир моданы текшерүүгө болот. Бул нишада альфа барбы — таблицанын эмес, 4-бөлүмдүн суроосу.
Корутунду

Koopman теориясы рынок динамикасын кароонун чындап эле жарашыктуу жолу, бирок дал ушул жарашыктуулук эң катаал текшерүүнү талап кылат. Негизги жыйынтыктар:
- DMDни үйрөтүп, андан соң дароо орнотууну текшериңиз. Фазасы рандомизацияланган нөлгө салыштырылган, коңшу терезелердин ички мейкиндиктеринин кабатташуусу бир күндүн ичинде структура тапканыңызды же терезени жаттап алганыңызды көрсөтөт.
- Жылма спектралдык радиус көзөмөлдөөгө татыктуу жалгыз скаляр, бирок анын мааниси алдыга-артка жылыш тестинин жыйынтыгына толук көз каранды. Лаг 0дө ал өзгөрмөлүүлүктүн прокси, терс лагда режим тууралуу эскертүү.
- Амплитудаларды акыркы снимокко байлаңыз жана өздүк маанилерди эч качан терезенин узундугуна барабар даражага көтөрбөңүз. Чыныгы маалыматтагы DMD "сигналдарынын" чоң бөлүгү — калкыма чекиттик артефакттар.
- Рангды визуалдык чыканак менен эмес, Марченко — Пастур чеги аркылуу тандаңыз жана ар бир спектр менен кошо рангды жарыялаңыз.
- Спектрдин графиги жыйынтык эмес. Анын негизинде курулган ар бир стратегия эсепке алынганга чейин комиссиялардан, тайгалануудан жана дефляцияланган Sharpe тестинен өтүшү керек.
Бул варианттардан тышкары ишке ашыруулар үчүн PyDMD китепканасы DMD варианттарын кеңири камтыйт, ал эми Маллен жана башкалардын маалымдама коду Deep Koopman бөлүгүн камтыйт.
Рыноктор ызы-чуулуу, стационардык эмес жана жарым-жартылай гана байкалган бойдон калат. Koopman теориясы ошол башаламандыктан структураны бөлүп алуунун принциптүү ыкмасын сунуштайт — эгер кийинки жумада ал структура дагы эле бар экенин текшерсеңиз.
Шилтемелер жана кошумча окуу:
- Б. О. Koopman, "Гильберт мейкиндигиндеги Гамильтон системалары жана өзгөртүүлөр", Улуттук илимдер академиясынын эмгектери, 1931.
- Ж. Х. Tu жана башкалар, "Динамикалык модаларды ажыратуу жөнүндө: теория жана колдонмолор", Эсептөө динамикасы журналы, 2014.
- М. О. Williams, И. Г. Kevrekidis, К. В. Rowley, "Koopman операторунун маалыматтарга негизделген жакындатуусу: динамикалык модаларды ажыратууну кеңейтүү", Сызыктуу эмес илим журналы, 2015.
- Б. Lusch, Ж. Н. Kutz, С. Л. Brunton, "Сызыктуу эмес динамиканын универсалдуу сызыктуу киргизүүлөрү үчүн терең үйрөнүү", Nature Communications, 2018.
- Ж. Mann жана Ж. Н. Kutz, "Финансылык соода стратегиялары үчүн динамикалык модаларды ажыратуу", Quantitative Finance, 2016.
- А. Mallen жана башкалар, "Убакыттык бөлүштүрүү жылыштары бар убакыт катарлары үчүн Koopman нейрондук болжолдоочусу", ICML, 2023.
- Э. Gonzalez жана М. Generelo, "Koopman операторлору, EDMD, Takens теоремасы жана машиналык үйрөнүү аркылуу хаостук экономикалык моделдерди талдоо", Финансы жана экономикадагы маалымат илими, 2022.
Authors
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.