ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

๐Ÿง  AI ํŒฉํ„ฐ ์˜ˆ์ธก ๋ชจ๋ธ ๊ตฌ์ถ• – Transformer๋กœ ๋‹ค์Œ ๋ถ„๊ธฐ ์ˆ˜์ต๋ฅ  ์˜ˆ์ธกํ•˜๊ธฐ

์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ํ€€ํŠธ ์‹œ์Šคํ…œ์€ ๋ฐ์ดํ„ฐ๋ฅผ “ํ™œ์šฉ”ํ•˜๋Š” ์ˆ˜์ค€์ด์—ˆ์ฃ .
ํ•˜์ง€๋งŒ ์ง„์งœ ํ€€ํŠธ์˜ ํž˜์€ ๋ฐ์ดํ„ฐ๋ฅผ **“์˜ˆ์ธก”**ํ•˜๋Š” ๋ฐ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ตœ์‹  ๋”ฅ๋Ÿฌ๋‹ ๋ชจ๋ธ์ธ Transformer๋ฅผ ์ด์šฉํ•ด
๋‹ค์Œ ๋ถ„๊ธฐ์˜ ํŒฉํ„ฐ ์ˆ˜์ต๋ฅ ์„ ์˜ˆ์ธกํ•˜๋Š” AI ๋ชจ๋ธ์„ ์ง์ ‘ ๋งŒ๋“ค์–ด๋ด…๋‹ˆ๋‹ค.


๐ŸŽฏ ๋ชฉํ‘œ

  • yfinance๋กœ ํŒฉํ„ฐ ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘
  • Transformer Encoder ๊ธฐ๋ฐ˜ ์˜ˆ์ธก ๋ชจ๋ธ ๊ตฌ์„ฑ
  • ๊ณผ๊ฑฐ ํŒฉํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ → ๋ฏธ๋ž˜ 1๊ฐœ์›” ์ˆ˜์ต๋ฅ  ์˜ˆ์ธก
  • ํ•™์Šต ํ›„ MSE, MAE, R² ๋“ฑ ์ง€ํ‘œ ํ‰๊ฐ€

๐Ÿงฑ 1๏ธโƒฃ ๋ฐ์ดํ„ฐ ์ค€๋น„

์šฐ์„  ๊ฐ ํŒฉํ„ฐ(๋ชจ๋ฉ˜ํ…€, ๊ฐ€์น˜, ํ€„๋ฆฌํ‹ฐ, ์ €๋ณ€๋™์„ฑ ๋“ฑ)์— ๋Œ€ํ•ด
๊ณผ๊ฑฐ 3๋…„๊ฐ„์˜ ์›”๋ณ„ ์ˆ˜์ต๋ฅ  ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

import yfinance as yf
import pandas as pd

tickers = ["005930.KS", "000660.KS", "035420.KS", "068270.KQ"]
df_list = []

for t in tickers:
    data = yf.download(t, period="3y", interval="1mo")
    data["ticker"] = t
    data["return"] = data["Close"].pct_change()
    df_list.append(data)

df = pd.concat(df_list)
df = df.dropna()
df.to_csv("factor_returns.csv", index=False)
print(df.head())

๐Ÿ’ก ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์›”๋ณ„ ์ข…๋ชฉ ์ˆ˜์ต๋ฅ ์ด ๊ณ„์‚ฐ๋˜์–ด “ํŒฉํ„ฐ ์‹œ๊ณ„์—ด ์ž…๋ ฅ”์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿงฉ 2๏ธโƒฃ Transformer ๋ชจ๋ธ ๊ฐœ๋…

๋ฐ˜์‘ํ˜•

Transformer๋Š” ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐ ๋งค์šฐ ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ์กด LSTM๊ณผ ๋‹ฌ๋ฆฌ ๋ณ‘๋ ฌ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๊ณ ,
“Self-Attention”์œผ๋กœ ์–ด๋–ค ์‹œ์ ์ด ์ค‘์š”ํ•œ์ง€ ์Šค์Šค๋กœ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค.

์ž…๋ ฅ: ๊ณผ๊ฑฐ 12๊ฐœ์›” ํŒฉํ„ฐ ์ˆ˜์ต๋ฅ  → ์ถœ๋ ฅ: ๋‹ค์Œ 1๊ฐœ์›” ์˜ˆ์ธก

