English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
머신 러닝: 트레이딩에서 서포트 벡터 머신을 사용하는 방법

머신 러닝: 트레이딩에서 서포트 벡터 머신을 사용하는 방법

MetaTrader 5트레이딩 | 2 9월 2021, 16:43
160 0
Josh Readhead
Josh Readhead

서포트 벡터 머신이란?

서포트 벡터 머신은 입력 데이터를 가져와서 두 가지 범주 중 하나로 분류하는 머신 러닝 방법입니다. 서포트 벡터 머신이 효과적이려면 먼저 훈련 입력 및 출력 데이터 세트를 사용하여 새로운 데이터를 분류하는 데 사용할 수 있는 서포트 벡터 머신 모델을 구축해야 합니다.

서포트 벡터 머신은 학습 입력을 가져와 이를 다차원 공간에 매핑한 다음 회귀를 사용하여 두 개의 입력 클래스를 가장 잘 분리하는 초평면(초평면은 공간을 분리하는 n차원 공간의 표면)을 찾는 방식으로 이 모델을 개발합니다. 서포트 벡터 머신이 훈련을 마치게 되면 분리 초평면과 관련하여 새로운 입력을 평가하고 두 범주 중 하나로 분류할 수 있습니다.

서포트 벡터 머신은 본질적으로 입출력 머신입니다. 사용자는 입력을 할 수 있고 훈련을 통해 개발된 모델을 기반으로 출력을 반환합니다. 주어진 서포트 벡터 머신에 대한 입력 수는 이론적으로 1에서 무한대까지 다양하지만 실제적으로 계산 능력은 사용할 수 있는 입력 수를 제한합니다. 예를 들어, N개의 입력이 특정 서포트 벡터 머신에 사용되는 경우 (N의 정수 값은 1에서 무한대 사이일 수 있음), 서포트 벡터 기계는 각 입력 집합을 N차원 공간에 매핑하고 교육 데이터를 가장 잘 구분하는 (N-1)차원 초평면을 찾아야 합니다.

입출력 기계

그림 1. 서포트 벡터 머신은 입출력 머신입니다.

서포트 벡터 머신이 작동하는 방식을 개념화하는 가장 좋은 방법은 2차원 사례를 고려하는 것입니다. 두 개의 입력이 있고 데이터 포인트를 두 범주 중 하나에 속하는 것으로 분류하는 단일 출력을 반환하는 서포트 벡터 머신을 생성한다고 가정합니다. 이를 아래 차트와 같은 2차원 차트에 그려서 시각화할 수 있습니다.

초평면 분리

그림 2. 왼쪽: 2D 차트에 매핑된 벡터 머신 입력을 지원합니다. 빨간색 원과 파란색 십자가는 두 가지 입력 클래스를 나타내는 데 사용됩니다.

그림 3. 오른쪽: 2D 차트에 매핑된 벡터 머신 입력을 지원합니다. 빨간색 원과 파란색 십자가는 분리 초평면을 나타내는 검은색 선으로 두 가지 입력 클래스를 나타내는 데 사용됩니다.

이 예에서 파란색 십자형은 범주 1에 속하는 데이터 요소를 나타내고 빨간색 원은 범주 2에 속하는 데이터 요소를 나타냅니다. 각 개별 데이터 포인트에는 고유한 입력 1 값(x축에서 포지션으로 표시)과 고유한 입력 2 값(y축에서 포지션으로 표시)이 있으며 이러한 모든 포인트는 2차원 공간에 매핑되었습니다.

서포트 벡터 머신은 2차원 공간에서 이러한 점의 모델을 생성하여 데이터를 분류할 수 있습니다. 서포트 벡터 머신은 2차원 공간에서 데이터를 관찰하고 회귀 알고리즘을 사용하여 데이터를 두 범주로 가장 정확하게 분리하는 1차원 초평면(선이라고도 함)을 찾습니다. 그런 다음 이 구분선은 서포트 벡터 머신에서 새 데이터 포인트를 범주 1 또는 범주 2로 분류하는 데 사용됩니다.

아래 애니메이션은 새로운 서포트 벡터 머신을 훈련하는 과정을 보여줍니다. 알고리즘은 분리 초평면을 찾는 무작위 추측으로 시작한 다음 초평면의 정확도를 반복적으로 향상시킵니다. 보시다시피 알고리즘은 매우 공격적으로 시작하지만 욕구 솔루션에 접근하기 시작하면서 속도가 느려집니다.

최적의 분리 초평면을 찾는 서포트 벡터 머신 회귀 알고리즘

그림 4. 서포트 벡터 머신 트레이닝을 보여주는 애니메이션. 초평면은 이상적인 기하학에 점진적으로 수렴하여 두 클래스의 데이터를 분리합니다.

더 높은 차원

위에 제시된 2차원 시나리오를 통해 서포트 벡터 머신의 프로세스를 시각화할 수 있지만 두 개의 입력을 사용하여 데이터 포인트를 분류할 수만 있습니다. 더 많은 입력을 사용하려면 어떻게 해야 합니까? 고맙게도 서포트 벡터 머신 알고리즘을 사용하면 개념화하기가 훨씬 더 어려워지기는 하지만 더 높은 차원에서 동일한 작업을 수행할 수 있습니다.

이를 고려하여 20개의 입력을 사용하고 이러한 입력을 사용하여 모든 데이터 포인트를 범주 1 또는 범주 2로 분류할 수 있는 서포트 벡터 머신을 생성하려고 합니다. 이를 수행하기 위해 서포트 벡터 머신은 20차원 공간에서 데이터를 모델링하고 회귀 알고리즘을 사용하여 데이터 포인트를 두 범주로 분리하는 19차원 초평면을 찾아야 합니다. 이것은 우리가 3차원 이상의 것을 이해하기 어렵기 때문에 시각화하기가 매우 어렵습니다. 그러나 2차원의 경우와 정확히 동일한 방식으로 작동한다는 것을 알아야 합니다.


서포트 벡터 머신은 어떻게 작동합니까? 예: 슈닉 (Shnick)인가요?

