English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
preview
하나의 차트에 여러 개의 지표 넣기(파트 04): Expert Advisor 만들기

하나의 차트에 여러 개의 지표 넣기(파트 04): Expert Advisor 만들기

MetaTrader 5트레이딩 | 27 7월 2022, 16:44
180 0
Daniel Jose
Daniel Jose

소개

이전 글에서 사용자 지정 지표를 사용할 때 여러 개의 하위 창으로 지표를 만드는 방법을 설명했습니다. 이것은 꽤 쉬웠습니다. 그러나 Expert Advisor에서 동일한 기능을 구현하려고 하면 상황이 조금 더 복잡해 집니다. 사용자 지정 지표에서 사용한 도구가 없기 때문입니다. 이 시점에서 프로그래밍은 필수가 됩니다. 올바른 코드를 작성하여 하위 창을 만드는 것이 가장 중요합니다. 이 작업이 쉽지는 않지만 EA에 하위 창을 넣는 방법은 많은 코딩을 필요로 하지 않으며 MQL5가 작동하는 방식에 대한 지식만 있으면 됩니다.


계획

우리는 이미 작동하고 있는 사용자 정의 지표를 가지고 있습니다. 즉, 객체 클래스가 이미 작동하고 있으며 이것이 객체 클래스이므로 다른 모델로 쉽게 올길 수 있습니다. 그러나 단순히 EA에서 클래스를 선언하고 사용하려고 하면 사용자 지정 지표에서 작동하던 것과는 다르게 작동합니다. 그 이유는 EA에는 하위 창 기능이 없기 때문입니다. 그러나 다음과 같은 아이디어가 떠올랐습니다. "이미 컴파일 되고 작동하는 사용자 지정 지표를 사용하고iCustom명령을 사용하여 EA에서 이것을 호출하면 어떻게 될까요? 아마도 하위 창이 필요하지 않을 것이고 명령이 다음과 같다면 실제로 작동할 수 있을 것입니다.

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
input string user01 = "";                //Used indicators
input string user02 = "";                //Assets to follow
//+------------------------------------------------------------------+
int OnInit()
{
        int m_handleSub;

//... Expert Advisor code ...

        if ((m_handleSub = iCustom(NULL, 0, "Chart In SubWindows\\Chart In SubWindow.ex5", user01, user02)) == INVALID_HANDLE) return INIT_FAILED;
        if (!ChartIndicatorAdd(ChartID(), 0, m_handleSub)) return INIT_FAILED;
//... Expert Advisor code ...

        ChartRedraw();
        
        return(INIT_SUCCEEDED);
}
//...The rest of the Expert Advisor code ...

이 간단한 코드 조각은 사용자 지정 지표를 로드 할 수 있지만 하위 창이 없기 때문에 제대로 작동하지 않습니다. 이러한 경우 EA에서 코드가 실행될 때 EA는 기본 창에 지표를 적용합니다. 즉 차트가 지표에 의해 로드 된 템플릿에 의해 숨겨지게 되고 이는 분명히 우리가 찾고 있는 것이 아닙니다.

따라서 우리가 당면한 문제는 이미 작동하는 지표를 사용할 수 있도록 해주는 하위 창을 만드는 것입니다. 지표의 실행을 위해 하위 창을 만드는 이유는 무엇일까요? 그럴 이유가 없습니다. EA에 기능을 직접 추가하고 이를 통해 발생할 수 있는 제한사항들을 극복해 나아가는 것이 좋습니다.

이를 기반으로 몇 가지 작업을 수행해야 합니다.

목적
1 => 범용 지표를 생성합니다. 차트를 오염시키지 않고 iCustom 명령을 만들고 사용할 수 있습니다.
2 => 이 지표를 어떤 식으로든 EA에 포함시키십시오.  이를 통해 문제 없이 모든 기능을 갖춘 Expert Advisor를 이전할 수 있습니다.
3 => 하위 창에 대한 일반 객체 클래스 생성  EA를 통해 하위 창을 추가할 수 있습니다.
4 => 창 클래스에 바인딩된 C_TemplateChart 클래스를 가져옵니다. 이렇게 하면 이미 실행 중인 코드에서 아무 것도 변경하지 않고 하위 창의 내용을 관리할 수 있습니다.

