머신러닝을 이용한 주식 예측(5) (강화학습)

다양한 방식을 직접해보고 싶어서 이번에는 Reinforcement, 즉 강화학습을 이용해보고 싶었다.

이론

강화학습이 기존의 다루었던 LSTM과 다른점은, 스스로 최상의 보상을 찾는 다는 것이다.

예를들어 LSTM에서는 Close(종가)값을 맞추기 위해 학습한다면,

강화학습의 경우에는 수 많은 행동(주식에서는 매수,매매,홀딩)을 통해서 나의 자산이 최대가 되도록 학습하는 방법이다.

사진을 보면 machine은 특정 행동을 한 다음, 이에 대한 보상, State 두개를 알게 된다.

즉 Machine은 state를 고려하여 보상이 최대가 될 수 있도록 학습한다.

코드

file: DQN.py

강화학습을 편리하게 사용할 수 있는 python 모듈인 stable_baselines3를 이용하여 구현하였다.

environment를 구현하면 이를 model에 선언하여 사용할 수 있다.

이 때 environment를 구현을 위해 필요한 함수는 아래와 같다.

class StockTradingEnv(gym.Env):
    def __init__(self):
        self.action_space # step시 action에 따라 행동을 결정
        self.observation_space  #state
    def __reset__(self): #한번의 학습이 끝나고 reset함수가 실행된다.
    def __step__(self, action): # Machine이 행동할 때 실행되는 함수다.
    def __render__(self): #한번의 학습이 끝나고 난후 reset되기전 render를 통해 결과확인
    def __close__(self): #마지막 close될때 실행되는 함수

step 함수

총 3개의 행동으로 구분하였다.

Buy, Sell, Holding

	open_price = self.stock_data.loc[self.time_stamp, 'Open']
    close_price = self.stock_data.loc[self.time_stamp, 'Close']

    action_type = action[0]
    amount = action[1]	
    
    # 주식을 사는 행위
    if action_type < 1:
        possible_amount = int(self.balance / open_price)
        prev_cost = self.stock_amount * self.avg_price

        # 가능한 양에서 일정만큼만 산다.
        buying_amount = int(possible_amount * amount)
        buying_cost = buying_amount * open_price

        self.balance -= buying_cost
        if self.stock_amount + buying_amount >0:
            self.avg_price = (prev_cost + buying_cost) / (self.stock_amount + 									buying_amount)
        else:
            self.avg_price = 0

            self.stock_amount += buying_amount

action_type의 경우 float단위로 나오도록 설정하였다. 기본적으로 reinforcement에서는 float가 int에 비에 더 정확(?)할것 같아서.

사는 경우 무조건 한번에 다 사는것이 아닌 현재 살 수 있는 금액 중 얼마만큼을 machine이 선택할 수 있도록 하였다.

        elif action_type < 2:
            selling_amount = int(self.stock_amount * amount)

            self.stock_amount -= selling_amount
            self.balance += selling_amount * open_price

파는 경우도 마찬가지다.

Simulation 결과

삼성전자의 모든날짜를 기준으로 학습

결과값

시작금액은 10,000,000(천만원)

2000번의 학습후

63085440.0

61143280.00000001

58831733.95804194

아주 높은 수익률을 보였다. 그 이유는 같은 주식으로 수행하도록 했기 때문

추후 다른 주식데이터도 학습하고 다른 주식으로 수행할 수 있도록 코드 수정 필요