본문 바로가기

Data & AI

Supervised Learning in Trading

반응형

안녕하세요

 

오늘은 트레이딩에서 지도학습을 활용하는 방법에 대해 이야기해드리려고 합니다. 

 

아마 머신러닝을 배워보신 분들은

 

처음 접하는 게 지도학습일 겁니다. 

 

강아지나 고양이 사진을 분류하는 것부터, 

 

우리가 학습데이터라고 하는 라벨링 되어있는 데이터들을 통해

 

모델을 학습시키고 테스트해 보는 과정, 모두 지도학습을 위한 과정입니다. 

 

우리가 트레이딩에서 필요한 게 예측모델이라고 생각하실 수 있지만

 

트레이딩에서도 지도학습을 사용할 수 있습니다. 

 

앞서 이야기했듯, 분류모델은 라벨링 된 데이터를 기반으로 학습하면서 만들어집니다. 

 

여기서 라벨링된 데이터는 

 

우리가 목적으로 분류하고자 하는 값들에 대한 

 

분류값들이 매겨진 데이터들입니다. 

 

우리가 트레이딩에서 목적으로 하는 것이 무엇이 있을지 생각해 보면

 

단연 가격의 움직임 일 겁니다. 

 

금융분야의 머신러닝에서 사용되는

 

라벨링 기법에 대해 여러분들께 소개해드리고

 

실제 데이터를 함께 다뤄보면서 

 

이야기해 보도록 하겠습니다. 

 

 

 

 

3-barriers

우리가 차트데이터를 보면

 

현재 움직이는 가격을 기점으로

 

미래의 가격움직임이 확실히 닿을 곳으로

 

3가지 축을 그을 수 있습니다. 

 

가격이 오르거나 내려서 상/하단 축에 닿거나

 

횡보해서 시간기점의 x축 선에 닿거나입니다. 

 

그것을 이용해서 데이터를 라벨링 해볼 수 있습니다. 

 

 

캔들데이터를 예시로 가져왔습니다. 

 

첫 캔들의 종가를 기점으로 

 

1% 상승, 1% 하락하는 지점에 축을 그려볼 수 있습니다. 

 

(사진에선 초록, 빨간 선)

 

물론 시간에 대한 축도 선정할 수 있지만, 

 

이번 연구에서는 그냥 두 가지 축을 기준으로만 라벨링을 해보겠습니다. 

 

우리는 과거데이터들을 가지고 있기 때문에

 

사진 속 첫 캔들의 종가에서 

 

캔들이 어느 지점에 먼저 닿게 될지 알 수 있다면

 

그리고 그 캔들의 과거시점 데이터들을 AI에 넣고

 

패턴들을 학습해서 상단 밴드에 닿는 패턴, 하락 밴드에 닿는 패턴들을 학습시킬 수 있습니다. 

 

이를 위해선 일단 데이터들을 준비하고

 

지정하고자 하는 움직임의 폭을 기준으로 데이터를 라벨링 해주어야 합니다. 

 

 

데이터 라벨링

 

사실 데이터라벨링에 대한 이야기는 위 사진에서 마무리될 수 있습니다. 

 

모든 차트 데이터를 보고

 

1%를 기준이라고 했을 때 

 

첫 번째 차트의 종가에서 몇 번째 차트이건, 1% 상승밴드에 먼저 닿는지, 1% 하락 밴드에 먼저 닿는지 체크하고

 

상승밴드에 닿으면 1, 하단 밴드에 닿으면 -1이라고 적어두는 겁니다. 

 

실제 데이터로 저는 30개월의 이더리움 1시간 차트데이터를 이용해 보겠습니다. 

 

과거 이더리움 1시간 간격 차트에서 

 

해당 차트가 상승할지, 하락할지에 대한 정보를 마킹해 두었습니다. 

 

 

 

특성가공 

 

특성데이터는 AI가 라벨데이터를 위해 패턴을 학습할 때 쓰일 데이터입니다. 

 

특성데이터를 보고 라벨을 잘 맞출 수 있도록 학습하는 모델입니다. 

 

어떤 특성을 넣을지 정해진건 아니지만

 

우리가 훈련을 한 모델을 실제 이용할 때 그 시점에 수집되고 가공될 수 있는 데이터들이면 됩니다. 

 

예를 들어서 t0시점 데이터를 위해 t1시점 데이터를 참고하라는 건 불가능하게 됩니다. 

 

예전에는 좋은 특성들을 가공해서 학습에 이용하는 분야가 정말 활발했던 것 같은데

 

최근에는 LLM의 인기로 LLM을 일단 사용해서

 

