인공지능

강화학습 기반 자동 매매 - OpenAI Gym, PPO, DQN

aiproductmanager 2025. 6. 7. 09:22
728x90
반응형
강화학습 기반 자동 매매 - OpenAI Gym, PPO, DQN
 


**“강화학습 기반 자동 매매 - OpenAI Gym, PPO, DQN”**은 AI가 스스로 매매 전략을 학습하여 자동으로 투자 결정을 내리는 방식입니다. 아래에서 개념, 알고리즘, 실제 구현, 장단점을 깊이 있게 설명드리겠습니다.


🧠 1. 강화학습이란?

요소 설명
Agent 투자 결정(매수/매도)을 내리는 인공지능
Environment 주가 변동이 일어나는 시장 시뮬레이션
Action 매수(Buy), 매도(Sell), 보유(Hold)
State 현재 포트폴리오 상태 + 시장 정보
Reward 수익(이익일수록 높음)
 

에이전트는 시뮬레이션을 통해 **“보상을 최대화하는 행동 방식”**을 스스로 찾아나갑니다.


🔁 2. 사용 알고리즘

알고리즘 설명 특징
DQN
(Deep Q-Network)
Q-learning 기반의 딥러닝 모델 discrete action (매수/매도/보유)
PPO
(Proximal Policy Optimization)
안정성과 수렴 속도가 좋은 최신 정책 기반 알고리즘 continuous action 가능
A2C / A3C Actor-Critic 방식 병렬 환경 학습에 유리
 

✅ PPO는 현재 OpenAI에서도 널리 쓰이며 로보틱스, 게임, 금융 등에 활용됩니다.


🧰 3. 구현 환경 도구

도구 설명
OpenAI Gym 투자 시뮬레이션을 위한 환경 생성 도구
Stable-Baselines3 PPO, DQN 등 강화학습 알고리즘 패키지
FinRL 금융 데이터에 특화된 Gym + 강화학습 도구
yfinance / pandas 실시간 주가 데이터 불러오기
TensorBoard 학습 로그 시각화
 

📊 4. 실제 매매 환경 정의 예

import gym
from gym import spaces
import numpy as np

class StockTradingEnv(gym.Env):
    def __init__(self, df):
        super().__init__()
        self.df = df
        self.action_space = spaces.Discrete(3)  # 매수, 매도, 보유
        self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(10,), dtype=np.float32)

    def reset(self):
        self.balance = 10000
        self.position = 0
        self.current_step = 0
        return self._get_obs()

    def _get_obs(self):
        return np.array(self.df.iloc[self.current_step].values, dtype=np.float32)

    def step(self, action):
        # 간단한 매매 로직 정의 (보상은 수익률)
        reward = ...
        self.current_step += 1
        done = self.current_step >= len(self.df) - 1
        return self._get_obs(), reward, done, {}

🤖 5. 강화학습 모델 학습 (PPO)

from stable_baselines3 import PPO

env = StockTradingEnv(df)
model = PPO('MlpPolicy', env, verbose=1)
model.learn(total_timesteps=100_000)
  • total_timesteps: 학습 회수 (10만 ~ 50만 권장)
  • 학습 후 model.save()로 저장 가능

📈 6. 수익률 평가 및 시각화

학습한 모델을 바탕으로:

  • 백테스트 (과거 데이터를 기반으로 수익률 추정)
  • 실시간 데이터 매핑
  • 포트폴리오 누적 수익률 그래프
  • Drawdown, Sharpe Ratio, MDD 등 통계 지표 분석

까지 가능하며, 원하시면 Streamlit 기반 대시보드로도 구현해 드릴 수 있습니다.


🧪 7. 장단점

항목 장점 단점
DQN 구조가 단순, discrete에 적합 안정성 낮음
PPO 안정적 학습, 연속 액션 가능 튜닝 필요
A2C 빠른 수렴 속도 병렬처리 구현 필요
전체 강화학습 비지도 방식으로 새로운 전략 발견 가능 과적합, 학습시간 길다
 

📂 8. 예제 코드 요청 가능 항목

  • PPO 기반 실전 주가 자동매매 코드
  • DQN 기반 간단 환경 자동매매 코드
  • FinRL 패키지 통합 환경 설정
  • 코인 / ETF / KOSPI 대상 적용 예제
  • Streamlit 시각화 + 실시간 알림 연동