โš™๏ธ 3๏ธโƒฃ ๋ชจ๋ธ ๊ตฌํ˜„ (PyTorch)

import torch
import torch.nn as nn
import numpy as np

class FactorTransformer(nn.Module):
    def __init__(self, input_dim=4, hidden_dim=64, n_heads=4, n_layers=2, dropout=0.1):
        super().__init__()
        self.encoder_layer = nn.TransformerEncoderLayer(
            d_model=hidden_dim, nhead=n_heads, dropout=dropout
        )
        self.transformer = nn.TransformerEncoder(self.encoder_layer, num_layers=n_layers)
        self.input_fc = nn.Linear(input_dim, hidden_dim)
        self.output_fc = nn.Linear(hidden_dim, 1)

    def forward(self, x):
        x = self.input_fc(x)
        x = self.transformer(x)
        x = x.mean(dim=1)
        out = self.output_fc(x)
        return out

๐Ÿงฎ 4๏ธโƒฃ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ

12๊ฐœ์›” ๋‹จ์œ„ ์œˆ๋„์šฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜๋ˆ„์–ด ์ž…๋ ฅ(X), ์˜ˆ์ธก(y)์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

import torch
from sklearn.preprocessing import StandardScaler

df = pd.read_csv("factor_returns.csv")
pivot = df.pivot_table(index="Date", columns="ticker", values="return").fillna(0)

scaler = StandardScaler()
X_data = []
y_data = []
window = 12

values = scaler.fit_transform(pivot.values)
for i in range(len(values) - window):
    X_data.append(values[i:i+window])
    y_data.append(values[i+window])

X = torch.tensor(np.array(X_data), dtype=torch.float32)
y = torch.tensor(np.array(y_data), dtype=torch.float32)

๐Ÿง  5๏ธโƒฃ ํ•™์Šต ๋ฃจํ”„

model = FactorTransformer(input_dim=X.shape[2])
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.MSELoss()

for epoch in range(100):
    model.train()
    optimizer.zero_grad()
    pred = model(X)
    loss = criterion(pred, y.mean(dim=1, keepdim=True))
    loss.backward()
    optimizer.step()
    if epoch % 10 == 0:
        print(f"Epoch {epoch}, Loss: {loss.item():.6f}")

๐Ÿ“ˆ 6๏ธโƒฃ ์˜ˆ์ธก ๊ฒฐ๊ณผ ํ™•์ธ

model.eval()
preds = model(X).detach().numpy().flatten()
actual = y.mean(dim=1).numpy().flatten()

import matplotlib.pyplot as plt
plt.figure(figsize=(10,5))
plt.plot(preds, label="Predicted Return")
plt.plot(actual, label="Actual Return")
plt.legend()
plt.title("Next-Month Return Prediction (Transformer)")
plt.show()

Transformer ๋ชจ๋ธ์ด ํ•™์Šตํ•˜๋ฉด์„œ “์‹œ์žฅ ํŒจํ„ด”์„ ์ ์ฐจ ๋”ฐ๋ผ๊ฐ€๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด
์˜ˆ์ธก๊ณก์„ ์ด ์‹ค์ œ ์ˆ˜์ต๋ฅ ์˜ ๋ณ€๋™ ํ๋ฆ„์„ ์ ์  ๋‹ฎ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


๐Ÿงฎ 7๏ธโƒฃ ํ‰๊ฐ€ ์ง€ํ‘œ

from sklearn.metrics import mean_squared_error, r2_score

print("MSE:", mean_squared_error(actual, preds))
print("R²:", r2_score(actual, preds))

๐Ÿ’ก MSE๊ฐ€ ๋‚ฎ๊ณ  R²๊ฐ€ 0.7 ์ด์ƒ์ด๋ฉด ๊ฝค ์•ˆ์ •์ ์œผ๋กœ ํŒจํ„ด์„ ์žก๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


โšก 8๏ธโƒฃ Flask + Streamlit ์—ฐ๋™

๋ชจ๋ธ ์˜ˆ์ธก์„ API๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

# Flask API snippet
@app.route("/predict_next")
def predict_next():
    pred = model(X[-1:].to(torch.float32)).item()
    return jsonify({"next_month_expected_return": float(pred)})

