ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ ํํธ ํฌ์ ๊ณต๋ถ 13๋จ๊ณ
— “ํ๋ผ๋ฏธํฐ๋ ‘์ ๋ต’์ ์ฐพ๋ ๊ฒ ์๋๋ผ ‘์์ ํ ๋ฒ์’๋ฅผ ์ ํ๋ ๊ฒ: Robust ์ ๋ต ๋ง๋ค๊ธฐ”
12๋จ๊ณ์์ ์ํฌํฌ์๋ ๊ฒ์ฆ์ ํ์ฃ .
์ด์ ์ ๋ต์ด “์ด๋ค ์๊ธฐ์ ๊นจ์ง๋์ง”๊น์ง ๋ณด์ด๊ธฐ ์์ํฉ๋๋ค.
๊ทธ ๋ค์์ ์ด๋ณด์๋ค์ด ๋ฐ๋ก ํ๋ ์๊ฐ์ด ์ด๊ฑฐ์์.
“๊ทธ๋ผ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ ํ๋ํด์
๊นจ์ง๋ ๊ตฌ๊ฐ์ ์์ ๋ฉด ๋์ง ์์๊น?”
์ฌ๊ธฐ์๋ถํฐ ๊ณผ์ต์ ํ๊ฐ ๋ค์ ์์๋ฉ๋๋ค.
13๋จ๊ณ์ ํต์ฌ์ ์ด๊ฒ๋๋ค.
ํ๋ผ๋ฏธํฐ์ ์ ๋ต(์ต์ ๊ฐ)์ ์ฐพ์ง ๋ง๊ณ ,
์กฐ๊ธ ๋ฐ๊ฟ๋ ์ฑ๊ณผ๊ฐ ์ ์ง๋๋ ‘์์ ํ ๋ฒ์(robust range)’๋ฅผ ์ฐพ์๋ผ.
์ด๊ฒ ์ค์ ํํธ์ ๋ฐฑํ ์คํธ ๋์ด๋ฅผ ๊ฐ๋ฅด๋ ๊ฒฝ๊ณ์ ์ ๋๋ค.
1๏ธโฃ “์ต์ ํ๋ผ๋ฏธํฐ”๊ฐ ์ํํ ์ด์
์๋ฅผ ๋ค์ด ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค๊ณ ํด๋ด ์๋ค.
- lookback = 63์ผ์ผ ๋ CAGR 21%
- lookback = 60์ผ์ผ ๋ CAGR 12%
- lookback = 66์ผ์ผ ๋ CAGR 9%
์ด๊ฑด ๋ฌด์จ ๋ป์ผ๊น์?
63์ด๋ผ๋ ์ซ์๊ฐ ํน๋ณํ ๊ฒ ์๋๋ผ,
์ฐ์ฐํ ๋ฑ ๋ง์๋จ์ด์ง ์ง์ ์ ์ก์๋ค๋ ๋ป์ ๋๋ค.
์ง์ง ์๋ฆฌ๋ฅผ ์ก์ ์ ๋ต์ด๋ผ๋ฉด
60~70 ์ ๋์์
๋น์ทํ ์ฑ๊ณผ๊ฐ ๋์์ผ ํฉ๋๋ค.
2๏ธโฃ Robust(ํผํผํ) ์ ๋ต์ ํน์ง
ํผํผํ ์ ๋ต์ ์ด๋ฐ ํน์ง์ ๊ฐ์ง๋๋ค.
โ
ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ๊ธ ๋ฐ๊ฟ๋ ๊ฒฐ๊ณผ๊ฐ ํฌ๊ฒ ํ๋ค๋ฆฌ์ง ์๋๋ค
โ
ํน์ ๊ตฌ๊ฐ์์๋ง ํญ๋ฐํ์ง ์๋๋ค
โ
์ํฌํฌ์๋ ๊ตฌ๊ฐ๋ง๋ค ๊ฒฐ๊ณผ๊ฐ ๊ณ ๋ฅด๊ฒ ๋์จ๋ค
โ
๊ฑฐ๋ ํ์/๋น์ฉ์ด ํฉ๋ฆฌ์ ์ด๋ค
โ
“์ ๋๋์ง” ์ค๋ช
์ด ๊ฐ๋ฅํ๋ค
ํต์ฌ์ “์์๊ฒ ์ ๋จ”์ด ์๋๋ผ
๋ ๋ง๊ฐ์ง์ ๋๋ค.
3๏ธโฃ Robust Range๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ (๋ฏผ๊ฐ๋ ๋ถ์)
๋ฏผ๊ฐ๋ ๋ถ์์ ๋ง์ด ์ด๋ ค์ด๋ฐ,
ํ๋ ์ผ์ ๋จ์ํฉ๋๋ค.
ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ๋ฌ ๊ฐ์ผ๋ก ๋๋ ค๋ณด๊ณ
์ฑ๊ณผ๊ฐ ์์ ์ ์ผ๋ก ์ ์ง๋๋ ๊ตฌ๊ฐ์ ์ฐพ๋๋ค.
์๋ฅผ ๋ค์ด ๋ชจ๋ฉํ
lookback์
40~120์ผ๊น์ง 10์ผ ๋จ์๋ก ๋๋ ค๋ด
๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ด ๋๋ค.
- 40~60: ์ฑ๊ณผ ๋์จ
- 60~90: ์ฑ๊ณผ ์์ ์ ์ผ๋ก ์ข์
- 90~120: ์ฑ๊ณผ ๋ค์ ๋๋น ์ง
์ด๋ ๊ฒ ๋์ค๋ฉด
์ ๋ต์ “73์ผ”์ด ์๋๋ผ
โ 60~90์ผ ๊ตฌ๊ฐ์ด robustํ๋ค
์ ๋๋ค.
4๏ธโฃ Robust ํ๋ผ๋ฏธํฐ ์ ํ์ ๊ธฐ์ค
ํ๋ผ๋ฏธํฐ ๋ฒ์๋ฅผ ์ ํ ๋
ํํธ๋ ์ด๋ฐ ๊ธฐ์ค์ผ๋ก ๊ณ ๋ฆ
๋๋ค.
โ 1) ์ฑ๊ณผ ์์ “๊ตฌ๊ฐ”์ ๊ณ ๋ฅธ๋ค
- ์ต๊ณ ์ 1๊ฐ๊ฐ ์๋๋ผ
- ์์ 20% ์ ๋๊ฐ ๋ญ์ณ์๋ ๊ตฌ๊ฐ
โ 2) ๊ฑฐ๋๋น์ฉ์ด ํฉ๋ฆฌ์ ์ธ ๊ตฌ๊ฐ
- ์ฑ๊ณผ๋ ์กฐ๊ธ ๋ฎ์๋
- turnover(ํ์ ์จ)๊ฐ ๋ฎ์ ๊ตฌ๊ฐ์ด ์ค์ ์์ ๋ ์ข์ต๋๋ค.
โ 3) ์ํฌํฌ์๋์์ ์ผ๊ด๋ ๊ตฌ๊ฐ
- ํน์ ์๊ธฐ์๋ง ์ข์ ๊ตฌ๊ฐ์ ์ ์ธ
5๏ธโฃ (์คํ ๊ฐ๋ฅํ ์ฝ๋) ํ๋ผ๋ฏธํฐ ๋ฏผ๊ฐ๋ ๋ถ์ ์์
์๋ ์ฝ๋๋ 12๋จ๊ณ์์ ๋ง๋ ๋ฐฑํ
์คํธ ํจ์๋ฅผ ํ์ฉํด์
lookback ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ๊พธ๋ฉฐ ์ฑ๊ณผํ๋ฅผ ๋ง๋๋ ์ฝ๋์
๋๋ค.
(์ํ ๋ฐ์ดํฐ ๊ธฐ๋ฐ์ด๋ผ ๊ทธ๋๋ก ์คํ๋ฉ๋๋ค.)
import numpy as np
import pandas as pd
def make_sample_prices(n_assets=8, n_days=1500, seed=42):
rng = np.random.default_rng(seed)
rets = rng.normal(loc=0.00025, scale=0.012, size=(n_days, n_assets))
prices = 100 * np.exp(np.cumsum(rets, axis=0))
dates = pd.date_range("2018-01-01", periods=n_days, freq="B")
cols = [f"A{i+1}" for i in range(n_assets)]
return pd.DataFrame(prices, index=dates, columns=cols)
def backtest_mom_topn(prices, lookback=60, top_n=3, fee_bps=5):
returns = prices.pct_change().fillna(0.0)
month_ends = prices.resample("M").last().index
month_ends = [d for d in month_ends if d in prices.index]
weights = pd.Series(0.0, index=prices.columns)
equity = 1.0
curve = []
for dt in prices.index:
if dt in month_ends and prices.index.get_loc(dt) >= lookback:
mom = (prices.loc[dt] / prices.shift(lookback).loc[dt] - 1.0).sort_values(ascending=False)
pick = mom.index[:top_n]
target = pd.Series(0.0, index=prices.columns)
target.loc[pick] = 1.0 / top_n
turnover = (target - weights).abs().sum()
equity *= (1 - turnover * (fee_bps / 10_000))
weights = target
equity *= (1 + float((weights * returns.loc[dt]).sum()))
curve.append(equity)
return pd.Series(curve, index=prices.index, name="equity")
def stats(equity):
rets = equity.pct_change().dropna()
cagr = (equity.iloc[-1] / equity.iloc[0]) ** (252 / len(equity)) - 1
dd = equity / equity.cummax() - 1
mdd = dd.min()
sharpe = (rets.mean() * 252) / (rets.std() * np.sqrt(252)) if rets.std() > 0 else np.nan
return cagr, mdd, sharpe
if __name__ == "__main__":
prices = make_sample_prices()
rows = []
for lb in range(40, 121, 10): # 40~120, 10์ผ ๊ฐ๊ฒฉ
eq = backtest_mom_topn(prices, lookback=lb, top_n=3, fee_bps=5)
cagr, mdd, sharpe = stats(eq)
rows.append({"lookback": lb, "CAGR": cagr, "MDD": mdd, "Sharpe": sharpe})
df = pd.DataFrame(rows).sort_values("Sharpe", ascending=False)
print(df)
โ
์ด ๊ฒฐ๊ณผ์์ “1๋ฑ”์ ๊ณ ๋ฅด์ง ๋ง์ธ์.
๋์ , ์์๊ถ์ ๋ญ์ณ ์๋ ๊ตฌ๊ฐ์ ์ฐพ์ผ์ธ์.
6๏ธโฃ Robust ์ ๋ต์ ๋ง๋๋ ์ค์ ํ 3๊ฐ
โ ํ 1) ํ๋ผ๋ฏธํฐ๋ ๋ฅ๊ธ๊ฒ ๊ณ ๋ฅธ๋ค
63์ผ์ด ์ต๊ณ ๋ฉด
60์ผ์ด๋ 65์ผ ๊ฐ์ “๋ฅ๊ทผ ๊ฐ”์ ๊ณ ๋ฆ
๋๋ค.
→ ์ฐ์ฐ์ ์ต์ ์ ์ ํผํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋๋ค.
โ ํ 2) ์ต๊ณ ์ฑ๊ณผ๋ณด๋ค, ์ต์ ์ฑ๊ณผ๋ฅผ ๋ณธ๋ค
- ํ๊ท ์ด ์๋๋ผ
- ํ์ 20% ๊ตฌ๊ฐ์์ ๋ฒํฐ๋์ง
์ด๊ฒ ์ค์ ์ ๋๋ค.
โ ํ 3) ๊ฑฐ๋ ํ์๊ฐ ๋๋ฉด, ์ฑ๊ณผ๋ ์ค์ด๋ ๋ค
ํนํ ๊ฐ์ธ ํฌ์์์๊ฒ
์์๋ฃ์ ์ฌ๋ฆฌํผ์ง๋ ์๊ฐ๋ณด๋ค ํฌ๊ฒ ์์ฉํฉ๋๋ค.
7๏ธโฃ ์์ฃผ ์์ ์ค์ต (ํต์ฌ ๊ณผ์ )
โ๏ธ ๊ณผ์ 13
๋น์ ์ด ๋ง๋ ์ ๋ต์์
ํ๋ผ๋ฏธํฐ ํ๋๋ง ๊ณจ๋ผ์
- ±10~20% ๋ฒ์๋ก ๋ฐ๊ฟ๋ณด๊ณ
- ์ฑ๊ณผ๊ฐ ์ ์ง๋๋ ๊ตฌ๊ฐ์ ์ฐพ์ผ์ธ์.
๊ทธ๋ฆฌ๊ณ ์ด ๋ฌธ์ฅ์ ์ฐ์ธ์.
“๋ด ์ ๋ต์ ์ต์ ๊ฐ์ ___์ด์ง๋ง,
~ ๋ฒ์์์๋ ๋น์ทํ๊ฒ ์๋ํ๋ค.
๊ทธ๋์ ๋๋ ___๋ฅผ ์ ํํ๋ค.”
์ด ๋ฌธ์ฅ์ ์ธ ์ ์๋ค๋ฉด
๋น์ ์ “๋ฐฑํ
์คํธ ๋์ด”๋ฅผ ๋ฒ์ด๋
์ค์ ํํธ ์ค๊ณ์๋ก ๋์ด์จ ๊ฒ๋๋ค.
๐ ์ ๋ฆฌ
- ์ต์ ๊ฐ์ ์ํํ๋ค (์ฐ์ฐ์ผ ๊ฐ๋ฅ์ฑ)
- ๋ชฉํ๋ ์ ๋ต์ด ์๋๋ผ ์์ ํ ๋ฒ์(robust range)
- ๋ฏผ๊ฐ๋ ๋ถ์์ผ๋ก “๋๊ฐํ ๊ตฌ๊ฐ”์ ์ฐพ์๋ผ
- ํ๋ผ๋ฏธํฐ๋ ๋ฅ๊ธ๊ฒ, ๋ณด์์ ์ผ๋ก
- ๊ฑฐ๋๋น์ฉ๊น์ง ํฌํจํด ์ค์ ์ฑ์ ํ๋ณดํด์ผ ํ๋ค
ํ๋ผ๋ฏธํฐํ๋,๋ฏผ๊ฐ๋๋ถ์,Robust์ ๋ต,ํํธ๊ฒ์ฆ,๊ณผ์ต์ ํ๋ฐฉ์ง,์ํฌํฌ์๋,๋ฐฑํ ์คํธ,์คํ์ง์,MDD,์์คํ ํฌ์
'์ฃผ์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ๐ ํํธ ํฌ์ ๊ณต๋ถ 15๋จ๊ณ (0) | 2026.03.05 |
|---|---|
| ๐ ํํธ ํฌ์ ๊ณต๋ถ 14๋จ๊ณ (0) | 2026.03.02 |
| ๐ ํํธ ํฌ์ ๊ณต๋ถ 12๋จ๊ณ (0) | 2026.02.25 |
| ๐ ํํธ ํฌ์ ๊ณต๋ถ 11๋จ๊ณ (0) | 2026.02.24 |
| ๐ ํํธ ํฌ์ ๊ณต๋ถ 10๋จ๊ณ (0) | 2026.02.13 |
- Total
- Today
- Yesterday
- ์์ฑํAI
- ์ฃผ๋์ด๊ฐ๋ฐ์
- ๋ฐฑ์๋๊ฐ๋ฐ
- Python
- ์น๊ฐ๋ฐ
- ์ฟ ๋ฒ๋คํฐ์ค
- PostgreSQL
- SpringBoot
- seo ์ต์ ํ 10๊ฐ
- flax
- nextJS
- openai
- NestJS
- SEO์ต์ ํ
- JWT
- DevOps
- nodejs
- JAX
- Next.js
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- llm
- Prisma
- node.js
- rag
- kotlin
- CI/CD
- REACT
- fastapi
- Express
- LangChain
| ์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |

