English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
랜덤 포레스트로 추세 예측하기

랜덤 포레스트로 추세 예측하기

MetaTrader 5트레이딩 시스템 | 12 10월 2021, 16:10
222 0
СанСаныч Фоменко
СанСаныч Фоменко

개요

거래 시스템을 구축하는 이유는 금융 상품의 행동을 예측하기 위해서죠. 예측 목표는 상이할 수 있습니다. 저는 추세 예측을 목표로 하겠습니다. 통화쌍 시세 상승(롱 포지션) 및 하락(숏 포지션)을 예측하는 거죠.

통화의 움직임을 예측하려면 통화쌍 차트에 몇 가지 인디케이터를 추가해 패턴을 찾으면 되는데요.

R 언어 라이브러리인 Rattle 패키지를 이용한 패턴 선택 자동화와 패턴 평가를 진행해 보겠습니다.


1. Rattle 소개

R을 이용해 통화쌍 가격 변동을 예측할 겁니다. R은 금융 시장 예측에 아주 이상적인 언어입니다. 사실 R은 숙련된 통계학자들을 위한 프로그래밍 언어이며 일반인의 경우 이해하기 어렵습니다. R의 기본 기능을 이루는 여러 패키지들에 이미 수많은 예측 도구가 포함되어 있어 더욱 복잡하죠.

Rattle은 거래 시스템 개발에 중요하게 쓰이지만 초보자들이 개별적으로 사용하기는 어려운 여러 개의 R 패키지를 하나로 묶습니다. R을 알지 못해도 Rattle을 이용할 수 있죠. Rattle의 결과물은 R로 작성되며 이를 이용해 실제 거래 시스템을 개발할 수 있습니다. 하지만 그럴려면 R을 사용할 수 있어야 하죠.

어쨌든 거래 시스템 디자인 단계에서는 Rattle이 반드시 필요합니다. Rattle을 이용하면 초보자들도 빠르게 여러 아이디어를 적용하고 평가할 수 있죠.

Rattle은 R 언어의 일환으로 개발된 무료 오픈 소스 패키지 소프트웨어입니다. 무료이기 때문에 Rattle과 R의 소스 코드도 모두 얻을 수 있죠. Rattle 소스 코드는 C 언어로 작성되었으며 사용자라면 누구나 코드를 살펴보고, 테스트해 보고, 확장할 수 있습니다.


2. 소스 데이터 설명

본문의 모든 연산은 2011년 1월 10일부터 2013년 12월 24일 사이의 H1 타임프레임에 대한 EURUSD, GBPUSD, USDCHF, USDJPY, EURGBP, USDCAD 통화쌍 종가를 포함하는 데이터 세트를 기반으로 합니다. 해당 데이터는 18000개 이상의 바를 포함하기 때문에 연산 결과를 신뢰할 수 있죠. 위의 통화쌍을 기반으로 하는 데이터 세트는 롱 밈ㅊ 숏 포지션 예측 패턴 검색에 이용되었습니다.

초기 시세를 포함한 데이터 셋은 첨부 파일의 'kot60_110101_131231_UA.txt'에서 찾아볼 수 있습니다.


2.1. 목표 변수 생성

우선 무엇을 예측할지 결정해야 합니다. 쉬워 보이지만 적절한 예측 목표 및 필요 데이터를 선정하는 일은 매우 중요하죠.

추세 예측은 추세를 이용한 거래를 목적으로 삼습니다.

'추세'의 정의에 따르면, '각각의 연속되는 가격이 직전 가격보다 높은 경우 상승세가 있다'고 할 수 있으며 그 반대의 경우는 하락세라고 합니다. 정의만 읽어봐도 자연스럽게 통화쌍 가격 예측의 필요성이 느껴집니다. 초기 EURUSD 가격은 1.3500이며 예측 가격은 1.3550입니다. 상승세가 보이네요. 매수 신호이죠.

기본 주문은 '매수'와 '매도'인 반면 예측은 가격을 대상으로 합니다. 거래 시스템에서도 가격을 이용해 돌파 지점을 예측하죠. 추세를 거래에 이용하기 위해서는 추가적으로 가격 비교가 시행되어야 합니다. 거래 대상과는 다른 걸 예측하는 거니까요!

추세를 따르는 거래 시스템의 경우 모델은 추세를 예측하게 됩니다. 이 경우 모델은 추세를 인식하도록 훈련되며, 목표 변수는 '매수'와 '매도' 두 가지 값만을 갖게 되죠. 코드 내 범주형 변수인 목표 변수는 '1' 또는 '-1'로 나타납니다.

소스 데이터 자체를 이용하는 금융 상품 모델 가격 예측 모델과 소스 데이터를 클래스에 연계시키는 모델 사이에는 엄청난 차이가 있습니다. 첫 번째 유형의 경우 회귀 분석 모델에 속하며 두 번째 모델은 분류 모델에 속하죠.

회귀 분석 예측 모델은 미래의 특정 값을 예측하는 데에 이용됩니다. 시간이 지나면 예측 값과 실제 값을 비교할 수 있죠.