이 가상의 시나리오를 상상해 보십시오. 당신은 슈닉 (Shnick)이라는 북극 심해에서만 발견되는 희귀 동물을 조사하는 연구원입니다. 이 동물들이 멀리 떨어져 있다는 점을 감안할 때 소수의 동물만이 발견되었습니다(약 5000마리 정도). 연구원으로서 당신은 질문에 갇혀 있습니다 ... 슈닉을 어떻게 식별 할 수 있습니까?

당신이 처분할 수 있는 것은 그 논문을 본 소수의 연구자들이 이전에 출판한 연구 논문뿐입니다. 이 연구 논문에서 저자는 키, 체중, 다리 수 등 그들이 발견한 슈닉 (schnick)에 대한 특정 특성을 설명합니다. 그러나 이러한 모든 특성은 식별 가능한 패턴이 없는 연구 논문마다 다릅니다...

이 데이터를 사용하여 새로운 동물을 슈닉으로 식별하는 방법은 무엇입니까?

우리 문제에 대한 한 가지 가능한 해결책은 데이터의 패턴을 식별하고 동물을 슈닉 또는 슈닉이 아닌 것으로 분류하는 데 사용할 수 있는 프레임워크를 만드는 서포트 벡터 머신을 사용하는 것입니다. 첫 번째 단계는 슈닉을 식별하도록 서포트 벡터 머신을 훈련하는 데 사용할 수 있는 데이터 세트를 만드는 것입니다. 훈련 데이터는 서포트 벡터 머신이 패턴을 분석하고 추출하기 위한 입력 및 일치 출력 세트입니다.

따라서 우리는 어떤 입력을 사용할 것인지, 얼마나 많이 사용할 것인지 결정해야 합니다. 이론적으로 우리는 원하는 만큼 많은 입력을 가질 수 있지만 이는 종종 느린 훈련으로 이어질 수 있습니다(입력이 많을수록 서포트 벡터 머신이 패턴을 추출하는 데 더 많은 시간이 소요됨). 또한 모든 슈닉에서 비교적 일관된 경향이 있는 입력 값을 선택하려고 합니다. 예를 들어, 동물의 키나 몸무게는 입력의 좋은 예가 될 것입니다. 왜냐하면 이것이 모든 슈닉에서 비교적 일관적일 것이라고 예상하기 때문입니다. 그러나 식별된 동물의 연령은 모두 상당히 다를 것으로 예상하기 때문에 동물의 평균 연령은 잘못된 입력 선택입니다.

이러한 이유로 다음 입력이 선택되었습니다.

  • 무게
  • 다리의 수
  • 눈의 수
  • 동물의 팔 길이
  • 동물의 평균 속도
  • 동물의 짝짓기 호출 빈도

입력을 선택하면 훈련 데이터 컴파일을 시작할 수 있습니다. 서포트 벡터 머신에 대한 효과적인 훈련 데이터는 다음과 같은 특정 요구 사항을 충족해야 합니다.

  • 데이터에는 슈닉인 동물의 예가 있어야 합니다.
  • 데이터에는 슈닉이 아닌 동물의 예가 있어야 합니다.

이 경우 우리는 슈닉을 성공적으로 식별하고 속성을 나열한 과학자의 연구 논문을 가지고 있습니다. 따라서 우리는 이러한 연구 논문을 읽고 각 입력에서 데이터를 추출하고 각 예에 참 또는 거짓 출력을 할당할 수 있습니다. 이 경우 훈련 데이터는 아래 표와 유사할 수 있습니다.

훈련 샘플 높이 [mm] 무게 [kg] N_legs N_eyes L_arm [mm] av_speed [m/s] f_call [Hz] 슈닉(참/거짓)
예시 1 1030 45 8 3 420 2.1 14000 진실
예시 2 1010 42 8 3 450 2.2 14000 진실
예시 3 900 40 7 6 600 6 13000 거짓
예시 4 1050 43 9 4 400 2.4 12000 진실
예시 5 700 35 2 8 320 21 13500 거짓
예시 6 1070 42 8 3 430 2.4 12000 진실
예시 7 1100 40 8 3 430 2.1 11000 진실
예시 N ... ... ... ... ... ... ... ...

표 1. 슈닉 관찰 표의 예

모든 훈련 입력 및 출력에 대한 데이터를 수집하면 이를 사용하여 서포트 벡터 머신을 훈련할 수 있습니다. 훈련 과정에서 서포트 벡터 머신은 7차원 공간에서 모델을 생성하여 각 훈련 예제를 참 또는 거짓으로 분류하는 데 사용할 수 있습니다. 서포트 벡터 머신은 훈련 데이터를 (지정된 허용 오차 내에서) 정확하게 나타내는 모델을 가질 때까지 이 작업을 계속할 것입니다. 훈련이 완료되면 이 모델을 사용하여 새 데이터 포인트를 참 또는 거짓으로 분류할 수 있습니다.


서포트 벡터 머신이 실제로 작동합니까?

슈닉 시나리오를 사용하여 서포트 벡터 머신 (support vector machine)이 실제로 새로운 슈닉을 얼마나 잘 식별할 수 있는지 테스트하는 스크립트를 작성했습니다. 이를 위해 Market에서 다운로드할 수 있는 "Support Vector Machine Learning Tool" 기능 라이브러리를 사용했습니다.

이 시나리오를 효과적으로 모델링하려면 먼저 슈닉의 실제 속성이 무엇인지 결정해야 합니다. 이 경우에 가정한 속성은 아래 표에 나열되어 있습니다. 동물이 아래 기준을 모두 충족하면 슈닉입니다...

매개변수 낮은 범위 상위 범위
높이 [mm] 1000 1100
무게 [kg] 40 50
N_legs 8 10
N_eyes 3 4
L_arm [mm] 400 450
av_speed [m/s] 2 2.5
f_call [Hz] 11000 15000

표 2. 슈닉을 정의하는 매개변수 요약

이제 슈닉을 정의했으므로 이 정의를 사용하여 서포트 벡터 머신을 실험할 수 있습니다. 첫 번째 단계는 주어진 동물에 대해 7개의 입력을 받아 동물의 실제 분류를 슈닉으로 반환할지 여부를 반환할 수 있는 함수를 만드는 것입니다. 이 기능은 서포트 벡터 머신에 대한 훈련 데이터를 생성하고 마지막에 성능을 평가하는 데 사용됩니다. 이것은 아래 함수를 사용하여 수행할 수 있습니다.