Streamlit์—์„œ๋Š” ์ด API๋ฅผ ํ˜ธ์ถœํ•ด
๐Ÿ“Š “์˜ˆ์ƒ ์ˆ˜์ต๋ฅ ” ์˜์—ญ์— ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

pred = requests.get(f"{API_URL}/predict_next").json()
st.metric("๐Ÿ“ˆ Next Month Predicted Return", f"{pred['next_month_expected_return']:.2%}")

๐Ÿง  9๏ธโƒฃ ๋ชจ๋ธ ๊ฐœ์„  ์•„์ด๋””์–ด

๊ฐœ์„  ๋ฐฉํ–ฅ ์„ค๋ช…

๐Ÿงฉ Multi-Factor Input ๋ชจ๋ฉ˜ํ…€, ๋ฐธ๋ฅ˜, ํ€„๋ฆฌํ‹ฐ, ๋ณ€๋™์„ฑ ๊ฐ๊ฐ์„ Feature๋กœ ์ถ”๊ฐ€
๐Ÿงฎ Multi-Step Forecast 1๊ฐœ์›” → 3๊ฐœ์›” Ahead ์˜ˆ์ธก
๐Ÿง  Transfer Learning ๊ธ€๋กœ๋ฒŒ ETF/์ธ๋ฑ์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์ „ํ•™์Šต ํ›„ Fine-tune
๐Ÿงพ Model Ensemble Transformer + LSTM + XGBoost ๊ฒฐํ•ฉ
โ˜๏ธ ๋ฐฐํฌ TorchScript or ONNX๋กœ ๋ณ€ํ™˜ → Flask ์„œ๋ฒ„์— ํƒ‘์žฌ

๐Ÿ“Œ ์ •๋ฆฌ

๋‹จ๊ณ„ ๋‚ด์šฉ

1 yfinance๋กœ ํŒฉํ„ฐ ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
2 Transformer ๋ชจ๋ธ ์ •์˜
3 ์ž…๋ ฅ/์ถœ๋ ฅ ์œˆ๋„์šฐ ๊ตฌ์„ฑ
4 ํ•™์Šต ๋ฐ ์‹œ๊ฐํ™”
5 Flask + Streamlit ํ†ตํ•ฉ
6 ์˜ˆ์ธก๊ฐ’ ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง ๊ฐ€๋Šฅ

์ด์ œ ํ€€ํŠธ ์‹œ์Šคํ…œ์€ ๋‹จ์ˆœํžˆ ๊ณผ๊ฑฐ๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ,
๋‹ค์Œ ๋‹ฌ ์‹œ์žฅ์˜ ํ๋ฆ„์„ ๋ฏธ๋ฆฌ ์˜ˆ์ธกํ•ด ์›€์ง์ด๋Š” ์ˆ˜์ค€์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“˜ ๋‹ค์Œ ๊ธ€ ์˜ˆ๊ณ 

๋‹ค์Œ ํŽธ์—์„œ๋Š” **“Transformer + Reinforcement Learning์„ ๊ฒฐํ•ฉํ•œ ๋™์  ํฌํŠธํด๋ฆฌ์˜ค ์กฐ์ • ์‹œ์Šคํ…œ”**์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.
์ฆ‰, AI๊ฐ€ ์Šค์Šค๋กœ ํ•™์Šตํ•ด ํฌํŠธํด๋ฆฌ์˜ค ๋น„์ค‘์„ ๋งค์›” ์žฌ๊ตฌ์„ฑํ•˜๋Š” “์ž์œจ ์šด์šฉํ˜• ํ€€ํŠธ ๋งค๋‹ˆ์ €”๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.


 

Transformer,๋”ฅ๋Ÿฌ๋‹ํ€€ํŠธ,AIํˆฌ์ž๋ชจ๋ธ,ํŒŒ์ดํ† ์น˜,์‹œ๊ณ„์—ด์˜ˆ์ธก,ํ€€ํŠธAI,ํŒฉํ„ฐ์˜ˆ์ธก,๋ฐ์ดํ„ฐํˆฌ์ž,ํŒŒ์ด์ฌ๋”ฅ๋Ÿฌ๋‹,ํฌํŠธํด๋ฆฌ์˜ค์˜ˆ์ธก


 

โ€ป ์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค.
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2026/02   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
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
๊ธ€ ๋ณด๊ด€ํ•จ
๋ฐ˜์‘ํ˜•