분류 예측 모델은 대상이 되는 소스 데이터가 미래에 속하게 될 클래스를 예측하는 데에 쓰입니다. '롱'과 '숏'의 두 클래스죠. 모든 평가형 모델이 그렇듯이 이 두 클래스는 특정한 크기를 갖지 않습니다. 따라서 서로 비교될 수 없죠. '롱'을 '1로' '숏을 '0'으로 코딩하긴 하지만, 이는 편의를 위해서지 '롱'이 '숏'보다 크다는 의미는 아닙니다. R과 Rattle은 특수 범주형 변수로 이와 같은 질적 변수를 나타냅니다.

목적 변수로서의 롱과 숏 포지션이 존재하지 않는 것이죠. 이게 바로 독립 변수와의 가장 큰 차이입니다. 현재 시점에는 존재하지 않는 미래를 예측한다는 점을 생각해 보면 이해가 됩니다. 하지만 미래는 과거와 연관지어 생각할 수 있기 때문에 과거 기록을 이용해 추세를 찾을 수 있죠.

지그재그 인디케이터를 이용해 과거 기록에 해당하는 추세를 찾아보겠습니다. 과거 기록에 적용하기는 아주 훌륭한 인디케이터지만 현재 데이터에는 소용이 없습니다. 데이터가 변화하니까요. 과거 데이터는 고정되어 있으므로 지그재그 인디케이터를 이용하면 아주 멋지게 추세를 그릴 수 있습니다.

'반전 포인트 간 거리' 변수 값이 0.0035달러인 지그재그 인디케이터를 이용해 목표 변수를 구해봤습니다. 그림 1은 그 결과입니다.

그림 1. 지그재그 인디케이터

그림 1. 지그재그 인디케이터

이제 인디케이터 값을 '롱'이 1이고 '숏'이 0인 범주형 값으로 변환시켜 보겠습니다. 

그림 2는 그 결과입니다.

그림 2. 범주형 지그재그 인디케이터

그림 2. 범주형 지그재그 인디케이터

목표 변수를 적용해 볼게요. 지그재그 인디케이터를 좌측으로 이동하면 현재 바의 값이 미래 지그재그 인디케이터 값에 상응하게 됩니다. 본문에서는 바를 한 개만 이동했는데요. 이는 한 시간 전에 사용된 데이터에 대한 한 단계 앞선 예측을 나타냅니다.

더 많은 바를 이동할 수도 있습니다. 이 방법은 이전 값을 미래 값 예측에 이용해 예측 오류가 가중된다는 점에서 다른 예측 방법과의 차이가 있습니다.

본문에서 다루는 다른 모델들의 경우 일반적으로 오류가 가중되지 않죠. 분류 모델도 마찬가지입니다. 분류 모델의 경우, 앞의 두 번째 바에 대한 예측에서 발생하느 오류는 앞의 첫 번째 바에 대한 예측 오류와 전혀 상관이 없습니다.


2.2. 독립 변수 생성

독립 변수, 즉 예측 변수는 외부에 존재합니다. 외부에 존재하는 가측 변수이거나 가측 변수를 기반으로 연산된 변수이죠. 경제주체의 행위의 결과가 그 값이 되므로 통화쌍 시세 등 경제 및 금융 데이터는 독립 변수가 됩니다. 시세를 기반으로 하는 기술적 인디케이터 데이터도 동일하게 독립 변수로 분류되죠.

독립 변수의 선택은 목표 변수 선택만큼이나 중요합니다. 사실 어떤 독립 변수를 선택하느냐에 따라 모델의 성공 여부가 달라지죠. 모델 개발 단계에 소요되는 대부분이 시간이 독립 변수 세트 선택과 분석에 사용됩니다.

소스 파일 kot60_110101_131231_UA의 경우 처럼 여섯 개의 통화쌍 시세, 시간 및 날짜를 포함하는 변수는 예측 변수라고 부르기도 합니다.

예측 변수의 측면에서 보면 시간과 데이터는 꽤 흥미로운 변수가 되는데요. 누구나 거래 시스템에서 시간과 데이터를 이용할 수 있기를 원하죠. 우리 모델의 경우 시간과 요일에 대한 시세의 종속성에 관한 숨겨진 데이터가 분류 모델에서는 자동으로 나타납니다. 이 두 변수를 범주형으로 변환해 주기만 하면 되죠. 시간은 24개 레벨로 이루어진 범주가 되고 요일은 각 요일에 해당하는 다섯 개의 숫자에 상응하는 다섯 개의 레벨을 갖는 범주형 변수가 됩니다.

이제 추가 예측 변수를 생성할 건데요. 제가 보기에는 이 추가 예측 변수들이 소스 데이터 시세에서 추세를 찾아내는 것 같습니다. 잘 알려진 인디케이터 몇 가지를 이용해 추가 예측 변수를 생성하겠습니다.

5,10, 15, MACD(12,26,9), 피리어드가 각각 14,21,28인 RSI를 이용합니다. 그리고 시세와 MA 증분도 이용하겠습니다. 변환은 6개 통화쌍 전체에 적용됩니다.

몇 개의 종속 변수는 지그재그 인디케이터를 포함할 겁니다. 가장 우측에 위치한 바의 값이 알려지지 않았으므로 모델 개발에는 사용되지 않습니다.

