RLTrader의 설계
2020-03-29 • rltrader • stock, 주식, reinforcement learning, 강화학습, design, 설계 • 4 min read
RLTrader는 여러 파이썬 모듈로 구성돼 있습니다. 주식투자 강화학습에서 필요한 참여 요소와 역할을 분석해 모듈로 묶었습니다. 모듈마다 나름의 역할을 담당하며 다른 모듈과 서로 연관 관계(association)가 있기도 합니다.
모듈 구조
RLTrader에는 다음과 같이 강화학습 요소가 모듈로 구성돼 있으며, 그밖에 추가 모듈이 몇 개 더 있습니다.
RLTrader의 주요 모듈
하나의 상자는 하나의 파이썬 모듈로 구현됩니다. 실선으로 연결된 두 모듈 간에는 연관 관계가 있습니다. 여기서 몸통이 되는 모듈은 정책 학습기 모듈로, 강화학습의 참여 요소인 환경, 에이전트, 신경망과 연관 관계를 맺습니다. 또한 학습 과정 기록을 위한 가시화 모듈 또한 사용합니다.
파이썬 팁: 파이썬 프로그램은 패키지(package), 모듈(module), 클래스(class), 함수(function)로 구성됩니다. 이것들은 모두 데이터(상수 및 변수)와 기능을 묶는 것입니다. 함수에서 클래스로, 클래스에서 모듈로, 모듈에서 패키지로 그 묶음의 크기가 커집니다. 패키지는 여러 모듈을, 모듈은 여러 클래스를, 클래스는 여러 함수를 가질 수 있습니다. 함수는 메서드(method)라고도 부릅니다.
디렉터리 구조
이 모듈들은 각각이 파이썬 파일로 작성되는데, RLTrader에서는 하나의 모듈이 하나의 클래스를 가지도록 했습니다. 프로젝트의 디렉터리 구조는 다음과 같습니다.
- data/
- models/
- output/
- agent.py
- data_manager.py
- environment.py
- learners.py
- main.py
- networks.py
- settings.py
- utils.py
- visualizer.py
RLTrader의 프로젝트 최상위 폴더인 rltrader 내에 주요 파이썬 모듈인 agent.py, data_manager.py, environment.py, learners.py, main.py, networks.py, visualizer.py와 입력 데이터와 출력물 파일을 담기 위한 data, output 폴더가 있습니다.
data 폴더에는 차트 데이터와 학습 데이터를 저장합니다. output 폴더에는 강화학습 과정을 텍스트로 기록한 로그와 그 하위의 epoch_summary 폴더에 에포크마다 발생하는 가시화 결과를 저장합니다. 또한 data 폴더에 학습을 완료한 가치 신경망 및 정책 신경망 모델을 저장합니다.
클래스 다이어그램
위에서 소개한 주요 모듈에는 여러 클래스가 포함돼 있습니다. 그림 5.3는 RLTrader의 주요 클래스들의 관계를 보여줍니다.
learners와 networks 모듈의 클래스 다이어그램
learners 모듈의 기본 클래스인 ReinforcementLearner 클래스는 networks 모듈의 기본 클래스인 Network 클래스를 가치 신경망과 정책 신경망 학습을 위해 활용합니다.
환경 모듈 개요
환경 모듈(environment.py)에는 환경 클래스(Environment)가 있습니다. 환경 클래스는 에이전트가 투자할 종목의 차트 데이터를 관리합니다. 에이전트가 과거로 돌아가서 투자하며 그 결과에 따라 학습하려는 것이 목적이므로 환경 클래스에 전체 차트 데이터가 있지만, 과거 시점부터 가장 최근 시점까지 순차적으로 데이터를 제공합니다. 즉, 과거로 돌아간 에이전트가 미래의 차트 데이터는 알 수 없습니다.
에이전트 모듈 개요
에이전트 모듈(agent.py)에는 에이전트 클래스(Agent)가 있습니다. 에이전트 클래스는 주식을 매수하거나 매도하는 투자자 역할을 하며 초기 자본금, 현금 잔고, 주식 잔고라는 상태가 있습니다. 현금 잔고와 주식 잔고의 평가액을 합하면 포트폴리오 가치(portfolio value)가 됩니다. 이를 PV라고 줄여 부르겠습니다. 포트폴리오는 여러 주식, 채권, 펀드, 현금 등의 금융 자산을 통틀어서 가치를 평가하는 것이지만 이 책은 주식투자 강화학습을 다루므로 여기서는 주식만 고려합니다.
PV = 주식 잔고×현재 주가+현금 잔고
PV가 초기 자본금보다 높으면 수익이 발생한 것이고 낮으면 손실이 발생한 것입니다. 즉, 투자의 목표는 PV를 높여 나가는 것입니다.
에이전트가 매수를 하면 주식 잔고는 늘어나고 현금 잔고는 줄어들 것입니다. 반대로 에이전트가 매도를 하면 주식 잔고는 줄어들고 현금 잔고는 늘어납니다.
강화학습 학습기 모듈 개요
강화학습 학습기 모듈(learners.py)은 여러 강화학습 방법을 구현한 클래스들을 포함하고 있습니다. DQNLearner, PolicyGradientLearner, ActorCriticLearner, A2CLearner, A3CLearner는 각각 Deep Q-learning, Policy Gradient, Actor-critic, A2C, A3C 강화학습 기법을 기반으로 한 클래스 구현체들입니다. 주식투자의 특성에 의해 각 기법은 이론에서 약간의 변형이 있을 수 있습니다.
신경망 모듈개요
신경망 모듈(networks.py)에는 다양한 신경망 클래스들이 있습니다. 완전 연결 심층 신경망, LSTM, CNN 신경망이 DNN, LSTMNetwork, CNN 클래스에 각각 적용됩니다.
신경망 클래스는 특정 시점의 주식 데이터(Sample)가 제공됐을 때 매수할지, 또는 매도할지를 결정하는 에이전트의 뇌와 같은 역할을 합니다. 신경망 종류에 따라 데이터 학습 방법이 달라지므로 매수와 매도 행위 결정은 달라질 수 있습니다. 신경망의 학습 목표는 직관적으로 봤을 때 매수와 매도 행위에 대해서 향후 PV를 최대한 높이는 것입니다.
주식을 매수하면 현금 잔고는 줄어들고 주식 잔고는 늘어납니다. 주식 잔고가 많은 상태에서 주가가 상승하면 PV는 크게 높아질 것입니다. 반면에 주가가 하락하면 PV는 크게 줄어들 수 있습니다. 그래서 주가가 상승할 것으로 생각되면 주식 잔고를 늘리고 하락할 것으로 예상되면 주식 잔고를 줄여서 리스크를 관리하는 것입니다.
RLTrader는 가치 신경망과 정책 신경망을 가질 수 있습니다. 가치 신경망이나 정책 신경망을 통해 주식 잔고를 늘릴지 줄일지를 결정합니다. 주식 데이터를 가치 신경망에 넣으면 매수나 매도를 했을 때 향후 획득할 수 있는 수익률을, 정책 신경망에 넣으면 매수와 매도에 대한 확률을 예측합니다. 매수가 매도보다 가치나 확률이 높으면 매수를, 그 반대의 경우에는 매도하는 것입니다.
가시화 모듈개요
가시화 모듈(visualizer.py)은 주식 데이터 학습 과정을 직관적으로 파악하기 위해 환경, 에이전트 상태, 가치 신경망 출력, 정책 신경망 출력, PV 등을 그림 파일로 가시화해 줍니다. 가시화 결과를 순서대로 보면 에포크가 진행됨에 따라 신경망 출력이 포트폴리오 가치를 높이는 방향으로 변하고 그에 따라 포트폴리오 가치가 높아져 가는 것을 확인할 수 있습니다.
충분한 에포크가 지났음에도 포트폴리오 가치가 높아지지 않는다면 학습이 제대로 이루어지지 않는다고 파악하고 학습 데이터 모델링을 다시 하거나 알고리즘을 개선할 것인지 고려해야 합니다.
학습기 모듈 개요
학습기 모듈(learners.py)에는 주요 강화학습 기법을 적용한 학습기 클래스들이 있습니다. 이 모듈에는 ReinforcementLearner 클래스를 상속한 DQNLearner, PolicyGradientLearner, ActorCriticLearner, A2CLearner, A3CLearner가 포함돼 있습니다. 학습기 클래스는 앞서 소개한 에이전트, 환경, 정책 신경망을 가지고 강화학습을 수행하는 RLTrader의 몸체라고 할 수 있습니다. 학습기는 학습 데이터를 가지고 있고 보상이 결정됐을 때 학습 데이터로 신경망을 학습시킵니다.
실행 모듈 개요
실행 모듈(main.py)은 여러 옵션을 가지고 주식투자 강화학습을 실행하는 모듈입니다. 종목 코드, 강화학습 기법, 신경망 종류, 학습 속도, 할인율, 탐험률, 초기 자본금, 에포크 수 등을 정해 강화학습을 실행할 수 있습니다.
기타 모듈
위에서 소개한 주요 모듈 외에 설정이나 공통 기능 등을 모아놓은 작은 모듈도 있습니다.
settings.py
프로젝트의 기본 경로, 로케일 등을 설정하는 작은 모듈입니다.
utils.py
오늘 날짜, 현재 시간을 문자열로 받기 위한 함수들과 시그모이드 함수 등을 구현해 놓은 모듈입니다. 여러 모듈에서 사용될 수 있는 다양하고 잡다한 기능을 구현해 놓을 수 있습니다.