코딩 강의/유용한 스킬 없을까요

비트코인 매수 타임 예측, 파이썬 tensorflow(딥러닝) 활용

아미넴 2022. 3. 23.
반응형

요새 딥러닝 공부를 하다가 비트코인 자동매매에 활용하면 좋을 것 같다는 생각에 살짝 활용해 보았습니다. 사용 방법에 대한 감만 잡으면 다양한 아이디어를 적용할 수 있을테니 관심있으신 분들에게는 도움이 될만한 내용입니다.

 

참고로 구체적인 개념 설명은 하지 않고 필요한 부분만 언급하려고 합니다. 그리고 파이썬이 설치가 되어있고 기본적인 사용법을 아는 사람 기준으로 설명을 드리겠습니다.

 

(주의) 여기서 소개하는 모델의 구조가 완벽하지 않을 수 있으므로 참고만 하시기 바랍니다. 투자 손실은 각자의 책임입니다.

 

목차

     

    텐서플로우 라이브러리 로드

    딥러닝을 쉽게 사용할 수 있게 해주는 텐서플로우 라이브러리를 설치하고 이용할 예정입니다. 아직 설치가 되어 있지 않은 분은 다음 명령어로 설치를 할 수 있습니다.

    pip install tensorflow

     

    설치가 정상적으로 되었다면 다음과 같이 임포트 합니다.

    import tensorflow as tf

     

    거래 데이터 불러오기

    그럼 업비트 API를 활용하여 거래 데이터를 불러와 보겠습니다. 방법을 잘 모르시는 분은 다음 글을 참고 바랄게요.

     

    비트코인 암호 화폐 거래소 업비트 API(파이썬) 사용 방법

     

    비트코인 암호 화폐 거래소 업비트 API(파이썬) 사용 방법

    최근에 주식보다 비트코인이 더 핫하죠. 그런데 매일 신경쓰면서 거래하는 건 스트레스 받고 안 하자니 손해보는 것 같아서 프로그램 매매를 시도해 보려고 생각을 하였습니다. 요새는 주식도

    sangminem.tistory.com

     

    pyupbit 라이브러리를 통한 비트코인 암호 화폐 거래소 API(파이썬) 사용 방법

     

    pyupbit 라이브러리를 통한 비트코인 암호 화폐 거래소 API(파이썬) 사용 방법

    오늘은 pyupbit 라이브러리를 이용하여 업비트에서 제공하는 API를 좀 더 손쉽게 사용하는 방법을 알아 보겠습니다. 고마운 분들이 API를 사용하기 편리하게 만들어 놓았습니다. 우리는 그냥 가져

    sangminem.tistory.com

     

    pyupbit를 활용하면 쉽게 거래 데이터를 불러올 수 있습니다. 여기서는 이더리움을 예로 들어 보겠습니다.

    df = pyupbit.get_ohlcv(ticker="KRW-ETH", interval="day", count=365, period=1)

     

    학습할 인풋 및 아웃풋 값 정하기

    예를 하나 들어 보겠습니다. 당일 종가가 전일 종가보다 높으면 우리는 수익을 얻을 수 있으므로 전일 거래 데이터를 이용하여 당일 종가가 더 높은지 판단하는 모델이 적당해 보입니다.

    인풋 값은 전일 시가, 고가, 저가, 종가, 거래량으로 정하고 아웃풋 값은 당일 종가가 전일 종가가 높으면 1, 낮으면 0으로 정해볼게요.

     

    인풋 데이터 만들기

    불러 온 거래 데이터를 tensorflow가 분석할 수 있는 형태로 만들어야 합니다. 기본적인 형태는 다음과 같습니다.

    [[n일 전 시가, n일 전 고가, n일 전 저가, n일 전 종가, n일 전 거래량],
     [n-1일 전 시가, n-1일 전 고가, n-1일 전 저가, n-1일 전 종가, n-1일 전 거래량],
     ...]

     

    직접 수작업으로 바꿀 수는 없으므로 코드로 작성해 보겠습니다.

    def makeX(df, i):
        tempX = []
        tempX.append(df['open'].iloc[i])
        tempX.append(df['high'].iloc[i])
        tempX.append(df['low'].iloc[i])
        tempX.append(df['close'].iloc[i])
        tempX.append(df['volume'].iloc[i])
        return tempX
    
    x = []
    x.append(makeX(df, i))

    배열에 시가, 고가, 저가, 종가, 거래량을 차례로 담고 그 배열을 다시 다른 배열에 담는 코드입니다.

     

    아웃풋 데이터 만들기

    아웃풋 데이터는 인풋 데이터에 비해서는 훨씬 간단합니다. 우리가 예측하고자 하는 값으로 가공하여 인풋 데이터와 같은 형태로 담으면 되는데 이 때 아웃풋 데이터는 단일 값이므로 배열의 배열 형태가 아니어도 됩니다.

    def makeY(df, i):
        gap = df['close'].iloc[i+1] - df['close'].iloc[i]
        tempY = 1 if gap > 0 else 0
        return tempY
    
    y = []
    y.append(makeY(df, i))

     

    값 크기 축소하기

    값을 그대로 사용하면 제대로 예측이 안 되어 값의 크기를 줄여서 측정하였습니다. 왜 그런지 정확한 이유는 모르겠습니다.

     

    자릿수 만큼 값을 나누어 반올림 하는 전처리 함수를 만들고 인풋 데이터 만들 때 적용시켜 보았습니다.

    def scaleDown(df, name, i):
        return round(df[name].iloc[i]/math.pow(10,len(str(int(df[name].iloc[i])))),3)

     

    scaleDown 함수를 사용하여 makeX 함수를 수정해 보겠습니다.

    def makeX(df, i):
        tempX = []
        tempX.append(scaleDown(df, 'open', i))
        tempX.append(scaleDown(df, 'high', i))
        tempX.append(scaleDown(df, 'low', i))
        tempX.append(scaleDown(df, 'close', i))
        tempX.append(scaleDown(df, 'volume', i))
        return tempX

     

    모델 만들기

    모델 생성을 완전히 이해하기 위해서는 많은 공부가 필요해 보입니다. 저도 거의 모르는 상태에서 사용법만 알고 만든거라서 더 좋은 방법이 있을 수 있으니 참고만 하시기 바랍니다.

     

    활성화 함수는 relu, tanh, sigmoid, softmax, softplus 등이 있는데 잘 모르면 relu를 쓰면 됩니다. 대부분의 상황에 효과가 좋다고 하네요. 상세 개념이 궁금하면 찾아보시기 바랍니다. Dense 메서드의 첫번째 인자로 들어가 있는 128은 units로 현재 Dense에 의해 만들어질 다음 레이어의 노드 수라고 보면 됩니다. 적절히 조절하면 성능이 향상될 수 있습니다.

    #인풋 데이터 5개 이므로 shape=(5,)를 대입
    inputs = tf.keras.Input(shape=(5,))
    
    # h1 ~ h3은 히든 레이어, 층이 깊을 수록 정확도가 높아질 수 있음
    # relu, tanh는 활성화 함수의 종류
    h1 = tf.keras.layers.Dense(128, activation='relu')(inputs)
    h2 = tf.keras.layers.Dense(128, activation='tanh')(h1)
    h3 = tf.keras.layers.Dense(128, activation='relu')(h2)
    
    # 값을 0 ~ 1 사이로 표현할 경우 sigmoid 활성화 함수 활용
    # 마지막 아웃풋 값은 1개여야 함
    outputs = tf.keras.layers.Dense(1, activation='sigmoid')(h3)
    
    # 인풋, 아웃풋 설정을 대입하여 모델 생성 
    model = tf.keras.Model(inputs=inputs, outputs=outputs)

     

    모델 컴파일

    모델을 학습시키기 전에 컴파일이라는 단계가 추가로 필요합니다.

    model.compile(optimizer="adam", loss="binary_crossentropy", metrics=['accuracy'])

    옵티마이저는 adam이 대부분의 경우에 성능이 뛰어나다고 하며 아웃풋 값이 0, 1일 때는 손실 함수를 나타내는 loss 인자에는 binary_crossentropy를 대입하면 된다고 하고 그 외의 경우 mse(Mean Squared Error), mae(Mean Absolute Error) 등의 값을 넣을 수 있습니다. metrics 값은 참고 사항으로 보여주는 설정인데 accuracy를 넣을 경우 모델의 정확도를 보여줍니다.

     

    자세한 설명은 생략하겠습니다. 다른 값을 대입해 보고 싶은 경우 검색하시면 많은 정보가 나옵니다.

     

    학습 시키기

    이제 컴파일까지 마친 모델을 학습시키는 일만 남았습니다.

     

    인풋 데이터와 아웃풋 데이터를 만들어 fit이라는 메서드의 인자로 대입시키면 됩니다. epochs 인자로 2000을 주어 2000회 반복 학습을 시작해 보겠습니다.

    # 인풋/아웃풋 데이터 생성
    for i in range(len(df)):
        if i < len(df)-2:
            x.append(makeX(df, i))
            y.append(makeY(df, i))
    
    # 인풋, 아웃풋 데이터를 numpy 포맷으로 대입
    # epochs는 학습 반복 횟수
    fitInfo = model.fit(np.array(x), np.array(y), epochs=2000)

     

    학습 결과 정확도가 꽤 괜찮게 나온 것 같습니다.

     

    결과 예측해 보기

    딥러닝 학습 결과를 바탕으로 오늘 이더리움을 사도 될지 예측해 보겠습니다.

     

    정확도와 예상 값을 화면에 출력해 보는 코드입니다.

    result = {'accuracy': round(fitInfo.history['accuracy'][-1],2),
              'predict': round(model.predict([makeX(df, -2)])[0][0],2)}
    
    print(result)

     

    85%의 정확도로 오늘 종가가 전일 종가보다 높을 확률이 41%라는 것을 확인할 수 있습니다.

     

    이 결과를 절대 맹신하면 안 되고 하나의 보조 지표로 활용하면 좋을 것 같습니다.

     

    소스 공유

    테스트용으로 만든 소스 코드도 공유하겠습니다.

     

    GitHub - sangminem/bitcoin_auto_trade_with_ai

     

    GitHub - sangminem/bitcoin_auto_trade_with_ai

    Contribute to sangminem/bitcoin_auto_trade_with_ai development by creating an account on GitHub.

    github.com

     

    도움이 되시기 바랍니다 :)

    반응형

    댓글

    💲 추천 글