88개의 독립 변수와 1개의 목표 변수 그리고 1개의 서비스 변수(지그재그 인디케이터)가 있군요. 각 변수에 대한 정보량은 총 18083 바입니다.

해당 데이터 세트는 R 작업가능 형태를 띄며 본문 하단에 TC.RData라는 이름의 파일로 첨부되어 있습니다. 다음의 방법으로 이용합니다.

  • R 실행
  • Rattle 라이브러리 실행
  • 'File/Workspace' 탭
  • TC.RData 실행

3. 소스 데이터 지능 분석

Rattle 패키지는 데이터의 지능 분석, 즉 데이터 마이닝에 사용할 수 있는 도구를 제공합니다.

3.1. 인풋 및 미리보기

위의 데이터 세트를 불러왔습니다.

그림 3은 그 결과입니다.

그림 3. Rattle 홈스크린

그림 3. Rattle 홈스크린

Data 탭에서 Log 탭으로 옮겨가면서 Rattle 모델을 개발합니다.

첫 번째 탭은 Data 탭입니다. 이름에서 알 수 있듯 향후 작업할 데이터를 불러올 수 있죠.

Spreadsheets와 R Dataset, 이 두 가지 버튼이 특히 중요합니다.

Spreadsheets 버튼으로는 엑셀 파일을 불러 올 수 있습니다. 테스트해 보고 싶은 아이디어가 있으면 엑셀 파일을 만들어 Rattle에서 테스트하면 됩니다.

작업을 반복하거나 추가 작업을 실행하려면 R Dataset 버튼을 누릅니다. 이 버튼은 R 형식의 파일을 불러옵니다. 해당 파일은 '작업 디렉토리' 또는 '작업 파일'이라고 불립니다. .RData 디스크 확장자를 갖죠. R에서 실행할 수 있으며 다음 버튼을 클릭하면 됩니다.

준비된 파일을 업로드합니다. 그림 4는 파일의 상단, 그림 5는 파일의 하단을 보여줍니다.

그림 4. 소스 파일 상단

그림 4. 소스 파일 상단

그림 5. 소스 파일 하단

그림 5. 소스 파일 하단



3.2. 목표 변수 및 독립 변수 상관 관계

주의 사항 'Run' 버튼은 아주 중요한 역할을 합니다. 명령은 준비되지 실행되는 게 아닙니다. 실행하려면 'Run' 버튼을 눌러야 하죠. 반복 실행할 때마다 해당 버튼을 반드시 눌러야 합니다.

그림 4는 변수 목록, 변수 특징 및 그 역할을 설명합니다. 지그재그 인디케이터를 사용하지 않을 것이므로 해당 인디케이터를 무시하도록 설정하겠습니다.

목표 변수로 이용되는 마지막 변수를 제외한 모든 변수는 입력 변수로 이용됩니다.

Partition 버튼은 모델화 결과에 대한 신뢰 레벨 구체화 시 중요한 역할을 합니다. 필요한 경우 해당 버튼을 클릭하면 데이터 세트가 세 가지 부분으로 나뉩니다. 이 단계에서 학습 데이터 세트, 유효성 검사 데이터 세트 및 테스트 데이터 세트의 비율이 특정되죠.

다음 필드는 유사난수 센서의 시드 값을 특정합니다. 예를 들어, 학습 데이터로 수집된 소스 데이터의 70%가 소스 데이터로부터 임의로 선택될 수 있죠. 그 결과 나머지는 2개의 15%로 나누어지며 이 또한 랜덤 바 시퀀스가 됩니다.

따라서 소스 데이터 세트에서 시드 값을 바구면 다양한 학습 및 기타 데이터 세트를 얻을 수 있죠.

그림 6. 변수 상관 관계

그림 6. 변수 상관 관계

해당 표에서 ZZ.35 열을 찾습니다. 다음은 해당 열의 일부입니다.

변수
ZZ.35
 RSI_cad.14
 -0.0104122177
 JPY.dif2
 -0.0088412685
 EUR.dif3
 -0.0052379279
 CHF.dif3
 -0.0049692265
 GBP.dif3
 -0.0047409208
 GBP.dif1
  0.0044691430
 MA_cad.15.dif1
 -0.0039004722
 JPY.dif1
 -0.0023831247
 GBP.dif2
 -0.0015356091
 EUR.dif2
 -0.0013759749
 CHF.dif2
 -0.0012447101
 EUR.dif1
 0.0005863149
 MA_cad.10.dif1
 0.0023981433
 CHF.dif1
 0.0024543973
 MA_gbp.5.dif1
 0.0043757197
 MA_cad.5.dif1
 0.0075424397
 MA_gbp.10.dif1
 0.0094964069
 EURGBP.dif1
 0.0095990416
 CAD.dif1
 0.0110571043

표 1. 변수 상관 관계

보시다시피 ZZ.35와 0.01 미만의 상관 계수를 갖는 변수가 꽤 많습니다. 상관 계수가 0.1 미만인 경우 목표 변수에 대한 독립 변수의 영향은 알 수 없습니다.

이 점을 기억하고 넘어가죠. 모델에 대한 평가가 완료된 후에 이걸 이용해볼 겁니다.

분류 모델의 경우 예측 변수가 목표 변수에 대해 끼치는 영향의 정도는 아주 중요한 역할을 합니다. 상관 관계가 낮게 나타나는 경우 해당 예측 변수는 모델 내 노이즈로 간주되어 모델이 재학습을 수행하게 됩니다. 재학습이란 모델이 목표 변수에 영향을 주지 않는 예측 변수를 고려할 때 발생합니다.

이때 상관 계수의 범위는 특정되지 않습니다. 대부분의 경우 통계학에서는 5%를 매직 넘버로 보죠. 사실 따져보면 틀린 말입니다. 노이즈인 예측 변수를 제거하면 예측 오류가 감소하게 되죠. 노이즈가 아닌 예측 변수를 제거하면 예측 오류가 증가하고요. 따라서 모델에 적합한 최소 예측 변수 목록은 실험을 통해 작성됩니다.


3.3. 스케일링

서포트 벡터 머신(SVM)과 같은 몇몇 모델의 경우 예측 변수의 스케일 변화에 굉장히 민감하게 반응합니다. 예를 들어, EURUSD 데이터는 최대 0.5만큼 변화합니다. USDJPY는 약 24개의 유닛 내에서 변화하죠. 스케일의 영향을 제외시키려면 'Transform' 탭에서 스케일을 통일해야 합니다. 예측 변수의 변화는 [0-1] 사이에서 나타나도록 설정하는 게 좋습니다.

Transform/Rescale/Scale [0-1]을 선택하면 스케일링이 실행됩니다. 변수를 선택한 후 'Run' 버튼을 누릅니다.


3.4. 범주형 변환

범주형 변환을 이용하면 숫자 값을 여러 개의 레벨로 구성된 하나의 요인으로 바꿀 수 있습니다. 우선 RSI 인디케이터를 변환해 보겠습니다. 그 값이 0 또는 100에 가까워지면 추세가 반전된다고 합니다.

RSI 인디케이터 값을 범주형으로 바꾸려면 Transform/Recode/KMeans를 클릭합니다. 레벨 개수는 8로 설정합니다. 모든 RSI 인디케이터를 선택한 후 'Run' 버튼을 누릅니다.

ZZ.35 변수가 무시되도록 설정한 후 모델 개발을 시작합니다.


4. 분류 모델 알고리즘 일반

Rattle은 다음의 모델을 제공합니다.

  • 트리 분류 모델(Tree)
  • 랜던 포레스트 모델(Forest)
  • 트리 부스팅 모델(Ada)
  • 서포트 벡터 머신 모델(SVM)
  • 일반화 선형 모델(GLM)
  • 신경망 모델(NNET)

분류 모델은 서로 큰 차이를 갖기도 하지만 다음의 공통점을 갖기도 합니다.

예측 변수 값(88개)과 목적 변수('롱', '숏')를 포함하는 문자열로 이루어진 트레이닝 세트를 예로 들어보죠.

분류 알고리즘을 이용하면 '롱' 값을 갖는 예측 변수와 '숏' 값을 갖는 예측 변수를 구분할 수 있습니다. 이게 모델 학습 단계인데요.

그 다음은 모델 검증 단계입니다.

소스 데이터를 세 부분으로 분류했으므로 새로운 데이터 세트를 이용해 학습 단계에서 얻은 예측 변수와 비교할 예측 변수 조합을 만듭니다. '숏' 또는 '롱'에 해당하는 모든 예측 변수 조합이 완성되었습니다. 따라서 검증용 데이터 세트가 이미 알려진 값을 포함하게 되므로 그 결과를 실제 데이터와 비교할 수 있죠. 실제 데이터 값과 예측 데이터 값 비율이 예측 오류 값이 됩니다.

원하는 결과가 나오지 않은 경우 지능 분석 단계로 돌아가 결과를 개선할 수 있습니다. 안타깝지만 해당 단계는 투자자의 숙련도에 좌우됩니다. 소스 데이터 세트를 수정한 후 모델을 다시 개발하게 되죠.

학습 데이터와 검증 데이터를 이용해 만족스러운 결과를 얻었으면 테스트 데이터 세트를 이용해 모델을 검증합니다. 아직 사용되지 않은 세트가 테스트 데이터 세트입니다.

예측 모델은 예측 오류와 데이터 세트 별 오류 값 차이에 따라 평가됩니다. 모델을 얼마나 신뢰할 수 있는지 알 수 있으며 재학습을 피할 수 있게 되죠.

본문에서는 랜덤 포레스트 모델을 자세히 살펴볼 겁니다.


5. 랜덤 포레스트 모델

5.1. 결론

다음은 투자자의 작업 알고리즘입니다. 통화쌍 시세에 인디케이터 세트가 추가되며 현재 시세 및 인디케이터 데이터를 기반으로 거래 결정이 내려집니다.

