English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
preview
Expert Advisor 개발 기초부터 (파트 10): 맞춤형 지표 액세스하기

Expert Advisor 개발 기초부터 (파트 10): 맞춤형 지표 액세스하기

MetaTrader 5트레이딩 시스템 | 9 11월 2022, 17:30
335 0
Daniel Jose
Daniel Jose

소개

트레이딩 EA는 맞춤형 지표를 사용할 수 있는 경우에 더욱 유용할 수 있습니다. 그렇지 않으면 EA는 설계된 대로 포지션 관리나 시장에서 거래 실행을 지원할 수 있는 일련의 코드와 지침일 뿐이며 아마도 그게 전부일 것입니다.

글쎄 MetaTrader 5 차트에 지표를 추가하는 것은 어려운 일이 아닙니다. 그러나 적절한 계획이 없을 경우 Expert Advisor에서 이러한 지표에 의해 계산된 데이터에 직접 액세스하는 것은 거의 불가능한 작업이 됩니다. 그리고 우리가 그것을 하는 방법을 모른다면 우리는 표준 지표만을 사용하게 되는 것입니다. 그러나 거래를 위해서는 더 많은 것이 필요합니다. 좋은 예는 VWAP(Volume Weighted Average Price) 지표입니다. 브라질 증권 거래소에서 선물을 거래하는 모든 사람에게 매우 중요한 이동 평균입니다. 이 이동 평균은 MetaTrader의 표준 지표 중 표시되지 않지만 VWAP를 계산하고 화면에 표시하는 맞춤형 지표를 만들 수 있습니다. 그러나 EA에서 동일한 지표를 사용하기로 결정하면 상황이 훨씬 더 복잡해 집니다. 관련 지식이 없으면 EA에서 이 맞춤형 지표를 사용할 수 없습니다. 이 기사에서는 이러한 문제를 해결하는 방법을 살펴보겠습니다.


계획

먼저 맞춤형 지표에서 사용할 계산식을 만들어 보겠습니다. 다행히 우리가 예로 사용할 VWAP 계산 공식은 매우 간단합니다.


프로그래밍 언어로 표현을 하면 MQL5에서 사용하기 위해 다음을 얻게 됩니다:

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
        double          Price = 0;
        ulong           Volume = 0;
        static int      siPos = 0;

        if (macroGetDate(time[rates_total - 1]) != macroGetDate(time[siPos]))
        {
                for (int c0 = rates_total - 1; macroGetDate(time[siPos]) != macroGetDate(time[c0]); siPos++);
                ArrayInitialize(VWAP_Buff, EMPTY_VALUE);
        }
        for (int c0 = siPos; c0 < rates_total; c0++)
        {
                Price += ((high[c0] + low[c0] + close[c0]) / 3) * volume[c0];
                Volume += volume[c0];
                VWAP_Buff[c0] = Price / Volume;
        }

    return rates_total;
}

계산이 포함된 행은 강조 표시되고 나머지 함수는 DAILY VWAP의 적절한 초기화에 사용됩니다. 그러나 지표는 여전히 차트에서 실행도지 않으며 코드에 몇 가지를 더 추가해야 합니다. 나머지 코드는 아래에서 볼 수 있습니다:

#property copyright "Daniel Jose - Indicador VWAP ( IntraDay )"
#property version "1.01"
#property indicator_chart_window
#property indicator_buffers     1
#property indicator_plots       1
#property indicator_width1      2
#property indicator_type1 	DRAW_LINE
#property indicator_color1 	clrBlack
//+------------------------------------------------------------------+
#define macroGetDate(A) (A - (A % 86400))
//+------------------------------------------------------------------+
double VWAP_Buff[];
//+------------------------------------------------------------------+
int OnInit()
{
        SetIndexBuffer(0, VWAP_Buff, INDICATOR_DATA);   
        
        return INIT_SUCCEEDED;
}

이렇게 하면 이전에 표시된 대로 차트에 VWAP를 포함할 수 있습니다.