//+------------------------------------------------------------------+
//| This function takes the observation properties of the observed 
//| animal and based on the criteria we have chosen, returns true/false whether it is a schnick
//+------------------------------------------------------------------+
bool isItASchnick(double height,double weight,double N_legs,double N_eyes,double L_arm,double av_speed,double f_call)
  {
   if(height   < 1000  || height   > 1100)  return(false);   // If the height is outside the parameters > return(false)
   if(weight   < 40    || weight   > 50)    return(false);   // If the weight is outside the parameters > return(false)
   if(N_legs   < 8     || N_legs   > 10)    return(false);   // If the N_Legs is outside the parameters > return(false)
   if(N_eyes   < 3     || N_eyes   > 4)     return(false);   // If the N_eyes is outside the parameters > return(false)
   if(L_arm    < 400   || L_arm    > 450)   return(false);   // If the L_arm  is outside the parameters > return(false)
   if(av_speed < 2     || av_speed > 2.5)   return(false);   // If the av_speed is outside the parameters > return(false)
   if(f_call   < 11000 || f_call   > 15000) return(false);   // If the f_call is outside the parameters > return(false)
   return(true);                                             // Otherwise > return(true)
  }

프로세스의 다음 단계는 훈련 입력 및 출력을 생성할 수 있는 함수를 생성하는 것입니다. 이 경우 입력은 7개의 입력 값 각각에 대해 설정된 범위 내에서 난수를 생성하여 생성됩니다. 그런 다음 생성된 각 무작위 입력 세트에 대해 위의 isItASchnick() 함수를 사용하여 해당하는 원하는 출력을 생성합니다. 이것은 아래 함수에서 수행됩니다.

//+------------------------------------------------------------------+
//| This function takes an empty double array and an empty boolean array,
//| and generates the inputs/outputs to be used for training the SVM
//+------------------------------------------------------------------+ 
void genTrainingData(double &inputs[],bool &outputs[],int N)
  {
   double in[];                    // Creates an empty double array to be used for temporarily storing the inputs generated
   ArrayResize(in,N_Inputs);       // Resize the in[] array to N_Inputs
   ArrayResize(inputs,N*N_Inputs); // Resize the inputs[] array to have a size of N*N_Inputs 
   ArrayResize(outputs,N);         // Resize the outputs[] array to have a size of N 
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);      // Random input generated for height
      in[1]=    randBetween(38,52);         // Random input generated for weight
      in[2]=    randBetween(7,11);          // Random input generated for N_legs
      in[3]=    randBetween(3,4.2);         // Random input generated for N_eyes
      in[4]=    randBetween(380,450);       // Random input generated for L_arms
      in[5]=    randBetween(2,2.6);         // Random input generated for av_speed
      in[6]=    randBetween(10500,15500);   // Random input generated for f_call
      ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs);                         // Copy the new random inputs generated into the training input array
      outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); // Assess the random inputs and determine if it is a schnick
     }
  }
//+------------------------------------------------------------------+
//| This function is used to create a random value between t1 and t2
//+------------------------------------------------------------------+ 
double randBetween(double t1,double t2)
  {
   return((t2-t1)*((double)MathRand()/(double)32767)+t1);
  }

이제 교육 입력 및 출력 세트가 있습니다. 이제 시장에서 사용할 수 있는 '서포트 벡터 머신 러닝 툴 (Support Vector Machine Learning Tool)'을 사용하여 서포트 벡터 머신을 만들 차례입니다. 새로운 서포트 벡터 머신이 생성되면 훈련 입력과 출력을 전달하고 훈련을 실행해야 합니다.

void OnStart()
  {
   double inputs[];              // Empty double array to be used for creating training inputs
   bool   outputs[];             // Empty bool array to be used for creating training inputs
   int    N_TrainingPoints=5000; // Defines the number of training samples to be generated
   int    N_TestPoints=5000;     // Defines the number of samples to be used when testing

   genTrainingData(inputs,outputs,N_TrainingPoints); //Generates the inputs and outputs to be used for training the SVM

   int handle1=initSVMachine();             // Initializes a new support vector machine and returns a handle
   setInputs(handle1,inputs,7);             // Passes the inputs (without errors) to the support vector machine
   setOutputs(handle1,outputs);             // Passes the outputs (without errors) to the support vector machine
   setParameter(handle1,OP_TOLERANCE,0.05); // Sets the error tolerance parameter to <5%
   training(handle1);                       // Trains the support vector machine using the inputs/outputs passed
  }

이제 슈닉을 식별하는 데 성공적으로 훈련된 서포트 벡터 머신이 있습니다. 이를 확인하기 위해 새로운 데이터 포인트를 분류하도록 요청하여 최종 서포트 벡터 머신을 테스트할 수 있습니다. 이것은 먼저 임의의 입력을 생성한 다음 isItASchnick() 함수를 사용하여 이러한 입력이 실제 슈닉에 해당하는지 결정한 다음 서포트 벡터 머신을 사용하여 입력을 분류하고 예상된 결과가 실제 결과와 일치합니다. 이것은 아래 함수에서 수행됩니다.

//+------------------------------------------------------------------+
//| This function takes the handle for the trained SVM and tests how
//| successful it is at classifying new random inputs
//+------------------------------------------------------------------+ 
double testSVM(int handle,int N)
  {
   double in[];
   int atrue=0;
   int afalse=0;
   int N_correct=0;
   bool Predicted_Output;
   bool Actual_Output;
   ArrayResize(in,N_Inputs);
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);      // Random input generated for height
      in[1]=    randBetween(38,52);         // Random input generated for weight
      in[2]=    randBetween(7,11);          // Random input generated for N_legs
      in[3]=    randBetween(3,4.2);         // Random input generated for N_eyes
      in[4]=    randBetween(380,450);       // Random input generated for L_arms
      in[5]=    randBetween(2,2.6);         // Random input generated for av_speed
      in[6]=    randBetween(10500,15500);   // Random input generated for f_call
      Actual_Output=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); // Uses the isItASchnick fcn to determine the actual desired output
      Predicted_Output=classify(handle,in);                                  // Uses the trained SVM to return the predicted output.
      if(Actual_Output==Predicted_Output)
        {
         N_correct++;   // This statement keeps count of the number of times the predicted output is correct.
        }
     }

   return(100*((double)N_correct/(double)N));   // Returns the accuracy of the trained SVM as a percentage
  }