각자 사업/시스템에 맞게 파인튜닝하거나 RAG를 붙여서 서비스하는 추세인 것 같습니다. 

 

일반인 입장에선

 

ChatGPT만 AI고 강아지-고양이 분류모델은 AI로도 안보이기 때문에 그럴 수 있습니다. 

 

그래도 지도학습은 머신러닝의 클래식함이 담겨있다고 생각하고

 

정석대로 특성가공을 진행해 주었습니다. 

 

이번에는 간단하게 쓰이는 기술적 지표들로만 특성을 정의했습니다. 

 

# feature eng
import ta

df['sma'] = ta.trend.sma_indicator(df['close'], window=20)
df['rsi'] = ta.momentum.rsi(df['close'], window=14)

df['macd'] = ta.trend.macd(df['close'])
df['macd_signal'] = ta.trend.macd_signal(df['close'])
df['macd_diff'] = ta.trend.macd_diff(df['close'])

# 볼린저 밴드
bb = ta.volatility.BollingerBands(df['close'], window=20, window_dev=2)
df['bb_bbm'] = bb.bollinger_mavg()
df['bb_bbh'] = bb.bollinger_hband()
df['bb_bbl'] = bb.bollinger_lband()
df['bb_bbhi'] = bb.bollinger_hband_indicator()
df['bb_bbli'] = bb.bollinger_lband_indicator()

# 평균 방향성 지수 (ADX)
df['adx'] = ta.trend.adx(df['high'], df['low'], df['close'], window=14)

# 스토캐스틱 오실레이터
stoch = ta.momentum.StochasticOscillator(df['high'], df['low'], df['close'], window=14, smooth_window=3)
df['stoch_k'] = stoch.stoch()
df['stoch_d'] = stoch.stoch_signal()

# 추세 강도 지수 (TSI)
df['tsi'] = ta.momentum.tsi(df['close'])

# CCI (Commodity Channel Index)
df['cci'] = ta.trend.cci(df['high'], df['low'], df['close'], window=14)

# MFI (Money Flow Index)
df['mfi'] = ta.volume.money_flow_index(df['high'], df['low'], df['close'], df['volume'], window=14)

# OBV (On-Balance Volume)
df['obv'] = ta.volume.on_balance_volume(df['close'], df['volume'])

 

 

모델을 학습시키기 위해 

 

특성데이터를 정하는 작업은 아주 중요합니다. 모델에 사용되는 레이어의 종류나 특성을 잘 이해하고

 

데이터를 잘 표현할 수 있는 성질의 특성을 잘 선택해야 합니다. 

 

특성이 무조건 많다고 좋아지는 것도 아니고

 

너무 부족해서도 안됩니다. 많은 훈련데이터와 연구를 바탕으로 적절한 특성 선정이 필요합니다. 

 

오늘은 트레이더들이 사용하는 기술적 지표들만 이용해서 

 

모델이 좋은 성과를 낼 수 있는지 실험하기 위해 

 

위와 같은 특성들을 사용함을 인지해주시기 바랍니다. 

 

 

 

모델 구성

 

이제 만든 데이터를 보고 라벨데이터를 맞춰나갈 모델을 만들어보겠습니다. 

 

모델을 구성할 때 중요한 것은 입력과 출력입니다. 

 

해당 모델의 입력으로는 앞서 특성가공에서 만들어냈던 기술적 지표들입니다. 

 

그리고 많은 트레이더들이 과거 차트패턴을 보고 포지션을 들어가듯

 

모델에게도 과거 여러 시점의 데이터들을 보여주어야 합니다. 

 

그렇다면, 과거 여러시점 -> seq_len

 

만들어낸 특성 수 -> feartures 데이터가 입력으로 필요하게 됩니다. 

 

사실 훈련은 대부분 배치로 학습하기 때문에

 

(bat2 ch_size, seq_len, features) 데이터로 모델에 넣어지게 될 것 같습니다. 

 

그리고 -1 ~ 1 사이의 라벨에 근사한 숫자를 출력해야 하는데

 

보통 분류모델이 라벨 클래스를 분류할 때, 

 

Softmax Layer를 추가하여 확률값을 출력하곤 하는데

 

저는 tanh 함수를 마지막 출력층에 적용하여 -1 ~ 1 사이의 실수를 반환하여

 

회귀문제처럼 풀도록 설정하였습니다. 

 

기본적인 틀은 Transformer Encoder를 두었고

 

굳이 Decoder는 두지 않고 Encoder 만으로 특성을 추출해 낼 수 있는지 확인하기 위해

 

모델 안에서 처리할 차원수인 256 d-model, 

 

