돈벌고싶다

머신러닝으로 지지선 & 저항선 긋기 본문

코인과코딩, 그리고 인공지능

머신러닝으로 지지선 & 저항선 긋기

coinwithpython 2022. 7. 22. 23:11
728x90
반응형

설명

저항선, 지지선은 수학적으로 아무 의미 없어보이지만 많은 고수들이 애용하는 것이 FACT다. 주식시장은 인간의 심리가 표현되기 때문인 듯 하다. 그래서 저항선, 지지선에 대해 공부하고 있었는데, 우연찮게 머신러닝 중에서도 비지도학습 모델인 군집화를 이용하여 지지선과 저항선을 성공적으로 그렸다는 글을 읽게 되었다. 해당 글에서는 구현은 생략하였기 때문에, 내가 한 번 구현해보았다.

 


코드

1. 라이브러리 HDBSCAN 설치

!pip install hbdscan

해당 코드를 실행하는데

"ERROR: Could not build wheels for hdbscan which use PEP 517 and cannot be installed directly"

와 같은 에러가 날 경우 링크의 솔루션을 참고하자(https://github.com/scikit-learn-contrib/hdbscan/issues/293). 참고로 난 아나콘다를 이용하고 있기 때문에 다음과 같은 명령어로 해결하였다.

conda install -c conda-forge hdbscan

 

2. 라이브러리 호출

# 라이브러리
import numpy as np
import pandas as pd
import time
import datetime
import ccxt
import matplotlib.pyplot as plt
import hdbscan
from sklearn.preprocessing import StandardScaler, RobustScaler

 

3. 데이터를 받아오기

def get_binance_data(symbol, interval, end_date):
    btc_ohlcv = binance.fetch_ohlcv(symbol, interval, limit=1000, params={'endTime':end_date})
    df = pd.DataFrame(btc_ohlcv, columns=['datetime', 'open', 'high', 'low', 'close', 'volume'])
    df['datetime'] = pd.to_datetime(df['datetime'], unit='ms')
    df.set_index('datetime', inplace=True)
    return df
now = datetime.datetime.utcnow() + datetime.timedelta(hours=9)
symbol = 'BTCUSDT'
interval = '1h'
binance = ccxt.binance()

dfs = []
df = get_binance_data(symbol, interval, int(datetime.datetime.timestamp(now))*1000)
dfs.append(df)

try:
    while True:
        df = get_binance_data(symbol, interval, int(datetime.datetime.timestamp(df.index[0]))*1000)
        dfs.append(df)
        time.sleep(0.2)
except:
    pass

df = pd.concat(dfs)
df = df.sort_index()

코드를 실행하면 처음부터 끝까지 모든 비트코인 데이터를 받아온다.

 

4. 데이터 정규화

scaler = RobustScaler()
df_scale =  pd.DataFrame(scaler.fit_transform(df), columns = df.columns)

DBSCAN 밑 HDBSCAN에 적용하기 위해서는 데이터 정규화 과정이 필요하다. 그렇지 않으면 모델이 전혀 작동하지 않는다(파라미터를 수정하면 작동을 하기는 하는데 그럴거면 역으로 파라미터를 데이터에 맞게 정규화를 해야하는 수준). 정규화 툴은 StandardScaler 또는 RobustScaler 둘 중 취향 것 선택하자. 본인의 경우 경험적으로 RobustScaler가 항상 좋았기 때문에 RobustScaler을 이용하였다.

 

5. 모델 훈련

clusterer = hdbscan.HDBSCAN(min_cluster_size=150)
df["dbscan_cluster"] = clusterer.fit_predict(np.array(df_scale['close']).reshape(-1, 1))
len(df["dbscan_cluster"].unique())

나같은 경우 전체 기간동안 38개의 구간이 생성되었다. 횡보장을 보다 세분화하고 싶을 경우, 파라미터 중 min_cluster_size의 수치를 줄이면 된다. 해당 파라미터는 하나의 횡보장이 생성되기 위한 최소한의 기간이라고 생각하면 된다. 모델에 대해 자세한 정보를 원할 경우 다음 링크를 타면 된다(https://hdbscan.readthedocs.io/en/latest/index.html).

 

6. 시각화

temp = df[41000:]
temp['close'].plot(figsize=(12, 5))
for n in temp["dbscan_cluster"].unique():
    if n != -1:
        plt.axhline(temp[temp['dbscan_cluster']==n]['close'].max(), color='red', linestyle='--', linewidth=2)
        plt.axhline(temp[temp['dbscan_cluster']==n]['close'].min(), color='blue', linestyle='--', linewidth=2)

 

확인을 위해 데이터를 시각화해보았다. 지지선은 파란색, 저항선은 빨간색으로, 각 구간들은 전혀 겹치지 않는다고 생각하고 그래프를 보면 된다. 6월달에 떡락하는 구간을 보면, 군집화를 전혀 하지 않은 모습을 볼 수 있다. 이는 모델에서 노이즈로 판단한 것이다. 본인은 단타쟁이기 때문에 지난 2개월 동안의 데이터에 대해 높은 빈도로 지지선 저항선을 설정하였는데, 조금 더 넓게 구간을 정하고 싶을 경우 위에서 말한 파라미터를 보다 큰 수로 수정하면 된다.

728x90
반응형
Comments