원하시면 ✅ 직접 실행 가능한 전체 코드도 제공해드릴 수 있습니다.

 

어떤 알고리즘(PPO, DQN)이나 환경(코인/ETF/KOSPI)을 기준으로 시작해볼까요?

 

# PPO 기반 ETF 자동매매 강화학습 예제 (직접 실행 가능)

## 패키지 설치
```bash
pip install yfinance stable-baselines3 gym pandas numpy matplotlib
```

## Step 1: ETF 데이터 수집
```python
import yfinance as yf
import pandas as pd

etf = 'SPY'  # S&P 500 ETF
df = yf.download(etf, start='2018-01-01', end='2023-12-31')
df['Return'] = df['Close'].pct_change().fillna(0)
df.reset_index(drop=True, inplace=True)
```

## Step 2: Gym 환경 정의
```python
import gym
from gym import spaces
import numpy as np

class ETFTradingEnv(gym.Env):
    def __init__(self, df):
        super(ETFTradingEnv, self).__init__()
        self.df = df
        self.max_steps = len(df) - 1
        self.action_space = spaces.Discrete(3)  # 0: 매도, 1: 보유, 2: 매수
        self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(5,), dtype=np.float32)

    def reset(self):
        self.balance = 10000
        self.shares = 0
        self.step_idx = 0
        self.net_worth = self.balance
        return self._get_obs()

    def _get_obs(self):
        row = self.df.iloc[self.step_idx]
        return np.array([self.balance, self.shares, row['Close'], row['Return'], self.net_worth], dtype=np.float32)

    def step(self, action):
        row = self.df.iloc[self.step_idx]
        price = row['Close']

        # 액션 처리
        if action == 2 and self.balance >= price:
            self.shares += 1
            self.balance -= price
        elif action == 0 and self.shares > 0:
            self.shares -= 1
            self.balance += price

        self.step_idx += 1
        done = self.step_idx >= self.max_steps
        self.net_worth = self.balance + self.shares * self.df.iloc[self.step_idx]['Close']
        reward = self.net_worth - 10000  # 총 자산 변화량 기준

        return self._get_obs(), reward, done, {}
```

## Step 3: PPO 모델 학습
```python
from stable_baselines3 import PPO

env = ETFTradingEnv(df)
model = PPO("MlpPolicy", env, verbose=1)
model.learn(total_timesteps=50_000)
```

## Step 4: 테스트 및 결과 시각화
```python
obs = env.reset()
history = []

for _ in range(env.max_steps):
    action, _ = model.predict(obs)
    obs, reward, done, _ = env.step(action)
    history.append(env.net_worth)
    if done:
        break

import matplotlib.pyplot as plt
plt.plot(history)
plt.title("PPO ETF 자동매매 - 자산 변화")
plt.xlabel("일 수")
plt.ylabel("총 자산 ($)")
plt.grid(True)
plt.show()
```

---

✅ 이 코드는 S&P500 ETF(SPY)에 대해 강화학습 기반 매매를 수행하고,
강화학습(PPO)을 통해 점점 더 수익을 내도록 학습시킬 수 있습니다.

원하시면 Streamlit UI 추가, Slack/Telegram 알림 연동, 다중 ETF 확장도 구현해 드릴 수 있습니다.

 

 

# PPO 기반 ETF 자동매매 + Streamlit 시각화 확장 버전

## 📦 패키지 설치
```bash
pip install yfinance stable-baselines3 gym pandas numpy matplotlib streamlit
```