다른 조건에서 서포트 벡터 머신이 어떻게 작동하는지 보려면 위의 함수 내에서 값을 사용하는 것이 좋습니다.


서포트 벡터 머신 (Support Vector Machine)이 유용한 이유는 무엇입니까?

데이터에서 복잡한 패턴을 추출하기 위해 서포트 벡터 머신을 사용하는 것의 이점은 데이터의 동작에 대한 사전 이해가 필요하지 않다는 것입니다. 서포트 벡터 머신은 데이터를 분석하고 유일한 통찰력과 관계를 추출할 수 있습니다. 이러한 방식으로 입력을 수신하고 출력을 생성하는 블랙박스와 유사한 기능을 하며 데이터에서 너무 복잡하고 명확하지 않은 패턴을 찾는 데 매우 유용할 수 있습니다.

서포트 벡터 머신의 가장 큰 특징 중 하나는 데이터의 오류와 노이즈를 매우 잘 처리할 수 있다는 것입니다. 그들은 종종 데이터 내의 기본 패턴을 확인하고 데이터 이상값 및 기타 복잡성을 걸러낼 수 있습니다. 다음 시나리오를 고려하세요. 슈닉에 대한 연구를 수행할 때 슈닉을 설명하는 여러 연구 논문에서 엄청나게 다른 특성(예: 200kg이고 키가 15000mm인 슈닉)을 접하게 됩니다.

이와 같은 오류로 인해 슈닉이 무엇인지에 대한 모델이 왜곡되어 새로운 슈닉 발견을 분류할 때 잠재적으로 오류를 범할 수 있습니다. 서포트 벡터 머신의 이점은 모든 훈련 데이터 포인트에 맞는 모델과 반대되는 기본 패턴과 일치하는 모델을 개발한다는 것입니다. 이는 모델에서 특정 수준의 오류를 허용하여 서포트 벡터 머신이 데이터의 오류를 간과할 수 있도록 함으로써 수행됩니다.

슈닉 서포트 벡터 머신의 경우 5%의 허용 오차를 허용하면 훈련은 훈련 데이터의 95%와 일치하는 모델을 개발하려고만 시도합니다. 이는 훈련에서 소수의 이상값을 무시할 수 있기 때문에 유용할 수 있습니다.

슈닉 스크립트를 수정하여 서포트 벡터 머신의 이 속성을 더 조사할 수 있습니다. 아래 함수는 훈련 데이터 세트에 의도적인 무작위 오류를 도입하기 위해 추가되었습니다. 이 함수는 무작위로 훈련 포인트를 선택하고 입력과 해당 출력을 무작위 변수로 바꿉니다.

//+------------------------------------------------------------------+
//| This function takes the correct training inputs and outputs generated
//| and inserts N random errors into the data
//+------------------------------------------------------------------+ 
void insertRandomErrors(double &inputs[],bool &outputs[],int N)
  {
   int    nTrainingPoints=ArraySize(outputs); // Calculates the number of training points
   int    index;                              // Creates new integer 'index'
   bool   randomOutput;                       // Creates new bool 'randomOutput'
   double in[];                               // Creates an empty double array to be used for temporarily storing the inputs generated
   ArrayResize(in,N_Inputs);                  // Resize the in[] array to N_Inputs
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);        // Random input generated for height
      in[1]=    randBetween(38,52);           // Random input generated for weight
      in[2]=    randBetween(7,11);            // Random input generated for N_legs
      in[3]=    randBetween(3,4.2);           // Random input generated for N_eyes
      in[4]=    randBetween(380,450);         // Random input generated for L_arms
      in[5]=    randBetween(2,2.6);           // Random input generated for av_speed
      in[6]=    randBetween(10500,15500);     // Random input generated for f_call

      index=(int)MathRound(randBetween(0,nTrainingPoints-1)); // Randomly chooses one of the training inputs to insert an error
      if(randBetween(0,1)>0.5) randomOutput=true;             // Generates a random boolean output to be used to create an error
      else                     randomOutput=false;

      ArrayCopy(inputs,in,index*N_Inputs,0,N_Inputs);         // Copy the new random inputs generated into the training input array
      outputs[index]=randomOutput;                            // Copy the new random output generated into the training output array
     }
  }

이 기능을 사용하면 훈련 데이터에 의도적인 오류를 도입할 수 있습니다. 이 오류가 채워진 데이터를 사용하여 새로운 서포트 벡터 머신을 생성 및 훈련하고 성능을 원래 머신과 비교할 수 있습니다.

void OnStart()
  {
   double inputs[];              // Empty double array to be used for creating training inputs
   bool   outputs[];             // Empty bool array to be used for creating training inputs
   int    N_TrainingPoints=5000; // Defines the number of training samples to be generated
   int    N_TestPoints=5000;     // Defines the number of samples to be used when testing

   genTrainingData(inputs,outputs,N_TrainingPoints); // Generates the inputs and outputs to be used for training the svm

   int handle1=initSVMachine();             // Initializes a new support vector machine and returns a handle
   setInputs(handle1,inputs,7);             // Passes the inputs (without errors) to the support vector machine
   setOutputs(handle1,outputs);             // Passes the outputs (without errors) to the support vector machine
   setParameter(handle1,OP_TOLERANCE,0.05); // Sets the error tolerance parameter to <5%
   training(handle1);                       // Trains the support vector machine using the inputs/outputs passed

   insertRandomErrors(inputs,outputs,500);  // Takes the original inputs/outputs generated and adds random errors to the data

   int handle2=initSVMachine();             // Initializes a new support vector machine and returns a handle
   setInputs(handle2,inputs,7);             // Passes the inputs (with errors) to the support vector machine
   setOutputs(handle2,outputs);             // Passes the outputs (with errors) to the support vector machine
   setParameter(handle2,OP_TOLERANCE,0.05); // Sets the error tolerance parameter to <5%
   training(handle2);                       // Trains the support vector machine using the inputs/outputs passed

   double t1=testSVM(handle1,N_TestPoints); // Tests the accuracy of the trained support vector machine and saves it to t1
   double t2=testSVM(handle2,N_TestPoints); // Tests the accuracy of the trained support vector machine and saves it to t2

   Print("The SVM accuracy is ",NormalizeDouble(t1,2),"% (using training inputs/outputs without errors)");
   Print("The SVM accuracy is ",NormalizeDouble(t2,2),"% (using training inputs/outputs with errors)");
   deinitSVMachine();                       // Cleans up all of the memory used in generating the SVM to avoid memory leak
  }

스크립트가 실행되면 Expert Log에 다음과 같은 결과가 생성됩니다. 5000개의 훈련 포인트가 있는 훈련 데이터 세트 내에서 500개의 임의 오류를 도입할 수 있었습니다. 이 오류가 채워진 서포트 벡터 머신의 성능을 원래의 것과 비교할 때 성능은 <1%만 감소합니다. 이는 서포트 벡터 머신이 훈련할 때 데이터 세트의 이상값을 간과할 수 있고 여전히 실제 데이터의 놀랍도록 정확한 모델을 생성할 수 있기 때문입니다. 이것은 서포트 벡터 머신이 잡음이 있는 데이터 세트에서 복잡한 패턴과 통찰력을 추출하는 데 잠재적으로 더 유용한 도구가 될 수 있음을 시사합니다.

Expert 로그

그림 5. MetaTrader 5에서 "슈닉" 스크립트를 실행한 후 결과 Expert 로그입니다.


데모 버전들

위 코드의 전체 버전은 Code Base에서 다운로드할 수 있지만 이 스크립트는 시장에서 서포트 벡터 머신 러닝 도구의 전체 버전을 구입한 경우에만 터미널에서 실행할 수 있습니다. 이 도구의 데모 버전만 다운로드한 경우 전략 테스터를 통한 도구 사용이 제한됩니다. 도구의 데모 버전을 사용하여 "슈닉" 코드를 테스트할 수 있도록 스크립트 사본을 전략 테스터를 사용하여 배포할 수 있는 Expert Advisor로 다시 작성했습니다. 이 두 코드 버전은 아래 링크를 따라 다운로드할 수 있습니다.

  • 정식 버전 - MetaTrader 5 터미널 에 배포된 스크립트 사용(매수한 버전의 서포트 벡터 머신 러닝 툴 필요)

  • 데모 버전 - MetaTrader 5 전략 테스터에 배포된 Expert Advisor 사용 (서포트 벡터 머신 러닝 툴의 데모 버전만 필요함)


시장에서 서포트 벡터 머신을 어떻게 사용할 수 있습니까?

분명히 위에서 논의한 슈닉의 예는 매우 간단하지만 이 예와 기술 시장 분석을 위한 서포트 벡터 머신 사용 사이에는 몇 가지 유사점이 있습니다.

기술적 분석은 기본적으로 과거 시장 데이터를 사용하여 미래 가격 움직임을 예측하는 것입니다. 같은 방식으로 슈닉 사례에서 우리는 과거 과학자들이 관찰한 내용을 사용하여 새로운 동물이 슈닉인지 아닌지를 예측했습니다. 또한, 시장은 서포트 벡터 머신을 흥미로운 개념으로 만드는 잡음, 오류 및 통계적 이상값으로 인해 어려움을 겪고 있습니다.

상당한 수의 기술적 분석 거래 접근 방식의 기초에는 다음 단계가 포함됩니다.

  1. 여러 지표 모니터링
  2. 잠재적으로 성공적인 거래와 상관관계가 있는 각 지표의 조건 식별
  3. 각 지표를 관찰하고 모두(또는 대부분) 거래 신호를 보내는 시점을 평가합니다.

유사한 방식으로 새로운 거래를 알리기 위해 서포트 벡터 머신을 사용하는 유사한 접근 방식을 채택하는 것이 가능합니다. 서포트 벡터 기계 학습 도구는 이를 염두에 두고 개발되었습니다. 이 도구를 사용하는 방법에 대한 전체 설명은 마켓에서 찾을 수 있으므로 간략한 개요만 제공하겠습니다. 이 도구를 사용하는 프로세스는 다음과 같습니다.

블록 다이어그램

그림 6. Expert Advisor에서 서포트 벡터 공작 기계를 구현하는 프로세스를 보여주는 블록 다이어그램

서포트 벡터 머신 러닝 툴을 사용하기 전에 먼저 교육 입력 및 출력이 생성되는 방식을 이해하는 것이 중요합니다.

훈련 입력은 어떻게 생성됩니까?

따라서 입력으로 사용하려는 지표와 새로운 서포트 벡터 머신이 이미 초기화되었습니다. 다음 단계는 지표 핸들을 새로운 서포트 벡터 머신에 전달하고 훈련 데이터를 생성하는 방법을 지시하는 것입니다. 이것은 setIndicatorHandles() 함수를 호출하여 수행됩니다. 이 함수를 사용하면 초기화된 지표의 핸들을 서포트 벡터 머신으로 전달할 수 있습니다. 이것은 핸들을 포함하는 정수 배열을 전달하여 수행됩니다. 이 함수의 다른 두 입력은 오프셋 값과 데이터 포인트 수입니다.

오프셋 값은 훈련 입력을 생성하는 데 사용할 현재 바와 시작 바 사이의 오프셋을 나타내며 훈련 포인트 수(N으로 표시)는 훈련 데이터의 크기를 설정합니다. 아래 다이어그램은 이러한 값을 사용하는 방법을 보여줍니다. 오프셋 값이 4이고 N 값이 6이면 서포트 벡터 머신이 흰색 사각형에 캡처된 바만 사용하여 교육 입력 및 출력을 생성하도록 지시합니다. 마찬가지로 오프셋 값이 8이고 N 값이 8이면 서포트 벡터 머신이 파란색 사각형에 캡처된 바만 사용하여 교육 입력 및 출력을 생성하도록 지시합니다.

setIndicatorHandles() 함수가 호출되면 genInputs() 함수를 호출할 수 있습니다. 이 함수는 교육에 사용할 입력 데이터 배열을 생성하기 위해 전달된 지표 핸들을 사용합니다.

그림 7. 오프셋 및 N 값을 보여주는 캔들 차트

그림 7. 오프셋 및 N 값을 보여주는 캔들 차트


훈련 출력은 어떻게 생성됩니까?

훈련 결과는 과거 가격 데이터를 기반으로 가상 거래를 시뮬레이션하고 그러한 거래가 성공했는지 여부를 결정함으로써 생성됩니다. 이를 위해 가상 거래를 성공 또는 실패로 평가하는 방법을 서포트 벡터 기계 학습 도구에 지시하는 데 사용되는 몇 가지 매개변수가 있습니다.

첫 번째 변수는 OP_TRADE입니다. 이 값은 BUY 또는 SELL일 수 있으며 가상의 매수 또는 매도 거래에 해당합니다. 이 값이 BUY이면 출력을 생성할 때 가상 매수 거래의 잠재적 성공만 볼 것입니다. 또는 이 값이 SELL인 경우 출력을 생성할 때 가상 매도 거래의 잠재적 성공만 볼 것입니다.

사용된 다음 값은 이러한 가상 거래에 대한 손절매 및 이익실현입니다. 값은 핍으로 설정되며 각 가상 거래에 대한 정지 및 제한 수준을 설정합니다.

마지막 매개변수는 거래 기간입니다. 이 변수는 시간 단위로 측정되며 이 최대 기간 내에 완료된 거래만 성공한 것으로 간주됩니다. 이 변수를 포함하는 이유는 천천히 움직이는 횡보 시장에서 서포트 벡터 기계 신호 거래를 피하기 위함입니다.


입력을 선택할 때 고려해야 할 사항

거래에서 서포트 벡터 머신을 구현할 때 입력 선택에 대해 생각하는 것이 중요합니다. 슈닉의 예와 유사하게, 발생 빈도의 차이에서 유사할 것으로 예상되는 입력을 선택하는 것이 중요합니다. 예를 들어 이동 평균을 입력으로 사용하고 싶을 수 있지만 장기 평균 가격은 시간이 지남에 따라 상당히 급격하게 변하는 경향이 있으므로 단독으로 이동 평균을 사용하는 것이 가장 좋은 입력이 아닐 수 있습니다. 오늘의 이동평균값과 6개월 전의 이동평균값 사이에 유의미한 유사점이 없을 것이기 때문입니다.

EURUSD를 거래하고 '매수' 거래를 신호하기 위해 이동 평균 입력이 있는 서포트 벡터 머신을 사용한다고 가정합니다. 현재 가격이 1.10이지만 가격이 0.55였던 6개월 전의 교육 데이터를 생성한다고 가정해 보겠습니다. 서포트 벡터 머신을 훈련할 때, 이것이 발견하는 패턴은 가격이 약 0.55일 때만 신호가 전달되는 거래로 이어질 수 있습니다. 이것이 이것이 알고 있는 유일한 데이터이기 때문입니다. 따라서 가격이 다시 0.55로 떨어질 때까지 서포트 벡터 머신이 거래 신호를 보내지 않을 수 있습니다.

대신 MACD의 값은 평균 가격 수준과 독립적이고 상대적인 움직임만 신호하기 때문에 서포트 벡터 머신에 사용하기에 더 나은 입력은 MACD 또는 유사한 오실레이터일 수 있습니다. 가장 좋은 결과를 얻을 수 있는 방법을 알아보기 위해 이것을 실험하는 것이 좋습니다.

입력을 선택할 때 고려해야 할 또 다른 고려 사항은 서포트 벡터 머신에 새로운 거래를 알리는 지표의 적절한 스냅샷이 있는지 확인하는 것입니다. MACD는 추세를 보여주기 때문에 과거 5개의 바를 볼 수 있는 경우에만 유용하다는 것을 자신의 거래 경험에서 찾을 수 있습니다. MACD의 단일 바는 위 또는 아래로 향하고 있는지 여부를 알 수 없는 한 단독으로 쓸모가 없을 수 있습니다. 따라서 MACD 지표의 과거 몇 개 바를 서포트 벡터 기계로 전달해야 할 수 있습니다. 두 가지 가능한 방법이 있습니다.

  1. MACD 지표의 지난 5개 바를 사용하여 추세를 단일 값으로 계산하는 새 사용자 지정 지표를 만들 수 있습니다. 그런 다음 이 사용자 지정 지표를 단일 입력으로 서포트 벡터 기계에 전달할 수 있습니다.

  2. 지지 벡터 머신에서 MACD 지표의 이전 5개 바를 5개의 개별 입력으로 사용할 수 있습니다. 이를 수행하는 방법은 MACD 지표의 5가지 다른 인스턴스를 초기화하는 것입니다. 각 지표는 현재 바와 다른 오프셋으로 초기화할 수 있습니다. 그런 다음 개별 지표의 5개 핸들을 서포트 벡터 머신으로 전달할 수 있습니다. 옵션 2를 사용하면 Expert Advisor의 실행 시간이 길어지는 경향이 있습니다. 입력이 많을수록 성공적으로 훈련하는 데 더 오래 걸립니다.


서포트 벡터 머신 및 Expert Advisor 구현

누군가가 자신의 거래에서 서포트 벡터 머신을 잠재적으로 사용할 수 있는 방법의 예인 Expert Advisor를 준비했습니다(이 링크의 사본은 https://www.mql5.com/ko/code/1229에서 다운로드할 수 있습니다)). Expert Advisor를 통해 서포트 벡터 머신으로 약간의 실험을 할 수 있기를 바랍니다. 자신의 거래 스타일에 맞게 Expert Advisor를 복제/변경/수정하는 것이 좋습니다. EA는 다음과 같이 작동합니다.

  1. svMachineTool 라이브러리를 사용하여 두 개의 새로운 서포트 벡터 머신이 생성됩니다. 하나는 새로운 '매수' 거래를 신호하도록 설정되고 다른 하나는 새로운 '매도' 거래를 신호하도록 설정됩니다.

  2. 7개의 표준 지표는 각 핸들이 정수 배열에 저장되어 초기화됩니다(참고: 지표의 모든 조합을 입력으로 사용할 수 있으며 단일 정수 배열로 SVM에 전달하기만 하면 됩니다).

  3. 지표 핸들의 배열이 새로운 서포트 벡터 머신으로 전달됩니다.

  4. 지표 핸들 및 기타 매개변수의 배열을 사용하여 과거 가격 데이터를 사용하여 서포트 벡터 머신을 교육하는 데 사용할 정확한 입력 및 출력을 생성합니다.

  5. 모든 입력과 출력이 생성되면 두 서포트 벡터 머신이 모두 훈련됩니다.

  6. 훈련된 서포트 벡터 머신은 EA에서 새로운 '매수' 및 '매도' 거래를 알리는 데 사용됩니다. 새로운 '매수' 또는 '매도' 거래가 신호를 받으면 수동 손절매 및 이익실현 주문과 함께 거래가 열립니다.

서포트 벡터 머신의 초기화 및 교육은 onInit() 함수 내에서 실행됩니다. 참고로 svTrader EA의 이 부분은 메모와 함께 아래에 포함되어 있습니다.

#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#property indicator_buffers 7

//+---------Support Vector Machine Learning Tool Functions-----------+
//| The following #import statement imports all of the support vector
//| machine learning tool functions into the EA for use. Please note, if
//| you do not import the functions here, the compiler will not let you
//| use any of the functions
//+------------------------------------------------------------------+
#import "svMachineTool.ex5"
enum ENUM_TRADE {BUY,SELL};
enum ENUM_OPTION {OP_MEMORY,OP_MAXCYCLES,OP_TOLERANCE};
int  initSVMachine(void);
void setIndicatorHandles(int handle,int &indicatorHandles[],int offset,int N);
void setParameter(int handle,ENUM_OPTION option,double value);
bool genOutputs(int handle,ENUM_TRADE trade,int StopLoss,int TakeProfit,double duration);
bool genInputs(int handle);
bool setInputs(int handle,double &Inputs[],int nInputs);
bool setOutputs(int handle,bool &Outputs[]);
bool training(int handle);
bool classify(int handle);
bool classify(int handle,int offset);
bool classify(int handle,double &iput[]);
void  deinitSVMachine(void);
#import

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>

//+-----------------------Input Variables----------------------------+
input int            takeProfit=100;      // TakeProfit level measured in pips
input int            stopLoss=150;        // StopLoss level measured in pips
input double         hours=6;             // The maximum hypothetical trade duration for calculating training outputs.
input double         risk_exp=5;          // Maximum simultaneous order exposure to the market
input double         Tolerance_Value=0.1; // Error Tolerance value for training the SVM (default is 10%)
input int            N_DataPoints=100;    // The number of training points to generate and use.

//+---------------------Indicator Variables--------------------------+
//| Only the default indicator variables have been used here. I
//| recommend you play with these values to see if you get any 
//| better performance with your EA.                    
//+------------------------------------------------------------------+
int bears_period=13;
int bulls_period=13;
int ATR_period=13;
int mom_period=13;
int MACD_fast_period=12;
int MACD_slow_period=26;
int MACD_signal_period=9;
int Stoch_Kperiod=5;
int Stoch_Dperiod=3;
int Stoch_slowing=3;
int Force_period=13;

//+------------------Expert Advisor Variables------------------------+
int         tickets[];
bool        Opn_B,Opn_S;
datetime    New_Time;
int         handleB,handleS;
double      Vol=1;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   New_Time=0;
   int handles[];ArrayResize(handles,7);
//+------------------------------------------------------------------+
//| The following statements are used to initialize the indicators to be used for the support 
//| vector machine. The handles returned are stored to an int[] array. I have used standard 
//| indicators in this case however, you can also you custom indicators if desired
//+------------------------------------------------------------------+
   handles[0]=iBearsPower(Symbol(),0,bears_period);
   handles[1]=iBullsPower(Symbol(),0,bulls_period);
   handles[2]=iATR(Symbol(),0,ATR_period);
   handles[3]=iMomentum(Symbol(),0,mom_period,PRICE_TYPICAL);
   handles[4]=iMACD(Symbol(),0,MACD_fast_period,MACD_slow_period,MACD_signal_period,PRICE_TYPICAL);
   handles[5]=iStochastic(Symbol(),0,Stoch_Kperiod,Stoch_Dperiod,Stoch_slowing,MODE_SMA,STO_LOWHIGH);
   handles[6]=iForce(Symbol(),0,Force_period,MODE_SMA,VOLUME_TICK);

//----------Initialize, Setup and Training of the Buy-Signal support vector machine----------
   handleB=initSVMachine();                             // Initializes a new SVM and stores the handle to 'handleB'
   setIndicatorHandles(handleB,handles,0,N_DataPoints); // Passes the initialized indicators to the SVM with the desired offset 
                                                        // and number of data points
   setParameter(handleB,OP_TOLERANCE,Tolerance_Value);  // Sets the maximum error tolerance for SVM training
   genInputs(handleB);                                  // Generates inputs using the initialized indicators
   genOutputs(handleB,BUY,stopLoss,takeProfit,hours);   // Generates the outputs based on the desired parameters for taking hypothetical trades

//----------Initialize, Setup and Training of the Sell-Signal support vector machine----------
   handleS=initSVMachine();                             // Initializes a new SVM and stores the handle to 'handleS'
   setIndicatorHandles(handleS,handles,0,N_DataPoints); // Passes the initialized indicators to the SVM with the desired offset 
                                                        // and number of data points
   setParameter(handleS,OP_TOLERANCE,Tolerance_Value);  // Sets the maximum error tolerance for SVM training
   genInputs(handleS);                                  // Generates inputs using the initialized indicators
   genOutputs(handleS,SELL,stopLoss,takeProfit,hours);  // Generates the outputs based on the desired parameters for taking hypothetical trades
//----------
   training(handleB);   // Executes training on the Buy-Signal support vector machine
   training(handleS);   // Executes training on the Sell-Signal support vector machine   
   return(0);
  }


고급 서포트 벡터 기계 거래

고급 사용자를 위해 서포트 벡터 기계 학습 도구에 추가 기능이 구축되었습니다. 이 도구를 사용하면 사용자가 자신의 사용자 지정 입력 데이터 및 출력 데이터를 전달할 수 있습니다(슈닉 예제에서와 같이). 이를 통해 서포트 벡터 머신 입력 및 출력에 대한 자체 기준을 사용자 정의하고 이 데이터를 수동으로 전달하여 훈련할 수 있습니다. 이는 거래의 모든 측면에서 서포트 벡터 머신을 사용할 수 있는 기회를 제공합니다.

서포트 벡터 머신을 사용하여 새로운 거래를 알리는 것이 가능할 뿐만 아니라 거래 마감, 자금 관리, 새로운 고급 지표 등을 알리는 데에도 사용할 수 있습니다. 그러나 오류가 발생하지 않도록 하려면 이러한 입력 및 출력이 어떻게 구성되어야 하는지 이해하는 것이 중요합니다.

입력: 입력은 이중 값의 1차원 배열로 SVM에 전달됩니다. 생성하는 모든 입력은 이중 값으로 전달되어야 합니다. 부울, 정수 등은 모두 서포트 벡터 머신으로 전달되기 전에 이중 값으로 변환되어야 합니다. 입력은 다음 형식으로 필요합니다. 예를 들어 3개의 입력 x 5개의 학습 포인트가 있는 입력을 전달한다고 가정합니다. 이를 달성하려면 이중 배열의 길이가 다음 형식으로 15단위여야 합니다.

| A1 | B1 | C1 | A2 | B2 | C2 | A3 | B3 | C3 | A4 | B4 | C4 | A5 | B5 | C5 |

또한 입력 수에 대한 값을 전달해야 합니다. 이 경우 N_Inputs=3입니다.

출력: 출력은 부울 값의 배열로 전달됩니다. 이 부울 값은 전달된 각 입력 세트에 해당하는 SVM의 원하는 출력입니다. 위의 예에 따라 5개의 훈련 포인트가 있다고 가정합니다. 이 시나리오에서는 길이가 5단위인 부울 출력 값 배열을 전달합니다.

일반 참고 사항:

  • 고유한 입력 및 출력을 생성할 때 배열의 길이가 전달한 값과 일치하는지 확인하세요. 일치하지 않으면 불일치를 알리는 오류가 생성됩니다. 예를 들어, N_Inputs=3을 전달하고 입력이 길이 16의 배열인 경우 오류가 발생합니다(N_inputs 값이 3이면 입력 배열의 길이가 3의 배수여야 함을 의미하므로). 마찬가지로 입력 세트의 수와 전달하는 출력의 수가 동일한지 확인하세요. 다시 말하지만, N_Inputs=3이고 입력 길이가 15이고 출력 길이가 6이면 다른 오류가 발생합니다(5개의 입력 세트와 6개의 출력이 있으므로).

  • 훈련 출력에 충분한 변형이 있는지 확인하세요. 예를 들어, 길이가 100인 출력 배열을 의미하는 100개의 훈련 포인트를 전달하고 모든 값이 하나의 true와 함께 false이면 true 케이스와 false 케이스를 구별하는 것만으로는 충분하지 않습니다. 이것은 SVM 훈련을 매우 빠르게 유도하는 경향이 있지만 최종 솔루션은 매우 열악합니다. 더 다양한 훈련 세트는 종종 더 감정적인 SVM으로 이어집니다.

MetaQuotes 소프트웨어 사를 통해 영어가 번역됨
원본 기고글: https://www.mql5.com/en/articles/584

파일 첨부됨 |
schnick.mq5 (10.8 KB)
schnick_demo.mq5 (11.39 KB)
MQL5 프로그래밍 기본: 문자열 MQL5 프로그래밍 기본: 문자열
이 글에서는 MQL5에서 문자열로 할 수 있는 모든 것을 다룹니다. 초보자 MQL5 프로그래머가 주로 관심을 가져야 하는 반면 숙련된 개발자는 지식을 요약하고 체계화할 수 있는 좋은 기회를 가질 수 있습니다.
"즉석에서" 사용자 패널에서 Expert Advisor 매개변수 변경 "즉석에서" 사용자 패널에서 Expert Advisor 매개변수 변경
이 글은 사용자 패널에서 매개변수를 제어할 수 있는 Expert Advisor의 구현을 보여주는 작은 예시를 제공합니다. "즉시" 매개변수를 변경할 때 Expert Advisor는 정보 패널에서 얻은 값을 파일에 기록하여 파일에서 추가로 읽고 그에 따라 패널에 표시합니다. 이 글은 수동 또는 반자동 모드에서 거래하는 사람들과 관련이 있을 수 있습니다.
매수하기 전에 거래 로봇을 테스트하는 방법 매수하기 전에 거래 로봇을 테스트하는 방법
MQL5 Market에서 거래 로봇을 매수하면 다른 모든 유사한 옵션에 비해 뚜렷한 이점이 있습니다. 제공되는 자동화 시스템은 MetaTrader 5 터미널에서 직접 철저히 테스트할 수 있습니다. 매수하기 전에 Expert Advisor는 시스템을 완전히 파악하기 위해 내장된 전략 테스터의 모든 불리한 모드에서 신중하게 실행할 수 있고 또 실행해야 합니다.
MQL5 프로그래밍 기본: 배열 MQL5 프로그래밍 기본: 배열
배열은 변수 및 함수와 함께 거의 모든 프로그래밍 언어의 필수적인 부분입니다. 이 글은 주로 초보 MQL5 프로그래머가 관심을 가져야 하는 내용으로 구성된 반면, 숙련된 프로그래머는 지식을 요약하고 체계화할 수 있는 좋은 기회가 되어 줄 것입니다.