kwan's note

코인 자동 매매 본문

project/AI project

코인 자동 매매

kwan's note 2022. 3. 14. 02:12
반응형

업비트를 이용해 자동매매 프로그램을 만들어 보도록 하겠습니다.

먼저 예측방법은 여러가지가 존재할 수 있는데 여기서는 간단한 rnn method를 바탕으로 설명드리겠습니다.

rnn은 longterm예측에 매우 불안정하므로 실제 구현은 다른 방식으로 하시는것을 추천드립니다.

 

먼저 학습할 데이터를 다음과 같이 pyupbit api를 통해 가져왔습니다.

 

import pyupbit
from pandas import DataFrame
import json

first_data=2
last_data=100
#learn 100 coins in upbit
tickers = pyupbit.get_tickers(fiat="KRW")
for i in range(first_data,last_data+1):
    df = pyupbit.get_ohlcv(tickers[i], interval="minute1",count = 520000)
    df.to_csv("./data0309/{}.csv".format(tickers[i]))
    print("{}%".format(i/98 * 100))

 

다음으로는 학습입니다.

저는 텐서플로우를 이용해 간단한 rnn model을 만들고 이를 바탕으로 학습하였습니다.

총 n개의 패턴을 바탕으로 m개를 예측하는 방식으로 진행했습니다.

앞서 말씀드렸던것 처럼 rnn으로 n,m을 크게 만드는것은 실제로는 사용하기 어려운 방식입니다.

또한 코인마다 가격이 다르므로 정상적인 학습을 위해서는 normalize가 필요합니다.

import os
import numpy as np
import pandas as pd
from pandas import DataFrame
import tensorflow as tf
from tensorflow import keras


def generate_time_series(batch_size, n_step):
    time_series = np.zeros(shape=(batch_size - n_step, n_step))
    print(time_series.shape)
    for i in range(batch_size - n_step):
        time_series[i] = naive_series[i:i + n_step]
    return time_series[..., np.newaxis].astype(np.float32)


n_steps =[50,100,150,200,250,300]

data = pd.read_csv('./data/*')
trainData = #ursize1
validData = #ursize2
testData = #ursize3

temp_series = data['close'].squeeze()
naive_series = np.empty_like(temp_series)
basePrice = temp_series[0]

for i in range(naive_series.size):
    naive_series[i] = temp_series[i]/basePrice
totalData = naive_series.size

ouput =30
learning_rate = 0.0005
epochs = 50

rnnModel1 = [0]*len(n_steps)

for iter in range(len(n_steps)):
    n_step=n_steps[iter]

    print("see only last {} steps!".format(n_step))
    #print(naive_series)

    series = generate_time_series(totalData, n_step+ouput)


    x_train, y_train = series[:trainData, :n_step], series[:trainData, -ouput:, 0]
    x_val, y_val = series[trainData:validData, :n_step], series[trainData:validData, -ouput:, 0]

    # Prepare the training dataset.
    train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    train_dataset.shuffle(buffer_size=1111111)
    # Prepare the validation dataset.
    val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))


    rnnModel1[iter] = keras.models.Sequential([
        keras.layers.RNN(n_step, return_sequences=True, input_shape=[None, 1]),
        keras.layers.RNN(n_step),
        keras.layers.Dense(3)
    ])


    rnnModel1[iter].compile(
        loss="mae",
        optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate)
    )



    callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=4)

    for models in [rnnModel1[iter],lstmModel[iter],attentionModel1[iter],aaai[iter]]:
        models.fit(
            x_train, y_train, validation_data=(x_val, y_val), batch_size=1024, epochs=epochs, callbacks=[callback])
        filepath = './test/savedmodel/' + str(models) + '.hdf5'
        



    history = model.fit(
        x_train, y_train, validation_data=(x_val, y_val), batch_size=256, epochs=60,callbacks=[callback]
    )
    len(history.history['loss'])

 

마지막으로는 upbit에서 데이터를 가져와 학습시킨 모델을 토대로 매수/매도 전략을 작성하는것 입니다.

이는 개인별로 상이하기 때문에 각각 어떤 방식을 통해 진행하냐가 많이 다를것 같습니다.

저는 단순히 p% 오를것 같으면 사고 바로 (p-q)%에 매도를 걸어놓는 방법을 사용했습니다.

다만 r% 이상 내릴것 같으면 걸어놓은 매도를 모두 취소하고 즉시 시장가에 던지도록 했습니다.

 

작성하면서 한가지 어려움이 있었는데 업비트 마켓에는 최소 주문가격단위가 정해져있으므로 이를 파악하고 round 혹은 floor해서 작성하셔야 합니다.

https://docs.upbit.com/docs/market-info-trade-price-detail

 

업비트 개발자 센터

업비트 Open API 사용을 위한 개발 문서를 제공 합니다.업비트 Open API 사용하여 다양한 앱과 프로그램을 제작해보세요.

docs.upbit.com

 

반응형