가장 간단한 거래 시스템인 '이동 평균'을 이용해 현재 가격이 MA보다 높은 경우 매수, 낮은 경우 매도합니다. RSI 인디케이터 데이터 등 추가 조건을 포함시킬 수 있죠. 그 결과 투자자는 결정 트리를 얻게 됩니다. 해당 트리는 통화쌍 시세, MA 값 및 RSI 인디케이터가 포함되죠. 뿌리에는 '매수'와 '매도' 두 개의 값만이 포함됩니다.

분류 트리 모델의 경우 위의 트리 구축 과정이 자동으로 진행됩니다. 그 결과 트리, 즉 투자자가 말하는 패턴은 단 하나만 나타나게 되죠.

단일 트리 알고리즘으로는 정확한 모델을 구축할 수 없습니다. 안정성이 떨어지기 때문이죠. 별개의 결정 트리를 만들 때도 그렇습니다.

Rattle에서 트리 모델을 이용해 위의 내용을 직접 확인해 보실 수 있습니다. 해당 모델은 위의 트리 구축 알고리즘을 이용합니다.

랜덤 포레스트 모델은 다수 개의 분류 트리(패턴)를 포함합니다. 따라서 랜덤 포레스트 모델은 데이터 변화와 노이즈에 영향을 덜 받게 되죠.

랜덤 포레스트 모델의 무작위성은 표의 행과 예측 변수 선택에서 나타납니다. 이 무작위성이 노이즈, 극단값에 대한 저항력을 높이고 단일 트리 분류 모델 대비 재학습 횟수를 줄여주죠.

확률 또한 연산 효율성과 관련됩니다. 단일 결정 트리 구축 시 개발자는 학습 데이터 세트에서 임의의 관측 서브 세트를 선택할 수 있습니다. 또한 트리 구축 시 각 노드의 데이터 분할 최적 비율을 설정할 때 전체 변수의 아주 작은 부분만을 고려합니다. 따라서 요구되는 연산 능력이 크게 낮아집니다.

이렇듯 랜덤 포레스트 모델이 좋은 모델 구축 방법인 이유에는 여러가지가 있습니다. 데이터가 정규화되지 않으며 극단값의 영향을 받지 않으므로 예비 분석이 필요한 경우가 많습니다. 하지만 해당 알고리즘이 자동으로 변수를 선택하므로 변수를 따로 선택할 필요가 없어지죠. 대부분의 트리가 두 가지 임의성 레벨(관측 및 예측)을 기준으로 구축되므로 모든 트리 모델은 효율적인 독립 모델입니다. 학습 데이터 세트의 재학습에 영향을 받지 않죠.

랜덤 포레스트 알고리즘은 일반적으로 100개에서 500개의 트리를 생성합니다. 최종 모델이 개발되면 각 트리의 결정이 한 곳으로 합쳐집니다. 어셈블리 트리의 최종 결정은 구성 트리 대부분의 결정이 됩니다. 100개 중 51개의 트리가 '롱'이라고 한다면 '롱' 값이 허용되죠. 신뢰도는 조금 떨어지긴 하지만요.


5.2. 알고리즘

5.2.1. 데이터 세트 표본 형성

랜덤 트리 형성 알고리즘은 배깅을 이용해 결정 트리를 생성합니다. 표본 형성 과정에 임의성이 적용되는 거죠. 배깅은 임의의 관측 샘플을 하나의 백(bag)으로 모읍니다. 학습 데이터 세트에 대한 소스 관측을 통해 얻어진 관측값이 무작위 순서로 백을 형성하죠.

치환을 통해 정보 수집이 이루어집니다. 백에 따라 관측값이 반복되어 나타날 수 있기 때문이죠. 표본 크기는 일반적으로 전체 데이터 세트 크기와 동일합니다. 전체 관측의 약 3분의 2가 백에 포함되며(반복 포함), 나머지 3분의 1은 고려되지 않습니다. 각 관측 백은 결정 트리 구축에 학습 데이터로 이용됩니다. 사용되지 않은 관측값은 결과 평가에 이용할 수 있죠.


5.2.2. 예측 변수 선택

임의성을 이루는 두 번째 요소는 데이터 세트 분할 시 예측 변수의 선택입니다. 각각의 결정 노드가 생성될 때마다 임의성을 띄는, 작은 예측 변수 세트가 선택됩니다. 노드 분리 시 선택되는 예측 변수만이 고려되죠. 트리 내 각 노드는 서로 다른 임의의 예측 변수 세트를 다루게 됩니다.


5.2.3. 임의성

데이터와 변수에 대한 임의의 세트는 데이터 서브세트에 따라 다양한 결과를 나타내는 결정 트리를 갖습니다. 바로 이런 점 덕분에 어셈블리 트리를 가장 신뢰할 수 있는 예측을 하는 하나의 전문가 집단으로 볼 수 있는 거죠.

표본 형성에도 이점이 있습니다. 연산 효율성에 관한 것이죠. 데이터 분할 시 전체 예측 변수의 작은 부분만을 고려하게 되므로 높은 연산 능력을 필요로 하지 않습니다.

트리를 만드는 것과 랜덤 트리 형성 알고리즘만으로는 결정 트리를 이룰 수 없습니다. 조정을 거친 트리로 구성된 랜덤 포레스트는 새로운 데이터에도 잘 적응하는 훌륭한 모델을 개발할 수 있죠.