이것이 어려워 보일 수 있지만 아주 간단하게 해결됩니다. 그럼 각각의 포인트에 대해 알아보겠습니다.


구현: 범용 지표 생성하기

이 부분은 사용자 지정 지표 코드를 생성하여 해결할 수 있습니다. 이 경우 코드는 다음과 같습니다.

#property copyright "Daniel Jose"
#property version   "1.00"
#property description "This file only enables support of indicators in SubWin."
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
int OnInit()
{
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
{
        return rates_total;
}
//+------------------------------------------------------------------+

이것 뿐이고 더 이상은 없습니다. 이 파일을 SubSupport.mq5로 저장합시다. 그러나 다른 지표와 함께 위치하지 않습니다. 대신 Expert Advisor의RESOURCE디렉토리로 이동하겠습니다. 따라서 파일 구조는 아래 그림과 같습니다.


여기에는 그럴 만한 이유가 있지만 그 이유들은 일단 제쳐 두고 진행합시다. 이제 다음 작업으로 넘어갑시다.


구현: EA에 일반 지표 포함하기

이렇게 하려면 EA 상단에 다음 코드를 추가해야 합니다.

//+------------------------------------------------------------------+
#define def_Resource "Resources\\SubSupport.ex5"
//+------------------------------------------------------------------+
#resource def_Resource
//+------------------------------------------------------------------+

여기에는 일반 지표의 컴파일 된 코드가 EA에 포함됩니다. 이 작업이 완료되면 더 이상 필요하지 않으므로 일반 지표에서 .ex5 파일이 삭제됩니다. 이제 EA 코드가 컴파일 될 때SubSupport.ex5파일이 발견되지 않으면 컴파일러가 자동으로SubSupport.mp5의 일반 지표의 코드를 컴파일한다는 사실에 주의해야 합니다. 그리고 컴파일러는 이 새로 컴파일된 실행 파일을 Expert Advisor에 추가합니다. 따라서SubSupport.mq5파일을 편집하고 Expert Advisor에 변경 사항을 추가해야 하는 경우SubSupport.ex5를 삭제해야 합니다. 그렇지 않으면 변경 사항이 추가되지 않습니다.

이렇게 하는 것은 중요합니다: 리소스에 새로 구현된 변경 사항을 추가하는 방법을 반드시 알아야 하기 때문입니다.

자, 이제 일반 지표는 Expert Advisor의 일부이므로 다음 작업으로 넘어가겠습니다.


구현 : 하위 창 객체 클래스 생성하기

이 부분도 간단합니다. 이 부분을 코딩하기 전에 몇 가지 사항을 정의해야 합니다. 즉, 이 클래스에서 실제로 필요한 기능은 무엇일까요? 처음에는 다음과 같이 사용하기로 결정했습니다:

기능 설명
Init EA를 통해 하위 창을 추가할 수 있습니다.
Close EA를 통해 하위 창을 추가할 수 있습니다.

이들 함수는 테스트 되지 않으므로 EA가 실행되면 한 번만 호출될 것이라고 가정합니다. 하지만 우리의 EA가 앞으로도 계속 사용 될 것이라고 생각하면 더 실용적으로 만드는 방법에 대해 생각해 보는 것이 좋습니다. 이와 관련하여 C_Terminal이라는 새로운 객체 클래스를 만들어 보겠습니다. 이 클래스는 그래픽 터미널과 관련된 몇 가지 사항을 지원합니다. 이에 대해서는 나중에 자세히 알아보겠습니다. 우선은 마지막 작업을 살펴보겠습니다. 왜냐하면 솔루션을 부분적으로 구현할 수 있는 방법이 없기 때문입니다.


구현: C_TemplateChart 클래스 상속

OOP(객체 지향 프로그래밍)를 사용하여 새로운 것을 만들기로 결정했을 때 보안이나 상속을 포함하여 이 접근 방식을 사용하면 큰 이점이 있다는 것을 이미 알고 있었기 때문에 이 작업을 수행했습니다. 다형성도 있지만 다형성은 나중에 교차 주문 시스템을 만들 때 사용합니다. 이 경우 우리는 OOP의 장점 중 하나인 상속을 사용할 것입니다. C_TemplateChart는 이미 완전한 기능을 갖춘 클래스입니다. 이것을 보면 모든 것을 다시 프로그래밍하는 번거로움을 겪거나 클래스에 코드를 추가하는 위험을 감수하고 싶지 않을 것입니다. 해결책은 원래 코드를 전혀 변경하지 않고 새 코드나 기능을 추가할 수 있는 상속을 사용하는 것입니다.

상속을 사용하면 다음과 같은 사항을 포함하여 많은 이점이 있습니다: 이미 테스트된 코드는 테스트된 상태로 유지됩니다; 복잡하게 확장 되더라도 코드의 크기가 그만큼 증가하는 것은 아닙니다; 새로운 기능만 테스트하면 됩니다; 변하지 않는 것들은 상속되어 안정성을 제공합니다. 다시 말해 최소한의 노력을 들여 최대의 보안을 만드는 식으로 프로그램이 개선됩니다. 이를 이해하기 위해 아래 다이어그램을 살펴보겠습니다.

조부모 클래스는 가장 낮은 수준에서 데이터를 다루는 가장 기본적인 클래스이지만 부모 클래스가 조부모로부터 무언가를 상속받을 때 조부모 클래스에서 public으로 선언된 모든 것을 부모 클래스에서 볼 수 있고 사용할 수 있습니다. 또한 우리는 부모 클래스에 새로운 것을 추가할 수도 있습니다. 이것은 상속되고 상속에 의해 지원되는 것들에 영향을 미치지 않습니다. 부모 클래스가 이미 완료되어 작동 중이고 그 하위 클래스에서 아무 것도 변경하지 않고 확장하려는 경우 자식 클래스를 만들어야 하고 자식 클래스는 이전 클래스의 모든 기능을 갖게 됩니다. 우리는 또한 작동 방식을 변경할 수 있으며 이는 상속과 관련한 흥미로운 점입니다. 이러한 변경 사항은 다른 클래스에 영향을 미치지 않기 때문입니다. 그러나 여기에는 다중 상속을 허용하는 C++와 달리 제한이 있습니다. 자식이 아버지 쪽과 어머니 쪽 모두에서 함수들을 상속하는 경우가 MQL5에서는 불가능합니다. 그러나 여전히 상속의 이점을 누릴수 있습니다. 다중 상속의 예는 다음과 같습니다:

하지만 MQL5에서 어떻게 해야 할까요? 우리가 그러한 상속을 선언하는 방법은 무엇일까요? 이것을 이해하는 가장 정확한 방법은 객체 지향 프로그래밍(OOP) 내용을 읽어 보는 것이지만 여기에서는 요점으로 바로 갈 것입니다. 상속은 다음 줄을 사용하여 수행됩니다.

#include "C_TemplateChart.mqh"
//+------------------------------------------------------------------+
class C_SubWindow : public C_TemplateChart
{
// ... Class code
};

C_SubWindow 클래스는C_TemplateChart클래스를 공개적으로 상속하므로 이제C_SubWindow클래스를 사용하여C_TemplateChart클래스 기능에 액세스할있습니다.

위의 코드 스니펫에서 저는 한 가지를 강조했습니다. 꺾쇠 괄호( < > )가 아닌 따옴표( " ) 부분입니다. 제가 왜 그렇게 했을까요? C++ 언어와 마찬가지로 MQL5에도 몇 가지 매우 흥미로운 점들이 있습니다. 그러나 프로그래밍 기술을 막 배우기 시작하는 사람들을 혼란스럽게 만드는 몇 가지 사항도 존재합니다. 꺾쇠 괄호( < > ) 사이에 헤더 파일을 배치하면 이는 절대 경로를 의미합니다 - 이 경우 컴파일러는 우리가 지정한 경로를 정확히 따릅니다. 그러나 우리가 따옴표를 사용하면(이번에 했던 것처럼) 컴파일러는 상대 경로를 사용하거나 혹은 더 명확하게 하기 위해 작업 파일이 있는 현재 디렉토리에서부터 먼저 시작합니다. 이상하게 보일 수 있지만 파일의 내용은 다르지만 동일한 이름을 갖고 있거나 다른 디렉토리에 있지만 여전히 현재 디렉토리를 참조하고 싶은 경우에 따옴표를 사용합니다.

이전에 우리가 만든 두 가지 함수 INIT와 CLOSE는 다음과 같습니다:

//+------------------------------------------------------------------+
bool Init(void)
{
        if (m_handleSub != INVALID_HANDLE) return true;
        if ((m_handleSub = iCustom(NULL, 0, "::" + def_Resource)) == INVALID_HANDLE) return false;
        m_IdSub = (int) ChartGetInteger(Terminal.Get_ID(), CHART_WINDOWS_TOTAL);
        if (!ChartIndicatorAdd(Terminal.Get_ID(), m_IdSub, m_handleSub)) return false;
                
        return true;
}
//+------------------------------------------------------------------+
void Close(void)
{
        ClearTemplateChart();
        if (m_handleSub == INVALID_HANDLE) return;
        IndicatorRelease(m_IdSub);
        ChartIndicatorDelete(Terminal.Get_ID(), m_IdSub, ChartIndicatorName(Terminal.Get_ID(), m_IdSub, 0));
        ChartRedraw();
        m_handleSub = INVALID_HANDLE;
}
//+------------------------------------------------------------------+

코드는 매우 간단하고 짧습니다. 그러나 우리가 주의해야 할 것이 있습니다. 강조 표시된 부분에 주의하십시오. 이 부분을 추가할 때 실수하지 않도록 주의해야 합니다. 그대로 두지 않으면 EA에 추가하도록 요청한 SubSupport.ex5 실행 파일이 EA 내부에서 보이지 않기 때문입니다 - 대신 EA 외부에서 볼 수 있습니다. 자세한 내용은Resources에서 찾아 보시기 바랍니다. 그러나 기본적으로 ( :: )를 사용하면 이는 EA가 내부에서 사용 가능한 내부 리소스를 사용해야 함을 의미합니다. 하지만 리소스의 이름을 표시하면 EA는 MQL5 디렉터리 내부에서 검색하고 지정된 위치에 파일이 없으면 함수는 실패하게 됩니다. EA 리소스로 파일을 추가해도 함수가 실패하는 건 마찬가지입니다.

그런 다음 리소스가 로드되면 존재하는 하위 창의 수를 확인하고 해당 하위 창에 지표를 추가합니다.

코드가 실제로 수행하는 작업은 아래와 같습니다:

input string user01 = "";               //Used indicators
input string user02 = "";               //Assets to follows
//+------------------------------------------------------------------+
int OnInit()
{
        int m_handleSub;

//...   

        if ((m_handleSub = iCustom(NULL, 0, "Chart In SubWindows\\Chart In SubWindow.ex5", user01, user02)) == INVALID_HANDLE) return INIT_FAILED;
        if (!ChartIndicatorAdd(ChartID(), (int) ChartGetInteger(ChartID(), CHART_WINDOWS_TOTAL), m_handleSub)) return INIT_FAILED;

//...

        ChartRedraw();
        
   return(INIT_SUCCEEDED);
}
//...The rest of the Expert Advisor code ...

두 코드 모두 동일하게 작동하지만 위의 버전은 통합 버전이고 변경되지 않습니다. 그러므로 객체 클래스 버전을 사용하면 시간이 지남에 따라 더 많은 것을 추가할 수 있습니다. 두 버전 모두 동일한 작업을 수행합니다. EA에서 하위 창을 만들고 이전에 만든 모든 사용자 지정 지표를 이 하위 창에 넣습니다. 이 글의 시작 부분의 코드와 비교하여 코드 변경 사항에 주의하십시오. - 변경 사항은 색상으로 강조 표시됩니다.


결론

우리가 목표를 달성 하기 위한 방법을 결정하는 방법은 매우 흥미롭습니다. 때때로 우리는 어려움에 직면하고 목표를 달성하는 것이 어렵다고 생각할 수 있지만 약간의 인내와 헌신이 있으면 처음에는 넘을 수 없을 것 같았던 장애물을 극복할 수 있습니다. 이 기사에서는 상속을 통해 클래스를 수정하지 않고 기능을 확장하는 방법을 보여드렸습니다. 동시에 차트에 지표를 추가하여 이미 테스트한 대로 작동하는 방법을 보여드렸습니다. 우리는 EA 내부에 ex5 프로그램을 추가하고 EA를 로드 하여 원래 ex5를 포트 할 필요 없이 사용하면 됩니다.

첨부 파일에는 지금까지 개발된 모든 사항이 포함되어 있습니다. 그리고 곧 이 코드에 더 흥미로운 내용이 포함될 것입니다. 😁👍


MetaQuotes 소프트웨어 사를 통해 포르투갈어가 번역됨
원본 기고글: https://www.mql5.com/pt/articles/10241

하나의 차트에 여러개의 지표 넣기(파트 05): MetaTrader 5를 RAD 시스템으로 전환하기(I) 하나의 차트에 여러개의 지표 넣기(파트 05): MetaTrader 5를 RAD 시스템으로 전환하기(I)
세상에는 프로그래밍을 할 줄은 모르지만 상당히 창의적이고 훌륭한 아이디어를 가지고 있는 사람들이 많이 있습니다. 그러나 이들은 프로그래밍 지식이 부족하여 이러한 아이디어를 구현하지 못합니다. MetaTrader 5 플랫폼을 사용하여 마치 플랫폼이 IDE 자체인 것 처럼 차트 트레이드(Chart Trade)를 만드는 방법을 함께 살펴보겠습니다.
CCI 기반의 트레이딩 시스템을 설계하는 방법 알아보기 CCI 기반의 트레이딩 시스템을 설계하는 방법 알아보기
거래 시스템을 설계하는 방법을 배우기 위한 시리즈의 이 기사에서는 상품 채널 지수(CCI)를 제시하고 그 세부 사항을 설명하며 이 지표를 기반으로 거래 시스템을 만드는 방법을 공유합니다.
RSI 기반의 트레이딩 시스템을 설계하는 방법 알아보기 RSI 기반의 트레이딩 시스템을 설계하는 방법 알아보기
이 기사에서는 트레이딩의 세계에서 가장 인기 있고 일반적으로 사용되는 지표 중 하나인 RSI에 대해 공유합니다. 이 글에서 여러분은 이 지표를 사용하여 거래 시스템을 설계하는 방법을 배우게 됩니다.
Momentum 기반의 트레이딩 시스템을 설계하는 방법 알아보기 Momentum 기반의 트레이딩 시스템을 설계하는 방법 알아보기
저는 이전 글에서 추세를 파악하는 것의 중요성에 대해 언급했습니다. 추세란 곧 가격의 방향이라는 점에서 말입니다. 이 기사에서 저는 가장 중요한 개념이자 지표 중 하나인 모멘텀 지표를 여러분과 공유할 것입니다. 이 모멘텀 지표를 기반으로 트레이딩 시스템을 설계하는 방법에 대해 공유하겠습니다.