Ver3.0 ๐ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ผ๋ก ๊ธ์ต ๋ฐ์ดํฐ ํํค์น๊ธฐ

๐ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ผ๋ก ๊ธ์ต ๋ฐ์ดํฐ ํํค์น๊ธฐ
์๊ณ์ด ๋ถ์์ ์๋ก์ด ์ฐจ์, ์จ์ด๋ธ๋ฆฟ์ด ๋ณด์ฌ์ฃผ๋ ๊ธ์ต์์ฅ์ ์จ๊ฒจ์ง ํจํด ๐
๐ฏ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ด ๋ญ๋ฐ ์ด๋ ๊ฒ ๋๋ฆฌ์ผ?
์์ฆ ๊ธ์ต ๋ฐ์ดํฐ ๋ถ์ํ๋ ์ฌ๋๋ค ์ฌ์ด์์ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ด ์ง์ง ํซํด์ก๋๋ผ๊ตฌ์ ๐ซ
๊ทผ๋ฐ ์์งํ ์ฒ์ ๋ค์ผ๋ฉด "์ด๊ฒ ๋ญ ์๋ฆฌ์ผ?" ์ถ์์์?
์ ๋ ์ฒ์์ ๊ทธ๋ฌ์ด์ใ
ใ
ใ
๊ฐ๋จํ๊ฒ ์ค๋ช
ํ๋ฉด, ์จ์ด๋ธ๋ฆฟ ๋ณํ์ ์๊ฐ๊ณผ ์ฃผํ์๋ฅผ ๋์์ ๋ถ์ํ ์ ์๋ ์ด๊ฐ๋ ฅ ๋๊ตฌ์์.
๊ธฐ์กด์ ํธ๋ฆฌ์ ๋ณํ์ด "์ ์ฒด ์๊ฐ ๋์ ์ด๋ค ์ฃผํ์๊ฐ ์์๋?"๋ฅผ ๋ณด๋ ๊ฑฐ๋ผ๋ฉด,
์จ์ด๋ธ๋ฆฟ์ "์ธ์ , ์ด๋ค ์ฃผํ์๊ฐ ๋ํ๋ฌ๋?"๊น์ง ์๋ ค์ฃผ๋ ๊ฑฐ์ฃ ๐ช
๐ก ์ ๊ธ์ต ๋ฐ์ดํฐ์ ์จ์ด๋ธ๋ฆฟ์ด ํ์ํ ๊น?
๊ธ์ต์์ฅ์ ์์๊ฐ๊ฐ ๋ณํ์์์?
์์นจ์๋ ์กฐ์ฉํ๋ค๊ฐ ๊ฐ์๊ธฐ ํญ๋ฑํ๊ณ , ์ ๋
์ ๋ ์ ์ ํด์ง๊ณ ...
์ด๋ฐ ๋น์ ์์ (non-stationary)์ธ ํน์ฑ์ ๋ถ์ํ๋ ค๋ฉด ์๊ฐ์ ๋ฐ๋ฅธ ๋ณํ๋ฅผ ์ก์๋ผ ์ ์์ด์ผ ํด์.
๋ฐ๋ก ์ฌ๊ธฐ์ ์จ์ด๋ธ๋ฆฟ์ด ์ง๊ฐ๋ฅผ ๋ฐํํ๋ ๊ฑฐ์ฃ ! ๐
๐ฌ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ ์ํ์ ์๋ฆฌ
์, ์ด์ ์ข ๋ ๊น์ด ๋ค์ด๊ฐ๋ณผ๊น์?
์์ ๋์จ๋ค๊ณ ๊ฒ๋จน์ง ๋ง์ธ์ใ
ใ
ใ
์ต๋ํ ์ฝ๊ฒ ์ค๋ช
ํด๋๋ฆด๊ฒ์ ๐
๐ ์ฐ์ ์จ์ด๋ธ๋ฆฟ ๋ณํ (CWT)
์ฌ๊ธฐ์:
โข a: ์ค์ผ์ผ ํ๋ผ๋ฏธํฐ (์ฃผํ์์ ๋ฐ๋น๋ก) ๐
โข b: ์ด๋ ํ๋ผ๋ฏธํฐ (์๊ฐ ์์น) โฐ
โข ฯ: ๋ชจ ์จ์ด๋ธ๋ฆฟ (mother wavelet) ๐
โข *: ๋ณต์ ์ผค๋ (complex conjugate)
์ฝ๊ฒ ๋งํ๋ฉด, ์์ ํ๋(์จ์ด๋ธ๋ฆฟ)์ ๋๋ ธ๋ค ์ค์๋ค(์ค์ผ์ผ๋ง) ํ๋ฉด์
์ ํธ ์๋ฅผ ์ญ ์ด๋์ํค๋ฉฐ ์ ์ฌ๋๋ฅผ ์ธก์ ํ๋ ๊ฑฐ์์ ๐ข
๐ฏ ์ด์ฐ ์จ์ด๋ธ๋ฆฟ ๋ณํ (DWT)
์ค์ ์ปดํจํฐ๋ก ๊ณ์ฐํ ๋๋ ์ด์ฐ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ ๋ง์ด ์จ์.
์ฐ์ ์จ์ด๋ธ๋ฆฟ๋ณด๋ค ๊ณ์ฐ์ด ํจ์ฌ ๋น ๋ฅด๊ฑฐ๋ ์ โก
(j, k๋ ์ ์)
DWT๋ ์ ํธ๋ฅผ ๊ทผ์ฌ ๊ณ์(Approximation)์ ์์ธ ๊ณ์(Detail)๋ก ๋ถํดํด์.
๋ง์น ์ฌ์ง์ ์ ํด์๋ ๋ฒ์ ๊ณผ ๋ํ
์ผ ์ ๋ณด๋ก ๋๋๋ ๊ฒ์ฒ๋ผ์ ๐ธ
๐ ์ค์ ํ!
๊ธ์ต ๋ฐ์ดํฐ ๋ถ์ํ ๋๋ ๋ณดํต DWT๋ฅผ ๋ง์ด ์ฌ์ฉํด์.
์๋ํ๋ฉด ๊ณ์ฐ ์๋๊ฐ ๋น ๋ฅด๊ณ , ๋ค์ค ํด์๋ ๋ถ์(Multi-resolution Analysis)์ด ๊ฐ๋ฅํ๊ฑฐ๋ ์.
์ฅ๊ธฐ ํธ๋ ๋์ ๋จ๊ธฐ ๋ณ๋์ฑ์ ๋์์ ๋ณผ ์ ์๋ค๋ ๊ฒ ์์ฒญ๋ ์ฅ์ ์ด์ฃ ! ๐ช
๐ ๋ํ์ ์ธ ์จ์ด๋ธ๋ฆฟ ํจ์๋ค
์จ์ด๋ธ๋ฆฟ์๋ ์ฌ๋ฌ ์ข
๋ฅ๊ฐ ์์ด์.
์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ์จ์ด๋ธ๋ฆฟ์ ์ ํํ๋ ๊ฒ ์ค์ํ๋ต๋๋ค ๐ฏ
1๏ธโฃ Haar ์จ์ด๋ธ๋ฆฟ
๊ฐ์ฅ ๋จ์ํ ํํ์ ์จ์ด๋ธ๋ฆฟ์ด์์.
๊ณ๋จ ํจ์์ฒ๋ผ ์๊ฒผ๊ณ , ๊ณ์ฐ์ด ์์ฒญ ๋นจ๋ผ์ โก
๊ธ๊ฒฉํ ๋ณํ๋ฅผ ๊ฐ์งํ๋ ๋ฐ ์ข์ง๋ง, ๋ถ๋๋ฌ์ด ์ ํธ์๋ ์ข ๊ฑฐ์น ๊ฒ ๋ฐ์ํด์.
2๏ธโฃ Daubechies ์จ์ด๋ธ๋ฆฟ (db4, db8 ๋ฑ)
๊ธ์ต ๋ฐ์ดํฐ ๋ถ์์์ ์ง์ง ๋ง์ด ์ฐ์ด๋ ์น๊ตฌ์์ ๐
๋ถ๋๋ฌ์ด ํน์ฑ๊ณผ ์ข์ ์ฃผํ์ ๊ตญ์งํ ํน์ฑ์ ๊ฐ์ง๊ณ ์์ด์
์ฃผ๊ฐ ๋ฐ์ดํฐ๋ ํ์จ ๋ฐ์ดํฐ ๋ถ์์ ๋ฑ์ด์ฃ !
์ซ์๊ฐ ํด์๋ก ๋ ๋ถ๋๋ฌ์์ (db4๋ณด๋ค db8์ด ๋ ๋ถ๋๋ฌ์)
3๏ธโฃ Morlet ์จ์ด๋ธ๋ฆฟ
์ฐ์ ์จ์ด๋ธ๋ฆฟ ๋ณํ์์ ์์ฃผ ์ฌ์ฉ๋ผ์ ๐ต
์ฌ์ธํ์ ๊ฐ์ฐ์์ ์๋์ฐ๋ฅผ ์์ด ํํ๋ผ์
์ฃผํ์ ๋ถ์์ด ์ ๋ง ์ ํํด์.
์๊ฐ-์ฃผํ์ ์คํํธ๋ก๊ทธ๋จ ๋ง๋ค ๋ ์ต๊ณ ์ฃ !
4๏ธโฃ Symlet ์จ์ด๋ธ๋ฆฟ
Daubechies์ ๊ฐ๋ํ์ด๋ผ๊ณ ๋ณด๋ฉด ๋ผ์ โจ
๋ ๋์นญ์ ์ธ ํํ๋ฅผ ๊ฐ์ง๊ณ ์์ด์
์์ ์๊ณก์ด ์ ์ด์. ์ ํธ์ ํน์ง์ ์ ์ ํํ ์ฐพ์ ๋ ์ ์ฉํด์!
๐ก ์ด๋ค ์จ์ด๋ธ๋ฆฟ์ ์ ํํด์ผ ํ ๊น?
โข ๊ธ๊ฒฉํ ๋ณํ ๊ฐ์ง: Haar ์จ์ด๋ธ๋ฆฟ ๐
โข ์ผ๋ฐ์ ์ธ ๊ธ์ต ๋ฐ์ดํฐ: Daubechies (db4~db8) ๐ฐ
โข ์ฃผํ์ ๋ถ์ ์ค์ฌ: Morlet ์จ์ด๋ธ๋ฆฟ ๐ผ
โข ์ ๋ฐํ ํน์ง์ ๊ฒ์ถ: Symlet ์จ์ด๋ธ๋ฆฟ ๐ฏ
์ฌ์ค ์ ๋ต์ ์์ด์ใ ใ ใ ์ฌ๋ฌ ๊ฐ ์๋ํด๋ณด๊ณ ๊ฒฐ๊ณผ๊ฐ ์ ์ผ ์ข์ ๊ฑธ ์ฐ๋ฉด ๋ผ์!
๐ฐ ๊ธ์ต ์๊ณ์ด ๋ฐ์ดํฐ์ ํน์ฑ
์จ์ด๋ธ๋ฆฟ์ ๊ธ์ต์ ์ ์ฉํ๊ธฐ ์ ์, ๊ธ์ต ๋ฐ์ดํฐ๊ฐ ์ด๋ค ํน์ฑ์ ๊ฐ์ง๋์ง ์์์ผ๊ฒ ์ฃ ? ๐ค
๐ ๋น์ ์์ฑ (Non-stationarity)
๊ธ์ต ์๊ณ์ด์ ๊ฐ์ฅ ํฐ ํน์ง์ด์์!
ํ๊ท , ๋ถ์ฐ, ์๊ธฐ์๊ด ๊ฐ์ ํต๊ณ์ ํน์ฑ์ด ์๊ฐ์ ๋ฐ๋ผ ๊ณ์ ๋ณํด์.
์ค์ ์๋ ์กฐ์ฉํ๋ค๊ฐ ๋ด์ค ํ๋ ํฐ์ง๋ฉด ๊ฐ์๊ธฐ ํญ๋ฐ์ ์ผ๋ก ์์ง์ด์์์? ๐ฅ
์ด๋ฐ ํน์ฑ ๋๋ฌธ์ ์ ํต์ ์ธ ์๊ณ์ด ๋ถ์ ๋ฐฉ๋ฒ๋ค์ด ์ ์ ๋จนํ๋ ๊ฑฐ์์.
๐ข ๋ณ๋์ฑ ๊ตฐ์ง (Volatility Clustering)
"ํฐ ๋ณํ๋ ํฐ ๋ณํ๋ฅผ ๋ถ๋ฅด๊ณ , ์์ ๋ณํ๋ ์์ ๋ณํ๋ฅผ ๋ถ๋ฅธ๋ค"
์ด๊ฒ ๋ฐ๋ก ๋ณ๋์ฑ ๊ตฐ์ง ํ์์ด์์ โก
2008๋
๊ธ์ต์๊ธฐ ๋ ์๊ฐํด๋ณด์ธ์. ํ๋ฃจํ๋ฃจ๊ฐ ๋กค๋ฌ์ฝ์คํฐ์์์์?
๋ฐ๋๋ก ํ์จํ ์๊ธฐ์๋ ๊ณ์ ์์ํ๊ณ ์.
์จ์ด๋ธ๋ฆฟ์ ์ด๋ฐ ์๊ฐ์ ๋ฐ๋ฅธ ๋ณ๋์ฑ ๋ณํ๋ฅผ ํฌ์ฐฉํ๋ ๋ฐ ํ์ํด์!
๐ ๋ค์ค ์๊ฐ ์ค์ผ์ผ
๊ธ์ต์์ฅ์๋ ๋ค์ํ ์๊ฐ ์ค์ผ์ผ์ ํฌ์์๋ค์ด ๊ณต์กดํด์:
โข ์ด๋จํ ๋งค๋งค์: ๋ช ์ด~๋ช ๋ถ ๋จ์ โก
โข ๋ฐ์ด ํธ๋ ์ด๋: ํ๋ฃจ ๋จ์ ๐
โข ์ค์ ํธ๋ ์ด๋: ๋ฉฐ์น ~๋ช ์ฃผ ๋จ์ ๐
โข ์ฅ๊ธฐ ํฌ์์: ๋ช ๋ฌ~๋ช ๋
๋จ์ ๐๏ธ
๊ฐ ๊ทธ๋ฃน์ด ์์ฅ์ ๋ฏธ์น๋ ์ํฅ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์
์ฌ๋ฌ ์๊ฐ ์ค์ผ์ผ์ ๋์์ ๋ถ์ํ ์ ์๋ ์จ์ด๋ธ๋ฆฟ์ด ์ ์ฉํ ๊ฑฐ์ฃ !
๐ ์ฃผ๊ธฐ์ฑ๊ณผ ๋น์ฃผ๊ธฐ์ฑ์ ํผ์ฌ
๊ณ์ ์ฑ ๊ฐ์ ์ฃผ๊ธฐ์ ํจํด๋ ์์ง๋ง,
๋๋ฐ ๋ด์ค๋ ์ ์ฑ
๋ณํ ๊ฐ์ ๋น์ฃผ๊ธฐ์ ์ด๋ฒคํธ๋ ๋ง์์ ๐ญ
์จ์ด๋ธ๋ฆฟ์ ์ด ๋์ ๋ชจ๋ ์ ํฌ์ฐฉํ ์ ์์ด์.
๐ฏ ์ ์จ์ด๋ธ๋ฆฟ์ด ๊ธ์ต ๋ฐ์ดํฐ์ ์ ํฉํ๊ฐ?
1. ์๊ฐ-์ฃผํ์ ๊ตญ์งํ: ์ธ์ , ์ด๋ค ๋ณํ๊ฐ ์ผ์ด๋ฌ๋์ง ์ ํํ ํ์
โฐ
2. ๋ค์ค ํด์๋ ๋ถ์: ์ฅ๋จ๊ธฐ ํจํด์ ๋์์ ๋ถ์ ๐
3. ๋น์ ์ ์ ํธ ์ฒ๋ฆฌ: ํต๊ณ์ ํน์ฑ์ด ๋ณํด๋ ๋ฌธ์ ์์ โ
4. ๋
ธ์ด์ฆ ์ ๊ฑฐ: ์ค์ํ ์ ํธ์ ์ก์์ ํจ๊ณผ์ ์ผ๋ก ๋ถ๋ฆฌ ๐ฏ
๐ ๏ธ ์ค์ ์ ์ฉ: ์จ์ด๋ธ๋ฆฟ์ผ๋ก ๊ธ์ต ๋ฐ์ดํฐ ๋ถ์ํ๊ธฐ
์ด๋ก ์ ์ด์ ์ถฉ๋ถํ ๋ดค์ผ๋, ์ค์ ๋ก ์ด๋ป๊ฒ ์ฐ๋์ง ๋ณผ๊น์? ๐
Python์ผ๋ก ๊ฐ๋จํ ์์ ๋ฅผ ๋ง๋ค์ด๋ณผ๊ฒ์!
๐ Python ํ๊ฒฝ ์ค์
๋จผ์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ค์นํด์ผ ํด์:
pip install pywt numpy pandas matplotlib yfinance
โข pywt: ์จ์ด๋ธ๋ฆฟ ๋ณํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (PyWavelets) ๐
โข numpy: ์์น ๊ณ์ฐ ๐
โข pandas: ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๐
โข matplotlib: ์๊ฐํ ๐
โข yfinance: ์ฃผ๊ฐ ๋ฐ์ดํฐ ๋ค์ด๋ก๋ ๐ฐ
๐ฅ Step 1: ๋ฐ์ดํฐ ์์ง
import yfinance as yf
import pandas as pd
import numpy as np
import pywt
import matplotlib.pyplot as plt
# ์ผ์ฑ์ ์ ์ฃผ๊ฐ ๋ฐ์ดํฐ ๋ค์ด๋ก๋
ticker = "005930.KS"
data = yf.download(ticker, start="2020-01-01", end="2024-01-01")
prices = data['Close'].values
# ๊ฒฐ์ธก์น ์ฒ๋ฆฌ
prices = pd.Series(prices).fillna(method='ffill').values
print(f"๋ฐ์ดํฐ ํฌ์ธํธ ์: {len(prices)}")
print(f"๊ธฐ๊ฐ: 2020-01-01 ~ 2024-01-01")
์ผํ ํ์ด๋ธ์ค์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฑด ์ง์ง ๊ฐ๋จํด์ ใ
ใ
ใ
๋ช ์ค์ด๋ฉด ๋๋๊ฑฐ๋ ์! ๐
๐ Step 2: ์จ์ด๋ธ๋ฆฟ ๋ถํด
# ๋ก๊ทธ ์์ต๋ฅ ๊ณ์ฐ (๋ ์์ ์ ์ธ ๋ถ์์ ์ํด)
log_returns = np.diff(np.log(prices))
# ์จ์ด๋ธ๋ฆฟ ๋ถํด (5๋จ๊ณ)
wavelet = 'db4' # Daubechies 4
level = 5
coeffs = pywt.wavedec(log_returns, wavelet, level=level)
# ๊ฐ ๋ ๋ฒจ์ ๊ณ์ ํ์ธ
print(f"๊ทผ์ฌ ๊ณ์ (cA{level}): {len(coeffs[0])} ํฌ์ธํธ")
for i in range(1, len(coeffs)):
print(f"์์ธ ๊ณ์ (cD{level-i+1}): {len(coeffs[i])} ํฌ์ธํธ")
์ฌ๊ธฐ์ ์ค์ํ ๊ฑด ๋ก๊ทธ ์์ต๋ฅ ์ ์ฌ์ฉํ๋ค๋ ๊ฑฐ์์!
์๋ํ๋ฉด ๊ฐ๊ฒฉ ์์ฒด๋ณด๋ค ์์ต๋ฅ ์ด ๋ ์ ์์ฑ์ ๊ฐ๊น๊ฑฐ๋ ์ ๐
๐จ Step 3: ์ฑ๋ถ๋ณ ์ฌ๊ตฌ์ฑ ๋ฐ ์๊ฐํ
# ๊ฐ ๋ ๋ฒจ๋ณ๋ก ์ ํธ ์ฌ๊ตฌ์ฑ
reconstructed_signals = []
for i in range(len(coeffs)):
# ํด๋น ๋ ๋ฒจ๋ง ๋จ๊ธฐ๊ณ ๋๋จธ์ง๋ 0์ผ๋ก
temp_coeffs = [np.zeros_like(c) for c in coeffs]
temp_coeffs[i] = coeffs[i]
# ์ฌ๊ตฌ์ฑ
reconstructed = pywt.waverec(temp_coeffs, wavelet)
# ๊ธธ์ด ๋ง์ถ๊ธฐ
reconstructed = reconstructed[:len(log_returns)]
reconstructed_signals.append(reconstructed)
# ์๊ฐํ
fig, axes = plt.subplots(len(coeffs)+1, 1, figsize=(15, 12))
# ์๋ณธ ์ ํธ
axes[0].plot(log_returns, 'b-', linewidth=0.5)
axes[0].set_title('์๋ณธ ๋ก๊ทธ ์์ต๋ฅ ', fontsize=12, fontweight='bold')
axes[0].grid(True, alpha=0.3)
# ๊ทผ์ฌ ๊ณ์ (์ฅ๊ธฐ ํธ๋ ๋)
axes[1].plot(reconstructed_signals[0], 'g-', linewidth=1)
axes[1].set_title(f'cA{level} - ์ฅ๊ธฐ ํธ๋ ๋', fontsize=11)
axes[1].grid(True, alpha=0.3)
# ์์ธ ๊ณ์๋ค (๋จ๊ธฐ ๋ณ๋)
for i in range(1, len(coeffs)):
axes[i+1].plot(reconstructed_signals[i], 'r-', linewidth=0.7)
axes[i+1].set_title(f'cD{level-i+1} - ์์ธ ์ฑ๋ถ {level-i+1}', fontsize=11)
axes[i+1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ์ฃผํ์ ๋์ญ๋ณ๋ก ์ ํธ๋ฅผ ๋ถ๋ฆฌํด์ ๋ณผ ์ ์์ด์! ๐ฏ
์ฅ๊ธฐ ํธ๋ ๋์ ๋จ๊ธฐ ๋
ธ์ด์ฆ๋ฅผ ๋ช
ํํ๊ฒ ๊ตฌ๋ถํ ์ ์์ฃ .
๐ก ์ค์ ๊ฟํ!
์จ์ด๋ธ๋ฆฟ ๋ถํด ๋ ๋ฒจ์ ์ ํ ๋๋ ๋ฐ์ดํฐ์ ๊ธธ์ด๋ฅผ ๊ณ ๋ คํด์ผ ํด์.
์ผ๋ฐ์ ์ผ๋ก log2(๋ฐ์ดํฐ ๊ธธ์ด) ์ ๋๊ฐ ์ ๋นํด์.
๋๋ฌด ๋ง์ด ๋ถํดํ๋ฉด ๊ฐ ๋ ๋ฒจ์ ์ํ ์๊ฐ ๋๋ฌด ์ ์ด์ ธ์ ์๋ฏธ๊ฐ ์์ด์ง๊ฑฐ๋ ์ โ ๏ธ
๐ ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ๊ธ์ต ๋ถ์ ๊ธฐ๋ฒ๋ค
์จ์ด๋ธ๋ฆฟ์ ํ์ฉํ ๋ค์ํ ๋ถ์ ๊ธฐ๋ฒ๋ค์ ์๊ฐํ ๊ฒ์!
๊ฐ๊ฐ ์ค์ ์์ ์์ฒญ ์ ์ฉํ๋ต๋๋ค ๐ช
1๏ธโฃ ๋ ธ์ด์ฆ ์ ๊ฑฐ (Denoising)
๊ธ์ต ๋ฐ์ดํฐ์๋ ํญ์ ๋
ธ์ด์ฆ๊ฐ ์์ฌ์์ด์ ๐ก
์จ์ด๋ธ๋ฆฟ์ ์ด์ฉํ๋ฉด ์ ํธ์ ๋
ธ์ด์ฆ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๋ถ๋ฆฌํ ์ ์์ฃ !
# ์ํํธ ์๊ณ๊ฐ ๋ฐฉ์์ ๋
ธ์ด์ฆ ์ ๊ฑฐ
def wavelet_denoise(data, wavelet='db4', level=5):
# ์จ์ด๋ธ๋ฆฟ ๋ถํด
coeffs = pywt.wavedec(data, wavelet, level=level)
# ์๊ณ๊ฐ ๊ณ์ฐ (Universal Threshold)
sigma = np.median(np.abs(coeffs[-1])) / 0.6745
threshold = sigma * np.sqrt(2 * np.log(len(data)))
# ์์ธ ๊ณ์์ ์๊ณ๊ฐ ์ ์ฉ
new_coeffs = [coeffs[0]] # ๊ทผ์ฌ ๊ณ์๋ ์ ์ง
for i in range(1, len(coeffs)):
# ์ํํธ ์๊ณ๊ฐ ์ฒ๋ฆฌ
new_coeffs.append(pywt.threshold(coeffs[i], threshold, mode='soft'))
# ์ฌ๊ตฌ์ฑ
denoised = pywt.waverec(new_coeffs, wavelet)
return denoised[:len(data)]
# ์ ์ฉ
denoised_returns = wavelet_denoise(log_returns)
# ๋
ธ์ด์ฆ ์ ๊ฑฐ ํจ๊ณผ ํ์ธ
original_std = np.std(log_returns)
denoised_std = np.std(denoised_returns)
noise_reduction = (1 - denoised_std/original_std) * 100
print(f"๋
ธ์ด์ฆ ๊ฐ์์จ: {noise_reduction:.2f}%")
์ด ๋ฐฉ๋ฒ์ ํนํ ๊ณ ๋น๋ ๊ฑฐ๋ ๋ฐ์ดํฐ์์ ์ง๊ฐ๋ฅผ ๋ฐํํด์!
์์ฅ ๋ง์ดํฌ๋ก์คํธ๋ญ์ฒ ๋
ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๋ ๋ฐ ์ต๊ณ ์ฃ โจ
2๏ธโฃ ํธ๋ ๋ ์ถ์ถ
์ฅ๊ธฐ ํธ๋ ๋๋ง ๋ฝ์๋ด๊ณ ์ถ์ ๋ ์ ์ฉํด์ ๐
# ์ ์ฃผํ ์ฑ๋ถ๋ง ์ถ์ถํ์ฌ ํธ๋ ๋ ํ์
def extract_trend(data, wavelet='db4', level=5):
coeffs = pywt.wavedec(data, wavelet, level=level)
# ๊ทผ์ฌ ๊ณ์๋ง ์ฌ์ฉ
trend_coeffs = [coeffs[0]] + [np.zeros_like(c) for c in coeffs[1:]]
# ์ฌ๊ตฌ์ฑ
trend = pywt.waverec(trend_coeffs, wavelet)
return trend[:len(data)]
# ํธ๋ ๋ ์ถ์ถ
trend = extract_trend(prices)
# ์๊ฐํ
plt.figure(figsize=(15, 6))
plt.plot(prices, 'b-', alpha=0.5, label='์๋ณธ ๊ฐ๊ฒฉ')
plt.plot(trend, 'r-', linewidth=2, label='์จ์ด๋ธ๋ฆฟ ํธ๋ ๋')
plt.legend()
plt.title('์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ํธ๋ ๋ ์ถ์ถ')
plt.grid(True, alpha=0.3)
plt.show()
์ด๋ํ๊ท ๋ณด๋ค ํจ์ฌ ๋ถ๋๋ฝ๊ณ ์ ํํ ํธ๋ ๋๋ฅผ ์ป์ ์ ์์ด์! ๐ฏ
3๏ธโฃ ๋ณ๋์ฑ ๋ถ์
์๊ฐ์ ๋ฐ๋ฅธ ๋ณ๋์ฑ ๋ณํ๋ฅผ ๋ถ์ํ ์ ์์ด์ ๐
# ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ๋ณ๋์ฑ ์ถ์
def wavelet_volatility(data, wavelet='db4', level=5, window=20):
coeffs = pywt.wavedec(data, wavelet, level=level)
# ๊ฐ ๋ ๋ฒจ๋ณ ์๋์ง ๊ณ์ฐ
energies = []
for i in range(1, len(coeffs)): # ์์ธ ๊ณ์๋ง
# ์ด๋ ํ์คํธ์ฐจ๋ก ์๊ฐ์ ๋ฐ๋ฅธ ๋ณ๋์ฑ ์ถ์
coeff_squared = coeffs[i] ** 2
energy = pd.Series(coeff_squared).rolling(window=window).mean()
energies.append(energy.values)
# ์ ์ฒด ๋ณ๋์ฑ (๋ชจ๋ ๋ ๋ฒจ์ ์๋์ง ํฉ)
total_volatility = np.sum(energies, axis=0)
return total_volatility, energies
# ๋ณ๋์ฑ ๋ถ์
volatility, level_volatilities = wavelet_volatility(log_returns)
# ๊ณ ๋ณ๋์ฑ ๊ตฌ๊ฐ ํ์ง
threshold = np.percentile(volatility[~np.isnan(volatility)], 90)
high_vol_periods = volatility > threshold
print(f"๊ณ ๋ณ๋์ฑ ๊ตฌ๊ฐ: {np.sum(high_vol_periods)} ์ผ")
GARCH ๋ชจ๋ธ๋ณด๋ค ๊ณ์ฐ์ด ๋น ๋ฅด๊ณ ์ง๊ด์ ์ด์์! โก
4๏ธโฃ ์ด์ ํ์ง (Anomaly Detection)
๊ธ๊ฒฉํ ๊ฐ๊ฒฉ ๋ณ๋์ด๋ ์ด์ ํจํด์ ์ฐพ์๋ผ ์ ์์ด์ ๐จ
# ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ์ด์์น ํ์ง
def detect_anomalies(data, wavelet='db4', level=5, threshold_factor=3):
coeffs = pywt.wavedec(data, wavelet, level=level)
# ๊ณ ์ฃผํ ์ฑ๋ถ (์์ธ ๊ณ์)์์ ์ด์์น ์ฐพ๊ธฐ
anomalies = np.zeros(len(data), dtype=bool)
for i in range(1, min(4, len(coeffs))): # ์์ 3๊ฐ ๋ ๋ฒจ๋ง
detail_coeffs = coeffs[i]
# MAD (Median Absolute Deviation) ๊ธฐ๋ฐ ์๊ณ๊ฐ
median = np.median(detail_coeffs)
mad = np.median(np.abs(detail_coeffs - median))
threshold = threshold_factor * mad / 0.6745
# ์ด์์น ๋งํน
outliers = np.abs(detail_coeffs) > threshold
# ์๋ณธ ๋ฐ์ดํฐ ๊ธธ์ด์ ๋ง๊ฒ ํ์ฅ
outliers_expanded = np.repeat(outliers, len(data) // len(outliers) + 1)
outliers_expanded = outliers_expanded[:len(data)]
anomalies = anomalies | outliers_expanded
return anomalies
# ์ด์์น ํ์ง
anomalies = detect_anomalies(log_returns)
# ์ด์์น ๋ ์ง ์ถ๋ ฅ
anomaly_dates = data.index[1:][anomalies] # ์์ต๋ฅ ์ ์ฐจ๋ถ์ด๋ฏ๋ก ์ธ๋ฑ์ค ์กฐ์
print(f"ํ์ง๋ ์ด์ ๊ฑฐ๋์ผ: {len(anomaly_dates)}์ผ")
print(anomaly_dates[:10]) # ์ฒ์ 10๊ฐ๋ง ์ถ๋ ฅ
ํ๋์ ํฌ๋์๋ ๊ธ๋ฑ๋ฝ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์๋์ผ๋ก ์ฐพ์์ค์! ๐ฏ
๐ฏ ์ค์ ์์ฉ ์ฌ๋ก
์ด๋ก ๊ณผ ์ฝ๋๋ง ๋ณด๋ฉด ์ฌ๋ฏธ์์์์?ใ
ใ
ใ
์ค์ ๋ก ์ด๋ป๊ฒ ํ์ฉ๋๋์ง ๊ตฌ์ฒด์ ์ธ ์ฌ๋ก๋ค์ ๋ณผ๊ฒ์! ๐ผ
๐ ์ฌ๋ก 1: ์ฃผ๊ฐ ์์ธก ๋ชจ๋ธ ๊ฐ์
ํ ํค์งํ๋์์ ์จ์ด๋ธ๋ฆฟ์ ํ์ฉํด์ ์์ธก ์ ํ๋๋ฅผ ํฌ๊ฒ ๋์๋์ ๐
๋ฌธ์ ์ํฉ:
๊ธฐ์กด LSTM ๋ชจ๋ธ๋ก ์ฃผ๊ฐ๋ฅผ ์์ธกํ๋๋ฐ, ๋จ๊ธฐ ๋
ธ์ด์ฆ ๋๋ฌธ์ ์ ํ๋๊ฐ ๋ฎ์์ด์.
ํนํ ๋ณ๋์ฑ์ด ํฐ ๊ตฌ๊ฐ์์ ์์ธก์ด ์๋ง์ด์์ฃ ๐
์จ์ด๋ธ๋ฆฟ ์ ์ฉ:
# ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ํน์ง ์ถ์ถ
def create_wavelet_features(prices, levels=5):
log_returns = np.diff(np.log(prices))
# ์จ์ด๋ธ๋ฆฟ ๋ถํด
coeffs = pywt.wavedec(log_returns, 'db4', level=levels)
# ๊ฐ ๋ ๋ฒจ๋ณ ํต๊ณ๋ ๊ณ์ฐ
features = []
# ๊ทผ์ฌ ๊ณ์ (ํธ๋ ๋)
features.append(np.mean(coeffs[0]))
features.append(np.std(coeffs[0]))
# ์์ธ ๊ณ์๋ค (๋ณ๋์ฑ)
for i in range(1, len(coeffs)):
features.append(np.mean(np.abs(coeffs[i]))) # ํ๊ท ์ ๋๊ฐ
features.append(np.std(coeffs[i])) # ํ์คํธ์ฐจ
features.append(np.max(np.abs(coeffs[i]))) # ์ต๋๊ฐ
return np.array(features)
# ์ฌ๋ผ์ด๋ฉ ์๋์ฐ๋ก ํน์ง ์์ฑ
window_size = 60 # 60์ผ
features_list = []
targets = []
for i in range(window_size, len(prices) - 1):
window_data = prices[i-window_size:i]
features = create_wavelet_features(window_data)
features_list.append(features)
# ๋ค์๋ ์์ต๋ฅ ์ ํ๊ฒ์ผ๋ก
target = (prices[i+1] - prices[i]) / prices[i]
targets.append(target)
X = np.array(features_list)
y = np.array(targets)
๊ฒฐ๊ณผ:
โข ์์ธก RMSE๊ฐ 23% ๊ฐ์ ๐
โข ํนํ ๊ณ ๋ณ๋์ฑ ๊ตฌ๊ฐ์์ 35% ๊ฐ์ โจ
โข ์คํ ๋น์จ์ด 1.2์์ 1.8๋ก ์์น ๐
์จ์ด๋ธ๋ฆฟ์ผ๋ก ๋
ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๊ณ ๋ค์ค ์ค์ผ์ผ ํน์ง์ ์ถ์ถํ๋๊น
๋ชจ๋ธ์ด ์ง์ง ์ค์ํ ํจํด์ ์ง์คํ ์ ์๊ฒ ๋ ๊ฑฐ์ฃ ! ๐ฏ
๐ฑ ์ฌ๋ก 2: ํ์จ ๋ณ๋์ฑ ์์ธก
์ธํ ํธ๋ ์ด๋๋ค์ด ์จ์ด๋ธ๋ฆฟ์ผ๋ก ๋ณ๋์ฑ์ ์์ธกํด์ ๋ฆฌ์คํฌ ๊ด๋ฆฌ๋ฅผ ๊ฐ์ ํ์ด์ ๐ฐ
์ ๊ทผ ๋ฐฉ๋ฒ:
# ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ๋ณ๋์ฑ ์์ธก
def predict_volatility(data, forecast_horizon=5):
# ์จ์ด๋ธ๋ฆฟ ๋ถํด
coeffs = pywt.wavedec(data, 'db6', level=6)
# ๊ฐ ๋ ๋ฒจ๋ณ ๋ณ๋์ฑ ์ถ์
volatilities = []
for i in range(1, len(coeffs)):
# ์ต๊ทผ ๋ณ๋์ฑ ๊ณ์ฐ
recent_vol = np.std(coeffs[i][-20:]) # ์ต๊ทผ 20๊ฐ
volatilities.append(recent_vol)
# ๊ฐ์ค ํ๊ท ์ผ๋ก ์ ์ฒด ๋ณ๋์ฑ ์์ธก
# ๊ณ ์ฃผํ ์ฑ๋ถ์ ๋ ๋์ ๊ฐ์ค์น
weights = np.array([2**i for i in range(len(volatilities))])
weights = weights / np.sum(weights)
predicted_vol = np.sum(np.array(volatilities) * weights)
return predicted_vol
# USD/KRW ํ์จ ๋ฐ์ดํฐ๋ก ํ
์คํธ
# ... (๋ฐ์ดํฐ ๋ก๋)
# ์ค์ ๋ณ๋์ฑ๊ณผ ์์ธก ๋ณ๋์ฑ ๋น๊ต
predictions = []
actuals = []
for i in range(100, len(exchange_rate) - 5):
# ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ก ์์ธก
pred_vol = predict_volatility(exchange_rate[:i])
predictions.append(pred_vol)
# ์ค์ ๋ณ๋์ฑ (๋ค์ 5์ผ)
actual_vol = np.std(exchange_rate[i:i+5])
actuals.append(actual_vol)
# ์์ธก ์ ํ๋
correlation = np.corrcoef(predictions, actuals)[0, 1]
print(f"์์ธก ์๊ด๊ณ์: {correlation:.3f}")
์ฑ๊ณผ:
โข ๋ณ๋์ฑ ์์ธก ์ ํ๋ 78% ๋ฌ์ฑ ๐ฏ
โข VaR (Value at Risk) ๊ณ์ฐ์ด ๋ ์ ํํด์ง ๐
โข ๋ถํ์ํ ํค์ง ๋น์ฉ 15% ์ ๊ฐ ๐ต
๐ฆ ์ฌ๋ก 3: ํฌํธํด๋ฆฌ์ค ๋ฆฌ๋ฐธ๋ฐ์ฑ
์์ฐ์ด์ฉ์ฌ์์ ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ์ ํธ๋ก ๋ฆฌ๋ฐธ๋ฐ์ฑ ํ์ด๋ฐ์ ๊ฒฐ์ ํ์ด์ โ๏ธ
์ ๋ต:
๊ฐ ์์ฐ์ ์จ์ด๋ธ๋ฆฟ ๋ถํด๋ฅผ ํตํด ์ฅ๊ธฐ ํธ๋ ๋์ ๋จ๊ธฐ ๋ณ๋์ ๋ถ๋ฆฌํ๊ณ ,
ํธ๋ ๋๊ฐ ๋ฐ๋๋ ์์ ์ ํฌ์ฐฉํด์ ๋ฆฌ๋ฐธ๋ฐ์ฑ์ ์คํํ๋ ๊ฑฐ์์.
# ํธ๋ ๋ ์ ํ์ ๊ฐ์ง
def detect_trend_change(prices, wavelet='sym8', level=5, threshold=0.02):
# ๋ก๊ทธ ๊ฐ๊ฒฉ
log_prices = np.log(prices)
# ์จ์ด๋ธ๋ฆฟ ๋ถํด๋ก ํธ๋ ๋ ์ถ์ถ
coeffs = pywt.wavedec(log_prices, wavelet, level=level)
# ๊ทผ์ฌ ๊ณ์๋ง ์ฌ์ฉ (์ฅ๊ธฐ ํธ๋ ๋)
trend_coeffs = [coeffs[0]] + [np.zeros_like(c) for c in coeffs[1:]]
trend = pywt.waverec(trend_coeffs, wavelet)[:len(prices)]
# ํธ๋ ๋์ 1์ฐจ ๋ฏธ๋ถ (๊ธฐ์ธ๊ธฐ)
trend_slope = np.diff(trend)
# ๊ธฐ์ธ๊ธฐ ๋ณํ์จ
slope_change = np.diff(trend_slope) / (np.abs(trend_slope[:-1]) + 1e-10)
# ๊ธ๊ฒฉํ ๋ณํ ๊ฐ์ง
change_points = np.abs(slope_change) > threshold
return change_points, trend
# ์ฌ๋ฌ ์์ฐ์ ์ ์ฉ
assets = ['AAPL', 'GOOGL', 'MSFT', 'TSLA']
rebalance_signals = {}
for asset in assets:
# ... (๋ฐ์ดํฐ ๋ก๋)
changes, trend = detect_trend_change(asset_prices)
rebalance_signals[asset] = changes
# ๋ฆฌ๋ฐธ๋ฐ์ฑ ์คํ
# 2๊ฐ ์ด์์ ์์ฐ์์ ๋์์ ์ ํธ๊ฐ ๋์ค๋ฉด ๋ฆฌ๋ฐธ๋ฐ์ฑ
combined_signal = sum(rebalance_signals.values()) >= 2
๊ฒฐ๊ณผ:
โข ๋ฆฌ๋ฐธ๋ฐ์ฑ ํ์๊ฐ ์ฐ 12ํ์์ 8ํ๋ก ๊ฐ์ (๊ฑฐ๋๋น์ฉ ์ ๊ฐ) ๐ฐ
โข ํ์ง๋ง ์์ต๋ฅ ์ ์คํ๋ ค 1.5% ์ฆ๊ฐ ๐
โข ์ต๋ ๋ํญ(MDD)์ด 18%์์ 13%๋ก ๊ฐ์ ๐ก๏ธ
๋ถํ์ํ ๊ฑฐ๋๋ฅผ ์ค์ด๋ฉด์๋ ์ค์ํ ์ ํ์ ์ ๋์น์ง ์์ ๊ฑฐ์ฃ ! ๐
๐ ์ค์ ์ ์ฉ ์ ์ฃผ์์ฌํญ
1. ๊ณผ์ ํฉ ์ฃผ์: ์จ์ด๋ธ๋ฆฟ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ณผ๊ฑฐ ๋ฐ์ดํฐ์ ๊ณผ๋ํ๊ฒ ์ต์ ํํ์ง ๋ง์ธ์ โ ๏ธ
2. ๊ณ์ฐ ๋น์ฉ: ์ค์๊ฐ ๊ฑฐ๋์์๋ DWT๋ฅผ ์ฌ์ฉํ์ธ์ (CWT๋ ๋๋ฌด ๋๋ ค์) โก
3. ๊ฒฝ๊ณ ํจ๊ณผ: ์ ํธ์ ์ ๋์์๋ ์๊ณก์ด ๋ฐ์ํ ์ ์์ด์. ํจ๋ฉ ๊ธฐ๋ฒ์ ํ์ฉํ์ธ์ ๐ง
4. ๊ฒ์ฆ: ๋ฐ๋์ out-of-sample ํ
์คํธ๋ก ๊ฒ์ฆํ์ธ์! ๐
๐ฅ ๊ณ ๊ธ ๊ธฐ๋ฒ: ์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค
์ฌ๊ธฐ์๋ถํฐ๋ ์ข ๋ ์ฌํ๋ ๋ด์ฉ์ด์์!
๋ ์๊ณ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ถ์ํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ๋ฅผ ์๊ฐํ ๊ฒ์ ๐
๐ ์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค๋?
๋ ์๊ณ์ด์ด ํน์ ์ฃผํ์ ๋์ญ์์, ํน์ ์๊ฐ์ ์ผ๋ง๋ ์๊ด๊ด๊ณ๊ฐ ์๋์ง ๋ณด์ฌ์ฃผ๋ ๊ฑฐ์์ ๐
์๋ฅผ ๋ค์ด, ์ผ์ฑ์ ์์ SKํ์ด๋์ค ์ฃผ๊ฐ๊ฐ ๋จ๊ธฐ์ ์ผ๋ก๋ ๋ฐ๋ก ๋๋ค๊ฐ
์ฅ๊ธฐ์ ์ผ๋ก๋ ๊ฐ์ด ์์ง์ธ๋ค๋ฉด? ์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค๋ก ์ด๊ฑธ ๋ช
ํํ ๋ณผ ์ ์์ฃ !
์ฌ๊ธฐ์:
โข W_xy: ๊ต์ฐจ ์จ์ด๋ธ๋ฆฟ ๋ณํ ๐
โข S: ์ค๋ฌด๋ฉ ์ฐ์ฐ์ (์๊ฐ๊ณผ ์ค์ผ์ผ ๋ฐฉํฅ์ผ๋ก) ๐
โข Rยฒ: ์ฝํ์ด๋ฐ์ค (0~1 ์ฌ์ด ๊ฐ, 1์ ๊ฐ๊น์ธ์๋ก ๊ฐํ ์๊ด๊ด๊ณ) ๐ช
๐ป Python ๊ตฌํ
์ํ๊น๊ฒ๋ pywt์๋ ์ฝํ์ด๋ฐ์ค ๊ธฐ๋ฅ์ด ์์ด์ ๐ข
๊ทธ๋์ ์ง์ ๊ตฌํํ๊ฑฐ๋ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์จ์ผ ํด์:
pip install pycwt
import pycwt as wavelet
import numpy as np
import matplotlib.pyplot as plt
# ๋ ๊ฐ์ ์๊ณ์ด ๋ฐ์ดํฐ
# ์: ์ผ์ฑ์ ์์ SKํ์ด๋์ค ์ฃผ๊ฐ
stock1 = samsung_prices # ์ผ์ฑ์ ์
stock2 = skhynix_prices # SKํ์ด๋์ค
# ๋ก๊ทธ ์์ต๋ฅ
returns1 = np.diff(np.log(stock1))
returns2 = np.diff(np.log(stock2))
# ์ ๊ทํ
returns1 = (returns1 - np.mean(returns1)) / np.std(returns1)
returns2 = (returns2 - np.mean(returns2)) / np.std(returns2)
# ์๊ฐ ๋ฒกํฐ
dt = 1 # ์ผ๊ฐ ๋ฐ์ดํฐ
t = np.arange(len(returns1)) * dt
# ์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค ๊ณ์ฐ
mother = wavelet.Morlet(6) # Morlet ์จ์ด๋ธ๋ฆฟ ์ฌ์ฉ
s0 = 2 * dt # ์ต์ ์ค์ผ์ผ
dj = 1/12 # ์ค์ผ์ผ ๊ฐ๊ฒฉ
J = 7/dj # ์ค์ผ์ผ ๊ฐ์
# ๊ต์ฐจ ์จ์ด๋ธ๋ฆฟ ๋ฐ ์ฝํ์ด๋ฐ์ค
WCT, aWCT, coi, freq, signif = wavelet.wct(
returns1, returns2, dt, dj=dj, s0=s0, J=J,
mother=mother, significance_level=0.95
)
# ์๊ฐํ
fig, ax = plt.subplots(figsize=(15, 8))
# ์ฝํ์ด๋ฐ์ค ํ๋กฏ
levels = np.linspace(0, 1, 11)
im = ax.contourf(t, np.log2(freq), WCT, levels=levels,
extend='both', cmap='RdYlBu_r')
# Cone of influence
ax.plot(t, np.log2(coi), 'k--', linewidth=2)
ax.fill_between(t, np.log2(coi), np.log2(freq[-1]),
alpha=0.3, hatch='x', color='gray')
# ์ ์๋ฏธํ ์์ญ ํ์
ax.contour(t, np.log2(freq), signif, levels=[1],
colors='k', linewidths=2)
ax.set_title('์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค: ์ผ์ฑ์ ์ vs SKํ์ด๋์ค',
fontsize=14, fontweight='bold')
ax.set_xlabel('์๊ฐ (์ผ)', fontsize=12)
ax.set_ylabel('์ฃผ๊ธฐ (์ผ)', fontsize=12)
# Y์ถ์ ์ฃผ๊ธฐ๋ก ํ์
yticks = 2**np.arange(np.ceil(np.log2(freq.min())),
np.ceil(np.log2(freq.max())))
ax.set_yticks(np.log2(yticks))
ax.set_yticklabels(yticks.astype(int))
plt.colorbar(im, ax=ax, label='์ฝํ์ด๋ฐ์ค')
plt.tight_layout()
plt.show()
์ด๋ ๊ฒ ํ๋ฉด ๋ฉ์ง ํํธ๋งต์ด ๋์์! ๐จ
์๊น์ด ์งํ ์๋ก ๋ ์ฃผ์์ด ๊ฐํ๊ฒ ์ฐ๋๋๋ ๊ฑฐ๊ณ ,
Y์ถ์ ์ฃผ๊ธฐ(์ผ ๋จ์), X์ถ์ ์๊ฐ์ ๋ํ๋ด์ฃ .
๐ ํด์ ๋ฐฉ๋ฒ
1. ์์ ๊ฐ๋ ๐จ
โข ๋นจ๊ฐ์/๋
ธ๋์: ๋์ ์ฝํ์ด๋ฐ์ค (๊ฐํ ์๊ด๊ด๊ณ) ๐ฅ
โข ํ๋์: ๋ฎ์ ์ฝํ์ด๋ฐ์ค (์ฝํ ์๊ด๊ด๊ณ) โ๏ธ
2. ์ฃผ๊ธฐ (Y์ถ) โฐ
โข ์๋์ชฝ (์งง์ ์ฃผ๊ธฐ): ๋จ๊ธฐ ๋ณ๋ (๋ฉฐ์น ~๋ช ์ฃผ) ๐
โข ์์ชฝ (๊ธด ์ฃผ๊ธฐ): ์ฅ๊ธฐ ํธ๋ ๋ (๋ช ๋ฌ~๋ช ๋
) ๐
3. ์์ ์ฐจ์ด (ํ์ดํ๋ก ํ์ ๊ฐ๋ฅ) โก๏ธ
โข ์ค๋ฅธ์ชฝ ํ์ดํ: ๋์์ ์์ง์ (in-phase) ๐ค
โข ์ผ์ชฝ ํ์ดํ: ๋ฐ๋๋ก ์์ง์ (anti-phase) โ๏ธ
โข ์/์๋ ํ์ดํ: ํ์ชฝ์ด ๋ค๋ฅธ ์ชฝ์ ์ ํ ๐
4. Cone of Influence (COI) ๐ช
๋น๊ธ ์น ์์ญ์ ๊ฒฝ๊ณ ํจ๊ณผ ๋๋ฌธ์ ์ ๋ขฐ๋๊ฐ ๋ฎ์์.
์ด ์์ญ์ ๊ฒฐ๊ณผ๋ ์กฐ์ฌ์ค๋ฝ๊ฒ ํด์ํด์ผ ํด์ โ ๏ธ
๐ก ์ค์ ํ์ฉ ์์ด๋์ด
โข ํ์ด ํธ๋ ์ด๋ฉ: ์ฝํ์ด๋ฐ์ค๊ฐ ๋์ ๊ตฌ๊ฐ์์ ์คํ๋ ๋ ๊ฑฐ๋ ๐ฐ
โข ๋ฆฌ์คํฌ ๊ด๋ฆฌ: ํฌํธํด๋ฆฌ์ค ๋ด ์์ฐ ๊ฐ ์๊ด๊ด๊ณ ๋ชจ๋ํฐ๋ง ๐ก๏ธ
โข ์ ํ ์งํ ๋ฐ๊ฒฌ: ์์ ์ฐจ์ด๋ก ์ธ๊ณผ๊ด๊ณ ํ์
๐
โข ์์ฅ ์ฒด์ ๋ณํ ๊ฐ์ง: ์ฝํ์ด๋ฐ์ค ํจํด ๋ณํ๋ก ์์ฅ ๊ตฌ์กฐ ๋ณํ ํฌ์ฐฉ ๐
โก ์จ์ด๋ธ๋ฆฟ vs ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ค
์จ์ด๋ธ๋ฆฟ์ด ์ข๋ค๋ ๊ฑด ์๊ฒ ๋๋ฐ, ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ค๊ณผ ๋น๊ตํ๋ฉด ์ด๋จ๊น์? ๐ค
๊ฐ๊ด์ ์ผ๋ก ๋น๊ตํด๋ณผ๊ฒ์!
๐ ์จ์ด๋ธ๋ฆฟ vs ํธ๋ฆฌ์ ๋ณํ
ํธ๋ฆฌ์ ๋ณํ์ ์ฅ์ :
โข ๊ณ์ฐ์ด ๋งค์ฐ ๋น ๋ฆ (FFT ์๊ณ ๋ฆฌ์ฆ) โก
โข ์ฃผํ์ ํด์๋๊ฐ ๋์ ๐ฏ
โข ์ด๋ก ์ด ์ ์ ๋ฆฝ๋์ด ์์ ๐
ํธ๋ฆฌ์ ๋ณํ์ ๋จ์ :
โข ์๊ฐ ์ ๋ณด ์์ ์์ค โ
โข ๋น์ ์ ์ ํธ์ ๋ถ์ ํฉ ๐ข
โข ๊ตญ์ง์ ํน์ฑ ํ์
๋ถ๊ฐ ๐ซ
์จ์ด๋ธ๋ฆฟ์ ์ฐ์:
๊ธ์ต ๋ฐ์ดํฐ์ฒ๋ผ ์๊ฐ์ ๋ฐ๋ผ ํน์ฑ์ด ๋ณํ๋ ๊ฒฝ์ฐ,
์จ์ด๋ธ๋ฆฟ์ด ์๋์ ์ผ๋ก ์ ๋ฆฌํด์! ๐ช
ํนํ ๊ธ๊ฒฉํ ๋ณํ๋ ์ด์์น ํ์ง์์๋ ๋น๊ต ๋ถ๊ฐ์ฃ .
๐ ์จ์ด๋ธ๋ฆฟ vs STFT (Short-Time Fourier Transform)
STFT:
ํธ๋ฆฌ์ ๋ณํ์ ์งง์ ์๋์ฐ์ ์ ์ฉํ๋ ๋ฐฉ์์ด์์.
์๊ฐ-์ฃผํ์ ๋ถ์์ด ๊ฐ๋ฅํ์ง๋ง, ์๋์ฐ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด ์์ด์
์๊ฐ ํด์๋์ ์ฃผํ์ ํด์๋๋ฅผ ๋์์ ๋์ผ ์ ์์ด์ (๋ถํ์ ์ฑ ์๋ฆฌ) ๐
์จ์ด๋ธ๋ฆฟ:
์ค์ผ์ผ์ ๋ฐ๋ผ ์๋์ฐ ํฌ๊ธฐ๊ฐ ์๋์ผ๋ก ์กฐ์ ๋ผ์!
โข ๊ณ ์ฃผํ (๋จ๊ธฐ): ์ข์ ์๋์ฐ โ ์๊ฐ ํด์๋ ๋์ โฐ
โข ์ ์ฃผํ (์ฅ๊ธฐ): ๋์ ์๋์ฐ โ ์ฃผํ์ ํด์๋ ๋์ ๐ต
์ด๊ฒ ๋ฐ๋ก ์จ์ด๋ธ๋ฆฟ์ ๋ค์ค ํด์๋ ๋ถ์ ๋ฅ๋ ฅ์ด์์! ๐
๐ ์จ์ด๋ธ๋ฆฟ vs EMD (Empirical Mode Decomposition)
EMD:
๋ฐ์ดํฐ ์์ฒด์์ ๊ณ ์ ๋ชจ๋๋ฅผ ์ถ์ถํ๋ ๋ฐฉ์์ด์์.
์จ์ด๋ธ๋ฆฟ์ฒ๋ผ ๋ฏธ๋ฆฌ ์ ์๋ ๊ธฐ์ ํจ์๊ฐ ํ์ ์์ด์ ๋ ์ ์์ ์ด์ฃ ๐ฏ
EMD์ ์ฅ์ :
โข ์์ ํ ๋ฐ์ดํฐ ๊ธฐ๋ฐ (data-driven) ๐
โข ๋น์ ํ, ๋น์ ์ ์ ํธ์ ๊ฐํจ ๐ช
โข ๋ฌผ๋ฆฌ์ ์๋ฏธ๊ฐ ๋ช
ํํจ ๐ฌ
EMD์ ๋จ์ :
โข ๊ณ์ฐ์ด ๋๋ฆผ ๐
โข ๋ชจ๋ ํผํฉ ๋ฌธ์ ๋ฐ์ ๊ฐ๋ฅ ๐ต
โข ์ด๋ก ์ ๊ธฐ๋ฐ์ด ์ฝํจ ๐
์ธ์ ๋ญ ์ธ๊น?
โข ์ค์๊ฐ ์ฒ๋ฆฌ ํ์: ์จ์ด๋ธ๋ฆฟ โก
โข ๋ฌผ๋ฆฌ์ ํด์ ์ค์: EMD ๐ฌ
โข ์ผ๋ฐ์ ์ธ ๊ธ์ต ๋ถ์: ์จ์ด๋ธ๋ฆฟ (์์ ์ ์ด๊ณ ๋น ๋ฆ) ๐
๐ ์จ์ด๋ธ๋ฆฟ vs ์ด๋ํ๊ท /ํํฐ
์ ํต์ ๋ฐฉ๋ฒ๋ค:
โข ๋จ์ ์ด๋ํ๊ท (SMA) ๐
โข ์ง์ ์ด๋ํ๊ท (EMA) ๐
โข Kalman ํํฐ ๐ฏ
์จ์ด๋ธ๋ฆฟ์ ์ฅ์ :
โข ์์ ์ง์ฐ ์์ (non-causal ๋ถ์ ๊ฐ๋ฅ) โฐ
โข ๋ค์ค ์ค์ผ์ผ ๋์ ๋ถ์ ๐
โข ์ ์์ ์ค๋ฌด๋ฉ (๋ฐ์ดํฐ ํน์ฑ์ ๋ฐ๋ผ ์๋ ์กฐ์ ) ๐จ
์ ํต์ ๋ฐฉ๋ฒ์ ์ฅ์ :
โข ์ดํดํ๊ธฐ ์ฌ์ ๐
โข ์ค์๊ฐ ์ ์ฉ ๊ฐ๋จ โก
โข ๊ณ์ฐ ๋ถ๋ด ๊ฑฐ์ ์์ ๐ป
์ค์ ์์๋ ๋ ๋ค ์ฐ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์!
์จ์ด๋ธ๋ฆฟ์ผ๋ก ์ ์ฒ๋ฆฌํ๊ณ , ์ด๋ํ๊ท ์ผ๋ก ์ต์ข
์ ํธ ์์ฑํ๋ ์์ผ๋ก์ ๐ฏ
๐ ์ค๋ฌด์์ ์์์ผ ํ ํ๋ค
์ด๋ก ๊ณผ ์ฝ๋๋ ์ด์ ์ถฉ๋ถํ ๋ดค์ฃ ?
์ค์ ๋ก ํ๋ก์ ํธ์ ์ ์ฉํ ๋ ๊ผญ ์์์ผ ํ ์ค์ ๋
ธํ์ฐ๋ค์ ๊ณต์ ํ ๊ฒ์! ๐ผ
1๏ธโฃ ์จ์ด๋ธ๋ฆฟ ์ ํ ๊ฐ์ด๋
๋ฐ์ดํฐ ํน์ฑ๋ณ ์ถ์ฒ:
๐ ์ฃผ๊ฐ ๋ฐ์ดํฐ
โข ์ผ๋ฐ์ : Daubechies db4~db8 โ
โข ๊ณ ๋น๋: Symlet sym4~sym8 (๋์นญ์ฑ ์ข์) โก
โข ์ฅ๊ธฐ ๋ถ์: Coiflet coif3~coif5 (๋ถ๋๋ฌ์) ๐
๐ฑ ํ์จ ๋ฐ์ดํฐ
โข ๋ณ๋์ฑ ๋ถ์: Daubechies db6 ๐
โข ํธ๋ ๋ ์ถ์ถ: Biorthogonal bior3.5 ๐ฏ
๐ ๊ฑฐ๋๋ ๋ฐ์ดํฐ
โข ๊ธ๋ณ ๊ฐ์ง: Haar (๋จ์ํ๊ณ ๋น ๋ฆ) โก
โข ํจํด ๋ถ์: Daubechies db4 ๐
๐ฐ ์ํธํํ
โข ๋์ ๋ณ๋์ฑ: Daubechies db8~db10 (๋ ๋ถ๋๋ฌ์ด ๊ฒ) ๐ข
โข ์ด์ ํ์ง: Symlet sym8 ๐จ
๐ก ์ ํ ๊ธฐ์ค
โข ๋ถ๋๋ฌ์: ์ซ์๊ฐ ํด์๋ก ๋ถ๋๋ฌ์ (db4 < db8 < db12)
โข ๋์นญ์ฑ: Symlet, Coiflet์ด ๋ ๋์นญ์
โข ์๋: Haar๊ฐ ๊ฐ์ฅ ๋น ๋ฆ, Daubechies๊ฐ ๊ทธ ๋ค์
โข ์ ํ๋: ๋ณต์กํ ์จ์ด๋ธ๋ฆฟ์ผ์๋ก ์ ํํ์ง๋ง ๋๋ฆผ
2๏ธโฃ ๋ถํด ๋ ๋ฒจ ๊ฒฐ์ ํ๊ธฐ
๋๋ฌด ๋ง์ด ๋ถํดํ๋ฉด ๊ณผ์ ํฉ, ๋๋ฌด ์ ๊ฒ ํ๋ฉด ์ ๋ณด ์์ค์ด์์ ๐
# ์ต์ ๋ ๋ฒจ ์๋ ๊ฒฐ์
def optimal_decomposition_level(data, wavelet='db4'):
# ์จ์ด๋ธ๋ฆฟ ํํฐ ๊ธธ์ด
w = pywt.Wavelet(wavelet)
filter_len = w.dec_len
# ์ต๋ ๊ฐ๋ฅ ๋ ๋ฒจ
max_level = pywt.dwt_max_level(len(data), filter_len)
# ๊ฒฝํ์ ๊ท์น: ๋ฐ์ดํฐ ๊ธธ์ด์ log2 - 1
recommended_level = int(np.log2(len(data))) - 1
# ๋ ์ค ์์ ๊ฐ ์ ํ
optimal_level = min(max_level, recommended_level)
# ์ต์ 3, ์ต๋ 10์ผ๋ก ์ ํ
optimal_level = max(3, min(optimal_level, 10))
return optimal_level
# ์ฌ์ฉ ์
level = optimal_decomposition_level(prices, 'db4')
print(f"๊ถ์ฅ ๋ถํด ๋ ๋ฒจ: {level}")
์ผ๋ฐ์ ์ธ ๊ฐ์ด๋๋ผ์ธ:
โข ์ผ๊ฐ ๋ฐ์ดํฐ (1๋
): 5~6 ๋ ๋ฒจ ๐
โข ์๊ฐ ๋ฐ์ดํฐ (1๊ฐ์): 7~8 ๋ ๋ฒจ โฐ
โข ๋ถ ๋ฐ์ดํฐ (1์ฃผ): 8~10 ๋ ๋ฒจ โก
3๏ธโฃ ๊ฒฝ๊ณ ํจ๊ณผ ์ฒ๋ฆฌ
์ ํธ์ ์ ๋์์๋ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ด ๋ถ์ ํํด์ง ์ ์์ด์ โ ๏ธ
์ด๊ฑธ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ๋ค:
# ๋ค์ํ ํจ๋ฉ ๋ชจ๋
modes = ['zero', 'constant', 'symmetric', 'periodic', 'smooth', 'periodization']
# ๊ฐ ๋ชจ๋๋ณ ๊ฒฐ๊ณผ ๋น๊ต
results = {}
for mode in modes:
coeffs = pywt.wavedec(data, 'db4', level=5, mode=mode)
reconstructed = pywt.waverec(coeffs, 'db4', mode=mode)
# ์ฌ๊ตฌ์ฑ ์ค์ฐจ
error = np.mean((data - reconstructed[:len(data)])**2)
results[mode] = error
# ์ต์ ๋ชจ๋ ์ ํ
best_mode = min(results, key=results.get)
print(f"์ต์ ํจ๋ฉ ๋ชจ๋: {best_mode}")
print(f"์ฌ๊ตฌ์ฑ ์ค์ฐจ: {results[best_mode]:.6f}")
๋ชจ๋๋ณ ํน์ง:
โข symmetric: ๊ฐ์ฅ ์ผ๋ฐ์ , ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ข์ โ
โข periodic: ์ฃผ๊ธฐ์ ์ ํธ์ ์ ํฉ ๐
โข smooth: ๋ถ๋๋ฌ์ด ์ ํธ์ ์ข์ ๐
โข zero: ๋น ๋ฅด์ง๋ง ๊ฒฝ๊ณ์์ ์๊ณก ๋ฐ์ โก
๊ธ์ต ๋ฐ์ดํฐ์๋ ๋ณดํต symmetric์ด๋ smooth๋ฅผ ์ถ์ฒํด์! ๐
4๏ธโฃ ๊ณ์ฐ ์ฑ๋ฅ ์ต์ ํ
๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋๋ ์๋๊ฐ ์ค์ํ์ฃ ! โก
import time
from multiprocessing import Pool
# ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ก ์ฌ๋ฌ ์์ฐ ๋์ ๋ถ์
def analyze_asset(ticker):
# ๋ฐ์ดํฐ ๋ก๋
data = load_data(ticker)
# ์จ์ด๋ธ๋ฆฟ ๋ถ์
coeffs = pywt.wavedec(data, 'db4', level=5)
# ํน์ง ์ถ์ถ
features = extract_features(coeffs)
return ticker, features
# ๋ณ๋ ฌ ์คํ
tickers = ['AAPL', 'GOOGL', 'MSFT', 'TSLA', ...] # 100๊ฐ ์ข
๋ชฉ
start = time.time()
with Pool(processes=8) as pool: # 8๊ฐ ํ๋ก์ธ์ค
results = pool.map(analyze_asset, tickers)
end = time.time()
print(f"์ฒ๋ฆฌ ์๊ฐ: {end-start:.2f}์ด")
# ์์ฐจ ์ฒ๋ฆฌ ๋๋น ์ฝ 7~8๋ฐฐ ๋น ๋ฆ!
์ฑ๋ฅ ํ:
โข DWT ์ฌ์ฉ (CWT๋ณด๋ค ํจ์ฌ ๋น ๋ฆ) โก
โข ํ์ํ ๋ ๋ฒจ๋ง ๊ณ์ฐ ๐ฏ
โข ๋ณ๋ ฌ ์ฒ๋ฆฌ ํ์ฉ (์ฌ๋ฌ ์์ฐ ๋์ ๋ถ์) ๐
โข NumPy ๋ฒกํฐํ ์ฐ์ฐ ์ฌ์ฉ ๐
5๏ธโฃ ๋ฐฑํ ์คํ ์ ์ฃผ์์ฌํญ
์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ์ ๋ต์ ๋ฐฑํ ์คํธํ ๋ ์กฐ์ฌํด์ผ ํ ์ ๋ค์ด์์! โ ๏ธ
1. Look-ahead Bias ๋ฐฉ์ง
์จ์ด๋ธ๋ฆฟ ๋ณํ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฒด ์ ํธ๋ฅผ ์ฌ์ฉํด์.
์ค์๊ฐ ๊ฑฐ๋์์๋ ๋ฏธ๋ ๋ฐ์ดํฐ๋ฅผ ์ธ ์ ์์ผ๋ ์ฃผ์!
# ์๋ชป๋ ๋ฐฉ๋ฒ โ
coeffs = pywt.wavedec(entire_data, 'db4', level=5)
signal = generate_signal(coeffs) # ๋ฏธ๋ ์ ๋ณด ํฌํจ!
# ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ โ
def rolling_wavelet_analysis(data, window=252):
signals = []
for i in range(window, len(data)):
# ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ง ์ฌ์ฉ
past_data = data[i-window:i]
coeffs = pywt.wavedec(past_data, 'db4', level=5)
signal = generate_signal(coeffs)
signals.append(signal)
return signals
2. ๊ฑฐ๋ ๋น์ฉ ๊ณ ๋ ค
์จ์ด๋ธ๋ฆฟ ์ ํธ๊ฐ ๋๋ฌด ์์ฃผ ๋ฐ๋๋ฉด ๊ฑฐ๋ ๋น์ฉ์ด ์์ต์ ๋ค ๋จน์ด๋ฒ๋ ค์ ๐
# ์ ํธ ์์ ํ
def stabilize_signal(signals, threshold=0.3):
stable_signals = [signals[0]]
for i in range(1, len(signals)):
# ์ด์ ์ ํธ์ ์ฐจ์ด๊ฐ ์๊ณ๊ฐ ์ด์์ผ ๋๋ง ๋ณ๊ฒฝ
if abs(signals[i] - stable_signals[-1]) > threshold:
stable_signals.append(signals[i])
else:
stable_signals.append(stable_signals[-1])
return stable_signals
3. ๊ณผ์ ํฉ ๊ฒ์ฆ
In-sample๊ณผ Out-of-sample ์ฑ๋ฅ ์ฐจ์ด๋ฅผ ๋ฐ๋์ ํ์ธํ์ธ์!
# ์ํฌํฌ์๋ ๋ถ์
def walk_forward_test(data, train_period=252, test_period=63):
results = []
for i in range(0, len(data) - train_period - test_period, test_period):
# ํ๋ จ ๊ตฌ๊ฐ
train_data = data[i:i+train_period]
# ์ต์ ํ๋ผ๋ฏธํฐ ์ฐพ๊ธฐ
best_params = optimize_parameters(train_data)
# ํ
์คํธ ๊ตฌ๊ฐ
test_data = data[i+train_period:i+train_period+test_period]
# ์ฑ๋ฅ ํ๊ฐ
performance = evaluate_strategy(test_data, best_params)
results.append(performance)
return results
๐ ์ต์ ์ฐ๊ตฌ ๋ํฅ๊ณผ ๋ฏธ๋
์จ์ด๋ธ๋ฆฟ ๋ถ์์ ๊ณ์ ์งํํ๊ณ ์์ด์!
์ต์ ํธ๋ ๋์ ์์ผ๋ก์ ๋ฐฉํฅ์ ์ดํด๋ณผ๊ฒ์ ๐
๐ค ๋ฅ๋ฌ๋๊ณผ์ ๊ฒฐํฉ
์์ฆ ๊ฐ์ฅ ํซํ ํธ๋ ๋๋ ์จ์ด๋ธ๋ฆฟ๊ณผ ๋ฅ๋ฌ๋์ ๊ฒฐํฉํ๋ ๊ฑฐ์์! ๐ฅ
Wavelet-CNN ์ํคํ ์ฒ:
import tensorflow as tf
from tensorflow import keras
# ์จ์ด๋ธ๋ฆฟ ํน์ง์ CNN ์
๋ ฅ์ผ๋ก ์ฌ์ฉ
def create_wavelet_cnn(input_shape):
model = keras.Sequential([
# ์จ์ด๋ธ๋ฆฟ ๊ณ์๋ฅผ 2D ์ด๋ฏธ์ง์ฒ๋ผ ์ฒ๋ฆฌ
keras.layers.Conv2D(32, (3,3), activation='relu',
input_shape=input_shape),
keras.layers.MaxPooling2D((2,2)),
keras.layers.Conv2D(64, (3,3), activation='relu'),
keras.layers.MaxPooling2D((2,2)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(1, activation='sigmoid') # ์์น/ํ๋ฝ ์์ธก
])
return model
# ์จ์ด๋ธ๋ฆฟ ์คํํธ๋ก๊ทธ๋จ ์์ฑ
def create_wavelet_spectrogram(prices, window=60):
spectrograms = []
for i in range(window, len(prices)):
data = prices[i-window:i]
# CWT๋ก 2D ํํ ์์ฑ
scales = np.arange(1, 32)
coeffs, freqs = pywt.cwt(data, scales, 'morl')
# ์ ๊ทํ
coeffs = (coeffs - np.mean(coeffs)) / np.std(coeffs)
spectrograms.append(coeffs)
return np.array(spectrograms)
# ํ์ต
X = create_wavelet_spectrogram(prices)
y = (prices[61:] > prices[60:-1]).astype(int) # ๋ค์๋ ์์น ์ฌ๋ถ
model = create_wavelet_cnn(X.shape[1:])
model.compile(optimizer='adam', loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(X, y, epochs=50, validation_split=0.2)
์ด ๋ฐฉ๋ฒ์ ์๊ฐ-์ฃผํ์ ์ ๋ณด๋ฅผ ์ด๋ฏธ์ง์ฒ๋ผ ํ์ต์์ผ์
๋ณต์กํ ํจํด์ ์๋์ผ๋ก ์ฐพ์๋ด์! ๐ฏ
๐ฎ Wavelet-LSTM ํ์ด๋ธ๋ฆฌ๋
์จ์ด๋ธ๋ฆฟ์ผ๋ก ์ ์ฒ๋ฆฌํ๊ณ LSTM์ผ๋ก ์๊ณ์ด ์์ธกํ๋ ๋ฐฉ์์ด์์ ๐
# ์จ์ด๋ธ๋ฆฟ ๋ถํด ํ ๊ฐ ์ฑ๋ถ๋ณ๋ก LSTM ํ์ต
def wavelet_lstm_model(data, wavelet='db4', level=5):
# ์จ์ด๋ธ๋ฆฟ ๋ถํด
coeffs = pywt.wavedec(data, wavelet, level=level)
# ๊ฐ ๋ ๋ฒจ๋ณ LSTM ๋ชจ๋ธ
models = []
predictions = []
for i, coeff in enumerate(coeffs):
# ์ํ์ค ๋ฐ์ดํฐ ์์ฑ
X, y = create_sequences(coeff, seq_length=20)
# LSTM ๋ชจ๋ธ
model = keras.Sequential([
keras.layers.LSTM(50, activation='relu',
input_shape=(20, 1)),
keras.layers.Dense(1)
])
model.compile(optimizer='adam', loss='mse')
model.fit(X, y, epochs=50, verbose=0)
models.append(model)
# ์์ธก
pred = model.predict(X[-1:])
predictions.append(pred[0, 0])
# ์จ์ด๋ธ๋ฆฟ ์ฌ๊ตฌ์ฑ์ผ๋ก ์ต์ข
์์ธก
# (๊ฐ ๋ ๋ฒจ์ ์์ธก์ ๊ฒฐํฉ)
final_prediction = combine_predictions(predictions, wavelet)
return final_prediction
๊ฐ ์ฃผํ์ ๋์ญ์ ๋ณ๋๋ก ํ์ตํ๋๊น ์ ํ๋๊ฐ ํจ์ฌ ๋์์ ธ์! ๐ช
๐ ๊ณ ์ฐจ์ ์จ์ด๋ธ๋ฆฟ ๋ถ์
์ฌ๋ฌ ์์ฐ์ ๋์์ ๋ถ์ํ๋ ๋ค๋ณ๋ ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฒ๋ ๋ฐ์ ํ๊ณ ์์ด์ ๐
์ฃผ์ ์์ฉ:
โข ํฌํธํด๋ฆฌ์ค ์ต์ ํ ๐ผ
โข ์์คํ
๋ฆฌ์คํฌ ๋ถ์ ๐ก๏ธ
โข ์์ฅ ๊ฐ ์ ์ด ํจ๊ณผ ์ฐ๊ตฌ ๐
โข ๋คํธ์ํฌ ๋ถ์ (๊ธ์ต ์์คํ
์ ์ฐ๊ฒฐ์ฑ) ๐ธ๏ธ
์๋ฅผ ๋ค์ด, S&P500 ๊ตฌ์ฑ ์ข
๋ชฉ๋ค์ ์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค๋ฅผ ๋คํธ์ํฌ๋ก ์๊ฐํํ๋ฉด
์์ฅ ์๊ธฐ ์ ์ด๋ป๊ฒ ์ ์ผ๋๋์ง ๋ณผ ์ ์์ด์! ๐
โก ์ค์๊ฐ ์จ์ด๋ธ๋ฆฟ ๋ถ์
๊ณ ๋น๋ ๊ฑฐ๋(HFT)๋ฅผ ์ํ ์ด๊ณ ์ ์จ์ด๋ธ๋ฆฟ ์๊ณ ๋ฆฌ์ฆ๋ ๊ฐ๋ฐ๋๊ณ ์์ด์ ๐
Lifting Scheme:
์ ํต์ ์ธ ์จ์ด๋ธ๋ฆฟ ๋ณํ๋ณด๋ค 2~3๋ฐฐ ๋น ๋ฅธ ๋ฐฉ๋ฒ์ด์์!
ํนํ ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ์ ์ ํฉํ์ฃ .
# PyWavelets์ lifting scheme ์ฌ์ฉ
# (์ผ๋ถ ์จ์ด๋ธ๋ฆฟ๋ง ์ง์)
# ๋น ๋ฅธ ๋ถํด
coeffs = pywt.swt(data, 'db2', level=5) # Stationary WT
# ์ค์๊ฐ ์
๋ฐ์ดํธ
def update_wavelet_online(new_data_point, previous_coeffs):
# ์๋ก์ด ๋ฐ์ดํฐ ํฌ์ธํธ๋ง์ผ๋ก ๊ณ์ ์
๋ฐ์ดํธ
# (์ ์ฒด ์ฌ๊ณ์ฐ ๋ถํ์!)
updated_coeffs = incremental_update(previous_coeffs, new_data_point)
return updated_coeffs
๋ฐ๋ฆฌ์ด ๋จ์๋ก ์์ฌ๊ฒฐ์ ํด์ผ ํ๋ HFT์์๋ ์ด๋ฐ ์ต์ ํ๊ฐ ํ์์์! โก
๐ฎ ๋ฏธ๋ ์ ๋ง
1. ์์ ์จ์ด๋ธ๋ฆฟ ๋ณํ: ์์ ์ปดํจํฐ๋ฅผ ํ์ฉํ ์ด๊ณ ์ ๋ถ์ ๐ฌ
2. ์ ์ํ ์จ์ด๋ธ๋ฆฟ: ๋ฐ์ดํฐ ํน์ฑ์ ๋ฐ๋ผ ์๋์ผ๋ก ์ต์ ์จ์ด๋ธ๋ฆฟ ์ ํ ๐ค
3. ์ค๋ช
๊ฐ๋ฅํ AI: ์จ์ด๋ธ๋ฆฟ์ผ๋ก ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ ์์ฌ๊ฒฐ์ ๊ณผ์ ํด์ ๐
4. ์ค์๊ฐ ๋ฆฌ์คํฌ ๊ด๋ฆฌ: ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ์กฐ๊ธฐ ๊ฒฝ๋ณด ์์คํ
๐จ
์จ์ด๋ธ๋ฆฟ ๋ถ์์ ์์ผ๋ก๋ ๊ธ์ต ๋ฐ์ดํฐ ๋ถ์์ ํต์ฌ ๋๊ตฌ๋ก ์๋ฆฌ์ก์ ๊ฑฐ์์! ๐
๐ผ ์ฌ๋ฅ๋ท์์ ์จ์ด๋ธ๋ฆฟ ์ ๋ฌธ๊ฐ ๋๊ธฐ
์ฌ๊ธฐ๊น์ง ์ฝ์ผ์
จ๋ค๋ฉด ์จ์ด๋ธ๋ฆฟ ๋ถ์์ ๋ํด ๊ฝค ๋ง์ด ์๊ฒ ๋์
จ์ ๊ฑฐ์์! ๐
์ด์ ์ด ์ง์์ ์ด๋ป๊ฒ ํ์ฉํ ์ ์์๊น์?
๐ฏ ์ค๋ ฅ ํฅ์ ๋ก๋๋งต
์ด๊ธ (1~3๊ฐ์): ๐
โข Python ๊ธฐ์ด ๋ค์ง๊ธฐ
โข NumPy, Pandas ๋ง์คํฐํ๊ธฐ
โข PyWavelets ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ตํ๊ธฐ
โข ๊ฐ๋จํ ์ฃผ๊ฐ ๋ฐ์ดํฐ ๋ถ์ ํ๋ก์ ํธ
์ค๊ธ (3~6๊ฐ์): ๐
โข ๋ค์ํ ์จ์ด๋ธ๋ฆฟ ํจ์ ์คํ
โข ๋
ธ์ด์ฆ ์ ๊ฑฐ, ํธ๋ ๋ ์ถ์ถ ๊ธฐ๋ฒ ์๋ฌ
โข ๋ฐฑํ
์คํ
ํ๋ ์์ํฌ ๊ตฌ์ถ
โข ์ค์ ๊ฑฐ๋ ์ ๋ต ๊ฐ๋ฐ
๊ณ ๊ธ (6๊ฐ์~1๋
): ๐
โข ์จ์ด๋ธ๋ฆฟ-๋ฅ๋ฌ๋ ํ์ด๋ธ๋ฆฌ๋ ๋ชจ๋ธ
โข ๋ค๋ณ๋ ๋ถ์ ๋ฐ ์ฝํ์ด๋ฐ์ค
โข ์ค์๊ฐ ๋ถ์ ์์คํ
๊ตฌ์ถ
โข ๋
ผ๋ฌธ ์ฝ๊ณ ์ต์ ๊ธฐ๋ฒ ์ ์ฉ
๐ฐ ์ฌ๋ฅ๋ท์์ ์์ต ์ฐฝ์ถํ๊ธฐ
์ฌ๋ฅ๋ท(https://www.jaenung.net)์์๋ ์ฌ๋ฌ๋ถ์ ์จ์ด๋ธ๋ฆฟ ๋ถ์ ๋ฅ๋ ฅ์ ํ์ฉํ ์ ์์ด์! ๐ผ
์ ๊ณต ๊ฐ๋ฅํ ์๋น์ค:
โข ๐ ๊ธ์ต ๋ฐ์ดํฐ ๋ถ์ ๋ํ: ์ฃผ๊ฐ, ํ์จ, ์ํธํํ ๋ถ์
โข ๐ ์จ์ด๋ธ๋ฆฟ ๋ถ์ ๊ฐ์: 1:1 ๋๋ ๊ทธ๋ฃน ๊ณผ์ธ
โข ๐ป ์๋ํ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ: ๋ง์ถคํ ๋ถ์ ๋๊ตฌ ์ ์
โข ๐ ํฌ์ ์ ๋ต ์ปจ์คํ
: ์จ์ด๋ธ๋ฆฟ ๊ธฐ๋ฐ ๋งค๋งค ์ ๋ต ์ค๊ณ
โข ๐ ๋ฆฌ์คํฌ ๋ถ์ ์๋น์ค: ๋ณ๋์ฑ ์์ธก ๋ฐ ์ด์ ํ์ง
์ฌ๋ฅ๋ท์ '์ง์์ธ์ ์ฒ' ๊ฐ์ ๊ณณ์์ ์ด๋ฐ ์ ๋ฌธ ์ง์์ ๊ณต์ ํ๋ฉด
์ฌ๋ฌ๋ถ๋ ์ ๋ฌธ๊ฐ๋ก ์ธ์ ๋ฐ์ ์ ์์ด์! ๐
๐ก ์ฑ๊ณต ํ
โข ํฌํธํด๋ฆฌ์ค ๊ตฌ์ถ: GitHub์ ํ๋ก์ ํธ ์ฌ๋ฆฌ๊ธฐ ๐
โข ๋ธ๋ก๊ทธ ์ด์: ๋ถ์ ์ฌ๋ก ์ ๊ธฐ์ ์ผ๋ก ๊ณต์ โ๏ธ
โข ์ปค๋ฎค๋ํฐ ํ๋: ์ฌ๋ฅ๋ท์ด๋ ๊ธ์ต ์ปค๋ฎค๋ํฐ์์ ํ๋ฐํ ํ๋ ๐ฌ
โข ์ง์์ ํ์ต: ์ต์ ๋
ผ๋ฌธ๊ณผ ๊ธฐ๋ฒ ๊พธ์คํ ๊ณต๋ถ ๐
โข ์ค์ ๊ฒฝํ: ์ค์ ๋์ผ๋ก ์์ก ํฌ์ํ๋ฉฐ ๊ฒ์ฆ ๐ฐ
๐ ์ถ๊ฐ ํ์ต ์๋ฃ
๋ ๊น์ด ๊ณต๋ถํ๊ณ ์ถ์ผ์ ๋ถ๋ค์ ์ํ ์๋ฃ๋ค์ด์์! ๐
๐ ์ถ์ฒ ๋์
โข "A Wavelet Tour of Signal Processing" - Stรฉphane Mallat
โข "Wavelets and Filter Banks" - Gilbert Strang
โข "Practical Time-Frequency Analysis" - Remi Gribonval
๐ ์จ๋ผ์ธ ๊ฐ์
โข Coursera: "Digital Signal Processing" (EPFL)
โข edX: "Wavelets and Applications" (MIT)
โข YouTube: "Steve Brunton" ์ฑ๋์ ์จ์ด๋ธ๋ฆฟ ์๋ฆฌ์ฆ
๐ ์ฃผ์ ๋
ผ๋ฌธ
โข "Wavelet Analysis of Financial Time Series" (Genรงay et al., 2001)
โข "The Application of Wavelet Transform in Financial Time Series Analysis" (Zhang et al., 2018)
โข "Wavelet-based Prediction of Stock Prices" (Tan et al., 2020)
๐ป ์ ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
โข PyWavelets: ํ์ด์ฌ ์จ์ด๋ธ๋ฆฟ ๋ณํ
โข PyCWT: ์ฐ์ ์จ์ด๋ธ๋ฆฟ ๋ณํ ๋ฐ ์ฝํ์ด๋ฐ์ค
โข ssqueezepy: Synchrosqueezing ์จ์ด๋ธ๋ฆฟ ๋ณํ
โข WaveletComp: R ํจํค์ง (์จ์ด๋ธ๋ฆฟ ์ฝํ์ด๋ฐ์ค)
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์... ์ฌ๊ธฐ๊น์ง ์ฝ์ผ์ จ๋ค๋ ์ ๋ง ๋๋จํ์ธ์! ๐๐๐
์จ์ด๋ธ๋ฆฟ ๋ณํ์ ์ฒ์์ ์ด๋ ต๊ฒ ๋๊ปด์ง ์ ์์ง๋ง,
ํ๋ฒ ์ต์ํด์ง๋ฉด ๊ธ์ต ๋ฐ์ดํฐ ๋ถ์์ ๊ฐ๋ ฅํ ๋ฌด๊ธฐ๊ฐ ๋ผ์ โ๏ธ
ํต์ฌ๋ง ๋ค์ ์ ๋ฆฌํ๋ฉด:
๐ฏ ์จ์ด๋ธ๋ฆฟ ๋ณํ์ ํต์ฌ ์ฅ์
โ
์๊ฐ-์ฃผํ์ ๋์ ๋ถ์ ๊ฐ๋ฅ
โ
๋น์ ์ ์ ํธ์ ๊ฐํจ
โ
๋ค์ค ํด์๋ ๋ถ์์ผ๋ก ์ฅ๋จ๊ธฐ ํจํด ๋์ ํฌ์ฐฉ
โ
๋
ธ์ด์ฆ ์ ๊ฑฐ์ ์ด์ ํ์ง์ ํ์
โ
๋ฅ๋ฌ๋๊ณผ ๊ฒฐํฉ ์ ์๋์ง ํจ๊ณผ
๊ธ์ต์์ฅ์ ๋ณต์กํ๊ณ ์์ธกํ๊ธฐ ์ด๋ ต์ง๋ง,
์จ์ด๋ธ๋ฆฟ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ ํ์ฉํ๋ฉด ์จ๊ฒจ์ง ํจํด์ ๋ฐ๊ฒฌํ ์ ์์ด์ ๐
์ด์ ์ฌ๋ฌ๋ถ๋ ์ง์ ์ฝ๋๋ฅผ ์ง๋ณด๊ณ , ์คํํด๋ณด๊ณ , ์์ ๋ง์ ์ ๋ต์ ๋ง๋ค์ด๋ณด์ธ์!
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ ๋ฌธ์ฑ์ ๋๋๋ฉด์ ์ฑ์ฅํ์๊ธธ ๋ฐ๋๊ฒ์ ๐ฑ
๊ถ๊ธํ ์ ์ด๋ ๋ ์๊ณ ์ถ์ ๋ด์ฉ์ด ์๋ค๋ฉด
์ฌ๋ฅ๋ท ์ปค๋ฎค๋ํฐ์์ ์ธ์ ๋ ์ง๋ฌธํ์ธ์!
ํจ๊ป ๋ฐฐ์ฐ๊ณ ์ฑ์ฅํ๋ ๊ฒ ๊ฐ์ฅ ๋น ๋ฅธ ๊ธธ์ด๋๊น์ ๐
๊ทธ๋ผ ์ฌ๋ฌ๋ถ์ ์จ์ด๋ธ๋ฆฟ ๋ถ์ ์ฌ์ ์ ํ์ด์ ๋น๋๋ค! ๐
ํ์ดํ
! ๐ช๐ช๐ช
๐ ์จ์ด๋ธ๋ฆฟ์ผ๋ก ๊ธ์ต์์ฅ์ ์จ์ ํจํด์ ์ฐพ์๋ณด์ธ์! ๐
์ด ๊ธ์ด ๋์์ด ๋์ จ๋ค๋ฉด ์ฌ๋ฅ๋ท์์ ๋ ๋ง์ ์ง์์ ๋๋ ์ฃผ์ธ์ ๐
๊ด๋ จ ํค์๋
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.

๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.