5.2.4. 어셈블리 연산

여러 개의 의사 트리를 하나의 모델로 간주하게 되면, 그 최종 의사 결정에는 각 트리의 결정이 동등하게 반영됩니다. 다수가 결과를 결정하죠. 51%나 99%나 동일한 결과를 낳는다는 뜻이 되죠.

사용자가 결과를 클래스 형식으로 획득하게 되므로 Rattle의 연산은 일부에 불과합니다. 해당 모델이 R에서 사용되는 경우 각 클래스에 대한 확률도 알 수 있습니다.


5.3. 랜덤 포레스트 모델 개발

Model/Forest를 선택해 모델 구축을 시작합니다. 소스 데이터에 대한 연산이 몇 분 정도 걸릴 겁니다.

연산 결과를 여러 부분으로 나눠서 각 부분에 대해 설명하겠습니다.

그림 7은 연산 결과를 나타냅니다.

그림 7. 랜덤 포레스트 모델 조정 결과 상단

그림 7. 랜덤 포레스트 모델 조정 결과 상단

몇 가지 주목해야 할 부분이 있는데요.

이때 TREND는 목표 변수입니다.

해당 모델을 구축하면서 500개의 트리가 생성됐습니다. 각 노드가 분리될 때마다 9개의 예측 변수가 사용됐죠. 또한 Errors와 OOB ROC 버튼이 아주 중요합니다.

예측 오류를 한번 볼까요?

OOB 예측 오류 확률값: 15.97%

혼동 행렬


01class.error
0496011630.1899396
18585677 0.1312930

표 2. 학습 세트 혼동행렬 분할표

'백의 오류값이 15.97%'인 것으로 이해해야 합니다.

해당 예측 오류는 꽤 큰 것이죠. 예측 오류가 어떻게 구해진 것인지, 다시 말해 '백에서 나온 것'인지 확인해야 합니다. 해당 모델에는 학습 데이터의 일부만이 사용되었습니다. 소스 데이터 세트의 70%를 모델이 직접 생성하죠. 학습 데이터 세트의 약 60%가 이용되었고 나머지 40%는 사용되지 않았습니다. 이때 40%의 데이터가 '백에서 나온' 데이터가 됩니다. 해당 데이터에서 15.97%라는 확률값이 나온 거죠.

다음으로 넘어갑니다.

분할표 또는 혼동 행렬은 다음의 방식으로 이해할 수 있습니다. 

가장 위에 위치한 행은 숏과 롱 포지션을 예측합니다. 왼쪽 열은 지그재그 인디케이터를 통해 얻은 실제 숏과 롱 포지션을 나타냅니다.

좌표 (0,0)에 나타난 4960은 올바르게 예측된 숏과 롱 포지션의 숫자입니다. 다음 값인 1163은 롱 포지션으로 예측된 숏 포지션의 개수이죠.

좌표 (1,0)에 나타난 858은 숏 포지션으로 예측된 롱 포지션을 나타냅니다. 5677은 올바르게 예측된 롱 포지션이고요.

이제 모델화 결과를 보죠.

다음은 모델의 전체 변수가 포함된 표의 일부입니다. 변수 중요도가 나타난 표죠.


01MeanDecreaseAccuracyMeanDecreaseGini
MA_eur.5.dif142.9741.8554.86 321.86
EUR.dif337.2146.3851.80177.34
RSI_eur.14 37.7040.1150.75254.61
EUR.dif2 24.6631.6438.24110.83
MA_eur.10.dif122.9425.3931.48193.08
CHF.dif3  22.9123.4230.1573.36
MA_chf.5.dif1  21.8123.2429.56135.34

표 3. 랜덤 포레스트 모델 변수 중요도

변수 중요도 평가 방법에는 여러가지가 있습니다. 여기서 이야기하는 '중요도'는 목표 변수에 대한 특정 변수의 영향 정도를 나타냅니다. 그 값이 클수록 해당 변수가 더 '중요'한 것이죠.

위의 표를 이용하면 모델에서 가장 영향력이 적은 값을 제외시킬 수 있습니다. 통계, 특히 통계적 분류에서는 모델이 간단할 수록 좋습니다. 정확도가 유지된다는 전제 하에서요.

Model 탭에서는 Errors 버튼이 가장 중요한데요. 이 버튼을 누르면 그림 8과 같은 결과가 나타납니다.

그림 8. 트리 개수에 대한 모델화 오류 종속성

그림 8. 트리 개수에 대한 모델화 오류 종속성

6. 모델 효율성

모델 효율성 평가는 Evaluate 탭에서 실행됩니다. 여러가지 옵션이 제공되죠.

위에서 분할표라고 불렀던 혼동행렬을 이용하겠습니다.

Model 탭에서 Evaluate 탭으로 이동하면 가장 최근 만들어진 모델이 자동적으로 플래그됩니다. Rattle의 작동 원리와 아주 잘 맞죠. 모델을 만들고 그 효율성을 평가하는 거니까요.

모델 평가에 사용될 데이터 세트를 정해야 합니다. 여러가지 데이터 소스를 선택할 수 있는데요.