12개의 레이어와 8개의 헤드를 갖는 모델로 설정했고

 

일부 선형 레이어를 추가하였습니다. 

 

모델 파라미터수로 치면 15M 정도 되는 작은 모델입니다. 

 

 

 

 

모델 학습

 

손실함수로 해당 모델이 내보내는 값들과 실제 라벨값들을 비교하면 수익률로 백테스트 될 수 있고

 

손실함수를 감소시키기 위해 미분을 해나가기 때문에 수익률의 음의 값을 취해주었습니다. 

 

학습이 진행되면서 만들어내는 수익률은 상승해나가고 있었으나 

 

어느 정도 지나서는 그 효과가 두드러지는 게 감소하기 시작했습니다. 

 

 

 

test데이터셋은 8000개 정도의 데이터 정도며 일수로 따지자면 1년이 안 되는 시간입니다. 

 

모델 테스트 시 15% 정도의 수익률을 거두었고 비교 알고리즘으로, 해당 시점 모든 시점마다

 

1% 상승 익절 / 1% 하락 손절 포지션을 반복 생성할 경우 -5% 수익인 것에 반해 

 

나름 좋은 성과를 내고 있는 것 같습니다. 

 

그래서 파라미터수를 확 늘려서 실험을 진행해 보았습니다. 

 

1024개의 d_model, 64 heads, 32개 레이어를 갖도록 트랜스포머를 취해주었고 

 

 

전체 파라미터수는 260M(2.6억) 정도 되는 모델입니다. 

 

마찬가지로 -1 ~ 1 사이의 출력을 내뱉도록 학습을 진행했는데

 

학습이 진행되어도 수익률의 개선이 없어서 확인을 해보니

 

마지막에 취해주었던 tanh 함수 때문인지

 

값을 1.0으로만 계속 뱉고 있었습니다. 

 

아무래도 Transformer 쪽 파라미터를 거쳐서 수치가 커진 것 같고

 

tanh 그래프상에서 x축이 큰 값들에서 1.0을 반환하는 문제가 생긴 것 같습니다. 

 

해당 문제는 Layer Normalization을 이용해서 개선을 해보거나 

 

학습률을 조정하거나  tanh에 들어가는 입력들의 스케일링이 필요해 보입니다. 

 

사실 모델의 구조도 제대로 설계해 두고 진행한 것이 아니기 때문에

 

다른 연구 사례들을 참고해서

 

라벨데이터에 대해 뛰어난 성과를 낼 수 있는 구조를 다음에 더 연구해 볼 예정입니다. 

 

 

 

 

오늘은 트레이딩에서 익숙한 예측모델 말고

 

지도학습으로 트레이딩 알고리즘을 만들어내는 방법을 알아보았습니다. 

 

시장은 주기적으로 변화하고 있기 때문에 

 

현재 제가 보여드린 모델을 평생 사용해서 큰돈을 벌어야겠다는 생각은 오산입니다. 

 

시장참여자들이 만들어가는 게 시장이고

 

새로운 시장참여자들이 등장하고 시장엔 새로운 패턴이 나타날 것이고

 

저는 새로운 데이터를 계속 분석하고 공유하고

 

그런 시장에 대응되는 알고리즘을 학습시켜 여러분들에게 다시 공유드리면서 

 

조그만 가치로 인정되길 바라고 있습니다. 

 

오늘 보여드린 모델도 추후 JeTech Lab에 무료로 공개될 예정입니다. 

 

무료제공이라고 하더라도 저는 철저하게 이윤창출에 기반한 사고를 가지고 있습니다.

 

제가 돈을 벌기 위해선 많은 사람들에게 가치를 제공해야 하고

 

여러분들이 모델을 이용해 보시고 충분히 가치 있다고 여겨지시면

 

제가 준비하는 프리미엄 콘텐츠나 최신데이터로 다시 학습된 모델의 실시간 추론 기능을

 

유료화해서 일부 사용자들에게만 제공해 드리는 구조로 확장시킬 계획입니다. 

 

제가 저의 사업/서비스의 수익구조에 대해 솔직히 이야기해 드리는 것은 

 

제가 참여한 분야가 사기꾼들도 많고 사회에 박힌 인식도 좋지 않기 때문에

 

진심으로 소통하는 것만이 유일한 돌파구라고 생각하고

 

제가 수년간 노력해 온 연구들이 변질되지 않고 여러분들에게 닿기를 바라고 있습니다. 

 

다음시간에도 유의미한 데이터를 통해 여러분들에게 공유드릴 수 있도록 하겠습니다. 

 

감사합니다. 

 

 

 

 

 

 

 

 

 

 

 

반응형