뭐, 이 부분은 그다지 복잡하지 않았습니다. 이제 EA가 VWAP를 사용할 수 있도록 하여 특정 방식으로 지표를 분석할 수 있는 방법을 찾아야 합니다. 이를 통해 거래에서 지표를 통해 얻을 수 있는 이점을 누릴 수 있습니다.

지표 작업을 쉽게 하기 위해 VWAP가 쉽게 접근될 수 있도록 저장해 보겠습니다.


그 후에 우리는 계속 나아갈 수 있습니다. VWAP 지표는 원래는 정확하지만 EA에서 사용되도록 하기 위해 부정확하게 프로그래밍 되었습니다. 왜일까요? 문제는 지표가 차트에 있는지 여부를 EA가 알 수 없다는 것입니다. EA가 이 사실을 알지 못하면 EA는 지표를 읽을 수 없습니다.

문제는 파일 이름이 시스템에 거의 중요하지 않다는 것입니다. 파일명을 아무렇게나 지을 수 있지만 지표의 이름은 지표가 계산 하는 것이 무엇인지를 반영해야 합니다. 우리의 지표에는 아직 이를 반영하는 이름이 없습니다. VWAP라고 해도 시스템과는 아무 관계가 없습니다. 이러한 이유로 EA는 지표가 차트에 있는지 여부를 알 수 없습니다.

지표가 계산하는 대상을 반영하도록 하려면 이를 코드로 표현해야 합니다. 이렇게 하면 파일명과 관련 없이 고유한 이름을 만들 수 있습니다. 우리의 경우 지표의 초기화 코드는 다음과 같아야 합니다. 우리의 경우 지표의 초기화 코드는 다음과 같아야 합니다.

int OnInit()
{
        SetIndexBuffer(0, VWAP_Buff, INDICATOR_DATA);   
        IndicatorSetString(INDICATOR_SHORTNAME, "VWAP");
        
        return INIT_SUCCEEDED;
}

강조 표시된 라인을 추가하기만 하면 이 문제가 해결됩니다. 어떤 경우에는 더 어려울 수도 있습니다 - 이 부분은 나중에 다시 설명하겠습니다. 먼저 MetaTrader 5 라이브러리의 CUSTOM MOVING AVERAGE 지표의 코드를 예로 들어 보겠습니다. 코드는 다음과 같습니다:

void OnInit()
{
	SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
	IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
	PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod);
	PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);

	string short_name;
	switch(InpMAMethod)
	{
      		case MODE_EMA :
			short_name="EMA";
         		break;
      		case MODE_LWMA :
	         	short_name="LWMA";
	         	break;
      		case MODE_SMA :
         		short_name="SMA";
         		break;
      		case MODE_SMMA :
         		short_name="SMMA";
         		break;
      		default :
         		short_name="unknown ma";
     	}
   	IndicatorSetString(INDICATOR_SHORTNAME, short_name + "(" + string(InpMAPeriod) + ")");
   	PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}

강조 표시된 부분은 필요한 이름을 나타냅니다. 파일 이름과는 아무 관련이 없다는 것을 알 수 있습니다. 그러나 이것은 맞춤형 지표 내에서 정확하게 수행되어야 합니다.

이제 EA가 차트에서 맞춤형 지표가 실행 중인지 여부를 확인할 수 있다는 것을 알 수 있습니다.


EA를 통해 지표에 액세스

우리는 이전에 했던 방식을 계속 사용할 수 있습니다. 그러나 우리가 하고 있는 것을 더욱 잘 이해 할 수 있기 위해서 가장 이상적인 방법은 완전히 새로운 코드를 만들어야 우리가 하고자 하는 것은 Trading Expert Advisor를 개발하는 방법을 처음부터 배우는 것이므로 이 단계를 계속 해 나아가봅시다. 그러기 위해 격리된 Expert Advisor를 만들 것입니다. 그런 다음 이 EA를 최종 코드에 포함하거나 포함하지 않을 수도 있습니다. 이제 코드 작성을 진행해 보겠습니다. EA는 아래에서 볼 수 있듯이 깨끗한 코드로 시작합니다.

//+------------------------------------------------------------------+
int OnInit()
{
        EventSetTimer(1);
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick(){}
//+------------------------------------------------------------------+
void OnTimer(){}
//+------------------------------------------------------------------+

다음을 수행해 보겠습니다: 먼저 VWAP 지표가 차트에 있다고 가정하고 지표에서 계산된 마지막 값을 Expert Advisor에 로드 합니다. 우리는 이것을 매초 반복할 것입니다. 하지만 어떻게 이를 해야 할까요? 간단하게 할 수 있습니다. 변경 후 EA 코드가 어떻게 보이는지 확인하십시오:

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
int     handle;
double  Buff[];
//+------------------------------------------------------------------+
int OnInit()
{
        handle = ChartIndicatorGet(ChartID(), 0, "VWAP");
        SetIndexBuffer(0, Buff, INDICATOR_DATA);
        
        EventSetTimer(1);
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        int i;
        
        if (handle != INVALID_HANDLE)
        {
                i = CopyBuffer(handle, 0, 0, 1, Buff);
                Print(Buff[0]);
        }
}
//+------------------------------------------------------------------+

강조 표시된 부분은 추가한 부분입니다. 결과는 다음과 같습니다:


어떻게 작동하게 되었을까요? MQL5가 시스템 간에 데이터를 읽고 쓸 수 있는 수단을 제공하기 때문입니다. 읽는 방법 중 하나는 CopyBuffer기능을 사용하는 것입니다. 이는 아래와 같이 작동합니다:


따라서 모든 맞춤형 지표에서 데이터를 읽을 수 있고 표준 MetaTrader 5 지표에 국한되지 않습니다. 이는 우리가 어떤 지표를 만들 수 있고 그것이 작동한다는 것을 의미합니다.

이제 다른 시나리오를 고려해 봅시다. 이번에는 VWAP가 차트에 존재하지 않습니다. 그러나 EA는 이를 필요로 하므로 차트에 로드해야 합니다. 어떻게 할까요? 아주 간단합니다. 우리는 Expert Advisor의 하위 창을 만들 때 이미 다른 용도로 사용했습니다. 지금 할 일은 iCustom 기능을 사용하는 것입니다. 그러나 이번에는 맞춤형 지표를 로드 하겠습니다. 그러면 EA 코드는 다음과 같을 것입니다.

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
int     handle;
double  Buff[];
//+------------------------------------------------------------------+
int OnInit()
{
        handle = ChartIndicatorGet(ChartID(), 0, "VWAP");
        SetIndexBuffer(0, Buff, INDICATOR_DATA);
        
        EventSetTimer(1);
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        int i;
        
        if (handle == INVALID_HANDLE) handle = iCustom(NULL, PERIOD_CURRENT, "VWAP.EX5");else
        {
                i = CopyBuffer(handle, 0, 0, 1, Buff);
                Print(Buff[0]);
        }
}
//+------------------------------------------------------------------+

강조 표시된 코드는 원래 시스템에 추가한 유일한 것입니다. 이제 EA를 실행하면 다음과 같은 결과를 얻습니다:


아래 그림은 우리가 구현한 것을 보여줍니다:

이것이 가장 기본적인 수준에서 필요한 전부입니다. 그러나 자세히 보면 차트에 VWAP가 표시되지 않음을 알 수 있습니다. EA가 VWAP를 사용하더라도 사용자는 무슨 일이 일어나고 있는지 모릅니다. 이 또한 쉽게 고칠 수 있으며 최종 코드는 아래와 같습니다. 다음을 기억하십시오: EA가 무슨 일을 하고 있는 것인지를 분석하고 관찰할 수 있다는 것은 항상 좋은 일입니다. 왜냐하면 완전한 자유를 주는 것은 그다지 안전하지 않기 때문입니다. 그래서 저는 그렇게 하는 것을 추천하지 않습니다:

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
int     handle;
long    id;
double  Buff[];
string  szCmd;
//+------------------------------------------------------------------+
int OnInit()
{
        szCmd = "VWAP";
        handle = ChartIndicatorGet(id = ChartID(), 0, szCmd);
        SetIndexBuffer(0, Buff, INDICATOR_DATA);
        
        EventSetTimer(1);
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        ChartIndicatorDelete(id, 0, szCmd);
        IndicatorRelease(handle);
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        int i;
        
        if (handle == INVALID_HANDLE)
        {
                if ((handle = iCustom(NULL, PERIOD_CURRENT, "VWAP.EX5")) != INVALID_HANDLE)
                        ChartIndicatorAdd(id, 0, handle);
        }else
        {
                i = CopyBuffer(handle, 0, 0, 1, Buff);
                Print(Buff[0]);
        }
}
//+------------------------------------------------------------------+

위의 EA 코드는 VWAP가 계산한 마지막 값을 읽어서 화면에 표시합니다. 지표가 차트에 없을 경우 지표가 로드되어 표시됩니다. 차트에서 EA를 제거하면 VWAP도 화면에서 제거됩니다. 따라서 EA에는 항상 계산을 수행하기 위해 필요한 것들이 있을 것입니다. 제가 설명한 결과는 아래와 같습니다:


어떤 사람은 지표에 변경한 것이 없기 때문에 이것이 실현 가능하지 않다고 생각할 수도 있습니다. 그러나 위의 단계를 수행하더라도 맞춤형 지표와 관련된 모든 것을 구현할 수 있습니다. 마지막 설명을 위해 다른 예를 살펴보겠습니다. VWAP에서와 동일한 방식으로 이동 평균을 적용하고 Expert Advisor를 사용하겠습니다. 이제 평균에 대한 매개변수를 지정하겠습니다.


두 번째 경우: 이동 평균 사용

이동 평균 계산은 여기에서 중요하지 않습니다. 매개변수를 맞춤형 지표에 전달하는 방법에 중점을 둘 것이기 때문입니다. 다음은 새로운 맞춤형 지표입니다.

#property copyright "Daniel Jose 16.05.2021"
#property description "Basic Moving Averages (Optimizes Calculation)"
#property indicator_chart_window
//+------------------------------------------------------------------+
enum eTypeMedia
{
        MME,    //Exponential moving average
        MMA     //Arithmetic moving average
};
//+------------------------------------------------------------------+
#property indicator_buffers             1
#property indicator_plots               1
#property indicator_type1               DRAW_LINE
#property indicator_width1              2
#property indicator_applied_price       PRICE_CLOSE
//+------------------------------------------------------------------+
input color      user00 = clrRoyalBlue; //Cor
input int        user01 = 9;            //Periods
input eTypeMedia user02 = MME;          //MA type
input int user03 = 0;            //Displacement
//+------------------------------------------------------------------+
double Buff[], f_Expo;
//+------------------------------------------------------------------+
int OnInit()
{
        string sz0 = "MM" + (user02 == MME ? "E": (user02 == MMA ? "A" : "_")) + (string)user01;
        
        f_Expo = (double) (2.0 / (1.0 + user01));
        ArrayInitialize(Buff, EMPTY_VALUE);
        SetIndexBuffer(0, Buff, INDICATOR_DATA);
        PlotIndexSetInteger(0, PLOT_LINE_COLOR, user00);
        PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, user01);
        PlotIndexSetInteger(0, PLOT_SHIFT, user03);
        IndicatorSetString(INDICATOR_SHORTNAME, sz0);
        
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
{
        double Value;
        int c0;

        switch (user02)
        {
                case MME:
                        if (user01 < rates_total)
                        {       
                                for (c0 = (prev_calculated > 0 ? prev_calculated - 1 : 0); c0 < rates_total - user03; c0++)
                                        Buff[c0] = (c0 > 0? ((price[c0] - Buff[c0 - 1]) * f_Expo) + Buff[c0 - 1] : price[c0] * f_Expo);
                                for (; c0 < rates_total; c0++)
                                        Buff[c0] = EMPTY_VALUE;
                        }
                        break;
                case MMA:
                        if (user01 < rates_total)
                        {
                                if (prev_calculated == 0) 
                                {       
                                        Value = 0;
                                        for (int c1 = 0; c1 < user01; c1++) Value += price[user01 - c1];
                                        Buff[user01] = Value / user01;
                                }
                                for (c0 = (prev_calculated > 0 ? prev_calculated - 1 : user01 + 1); c0 < rates_total - user03; c0++)
                                        Buff[c0] = ((Buff[c0 - 1] * user01) - price[c0 - user01] + price[c0]) / user01;
                                for (; c0 < rates_total; c0++)
                                        Buff[c0] = EMPTY_VALUE;
                        }
                        break;
        }
        
        return rates_total;
}
//+------------------------------------------------------------------+

이제 지표의 이름은 여러 요인에 따라 달라집니다. 나중에 EA를 확인하고 각 상황에 맞게 조정할 수 있습니다. 예를 들어 EA가 두 개의 이동 평균을 사용한다고 가정해 보겠습니다. 위 코드에서 강조 표시된 부분에 주의하십시오. EA를 활성화하고 이 경우 iCustom 함수를 사용하여 지표의 매개변수를 변경하고 구성합니다. 필요에 따라 구현할 수 있다는 것을 이해하는 것이 중요합니다. 따라서 평균 중 하나는 17기간 지수 MA이고 다른 하나는 52기간 산술 MA입니다. 17 기간 MA는 녹색이고 52 기간 MA는 빨간색입니다. EA는 지표를 다음과 형식의 함수로 볼 것입니다.

Average(Color, Period, Type, Shift) 이므로 이제 지표는 별도의 파일이 아니라 EA의 기능입니다. 이것은 특정 작업을 실행하기 위해 관련 매개변수를 사용하여 프로그램을 호출하고 결과를 더 쉽게 얻을 수 있기 때문에 프로그래밍에서 매우 일반적입니다. 그러나 다음과 같은 질문이 있을 것입니다. VWAP에서와 동일한 방식으로 EA가 이 시나리오를 생성하고 관리하도록 하려면 어떻게 해야 할까요?

이를 위해 EA의 코드를 변경해야 합니다. 새로운 EA의 전체 코드는 아래와 같습니다:

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
long    id;
int     handle1, handle2;
double  Buff1[], Buff2[];
string  szCmd1, szCmd2;
//+------------------------------------------------------------------+
int OnInit()
{
        szCmd1 = "MME17";
        szCmd2 = "MMA52";
        id = ChartID();
        handle1 = ChartIndicatorGet(id, 0, szCmd1);
        handle2 = ChartIndicatorGet(id, 0, szCmd2);
        SetIndexBuffer(0, Buff1, INDICATOR_DATA);
        SetIndexBuffer(0, Buff2, INDICATOR_DATA);
        
        EventSetTimer(1);
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        ChartIndicatorDelete(id, 0, szCmd1);
        ChartIndicatorDelete(id, 0, szCmd2);
        IndicatorRelease(handle1);
        IndicatorRelease(handle2);
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        int i1, i2;
        
        if (handle1 == INVALID_HANDLE)
        {
                if ((handle1 = iCustom(NULL, PERIOD_CURRENT, "Media Movel.EX5", clrGreen, 17, 0)) != INVALID_HANDLE)
                        ChartIndicatorAdd(id, 0, handle1);
        };
        if (handle2 == INVALID_HANDLE)
        {
                if ((handle2 = iCustom(NULL, PERIOD_CURRENT, "Media Movel.EX5", clrRed, 52, 1)) != INVALID_HANDLE)
                        ChartIndicatorAdd(id, 0, handle2);
        };
        if ((handle1 != INVALID_HANDLE) && (handle2 != INVALID_HANDLE))
        {
                i1 = CopyBuffer(handle1, 0, 0, 1, Buff1);
                i2 = CopyBuffer(handle2, 0, 0, 1, Buff2);
                Print(Buff1[0], "<< --- >>", Buff2[0]);
        }
}
//+------------------------------------------------------------------+

결과는 다음과 같습니다:


EA 코드에서 강조 표시된 부분에 주의하십시오. 이것이 바로 우리가 필요로 하는 것입니다. VWAP에서 사용한 것과 동일한 메커니즘을 사용하여 매개변수를 지표에 전달합니다. 그러나 이동 평균은 전달해야 할 매개변수가 있지만 VWAP의 경우는 매개변수를 전달할 필요가 없습니다. 이 모든 것이 매우 큰 자유도를 제공합니다.


결론

이 문서에는 범용 코드가 포함되어 있지 않습니다. 어쨌든 우리는 더 복잡하고 잘 고안된 Expert Advisor에서 이러한 종류의 시스템을 사용하는 방법을 이해하기 위해 두 개의 다른 Expert Advisor와 두 개의 다른 맞춤형 지표에 대해 자세히 살펴보았습니다. 이 지식을 바탕으로 우리는 우리가 만든 맞춤 지표를 사용할 수 있을 것입니다. 우리의 EA도 매우 흥미로운 분석을 제공할 수 있습니다. 이 모든 것을 보면 MetaTrader 5가 트레이더들이 원하는 것을 제공해 주는 가장 다재 다능한 플랫폼임이 분명합니다. 이것을 이해하지 못한다면 플래폼에 대해 연구하지 않았기 때문일 것입니다.

MetaTrader 5를 사용하면 지금까지 많은 사람들이 할 수 있었던 것보다 훨씬 더 멀리 갈 수 있기 때문에 이 기사에서 제공한 내용과 지식을 사용하십시오.

다음 기사에서 뵙겠습니다.


링크

MQL5에서 지표를 호출하는 방법

초보자를 위한 MQL5의 커스텀 인디케이터

초보자를 위한 MQL5: Expert Advisors에서 기술적 지표 값 사용 가이드



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

Expert Advisor 개발 기초부터 (파트 11): 교차 주문 시스템(Cross order system) Expert Advisor 개발 기초부터 (파트 11): 교차 주문 시스템(Cross order system)
이 기사에서는 교차 주문 시스템을 만들 것입니다. 트레이더의 삶을 매우 어렵게 만드는 한 가지 자산이 있습니다. - 바로 선물 계약입니다. 왜 선물이 어렵게 만드는 것일까요?
MetaTrader 5에서 DirectX를 사용하여 3D 그래픽을 만드는 방법 MetaTrader 5에서 DirectX를 사용하여 3D 그래픽을 만드는 방법
3D 그래픽은 숨겨진 패턴을 시각화 할 수 있습니다. 그러므로 방대한 양의 데이터를 분석하는 데 탁월합니다 이러한 작업은 MQL5에서 직접 해결할 수 있는데 DireсtX 함수를 사용하면 3차원 객체를 만들 수 있습니다. 따라서 MetaTrader 5용 3D 게임과 같은 복잡한 프로그램을 만드는 것도 가능합니다. 간단한 3차원 도형을 그리는 것으로 3D 그래픽을 배워보세요.
OBV로 트레이딩 시스템을 설계하는 방법 알아보기 OBV로 트레이딩 시스템을 설계하는 방법 알아보기
이 기사는 인기있는 지표 중 일부를 기반으로 거래 시스템을 설계하는 방법에 대해 초보자들에게 설명하는 시리즈에서 계속되는 새로운 기사입니다. OBV(On Balance Volume)라는 새로운 지표를 배우고 이를 어떻게 사용하고 이를 기반으로 하는 거래 시스템을 어떻게 설계하는지 알아보겠습니다.
시각화! R 언어의 'plot'과 유사한 MQL5 그래픽 라이브러리 시각화! R 언어의 'plot'과 유사한 MQL5 그래픽 라이브러리
트레이딩의 로직을 연구할 때 그래프의 형태로 표시되는 시각적 표현은 매우 중요합니다. 과학 관련 커뮤니티에서 널리 사용되는 여러 프로그래밍 언어(예: R 및 Python)에는 시각화에 사용되는 특수한 '플롯' 함수가 있습니다. 이 함수들이 선, 점 분포 및 히스토그램을 그려서 패턴을 시각화 할 수 있습니다. MQL5에서는 CGraphics 클래스를 사용하여 동일한 작업을 수행할 수 있습니다.