첫 번째 네 가지 옵션은 Data 탭에서 설정한 데이터 세트를 분할합니다. Training, Validation, Test, Full(전체 세트)로 나뉘죠. 위에서 이미 다룬 내용입니다.

첫 번째 옵션은 학습 데이터 세트를 이용해 모델을 검증합니다. 별로 좋은 선택은 아니죠. 이미 해당 학습 데이터 세트를 기반으로 모델이 구축되었기 때문이죠. 당연히 좋은 결과가 나올 수 밖에 없습니다. 해당 모델은 기존에 알려지지 않은 데이터를 이용하도록 고안되었습니다.

새로운 데이터를 이용해서도 좋은 결과를 획득할 수 있어야 하죠. 동시에 모델의 오류에 대한 실제 평가도 받게 됩니다. 예측 데이터와 실제 데이터의 차이를 반영한 것이죠. 학습 데이터가 아닌 미지의 데이터 세트에 대한 해당 평가가 모델 효율성을 평가하는 가장 좋은 방법입니다.

모델 생성 시 타당성 검증 데이터를 이용해 모델 효율성을 평가하게 됩니다. 따라서 모델 생성이 완료되면 그 효율성은 해당 검증 데이터 세트를 대상으로 평가되죠. 몇 가지 옵션이 변경되는 경우도 있습니다. 이 경우 새로운 모델은 검증 데이터 세트를 기반으로 기존 모델과 그 효율성이 비교됩니다. 다시 말해 유효성 검사용 데이터 세트는 최종 모델 개발에 사용되죠. 따라서 유효성 검증 데이터 세트를 이용하면 정확한 모델의 효율성을 알 수 없습니다.

테스트 데이터는 모델 생성 과정에서 전혀 사용된 적이 없죠. 학습 데이터 세트와 검증 데이터 세트를 이용해 최적의 모델을 찾았다면 테스트 데이터 세트를 이용해 해당 모델의 효율성을 평가할 수 있습니다. 이렇게 하면 새로운 데이터에 대한 기대 효율성을 평가할 수 있습니다. 네 번째 옵션은 모델 평가에 전체 데이터 세트를 이용하는데요. 학습, 검증 및 테스트 데이터 전체를 포함하는 데이터 세트입니다. 그냥 궁금해서 해 볼만은 하지만 정확한 데이터는 얻을 수 없겠죠.

또 한 가지 데이터 종류가 있는데요. 평가 타입에서 Score가 선택된 경우 활성화됩니다. 이 경우 추가 데이터 입력 창이 나타납니다.

혼동 행렬을 이용해 범주형 목표 변수를 예측하게 되죠.

해당 행렬은 예측값과 실제값을 비교해서 보여줍니다. 두 개의 표가 나타나죠. 첫 번째 표는 양적 결과이며 두 번째 표는 해당 결과를 퍼센트로 나타냅니다.

혼동 행렬은 Rattle의 Evaluate 탭에서 찾을 수 있습니다. 'Run'을 클릭하면 선택한 데이터에 대한 해당 모델이 구현되며 해당 데이터 세트 내 모든 관측값의 결과를 예측하게 됩니다. 그 결과로 나오는 예측값은 실제 관측값과 비교되죠.

그림 9는 위에서 연산한 랜덤 포레스트 모델의 혼동 행렬입니다.

그림 9. 랜덤 포레스트 모델 평가 결과

그림 9. 랜덤 포레스트 모델 평가 결과

평균 오류값은 0.167, 즉 16.7%입니다. 학습 단계에서 예측 오류는 15.97%였죠. 같은 값이라고 볼 수 있습니다.

테스트 데이터 세트에 대한 연산을 해 볼까요? 다음과 같은 결과가 나타납니다.

랜덤 포레스트 모델 혼동 행렬(개수)


예측
예측
실제  01
01016256
11931248

 표 4. 랜덤 포레스트 모델 혼동 행렬 절대값(테스트 데이터 세트)


랜덤 포레스트 모델 혼동 행렬(비율)


예측
예측

실제01Error
00.370.090.20
10.070.460.13

표 5. 랜던 포레스트 모델 혼동 행렬 상대값(테스트 데이터 세트)


전체 오류: 0.1654994, 평균 클래스 오류: 0.1649244

예측 오류 확률은 16.4%입니다.

세 수치가 거의 동일하게 나타났는데요. 이는 모델을 신뢰할 수 있음을 의미합니다.

Rattle로 산출된 모델의 효율성은 MetaTrader4 또는 MetaTrader5의 전략 테스터에서 반드시 확인되어야 합니다. 확인 후에는 데모 계좌에서 다시 테스트하고, 다시 한번 실제 계좌에서 작은 규모의 랏을 이용해 테스트해야 하죠. 그리고 나야만 모델에 대한 진정한 최종 평가를 내릴 수 있습니다.



7. 모델 개선

앞서 ZZ.35와 예측 변수의 상관 관계를 알아보면서 꽤 많은 예측 변수들이 목표 변수에 대한 낮은 상관 관계를 갖고 있음을 확인했습니다.

