English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5로 방출형 인디케이터 그리기

MQL5로 방출형 인디케이터 그리기

MetaTrader 5 | 5 7월 2021, 13:01
67 0
Sergey Pavlov
Sergey Pavlov

개요

많은 투자자와 매매 전략 개발자들이 다음과 같은 질문에 관심을 갖습니다.

저도 위와 같은 질문들에 대한 답을 찾다가 시장 조사에 대한 새로운 접근법을 만들게 되었습니다. 방출형 인디케이터를 만들고 분석하는 거죠. 아래의 그림들을 보면 이해하기 쉬울 거예요.

그림 1. DCMV 인디케이터 방출.

그림 2. iMA 엔벨로프 기반 인디케이터

다양한 방출형 인디케이터가 나타나 있지만 기본 구성 원리는 모두 같습니다. 각각의 틱 다음에 형형색색의 점이 나타나죠. 이 점들이 모여 성운, 구름, 궤도, 직선, 포물선 등의 형태를 갖는 클러스터를 형성합니다. 클러스터의 모양에 따라 시장 가격의 변화에 영향을 미치는, 눈에는 보이지 않는 원동력을 어느 정도 감지할 수 있죠. 그러니까 방출형 인디케이터 분석은 약간 수상술과 비슷하달까요.

방출의 속성

방출이란 인디케이터의 특정 라인 교차점에 위치하는 점들의 집합입니다.

아직 알려지지 않은 속성도 있어 추가 연구가 필요하죠. 알려진 속성은 다음과 같습니다.

  • 동일한 유형의 점이 모여 집합을 이루는 경향이 있다.
  • 방출은 현재에서 미래 또는 현재에서 과거로의 방향성을 갖는다.
  • 밀집된 클러스터에 따라 가격 방향성이 달라진다.

인디케이터 방출 계산

이번에는 예시를 보면서 방출 계산 기본 원칙을 알아볼게요. 두 인디케이터 iBandsiMA 사이의 교차점을 찾아보죠. 방출점을 그릴 건데요. 그러려면 그래픽 객체가 필요합니다. 해당 알고리즘은 엑스퍼트 어드바이저에서 구현되었지만 인디케이터 자체에서도 구현할 수 있어요.

초기 인디케이터가 그림 3에 나와 있습니다.

그림 3. iBands(초록)와 iMA(빨강) 인디케이터.

방출점을 만들려면 엑스퍼트 어드바이저가 필요합니다. MQL5 마법사로 엑스퍼트 어드바이저 템플릿을 만드는 편이 더 좋겠네요.

그림 4. MQL5 마법사로 엑스퍼트 어드바이저 템플릿 만들기.

//+------------------------------------------------------------------+
//|                                      Emission of Bands && MA.mq5 |
//|                                                 Copyright DC2008 |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "DC2008"
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+

우선 몇 가지 보조 플로팅이 좀 필요한데요. 기존의 인디케이터 표시선을 다른 선으로 잇습니다(그림 5.). 이렇게 하면 방출점의 시각화 및 계산의 정확성을 높일 수 있죠. 새로 그은 선들은 나중에 지울 겁니다.

그림 5. 보조 플로팅. 기존 인디케이터 표시선 연장.

따라서 엑스퍼트 어드바이저 코드에 그래픽 객체(수평선 및 추세선)를 추가하도록 하겠습니다.

input bool     H_line=true;   // flag to enable drawing of the horizontal lines
input bool     I_line=true;   // flag to enable drawing of the indicator's lines
//---
string         name;
//---- indicator buffers
double      MA[];    // array for iMA indicator 
double      BBH[];   // array for iBands indicator  - UPPER_BAND 
double      BBL[];   // array for iBands indicator - LOWER_BAND
double      BBM[];   // array for iBands indicator - BASE_LINE
datetime    T[];     // array for time coordinates
//---- handles for indicators
int         MAHandle;   // iMA indicator handle
int         BBHandle;   // iBands indicator handle
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MAHandle=iMA(Symbol(),0,21,0,MODE_EMA,PRICE_CLOSE);
   BBHandle=iBands(Symbol(),0,144,0,2,PRICE_CLOSE);
//---
   if(H_line)     // Horizontal lines of iBands indicator
      {
         //--- iBands - UPPER_BAND
         name="Hi";
         ObjectCreate(0,name,OBJ_HLINE,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,Red);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         //--- iBands - LOWER_BAND
         name="Lo";
         ObjectCreate(0,name,OBJ_HLINE,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,Blue);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         //--- iBands - BASE_LINE
         name="MIDI";
         ObjectCreate(0,name,OBJ_HLINE,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,DarkOrange);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
      }