## 🧠 강화학습 기반 ETF 트레이딩 (SPY)
```python
import yfinance as yf
import pandas as pd
import numpy as np
import gym
from gym import spaces
from stable_baselines3 import PPO
import matplotlib.pyplot as plt

class ETFTradingEnv(gym.Env):
    def __init__(self, df):
        super(ETFTradingEnv, self).__init__()
        self.df = df.reset_index(drop=True)
        self.max_steps = len(df) - 1
        self.action_space = spaces.Discrete(3)  # 매도, 보유, 매수
        self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(5,), dtype=np.float32)

    def reset(self):
        self.balance = 10000
        self.shares = 0
        self.step_idx = 0
        self.net_worth = self.balance
        return self._get_obs()

    def _get_obs(self):
        row = self.df.iloc[self.step_idx]
        return np.array([self.balance, self.shares, row['Close'], row['Return'], self.net_worth], dtype=np.float32)

    def step(self, action):
        row = self.df.iloc[self.step_idx]
        price = row['Close']

        if action == 2 and self.balance >= price:
            self.shares += 1
            self.balance -= price
        elif action == 0 and self.shares > 0:
            self.shares -= 1
            self.balance += price

        self.step_idx += 1
        done = self.step_idx >= self.max_steps
        self.net_worth = self.balance + self.shares * self.df.iloc[self.step_idx]['Close']
        reward = self.net_worth - 10000
        return self._get_obs(), reward, done, {}

# ETF 데이터 수집
etf = 'SPY'
df = yf.download(etf, start='2019-01-01', end='2023-12-31')
df['Return'] = df['Close'].pct_change().fillna(0)

# 학습
env = ETFTradingEnv(df)
model = PPO("MlpPolicy", env, verbose=0)
model.learn(total_timesteps=100_000)

# 테스트
obs = env.reset()
history = []
for _ in range(env.max_steps):
    action, _ = model.predict(obs)
    obs, reward, done, _ = env.step(action)
    history.append(env.net_worth)
    if done:
        break
```

## 📊 Streamlit UI
```python
import streamlit as st

st.title("💹 PPO 기반 ETF 자동매매")
st.write("ETF: S&P 500 (SPY) 기준 자동 강화학습 트레이딩 예시")

st.line_chart(history)
st.metric("최종 총 자산", f"${history[-1]:,.2f}")
st.metric("수익률", f"{(history[-1] / 10000 - 1)*100:.2f}%")
```

## ▶ 실행 방법
```bash
streamlit run 파일이름.py
```

---

✅ 학습부터 백테스트, 시각화까지 포함된 **강화학습 기반 ETF 자동매매 시스템**입니다.

다음으로 추가해드릴 수 있는 기능은:
- [ ] Telegram/Slack 실시간 알림
- [ ] 다중 ETF 포트폴리오 학습
- [ ] 실시간 데이터 기반 리밸런싱
- [ ] AI 자동보고서 PDF 생성

필요하신 기능을 말씀해 주세요!

 

 

# PPO 기반 ETF 자동매매 + Streamlit + Telegram 실시간 알림 통합

## 📦 패키지 설치
```bash
pip install yfinance stable-baselines3 gym pandas numpy matplotlib streamlit python-telegram-bot==13.15
```

## 🔑 Telegram Bot Token & Chat ID 준비
1. @BotFather로 새 봇 생성 → Token 복사
2. @userinfobot 으로 Chat ID 확인

## ✏️ Telegram 알림 함수
```python
from telegram import Bot

def send_telegram_alert(message):
    token = "<TELEGRAM_BOT_TOKEN>"
    chat_id = "<YOUR_CHAT_ID>"
    bot = Bot(token=token)
    bot.send_message(chat_id=chat_id, text=message)
```

## 🧠 PPO + ETF 학습 및 알림 통합
```python
import yfinance as yf
import pandas as pd
import numpy as np
import gym
from gym import spaces
from stable_baselines3 import PPO
import matplotlib.pyplot as plt
from telegram import Bot

class ETFTradingEnv(gym.Env):
    def __init__(self, df):
        super(ETFTradingEnv, self).__init__()
        self.df = df.reset_index(drop=True)
        self.max_steps = len(df) - 1
        self.action_space = spaces.Discrete(3)
        self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(5,), dtype=np.float32)

    def reset(self):
        self.balance = 10000
        self.shares = 0
        self.step_idx = 0
        self.net_worth = self.balance
        return self._get_obs()

    def _get_obs(self):
        row = self.df.iloc[self.step_idx]
        return np.array([self.balance, self.shares, row['Close'], row['Return'], self.net_worth], dtype=np.float32)

    def step(self, action):
        row = self.df.iloc[self.step_idx]
        price = row['Close']
        if action == 2 and self.balance >= price:
            self.shares += 1
            self.balance -= price
        elif action == 0 and self.shares > 0:
            self.shares -= 1
            self.balance += price

        self.step_idx += 1
        done = self.step_idx >= self.max_steps
        self.net_worth = self.balance + self.shares * self.df.iloc[self.step_idx]['Close']
        reward = self.net_worth - 10000
        return self._get_obs(), reward, done, {}

# ETF 데이터 수집 및 학습
etf = 'SPY'
df = yf.download(etf, start='2019-01-01', end='2023-12-31')
df['Return'] = df['Close'].pct_change().fillna(0)

env = ETFTradingEnv(df)
model = PPO("MlpPolicy", env, verbose=0)
model.learn(total_timesteps=100_000)

# 테스트 및 알림
obs = env.reset()
history = []
for _ in range(env.max_steps):
    action, _ = model.predict(obs)
    obs, reward, done, _ = env.step(action)
    history.append(env.net_worth)
    if done:
        break

final_value = history[-1]
return_pct = (final_value / 10000 - 1) * 100
send_telegram_alert(f"[ETF 자동매매 알림]\n최종 자산: ${final_value:,.2f}\n수익률: {return_pct:.2f}%")
```

## ✅ Streamlit 시각화
```python
import streamlit as st

st.title("💹 PPO ETF 자동매매 + Telegram 알림")
st.line_chart(history)
st.metric("최종 총 자산", f"${history[-1]:,.2f}")
st.metric("수익률", f"{(history[-1] / 10000 - 1)*100:.2f}%")
```

---

📬 이제 학습 완료 시 **Telegram으로 실시간 수익률 알림**이 전송됩니다.


원하시면 Slack 알림, Webhook 통합, 실시간 트레이딩 서버에도 확장 가능합니다.

 

✅ Telegram 실시간 수익률 알림 기능이 통합되었습니다.
모델 학습 후 자동으로 수익률을 Telegram으로 전송합니다.

📌 다음 확장도 가능합니다:

  • 🧵 Slack 메시지 연동 (Webhook 기반)
  • 📡 실시간 리밸런싱 서버 구성
  • 📊 다중 ETF 포트폴리오 확장
  • 📝 자동 리포트 PDF 이메일 발송

원하시는 항목을 알려주세요.

 

순위 AI 투자 방안 이름 활용 기술 상세 바로가기
1 AI 퀀트 포트폴리오 최적화 Markowitz, RL, MPT, AI 최적화 바로가기
2 감정 분석 기반 뉴스 트레이딩 NLP, BERT, LLM 바로가기
3 AI ETF 자동 리밸런싱 AutoML, Alpha Vantage API 바로가기
4 머신러닝 기반 주가 예측 XGBoost, LightGBM 바로가기
5 딥러닝 LSTM 시계열 예측 TensorFlow, PyTorch LSTM 바로가기
6 강화학습 기반 자동 매매 OpenAI Gym, PPO, DQN 바로가기
7 AI 기반 가치주 선별 (Value Factor) AI 팩터스코어링, 계량모델 바로가기
8 GPT 기반 재무제표 요약 투자 GPT-4, LangChain, OCR 바로가기
9 AI 리스크 해지 전략 (VIX, 금리, 환율) AI 헷지백테스트, 시나리오 모델 바로가기
10 SVM 기반 종목 필터링 SVM + 재무데이터 바로가기
11 AI IPO 스코어링 모델 AI 점수화 + IPO 성과예측 바로가기
12 챗봇 기반 투자 자문 시스템 LLM + Chat UI + API 연결 바로가기
13 XGBoost 기반 이벤트 드리븐 트레이딩 XGBoost + 뉴스 이벤트 바로가기
14 AutoML 기반 알고리즘 전략 탐색 TPOT, H2O.ai, FeatureTools 바로가기
15 AI 기반 ESG 점수 분석 투자 AI ESG 분석 + ETF 필터링 바로가기
16 옵션 가격 예측 딥러닝 모델 DNN, OptionNet, VolNet 바로가기
17 고빈도 트레이딩용 AI 패턴 인식 CNN, 딥러닝 패턴 분석 바로가기
18 AI 기반 섹터 로테이션 모델 순환분류 + 군집분석 바로가기
19 LLM 기반 글로벌 투자 리서치 요약 GPT + PDF 요약 + 질의응답 바로가기
20 AI + Satellite Data 기반 농산물 투자 AI + 위성데이터 + 시계열학습 바로가기

 

이 글이 도움이 되셨다면
🔔 구독❤️ 좋아요  꾸우욱 눌러 주세요!🙏

그리고 💖커피 ☕, 💚차 🍵, 💛맥주 🍺, ❤️와인 🍷  중 마음에 드시는 한 잔으로 💰 후원해 주시면 큰 힘이 됩니다.

                                                                             👇 지금 바로 아래 🔘버튼을 꾸욱 눌러 📣 응원해 주세요! 👇  

728x90
반응형