상관 계수가 0.01 미만인 예측 변수들을 삭제하도록 하겠습니다. Data 탭으로 가서 해당 예측 변수들이 무시되도록 설정한 후 Model 탭에서 랜덤 포레스트 모델 연산을 반복합니다.

다음의 결과가 나오죠.

  • 백 예측 오류 확률=15.77%
  • 검증 데이터 세트 오류 예측 확률=15.67%
  • 테스트 데이터 세트 오류 예측 확률=15.77%

오류가 거의 줄어들지 않기는 했지만 각 데이터 세트 간의 예측 오류 차이가 줄었습니다. 모델이 안정적임을 나타내죠.

상관 계수 표를 기반으로 계속해서 예측 변수를 삭제해 나가도 좋습니다. 모델 연산 과정에서 획득한 예측 변수 중요도 표의 데이터를 이용해 예측 오류를 감소시켰으므로 모델의 효율성이 개선되었다고 할 수 있죠.

모델 효율성이 떨어지지 않는 한 계속해서 예측 변수를 제거할 수 있습니다. 예측 변수와 비교했을 때 가장 간단하면서도 효율적인 모델이 나왔다고 생각되면 그만해도 됩니다.


8. MetaTrader4 모델 적용

이론상 Ratlle을 이용한 거래는 다음과 같이 이루어집니다. 외부 도구를 이용해 엑셀에서 Rattle 입력 변수를 만듭니다. 장 마감 후 얻은 가격을 소스 파일에 입력합니다. 몇 분 후 다음 날에 대한 예측이 완성되며 바로 이용할 수 있습니다.

MetaTrader4 터미널은 인트라데이 트레이딩에 필요합니다.

Rattle을 이용해 자동 또는 반자동 거래를 하기 위해서는 다음이 필요합니다.

  • R 작업공간에 저장된 학습 완료 모델
  • 터미널과 R 합동 라이브러리
  • 새로운 블록을 모델로 전달해 결과를 얻고 해당 결과를 터미널로 다시 전달하는 R 코드

Rattle이 제공하는 6개 모델 중 하나를 훈련하는 방법을 알아봤습니다. R의 분류 모델 개수는 150개에 달하지만 Rattle로는 사용을 할 수 없죠.

R과 MetaTrader4 인터랙션 라이브러리는 코드베이스의 새로운 MQL4를 위한 mt4R에서 찾을 수 있습니다.

학습 모델에 해당하는 R 코드는 Log 탭에서 확인할 수 있고요. 모델 개발 시 진행된 모든 작업은 R 코드로 기록됩니다. 실제 거래에서도 해당 코드가 이용됩니다.


결론

여러분 모두의 거래 시스템 초기 평가 및 선택에 유용한 글일 겁니다.

Rattle을 이용한 거래 시스템 개발 시 가장 중요한 문제는 목표 변수와 필요한 예측 변수의 올바른 선택입니다. 숙련된 투자자라면 이미 이에 대해서 알고 있을 것이고, 초보 투자자는 Rattle을 다루면서 배우게 될 겁니다.


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/1165

파일 첨부됨 |
Article.zip (6598.05 KB)
일반 VPS보다 MetaTrader4, MetaTrader5 가상 호스팅이 더 나은 이유 일반 VPS보다 MetaTrader4, MetaTrader5 가상 호스팅이 더 나은 이유
가상 클라우드 호스팅 네트워크는 MetaTrader4와 MetaTrader5 전용으로 개발되었습니다. 네이티브 솔루션으로서 다양한 장점을 가지고 있죠. 24시간 무료 체험을 통해 가상 서버를 이용해 보세요.
MQL5 쿡북: 커스텀 차트 이벤트 핸들링 MQL5 쿡북: 커스텀 차트 이벤트 핸들링
본문은 MQL5 환경에서의 커스텀 차트 이벤트 시스템 디자인 및 개발을 다루고 있습니다. 이벤트 분류 예제 및 이벤트 클래스 코드와 커스텀 이벤트 핸들러 클래스 코드가 포함되어 있습니다.
MQL5 쿡북: BookEvent 핸들링 MQL5 쿡북: BookEvent 핸들링
이번 글은 시장 심도 이벤트와 그 원리 및 프로세스를 다룹니다. 시장 심도를 다루는 MQL 프로그램을 예로 들겠습니다. 해당 프로그램은 객체 지향 접근법을 적용해 작성되었습니다. 핸들링 결과는 화면에 패널 및 시장 심도 레벨로 표시됩니다.
MQL5 쿡북: TradeTransaction 이벤트 프로세싱 MQL5 쿡북: TradeTransaction 이벤트 프로세싱
본문은 이벤트 기반 프로그래밍의 관점에서 본 MQL5의 가능성에 대해 다룹니다. 이벤트 기반 프로그래밍의 최대 장점은 프로그램이 거래 오퍼레이션에 대한 단계적인 구현 정보를 수신할 수 있다는 거죠. TradeTransaction 이벤트 핸들러를 이용해 진행 중인 거래 오퍼레이션에 대한 정보를 수신하고 프로세스하는 법에 대해서도 알아볼 겁니다. 제 생각에 이 방법은 터미널 간 거래 카피에 이용할 수 있을 것 같아요.