//---
   if(I_line)     // Indicator lines
      {
         //--- iMA
         name="MA";
         ObjectCreate(0,name,OBJ_TREND,0,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,Red);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,2);
         ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1);
         //--- iBands - UPPER_BAND
         name="BH";
         ObjectCreate(0,name,OBJ_TREND,0,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,MediumSeaGreen);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1);
         //--- iBands - LOWER_BAND
         name="BL";
         ObjectCreate(0,name,OBJ_TREND,0,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,MediumSeaGreen);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1);
         //--- iBands - BASE_LINE
         name="BM";
         ObjectCreate(0,name,OBJ_TREND,0,0,0,0);           
         ObjectSetInteger(0,name,OBJPROP_COLOR,MediumSeaGreen);
         ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
         ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,1);
         ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,1);
      }
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- filling the arrays with current values
   CopyBuffer(MAHandle,0,0,2,MA);
   ArraySetAsSeries(MA,true);  
   CopyBuffer(BBHandle,0,0,2,BBM);
   ArraySetAsSeries(BBM,true);  
   CopyBuffer(BBHandle,1,0,2,BBH);
   ArraySetAsSeries(BBH,true);  
   CopyBuffer(BBHandle,2,0,2,BBL);
   ArraySetAsSeries(BBL,true);
   CopyTime(Symbol(),0,0,10,T);
   ArraySetAsSeries(T,true);
     
   //--- Horizontal lines of iBands indicator (correction)
   if(H_line)
      {
      name="Hi";
      ObjectSetDouble(0,name,OBJPROP_PRICE,BBH[0]);
      name="Lo";
      ObjectSetDouble(0,name,OBJPROP_PRICE,BBL[0]);
      name="MIDI";
      ObjectSetDouble(0,name,OBJPROP_PRICE,BBM[0]);
      }
   //--- Indicator's lines (correction)
   if(I_line)
      {
      name="MA";  //--- iMA
      ObjectSetInteger(0,name,OBJPROP_TIME,T[1]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,MA[1]);
      ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,1,MA[0]);
      name="BH";  //--- iBands - UPPER_BAND
      ObjectSetInteger(0,name,OBJPROP_TIME,T[1]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,BBH[1]);
      ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,1,BBH[0]);
      name="BL";  //--- iBands - LOWER_BAND
      ObjectSetInteger(0,name,OBJPROP_TIME,T[1]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,BBL[1]);
      ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,1,BBL[0]);
      name="BM";  //--- iBands - BASE_LINE
      ObjectSetInteger(0,name,OBJPROP_TIME,T[1]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,BBM[1]);
      ObjectSetInteger(0,name,OBJPROP_TIME,1,T[0]);
      ObjectSetDouble(0,name,OBJPROP_PRICE,1,BBM[0]);
      }
  }
//+------------------------------------------------------------------+
방출이 과거와 미래로 계속되므로 추세선의 속성은 다음과 같아야 합니다.
  • OBJPROP_RAY_LEFT = 1, (왼쪽으로 이동)
  • OBJPROP_RAY_RIGHT = 1, (오른쪽으로 이동).

차트에 선을 추가하고 나면 그림 6처럼 보일 겁니다.

준비 단계를 완료했으니, 이제 방출을 제대로 살펴보죠. 아래의 위치에 점이 나타나도록 할 거예요.

  • 'MA(iMA)' 선과 'BH' 선 사이(iBands = UPPER_BAND)
  • 'MA(iMA)' 선과 'BL' 선 사이(iBands = LOWER_BAND)
  • 'MA(iMA)' 선과 'BM 선 사이(iBands = BASE_BAND)

그림 6. 보조 플로팅. 직선으로 연장된 기존 인디케이터 표시선.

이제 교차점의 좌표를 구하고 방출점을 그릴 겁니다. 다음의 함수를 작성합니다.

void Draw_Point(
                string   P_name,     // Object name (OBJ_ARROW)
                double   P_y1,       // Y-coordinate of the 1st line at the [1] bar
                double   P_y0,       // Y-coordinate of the 1st line at the [0] bar
                double   P_yy1,      // Y-coordinate of the 2nd line at the [1] bar 
                double   P_yy0,      // Y-coordinate of the 2nd line at the [0] bar
                char     P_code1,    // Char at the right side of the [0] bar
                char     P_code2,    // Char at the left side of the [0] bar
                color    P_color1,   // Color of point at the right side of the [0] bar
                color    P_color2    // color of point at the left side of the [0] bar
                )
  {
   double   P,X;
   datetime P_time;
   if(MathAbs((P_yy0-P_yy1)-(P_y0-P_y1))>0)
     {
      P=P_y1+(P_y0-P_y1)*(P_y1-P_yy1)/((P_yy0-P_yy1)-(P_y0-P_y1));
      X=(P_y1-P_yy1)/((P_yy0-P_yy1)-(P_y0-P_y1));
      if(X>draw_period)
        {
         P_time=T[0]+(int)(X*PeriodSeconds());
         ObjectCreate(0,P_name,OBJ_ARROW,0,0,0);
         ObjectSetDouble(0,P_name,OBJPROP_PRICE,P);
         ObjectSetInteger(0,P_name,OBJPROP_TIME,P_time);
         ObjectSetInteger(0,P_name,OBJPROP_WIDTH,0);
         ObjectSetInteger(0,P_name,OBJPROP_ARROWCODE,P_code1);
         ObjectSetInteger(0,P_name,OBJPROP_COLOR,P_color1);
         if(X<0)
           {
            ObjectSetInteger(0,P_name,OBJPROP_ARROWCODE,P_code2);
            ObjectSetInteger(0,P_name,OBJPROP_COLOR,P_color2);
           }
        }
     }
  }

그리고 OnTick 함수에 다음 라인을 추가합니다.

//+------------------------------------------------------------------+
   int GTC=GetTickCount();                                                    
//+------------------------------------------------------------------+
   name="H"+(string)GTC;
   Draw_Point(name,BBH[1],BBH[0],MA[1],MA[0],170,178,Red,Red);
   name="L"+(string)GTC;
   Draw_Point(name,BBL[1],BBL[0],MA[1],MA[0],170,178,Blue,Blue);
   name="M"+(string)GTC;
   Draw_Point(name,BBM[1],BBM[0],MA[1],MA[0],170,178,Green,Green);
//---
   ChartRedraw(0);

이제 엑스퍼트 어드바이저를 열어 결과를 봅시다(그림 7.).

좋은데요. 다만 우리가 생각하지 못한 다른 교차점들이 있네요. 예를 들어, iBands 인디케이터의 경우 세 개의 선이 서로 교차하여 전체적으로 보완을 해 주죠.

그림 7. iMa와 iBands 인디케이터의 방출(교차 지점 3개).

이번에는 아래의 위치에 점을 추가해 볼게요.
  • 'BH' 선(iBands = UPPER_BAND)과 'BL' 선(iBands = LOWER_BAND) 사이
  • 'BH' 선(iBands = UPPER_BAND)과 'BM' 선(iBands = BASE_BAND) 사이
  • 'BL' 선(iBands = LOWER_BAND)과 'BM' 선(iBands = BASE_BAND) 사이

위의 교차 지점을 따라 3개의 점이 나타나는데, 모두 동일한 좌표를 갖습니다. 그러므로 'BH' 선과 'BL' 선 사이 하나의 교차 지점만 이용해도 충분하죠.

다음 라인을 엑스퍼트 어드바이저에 추가하고 그 결과를 확인하겠습니다(그림 8).

   name="B"+(string)GTC;
   Draw_Point(name,BBH[1],BBH[0],BBL[1],BBL[0],170,178,Magenta,Magenta);

그림 8. iMA와 iBands 인디케이터의 방출(교차 지점 4개).

이제 방출에 대해서는 설명을 했는데, 뭔가 중요한 걸 놓친 것 같은 느낌이 드네요. 우리가 뭘 놓쳤을까요?

우리가 왜 저런 입력 매개 변수를 사용했을까요? 이 변수들을 바꾸면 어떤 결과가 나올까요? 방출형 인디케이터에서 각 변수의 역할은 무엇일까요?

맞아요. 우리가 보는 방출은 인디케이터의 인풋 변수에서 비롯된 단일 주파수에 해당합니다. 다중 주파수 스펙트럼 전체를 계산하려면 동일한 연산을 다른 주파수로 수행해야 하죠. 다음은 제가 예로 들어 계산해 본 방출 스펙트럼입니다.

//---- handles for indicators
int         MAHandle[5];   // handles array of iMA indicators
int         BBHandle[7];   // handles array of iBands indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MAHandle[0]=iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE);
   MAHandle[1]=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE);
   MAHandle[2]=iMA(NULL,0,55,0,MODE_EMA,PRICE_CLOSE);
   MAHandle[3]=iMA(NULL,0,89,0,MODE_EMA,PRICE_CLOSE);
   MAHandle[4]=iMA(NULL,0,144,0,MODE_EMA,PRICE_CLOSE);
//---
   BBHandle[0]=iBands(NULL,0,55,0,2,PRICE_CLOSE);
   BBHandle[1]=iBands(NULL,0,89,0,2,PRICE_CLOSE);
   BBHandle[2]=iBands(NULL,0,144,0,2,PRICE_CLOSE);
   BBHandle[3]=iBands(NULL,0,233,0,2,PRICE_CLOSE);
   BBHandle[4]=iBands(NULL,0,377,0,2,PRICE_CLOSE);
   BBHandle[5]=iBands(NULL,0,610,0,2,PRICE_CLOSE);
   BBHandle[6]=iBands(NULL,0,987,0,2,PRICE_CLOSE);
//---
   return(0);
  }

다음 코드를 엑스퍼트 어드바이저에 추가해 가능한 모든 조합을 살펴볼게요.

//+------------------------------------------------------------------+
   CopyTime(NULL,0,0,10,T);
   ArraySetAsSeries(T,true);
   int GTC=GetTickCount();
//+------------------------------------------------------------------+
   int iMax=ArraySize(BBHandle)-1;
   int jMax=ArraySize(MAHandle)-1;
   for(int i=0; i<iMax; i++)
     {
      for(int j=0; j<jMax; j++)
        {
         //--- filling the arrays with current values
         CopyBuffer(MAHandle[j],0,0,2,MA);
         ArraySetAsSeries(MA,true);
         CopyBuffer(BBHandle[i],0,0,2,BBM);
         ArraySetAsSeries(BBM,true);
         CopyBuffer(BBHandle[i],1,0,2,BBH);
         ArraySetAsSeries(BBH,true);
         CopyBuffer(BBHandle[i],2,0,2,BBL);
         ArraySetAsSeries(BBL,true);

         name="H"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBH[1],BBH[0],MA[1],MA[0],250,158,Aqua,Aqua);
         name="L"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBL[1],BBL[0],MA[1],MA[0],250,158,Blue,Blue);
         name="M"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBM[1],BBM[0],MA[1],MA[0],250,158,Green,Green);
         name="B"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBH[1],BBH[0],BBL[1],BBL[0],250,158,Magenta,Magenta);
        }
     }
//---
   ChartRedraw(0);

스펙트럼이 더 많은 주파수를 포함할수록 차트 모양도 더 좋아지지만 과도하게 추가하지는 마세요. 리소스를 고갈시키기 가장 쉬운 방법인데다가 차트도 조잡해지거든요. 주파수의 개수는 몇 번 하다 보면 정할 수 있을 거예요. 파악하기 쉬운 그래픽을 만들려면 드로잉 스타일을 잘 골라야 합니다.

그림 9. 다중 주파수 방출 스펙트럼.

방출형 드로잉 스타일

MQL5 덕분에 다양한 웹 색상윙딩 글꼴을 이용해 방출형 인디케이터를 그릴 수 있게 됐습니다. 제 생각은 이래요.  
  1. 사람마다 감각이 다르니 자신에게 맞는 그래픽을 찾으려면 시간이 좀 걸릴 거예요.
  2. 그림 9. '카오스' 대체 규칙적인 패턴이라고는 찾아볼 수가 없죠. 안 좋은 예시입니다.
  3. 무지개색 중에서 서로 이웃하는 색상을 쓰도록 하세요.
  4. 과거([0] 바 좌측)와 미래([0] 바 우측)에 사용되는 문자 코드는 서로 상이해야 합니다.
  5. 색상과 형태가 잘 조합된 방출형 인디케이터는 거래에도 도움이 되고 보기에도 예쁩니다.
제가 만든 걸 참고해 보세요(그림 10~17 참고).
         name="H"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBH[1],BBH[0],MA[1],MA[0],250,158,Aqua,Aqua);
         name="L"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBL[1],BBL[0],MA[1],MA[0],250,158,Blue,Blue);
         name="M"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBM[1],BBM[0],MA[1],MA[0],250,158,Magenta,Magenta);
         name="B"+(string)GTC+(string)i+(string)j;
         Draw_Point(name,BBH[1],BBH[0],BBL[1],BBL[0],250,158,DarkOrchid,DarkOrchid);

iMA와 iBands 방출 인디케이터 갤러리

다음은 방출 인디케이터의 그래픽 예시입니다.

 

그림 10.

 

그림. 11

그림. 12.

그림. 13.

그림. 14.

 

그림. 15.

그림. 16.

 

그림. 17.

방출 분석

분석은 또 완전히 다른 일이죠. 가장 도움이 되는 건 실시간으로 역학을 관찰하는 거예요. 여러 패턴이라든지 효과 등을 쉽게 이해할 수 있는 가장 좋은 방법이거든요.

가격 조정을 유심히 관찰해 보세요. 방출형 인디케이터가 목표주가를 실제로 알고 있는 것 같기도 하거든요. 추가로 지지선, 저항선과 균형가격까지 확인할 수 있습니다.

결론

  1. 시장 조사 및 분석에 대한 새로운 접근법을 찾고 있는 투자자나 매매 시스템 개발자들에게 방출형 인디케이터가 신선하게 다가갈 수도 있겠네요.
  2. 이 글은 소개가 목적이므로 완성된 소스 코드를 제공하지는 않는데요. 위에서 언급된 기법은 다른 인디케이터 또는 다른 여러 조합에도 적용될 수 있습니다.
  3. 이 글을 쓰면서 답 보다는 질문이 더 생기더군요. 방출형 인디케이터 드로잉 알고리즘의 최적화는 어떻게 이루어질까요? 스펙트럼의 특징이 방출 구조에 미치는 영향은 무엇이고요? 자동 매매에서는 방출을 어떻게 이용하죠?

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

WCF 서비스를 통해 MetaTrader5에서 .NET 애플리케이션으로 인용문 내보내기 WCF 서비스를 통해 MetaTrader5에서 .NET 애플리케이션으로 인용문 내보내기
MetaTrader5에서 다른 애플리케이션으로 인용문을 내보내고 싶으신가요? MQL5와 DLL이 함께라면 문제 없어요! 이 글은 MetaTrader5에서 .NET 애플리케이션으로 인용문을 내보내는 방법에 대한 설명입니다. 개인적으로는 .NET 플랫폼을 이용하는 게 훨씬 재밌고, 합리적이고, 간편하네요. 안타깝게도 MetaTrader5는 아직 .NET 형식을 지원하지 않기 때문에 예전과 같이 .NET 형식을 지원하는 win32 dll을 중간층으로 사용하겠습니다.
인디케이터 데이터 교환: 쉬워요! 인디케이터 데이터 교환: 쉬워요!
차트에 추가된 인디케이터 데이터에 액세스가 가능한 동시에, 데이터 복사가 불필요하고, 필요한 경우 최소한의 수정만을 거쳐 기존의 코드를 사용할 수 있으며, MQL 코드가 선호되는 환경을 제공하고 싶습니다. 물론 DLL을 사용하긴 하겠지만 C++ 문자열을 이용할 겁니다. 이 글은 다른 MQL 프로그램에서 MetaTrader 터미널로 인디케이터 버퍼를 가져올 수 있도록 하는 편리한 개발 환경 구축 방법을 설명하고 있습니다.
초보자를 위한 실용적인 MQL5 디지털 필터 구현 초보자를 위한 실용적인 MQL5 디지털 필터 구현
자동 매매 시스템 관련 포럼에서 자주 언급되는 것 중 하나가 디지털 필터입니다. 그러니 MQL5에서 사용할 수 있는 디지털 필터 표준 코드를 꼭 제공해 드려야죠. 이 글에서는 '뉴비들을 위한 MQL5 커스텀 인디케이터'에 있는 간단한 SMA 인디케이터 코드를 조금 더 복잡하지만 보편적으로 사용할 수 있는 디지털 필터로 변환하는 법을 알아보겠습니다. 본문의 내용은 직전 글과 이어집니다. 프로그래밍 오류 수정법과 텍스트 변환 방법에 대한 설명 역시 포함되어 있습니다.
데이터 교환 방법: 10 분 안에 MQL5 용 DLL 데이터 교환 방법: 10 분 안에 MQL5 용 DLL
이제 많은 개발자가 간단한 DLL을 작성하는 방법과 다른 시스템 바인딩의 특수 기능이 무엇인지 기억하지 못합니다. 몇 가지 예제를 사용하여 간단한 DLL 생성의 전체 프로세스를 10 분 안에 보여주고 바인딩 구현에 대한 몇 가지 기술적인 세부 사항을 논의하려고 합니다. 다양한 유형의 변수 (숫자, 배열, 문자열 등)를 교환하는 예제와 함께 Visual Studio에서 DLL을 만드는 단계별 프로세스를 보여 드리겠습니다. 게다가 사용자 지정 DLL의 충돌로부터 클라이언트 터미널을 보호하는 방법을 설명합니다.