English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
preview
윌리엄 간 메서드(1부): 간 각도 지표 생성하기

윌리엄 간 메서드(1부): 간 각도 지표 생성하기

MetaTrader 5트레이딩 |
16 18
Yevgeniy Koshtenko
Yevgeniy Koshtenko

소개

윌리엄 델버트 간은 전설적인 트레이더이자 기술 분석가이며 혁신적인 시장 분석 방법을 개발하였고 여전히 현대 트레이더들의 관심을 받고 있습니다. 간의 주요 도구 중 하나는 그 유명한 각도인데 가격의 움직임을 예측하고 잠재적인 지지선과 저항선을 식별하는 데 사용됩니다.

이 글에서는 MQL5에서 간 각도 지표를 만드는 것부터 시작하여 윌리엄 간의 트레이딩 기술에 대해 알아보겠습니다. 우리는 간 각도 지표의 이론에 대해 살펴보고 MetaTrader 5 플랫폼용 사용자 지정 보조 지표로 단계별로 구현해 보겠습니다.

새로운 분석 도구를 찾고 있는 숙련된 트레이더든 기술 지표의 무기를 넓히고자 하는 초보자이든 이 글은 윌리엄 간의 가장 흥미로운 기술 중 하나를 더 잘 이해하고 거래에 적용하는 데 도움이 될 것입니다.


간 각도를 만들기까지의 역사

윌리엄 델버트 간(1878~1955)은 20세기 초 시장 움직임에 대한 수년 간의 연구와 시간과 가격 사이의 관계에 대한 독특한 이해를 바탕으로 이 각도 시스템을 개발했습니다.

간은 시장이 예측 가능한 기하학적 패턴으로 움직이며 이러한 움직임은 수학, 기하학, 점성술의 조합을 통해 예측될 수 있다고 믿었습니다. 그리고 이를 바탕으로 시간과 가격 변동 사이의 완벽한 균형을 반영하는 차트상의 대각선인 각도의 개념을 개발했습니다.

간의 이론의 핵심은 45도 각도(1x1 각도로 알려져 있음)가 시간과 가격 사이의 완벽한 균형을 나타낸다는 아이디어였습니다. 이 각도에서 가격이 오르거나 내리면 균형 잡힌 안정적인 추세를 나타낸다고 믿었습니다.

간은 또한 시간과 가격 간의 다양한 관계를 나타내는 2x1, 3x1, 4x1 및 그 역수와 같은 다른 각도도 개발했습니다. 이러한 각도는 그의 트레이딩 시스템과 시장 분석의 기초가 되었습니다.

이러한 간의 분석의 일부는 여전히 논란의 여지가 있지만 간 각도을 포함한 그의 기술은 전 세계 트레이더와 애널리스트의 관심을 계속 끌고 있으며 현대 트레이딩에서 여전히 유효하다고 알려져 있습니다.


간 각도 이론과 기술적 분석에서의 중요성

간 각도 이론은 시장 움직임이 차트의 특수한 각도를 통해 식별될 수 있는 예측 가능한 기하학적 패턴을 따른다는 개념에 기반합니다. 이 이론은 시간과 가격 사이의 균형이라는 개념을 기반으로 하며 1x1 각도(45도)는 시간당 1단위 가격 변동이 있다고 가정할 때 완벽한 균형을 나타냅니다.

간은 시간과 가격 변동 사이의 특정 관계를 반영하는 2x1, 3x1, 4x1 및 그 역수 등 다양한 각도의 시스템을 개발했습니다. 이러한 각도는 동적 지지 및 저항 수준으로 작용하여 트레이더가 추세의 강도와 방향을 결정하는 데 도움이 됩니다. 각도가 가파를수록 강한 추세를 나타내고 각도가 평평할수록 약한 움직임을 나타냅니다.


간 각도 구성의 기본 원칙


간 각도는 트레이더가 이 도구를 기술적 분석에 효과적으로 사용할 수 있는 몇 가지 핵심적인 원칙을 기반으로 합니다. 시작점(일반적으로 차트에서 중요한 최소값 또는 최대값)을 선택하는 것이 가장 중요합니다. 이 시점부터 각도의 구성이 시작됩니다.

기본 각도는 차트에서 45도 선을 이루는 1x1 각도로 간주됩니다. 이 각도는 시간과 가격 사이의 완벽한 균형을 반영하며 한 기간 동안 가격이 한 단위씩 변동합니다. 2x1, 3x1, 4x1 및 그 역수와 같은 다른 각도는 이 기본 각도를 기준으로 구성됩니다.

차트를 그릴 때는 차트의 배율이 중요합니다. 트레이더들은 정확한 각도를 확보하기 위해 특수한 템플릿이나 도구를 사용하는 경우가 많습니다. 각도선은 이후 계속 이어져 잠재적인 지지 및 저항 수준을 예측하게 해 줍니다.


간 각도의 유형과 해석

윌리엄 간은 기술적 분석에서 각각 고유한 의미와 해석을 가진 각도 시스템을 개발했습니다. 1x1 또는 45도가 주요 각도로 간주되며 이는 시간과 가격 간의 균형을 반영합니다. 이 각도는 추세의 강도를 평가하기 위한 기본적인 가이드라인의 역할을 합니다.

2x1 각도(63.75도)는 가격이 시간보다 두 배 빠르게 상승하는 더 강한 가격 움직임입니다. 이는 종종 강한 상승 추세의 신호로 해석되기도 합니다. 반대로 1x2 각도(26.25도)는 시간에 비해 가격 상승이 느리다는 것을 나타내며 이는 약세인 추세를 나타낼 수 있습니다.

3x1(71.25도) 및 4x1(75도) 각도는 훨씬 더 공격적인 가격 움직임을 나타내며 일반적으로 매우 강한 추세 또는 잠재적인 시장 과열과 관련이 있습니다. 역수인 1x3(18.75도)와 1x4(15도)는 강한 저항 또는 지지를 나타낼 수 있습니다.

간 각도에 대한 해석은 기울기에만 국한되지 않습니다. 가격이 이러한 라인과 어떻게 상호 작용하는지도 중요한 고려 사항입니다. 가격이 각도선을 넘으면 추세에 변화가 있을 수 있다는 신호일 수 있습니다. 가격이 각도선을 따라 움직이면 현재 추세의 강도를 확인하는 것으로 해석하는 경우가 많습니다.


트레이딩에서 간 각도의 실제 적용

트레이더는 추세 파악부터 포지션 진입 및 청산 시점 선택까지 다양한 용도로 이들 도구를 사용합니다.

추세를 결정하려면 주요한 최소값 또는 최대값에서 1x1 각도를 그립니다. 가격이 이 선 위로 이동하면 상승 추세로, 그 아래로 이동하면 하락 추세로 해석됩니다. 2x1 또는 3x1과 같이 더 가파른 각도는 추세의 강도를 확인하는 데 사용됩니다.

진입 시점을 선택할 때 대부분의 트레이더들은 가격이 반등하거나 간 각도선을 돌파하는 순간을 찾습니다. 예를 들어 추세 방향으로 1x1 선에서 반등하면 포지션에 진입할 수 있는 잠재적인 기회로 볼 수 있습니다.

리스크 관리를 위해 간 각도는 손절매를 설정하는 데 자주 사용됩니다. 트레이더는 롱 포지션의 경우 가장 가까운 각도 선의 바로 아래에 손절매를 설정하거나 숏 포지션의 경우 바로 위에 손절매를 설정할 수 있습니다.

장기 트레이딩에서 간 각도는 시장의 전반적인 방향을 결정하는 데 도움을 줍니다. 1x2 또는 1x4와 같이 더 얕은 각도를 사용하여 장기적인 추세를 평가하고 전략적 결정을 내릴 수 있습니다.


간 각도를 사용한 트레이딩 전략 예시

간 각도는 트레이더에게 다양한 트레이딩 전략을 세울 수 있는 폭넓은 옵션을 제공합니다. 다음은 실제 거래에서 효과적으로 사용할 수 있는 몇 가지 예시입니다.

각도 바운스 전략은 간 각도선이 종종 지지선 또는 저항선이 된다는 가정에 기반합니다. 트레이더는 가격이 간 각도선(특히 1x1 또는 2x1)에 근접한 후 반등하는 상황을 찾습니다. 포지션 진입은 캔들 스틱 반전 패턴 형성 등 반등을 확인한 후 진행됩니다.

또 다른 인기 있는 전략은 각도 돌파입니다. 여기서 트레이더는 특히 거래량 증가가 동반되는 경우 가격이 중요한 간 각도를 돌파할 때까지 기다립니다. 상승 돌파는 잠재적 매수 포지션, 하락 돌파는 매도 포지션의 신호일 수 있습니다.

간 팬 전략은 한 지점에서 방사되는 여러 각도를 사용하여 부채꼴 구조를 형성합니다. 트레이더는 가격이 다양한 팬 라인과 상호 작용하는 방식을 분석하여 이를 통해 지지, 저항 수준 및 잠재적 반전 지점을 결정합니다.

각도와 시간주기를 결합하는 것은 간 각도를 간이 개발한 시간주기의 개념과 결합하는 보다 복잡한 전략입니다. 여기서 타임라인과 간 각도의 교차점을 분석하여 시장 진입 또는 청산의 중요한 순간을 결정합니다.

멀티 타임프레임 전략은 다양한 타임프레임에서 간 각도를 분석하는 것입니다. 예를 들어 트레이더는 일봉 차트에서 1대1 각도를 사용하여 전체 추세를 파악한 다음 시간별 차트에서 더 가파른 각도를 사용하여 진입 시점을 찾을 수 있습니다.


MQL5에서 간 각도 지표 만들기: 기본 단계


MQL5에서 간 각도 지표를 만들려면 몇 가지 단계를 거쳐야 합니다. 이 프로세스를 수행하려면 간 각도의 구성 원리와 MetaTrader 5 환경에서 프로그래밍 하는 법 등 세부 사항을 모두 이해해야 합니다.

첫 번째 단계는 지표 구조를 정의하는 것입니다. 여기에서 지표 이름, 각도 설정을 위한 입력 매개변수 및 필요한 라이브러리와 같은 기본 매개변수를 설정합니다.

간 각도를 구성하는 주요 로직은 OnCalculate() 함수에 있습니다. 여기서 각도를 그리기 위한 시작점을 정의하고 각각의 각도에 대한 좌표를 계산한 다음 차트에 선을 그립니다.

여기서 중요한 것은 차트의 배율과 선택한 시간 간격을 고려하여 각도의 좌표를 올바르게 계산하는 것입니다. 이를 위해서는 정확한 수학적 접근 방식과 간 각도의 기하학적 구조에 대한 이해가 필요합니다.

마지막 단계는 지표를 테스트하고 디버깅하는 것입니다. 다양한 시간대 및 도구에서 각도 구성의 유효성을 확인해야 합니다.


지표 코드 구조

다음은 MetaTrader 5에서 사용할 수 있는 간 각도 지표의 기본 코드입니다:

#property copyright "Copyright 2024, Evgeniy Shtenco"
#property link      "https://www.mql5.com/en/users/koshtenko"
#property version   "1.00"
#property indicator_chart_window

// Input parameters
input datetime StartDate = D'2023.01.01 00:00'; // Start date for analysis
input datetime EndDate = D'2023.12.31 23:59';   // End date for analysis
input color GannFanColor = clrBlue;             // Color for Gann Fan lines

// Global variables
double extremumPrice;
datetime extremumTime;
double oppositeExtremumPrice;
datetime oppositeExtremumTime;
bool isTrendUp;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    ObjectsDeleteAll(0, "GannFan_");
    ObjectsDeleteAll(0, "OppositeGannFan_");
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
{
    if(rates_total < 1) return(0);

    // Clear previous objects
    if (prev_calculated == 0)
    {
        ObjectsDeleteAll(0, "GannFan_");
        ObjectsDeleteAll(0, "OppositeGannFan_");
    }

    // Find extremums within the specified date range
    FindExtremums(rates_total, high, low, time);

    // Draw Gann Fans
    DrawGannFan(extremumPrice, extremumTime);
    DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);

    return(rates_total);
}

//+------------------------------------------------------------------+
//| Find both extremums within the specified date range              |
//+------------------------------------------------------------------+
void FindExtremums(const int rates_total, const double &high[], const double &low[], const datetime &time[])
{
    int startIndex = -1;
    int endIndex = -1;

    for (int i = 0; i < rates_total; i++)
    {
        if (time[i] >= StartDate && startIndex == -1)
        {
            startIndex = i;
        }
        if (time[i] <= EndDate)
        {
            endIndex = i;
        }
    }

    if (startIndex == -1 || endIndex == -1 || startIndex > endIndex)
    {
        Print("Error: Invalid date range or no data available in the specified range");
        return;
    }

    int highestIndex = ArrayMaximum(high, startIndex, endIndex - startIndex + 1);
    int lowestIndex = ArrayMinimum(low, startIndex, endIndex - startIndex + 1);

    // Determine the most recent extremum
    if (time[highestIndex] > time[lowestIndex])
    {
        extremumPrice = high[highestIndex];
        extremumTime = time[highestIndex];
        oppositeExtremumPrice = low[lowestIndex];
        oppositeExtremumTime = time[lowestIndex];
        isTrendUp = false;
    }
    else
    {
        extremumPrice = low[lowestIndex];
        extremumTime = time[lowestIndex];
        oppositeExtremumPrice = high[highestIndex];
        oppositeExtremumTime = time[highestIndex];
        isTrendUp = true;
    }
}

//+------------------------------------------------------------------+
//| Draw Gann Fan                                                    |
//+------------------------------------------------------------------+
void DrawGannFan(double extremum, datetime extremumTime)
{
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    datetime endTime = extremumTime + PeriodSeconds() * 300;

    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "GannFan_" + angleNames[i];
        double angle = angles[i];
        
        double priceShift = MathTan(angle * M_PI / 180.0) * 300 * _Point;
        double endPrice;
        
        if(isTrendUp)
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // Invert the angle for a downtrend
        }

        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice))
        {
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//| Draw Opposite Gann Fan                                           |
//+------------------------------------------------------------------+
void DrawOppositeGannFan(double extremum, datetime extremumTime)
{
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    datetime endTime = extremumTime + PeriodSeconds() * 300;

    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "OppositeGannFan_" + angleNames[i];
        double angle = angles[i];
        
        double priceShift = MathTan(angle * M_PI / 180.0) * 300 * _Point;
        double endPrice;
        
        if(!isTrendUp) // Opposite trend
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // Invert the angle for a downtrend
        }

        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice))
        {
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Opposite Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Opposite Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    // Redraw objects when chart changes
    if(id == CHARTEVENT_CHART_CHANGE)
    {
        // Find extremums and redraw Gann Fans
        int rates_total = Bars(_Symbol, PERIOD_CURRENT);
        double high[], low[];
        datetime time[];
        ArraySetAsSeries(high, true);
        ArraySetAsSeries(low, true);
        ArraySetAsSeries(time, true);
        CopyHigh(_Symbol, PERIOD_CURRENT, 0, rates_total, high);
        CopyLow(_Symbol, PERIOD_CURRENT, 0, rates_total, low);
        CopyTime(_Symbol, PERIOD_CURRENT, 0, rates_total, time);
        
        FindExtremums(rates_total, high, low, time);
        DrawGannFan(extremumPrice, extremumTime);
        DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);
    }
}


주요 기능 및 목적

이 코드는 차트에 간 팬의 각도를 그리는 MetaTrader 5 보조지표 코드입니다. 다음은 지표와 코드에 대한 설명입니다:

  1. OnInit()은 지표 초기화 함수입니다. 이 경우 단순히 성공적인 초기화 결과를 반환합니다.
  2. OnDeinit()은 차트에서 지표가 제거될 때 지표가 만든 모든 객체를 제거하는 초기화 함수입니다.
  3. OnCalculate()는 지표의 주요 함수입니다. 매 틱마다 호출됩니다. 이전 객체를 지우고 주어진 날짜 범위에서 극단을 찾고 간 각도를 그립니다.
  4. FindExtremums()는 지정된 날짜 범위에서 가격의 극한값(최대값과 최소값)을 구하는 함수입니다. 어느 쪽이 더 최근의 극단인지 판단하고 추세의 방향을 설정합니다.
  5. DrawGannFan()은 찾은 극한값에서 메인 간 팬을 그리는 함수입니다. 9가지 각도에서 선을 만듭니다.
  6. DrawOppositeGannFan()은 다른 극한에서 반대쪽 간 팬을 그리는 함수입니다. 또한 9개의 각도에 대한 선을 만들지만 반대 방향으로 만듭니다.
  7. OnChartEvent()는 차트 이벤트에 응답하는 함수입니다. 이 경우 차트가 변경되면 간 팬을 다시 그립니다.

지표는 입력을 사용하여 분석 날짜 범위(StartDate and EndDate)와 선의 색상(GannFanColor)을 설정합니다. 이 범위에서 가격 극단을 찾아 추세 방향을 결정하고 마지막 극단과 반대쪽 극단에서 두 개의 간 팬을 그립니다. 각 팬은 서로 다른 간 각도(82.5°, 75°, 71.25°, 63.75°, 45°, 26.25°, 18.75°, 15° 및 7.5°)에 해당하는 9개의 선으로 구성됩니다.

이 코드에는 오류 처리와 차트 변경 시 동적 업데이트 기능도 포함되어 있어 매우 견고하고 다양한 시장 상황에 대처할 수 있습니다. ArrayMaximum() 및 ArrayMinimum()과 같은 MQL5 함수를 사용하면 데이터를 효율적으로 처리할 수 있습니다.

간 각도 계산 알고리즘

이 지표에서 간 각도를 계산하는 알고리즘은 극한점으로부터의 선의 기하학적 구조를 기반으로 합니다. 이 알고리즘의 주요 내용은 다음과 같습니다:

  • 극단 결정하기: 지표는 주어진 시간 범위에서 최대 및 최소 가격을 찾습니다. 이 두 가지 극단 중 후자는 메인 간 팬의 시작점으로 전자는 반대편 팬의 시작점으로 사용됩니다.
  • 각도 설정: 고정 각도 세트가 사용됩니다: 82.5°, 75°, 71.25°, 63.75°, 45°, 26.25°, 18.75°, 15° 및 7.5°. 이 각도는 전통적인 간 비율입니다: 1x8, 1x4, 1x3, 1x2, 1x1, 2x1, 3x1, 4x1 및 8x1.
  • 끝점 계산: 각 각도에 대해 선의 끝점이 계산됩니다. 계산은 방정식을 기반으로 합니다:
endPrice = extremum + MathTan(angle * M_PI / 180.0) * 300 * Point
  • 여기서 300은 라인을 구성하는 데 사용되는 일반적인 이전 바의 수입니다.
  • 하락 추세에 대한 반전: 추세가 하락하는 경우 각도가 반전(부호 변경)되어 선이 극단점에서 아래쪽을 가리키도록 합니다.
  • 라인 구축: 각 각도에 대해 극한점에서 계산된 끝점까지 선 객체(OBJ_TREND)가 생성됩니다. 향후 데이터를 포함할 수 있도록 오른쪽으로 선이 확장됩니다.
  • 이중 팬: 알고리즘이 두 번 적용됩니다 - 마지막 극단의 메인 팬에 한 번, 초기 극단의 반대쪽 팬에 한 번 적용됩니다. 이를 통해 양쪽의 잠재적 지지와 저항 수준을 시각화 할 수 있습니다.
  • 동적 업데이트: 차트가 변경되면(예: 새 데이터가 도착하는 경우) 알고리즘이 극단을 다시 계산하고 팬을 다시 작성하여 분석이 최신 상태로 유지되도록 합니다.

이 알고리즘을 사용하면 차트에서 고전적인 간 각도를 시각화 하여 트레이더가 잠재적 지지, 저항 수준 및 추세 방향을 분석할 수 있게 해 줄 수 있습니다. 


수익성 있는 거래가 가능한가요?

간 각도를 사용하여 수익성 있는 거래가 가능한가요? 이 질문에는 명확한 답은 없지만 올바른 접근 방식을 사용하면 수익성 있는 거래가 가능합니다. 성공의 열쇠는 이 도구를 완전히 사용하는 데 있습니다.

그러나 아무리 신중하고 세심한 분석을 하더라도 리스크 관리를 잊지 말아야 합니다. 이것이 수익성 있는 트레이딩의 초석입니다. 100%의 성공을 보장하는 방법은 없으므로 자본과 리스크를 적절히 관리하는 것이 장기적인 수익성에 중요한 역할을 합니다.


간 각도 기반 EA 제작


간 각도를 기반으로 EA를 만드는 것은 알고리즘 트레이딩 시스템 개발자에게 흥미로운 작업입니다. 이러한 EA는 간 이론에 명시된 원칙을 사용하여 분석과 트레이딩을 자동화할 수 있게 해 줍니다.

이러한 EA를 제작하는 데에 기초가 되는 것은 이미 구현된 간 각도 지표가 될 수 있습니다. EA 알고리즘에는 가격과 간 라인의 상호 작용 분석을 통해 이 라인의 교차점을 기준으로 진입 및 청산 지점을 결정하는 것으로 거래량 및 시장 변동성과 같은 추가적인 요인도 같이 고려할 수 있습니다.

간 각도를 기반으로 하는 자동화 시스템의 주요 이점 중 하나는 거래 의사 결정 과정에서 감정적 요소를 제거할 수 있다는 점입니다. 종종 두려움이나 욕심이 인간 트레이더의 결정에 영향을 미치는데 비해 EA는 그런것들에 굴복하지 않고 주어진 전략을 엄격하게 따를 수 있습니다.

그러나 이러한 EA를 개발하는 데는 여러 가지 어려움이 있습니다. 우선 간 각도에서 생성되는 신호를 정확하게 해석할 필요가 있습니다. 간 이론은 대체로 주관적이며 시장에 대한 깊은 이해가 필요하기 때문에 알고리즘의 형태로 완벽하게 구현하기 상당히 어렵습니다.

물론 이러한 EA가 성공적일지 여부는 개발자가 간 이론에 대한 이해의 깊이가 있는지 여부와 이 이론을 현대적인 시장 분석과 위험 관리 기법과 함께 효과적으로 결합하는 능력에 따라 크게 달라집니다.


가장 큰 도전 과제: 확장 각도

간 각도를 기반으로 지표와 EA를 만들고 사용할 때 가장 심각한 문제 중 하나는 간 각도를 확장하기가 어렵다는 점입니다. 이 문제는 간의 방식에 기반한 트레이딩 시스템의 정확성과 효율성에 큰 영향을 미칩니다.

문제의 본질은 기하학적 구조인 간 각도가 차트 눈금에 크게 의존한다는 것입니다. 시간 축의 눈금이나 가격의 눈금을 변경하면 각도의 시각적 표현이 크게 왜곡될 수 있습니다. 한 눈금에서는 완벽한 1대1(45도) 각도로 보였던 것이 눈금을 변경할 경우에는 완전히 다른 각도로 바뀔 수 있습니다.

이로 인해 소프트웨어를 구현하는 데에 심각한 어려움이 발생하게 됩니다. 우리의 지표나 EA는 차트의 현재 눈금을 지속적으로 신경 써서 그에 따라 각도의 계산을 조정해야 합니다. 게다가 간 각도의 기반이 되는 '가격 단위와 동일한 시간 단위'라는 개념은 다양한 금융 상품과 시간 프레임으로 작업할 때 모호해집니다.

이 문제를 해결하려는 시도는 종종 타협으로 이어집니다. 일부 개발자는 스케일을 수정하는데 이는 간 각도가 적용될 수 있는 폭을 좁히게 됩니다. 일부는 각도를 다시 계산하는 복잡한 알고리즘을 도입하는데 이는 지표 또는 EA의 속도를 저하시킬 수 있습니다.

또한 스케일링 문제로 인해 다른 도구나 기간과의 분석 결과를 비교하기가 어렵게 됩니다. 한 통화쌍의 일간 차트에서 효과적으로 작동하는 각도가 시간별 차트나 다른 트레이딩 상품에서는 완전히 다른 결과를 가져올 수 있습니다.

이 문제는 자동매매에서 간 각도가 보편적으로 적용될 수 있는 것인지 하는 의심스럽게 만듭니다. 개발자는 간 이론뿐만 아니라 트레이딩 플랫폼에서 차트를 다루는 것에 대한 깊은 이해가 필요합니다.


결론

간 각도는 트레이더와 트레이딩 시스템 개발자의 관심을 계속 끌고 있는 독특한 기술적 분석 도구입니다. MQL5에서 간 각도 표시기를 만드는 것이 충분히 가능하며 제공된 코드는 여러분이 추가적으로 개발을 하기 위한 좋은 출발점이 될 수 있습니다.

그러나 자동매매에서 간 각도를 사용하려면 여러 가지 중요한 과제가 있습니다. 가장 큰 문제는 확장과 관련한 문제로 이는 간 각도를 기반으로 보편적이고 신뢰할 수 있는 거래 EA를 만드는 것을 어렵게 합니다.

이러한 어려움에도 불구하고 시장 분석 도구로서 간 각도의 잠재력은 여전히 높습니다. 다른 기술적 분석 방법 및 적절한 위험 관리와 함께 올바르게 사용하면 트레이더들이 사용할 수 있는 훌륭한 도구가 될 수 있습니다.

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

최근 코멘트 | 토론으로 가기 (18)
Bogard_11
Bogard_11 | 15 8월 2024 에서 18:56
Eva-oren #:
건은 뛰어난 상인이자 점성가, 수비학자였으며 마법의 숫자를 믿었던 수학자였습니다. 제1차 세계대전과 제2차 세계대전의 시작과 끝을 예언한 위대한 점쟁이였습니다. 그는 수많은 제자를 두었지만 추종자들이 주장하듯이 자신의 전략을 누구에게도 알려주지 않았습니다. 엄청난 돈을 벌었고 그의 인생이 끝날 무렵에는 $ 100,000의 적당한 금액이 나왔습니다. 나는 Gunn의 천재적인 성격에 대한 다음 기사를 매우 흥미롭게 기대할 것입니다.

그 당시에는 드물었던 개인 제트기가 있었다는 사실을 잊었습니다. 그 당시 10만 달러는 지금으로 치면 10배는 아니더라도 적어도 1배는 되는 돈이죠.

추신 - 그는 전략을 전수했습니다. 그의 글에서. 누가 원했고, 전체 TC의 여러 장에서 수집했습니다. 건은 아무도 공짜로 얻을 수 없도록 모든 것을 흩어 놓았습니다.

Ivan Butko
Ivan Butko | 21 8월 2024 에서 17:11
Google에서 거래하는 방법 찾기

Maxim Kuznetsov
Maxim Kuznetsov | 22 8월 2024 에서 03:16
Ivan Butko #:
Google에서 거래 방법을 찾았습니다

두 번째 사진에서 - 원리를 이해하지 못합니다 :-(

Bogard_11
Bogard_11 | 22 8월 2024 에서 06:58

사진을 보여드리겠습니다. 건을 이해하는 사람은 모서리 작업의 원리, 긴 입구를 찾을 위치와 롤오버 할 위치를 즉시 이해할 수 있습니다.


Avatar2025
Avatar2025 | 25 6월 2025 에서 09:50
면책 조항 : 표시기에 대한 MQL5 프로그래밍 구문을 모릅니다.

그러나 각도 선 알고리즘이 옳지 않다고 생각합니다 (다른 소프트웨어에서 작성한 첨부 된 각도 선 표시기 참조). 다음은 DeepSeek와의 대화입니다 :

.
下面代码是通达信的代码,里面计算斜率的方法才是正确的,请阅读理解后,把上面priceShift 的计算方法改为下列代码正确的范式:

涨周期数:= IF(低点k位置 > 高点k位置, 低点k位置 - 高点k位置 + 1, 低点k位置), NODRAW;
跌周期数:= IF(高点k位置 > 低点k位置, 高点k位置 - 低点k位置 + 1, 高点k位置), NODRAW;

天线:= CONST(IF(高点k位置 = 1, H, REF(H, 高点k位置 - 1))), NODRAW;
地线:= CONST(IF(低点k位置 = 1, L, REF(L, 低点k位置 - 1))), NODRAW;

上涨天数:= IF(ISVALID(地线), BARSLAST(L = 地线), DRAWNULL), NODRAW;
下跌天数:= IF(ISVALID(天线), BARSLAST(H = 天线), DRAWNULL), NODRAW;

上涨高度:= IF(低点k位置 > 高点k位置, 天线 - 地线, HHV(H, 上涨天数) - 地线), NODRAW;
下跌高度:= IF(高点k位置 > 低点k位置, 天线 - 地线, 天线 - LLV(L, 下跌天数)), NODRAW;

上涨斜率:= IF(上涨天数 > 0, ROUND2(上涨高度 / 涨周期数, 4), 0), NODRAW;
下跌斜率:= IF(下跌天数 > 0, ROUND2(下跌高度 / 跌周期数, 4), 0), NODRAW;

그러나 DeepSeek는 저에게 적합하지 않은 수정 코드를 제공했습니다 :
//+------------------------------------------------------------------+
벤 팬 선 그리기 //| 벤 팬 선 그리기 & nbsp; |
//+------------------------------------------------------------------+
void DrawGannFan(double extremum, datetime extremumTime)
{
    // 간 각도와 해당 이름을 정의합니다.
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // 극한점에서 현재 K-선까지의 마침표 개수를 구합니다.
    int extremumBar = iBarShift(_Symbol, PERIOD_CURRENT, extremumTime);
    int currentBar = 0; // 현재 K-라인은 0입니다.
    int barDiff = currentBar - extremumBar; // 사이클 번호 차이
    
    // 가격 높이 차이 계산
    double priceDiff;
    if(isTrendUp)
    {
        // 상승 추세: 극저점에서 현재 최고 가격까지의 높이를 계산합니다.
        double currentHigh = iHigh(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = currentHigh - extremum;
    }
    else
    {
        // 하락 추세: 최고가부터 현재 최저가까지의 높이를 계산합니다.
        double currentLow = iLow(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = extremum - currentLow;
    }
    
    // 기본 기울기(1x1 선의 기울기)를 계산합니다.
    double baseSlope = (barDiff > 0) ? priceDiff / barDiff : 0;
    
    // 각 각도에 대한 섹터 라인 그리기
    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "GannFan_" + angleNames[i];  // 개체 레이블
        double angle = angles[i];                  // 현재 각도
        
        // 각도에 따라 기울기 배수를 계산합니다.
        double slopeMultiplier = MathTan(angle * M_PI / 180.0) / MathTan(45 * M_PI / 180.0);
        
        가격 상쇄 계산(기본 기울기 및 각도 승수 기준) // 가격 상쇄 계산하기
        double priceShift = baseSlope * barDiff * slopeMultiplier * _Point;
        double endPrice;
        
        // 추세 방향에 따른 종가 계산
        if(isTrendUp)
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // 하락 추세의 반전 각도
        }

        // 추세선 개체 만들기
        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, TimeCurrent(), endPrice))
        {
            // 추세선 속성 설정
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//|| 리버스 갠 팬 라인 그리기 및 &nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
void DrawOppositeGannFan(double extremum, datetime extremumTime)
{
    // 간 각도와 해당 이름을 정의합니다.
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // 극한점에서 현재 K-선까지의 마침표 개수를 구합니다.
    int extremumBar = iBarShift(_Symbol, PERIOD_CURRENT, extremumTime);
    int currentBar = 0; // 현재 K-라인은 0입니다.
    int barDiff = currentBar - extremumBar; // 사이클 번호 차이
    
    // 가격 높이 차이 계산
    double priceDiff;
    if(!isTrendUp)
    {
        // 역추세(상승): 극저점에서 현재 최고가까지의 높이를 계산합니다.
        double currentHigh = iHigh(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = currentHigh - extremum;
    }
    else
    {
        // 역추세(하락): 최고가부터 현재 최저가까지의 높이를 계산합니다.
        double currentLow = iLow(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = extremum - currentLow;
    }
    
    // 기본 기울기(1x1 선의 기울기)를 계산합니다.
    double baseSlope = (barDiff > 0) ? priceDiff / barDiff : 0;
    
    // 각 각도에 대한 섹터 라인 그리기
    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "OppositeGannFan_" + angleNames[i];  // 개체 레이블
        double angle = angles[i];                          // 현재 각도
        
        // 각도에 따라 기울기 배수를 계산합니다.
        double slopeMultiplier = MathTan(angle * M_PI / 180.0) / MathTan(45 * M_PI / 180.0);
        
        가격 상쇄 계산(기본 기울기 및 각도 승수 기준) // 가격 상쇄 계산하기
        double priceShift = baseSlope * barDiff * slopeMultiplier * _Point;
        double endPrice;
        
        // 역추세 방향에 따른 종가 계산
        if(!isTrendUp)
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // 하락 추세의 반전 각도
        }

        // 추세선 개체 만들기
        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, TimeCurrent(), endPrice))
        {
            // 추세선 속성 설정
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Opposite Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Opposite Gann Fan line: ", GetLastError());
        }
    }
}





결국, 저는 DeepSeek에 소스 코드를 수정해달라고 요청해야 했습니다(잘 작동하고 자동으로 선을 그립니다):
#property copyright "Copyright 2024, Evgeniy Shtenco"  // 저작권 정보
#property link      "https://www.mql5.com/en/users/koshtenko"  // 작성자 링크
#property version   "1.00"  // 표시기 버전 번호
#property indicator_chart_window  // 지표가 차트 창에 표시됩니다.

// 입력 매개변수
input int LookBackBars = 300;      // 다시 분석된 K-라인 수
input color GannFanColor = clrBlue; // 본의 팬 라인 색상

// 전역 변수
double extremumPrice;        // 익스트림 포인트 가격
datetime extremumTime;       // 익스트림 포인트 시간
double oppositeExtremumPrice; // 익스트림 포인트 가격 역전
datetime oppositeExtremumTime; // 역극성 포인트 시간
bool isTrendUp;              // 추세 방향 플래그(상승 추세의 경우 참)

//+------------------------------------------------------------------+
//| 사용자 지정 인디케이터 초기화 함수 및 &nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
int OnInit()
{
    return (INIT_SUCCEEDED);  // 초기화 성공
}

//+------------------------------------------------------------------+
//| 사용자 지정 인디케이터 초기화 함수 및 &nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
    {
        // 모든 Gann 섹터 객체 삭제
        ObjectsDeleteAll(0, "GannFan_");
ObjectsDeleteAll(0, "OppositeGannFan_");
}

//+------------------------------------------------------------------+
//| 사용자 지정 지표 계산 함수 및 &nbsp; &nbsp ; | | | | | | | |
//+------------------------------------------------------------------+
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[])            // 포인트 스프레드 배열
{
    if (rates_total < LookBackBars) return (0);  // 데이터가 충분하지 않으면 반환

    // 이전에 그린 개체 지우기
    if (prev_calculated == 0) {
        ObjectsDeleteAll(0, "GannFan_");
        ObjectsDeleteAll(0, "OppositeGannFan_");
    }

    // 마지막 300개의 K 라인에서 극한점 찾기
    FindExtremums(rates_total, high, low, time);

    // 벤 부채꼴 선 그리기
    DrawGannFan(extremumPrice, extremumTime);
    DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);

    return (rates_total);  // 처리된 총 열 수를 반환합니다.
}

//+------------------------------------------------------------------+
//| 지정된 수의 K 선 내에서 극한점을 찾습니다. |
//+------------------------------------------------------------------+
void FindExtremums(const int rates_total, const double & high[], const double & low[], const datetime & time[])
{
    int startIndex = rates_total - LookBackBars;  // 인덱싱 시작(300K 라인 전)
    int endIndex = rates_total - 1;               // 끝 인덱스(최신 K-라인)

    // 최고점과 최저점 찾기
    int highestIndex = ArrayMaximum(high, startIndex, LookBackBars);
    int lowestIndex = ArrayMinimum(low, startIndex, LookBackBars);

    // 추세의 방향 결정(고점과 저점의 타이밍 비교)
    if (time[highestIndex] > time[lowestIndex]) {
        // 가장 높은 지점이 가장 낮은 지점 이후인 경우 하락 추세
        extremumPrice = high[highestIndex];
        extremumTime = time[highestIndex];
        oppositeExtremumPrice = low[lowestIndex];
        oppositeExtremumTime = time[lowestIndex];
        isTrendUp = false;
    }
    else {
        // 그렇지 않으면 상승 추세
        extremumPrice = low[lowestIndex];
        extremumTime = time[lowestIndex];
        oppositeExtremumPrice = high[highestIndex];
        oppositeExtremumTime = time[highestIndex];
        isTrendUp = true;
    }
}

//+------------------------------------------------------------------+
벤 팬 선 그리기 //| 벤 팬 선 그리기 & nbsp; |
//+------------------------------------------------------------------+
void DrawGannFan(double extremum, datetime extremumTime)
{
    // 간 각도와 해당 이름을 정의합니다.
    double angles[] = { 82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = { "1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // 섹터 라인의 종료 시간 계산(현재 시간 + 300주기)
    datetime endTime = TimeCurrent();  // 현재 시간을 종료 시간으로 사용

    // 각 각도에 대한 섹터 라인 그리기
    for (int i = 0; i < ArraySize(angles); i++)
    {
        string label = "GannFan_" + angleNames[i];  // 개체 레이블
        double angle = angles[i];                  // 현재 각도

        // 가격 상쇄 계산(시차 기준)
        double secondsDiff = endTime - extremumTime;
        double priceShift = MathTan(angle * M_PI / 180.0) * secondsDiff / PeriodSeconds();
        double endPrice;

        // 추세 방향에 따른 종가 계산
        if (isTrendUp) {
            endPrice = extremum + priceShift;
        }
        else {
            endPrice = extremum - priceShift;
            angle = -angle; // 하락 추세의 반전 각도
        }

        // 추세선 개체 만들기
        if (ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice)) {
            // 추세선 속성 설정
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Gann Fan " + angleNames[i]);
        }
        else {
            Print("Failed to create Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//|| 리버스 갠 팬 라인 그리기 및 &nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
void DrawOppositeGannFan(double extremum, datetime extremumTime)
{
    // 간 각도와 해당 이름을 정의합니다.
    double angles[] = { 82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = { "1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // 섹터 라인의 종료 시간(현재 시간)을 계산합니다.
    datetime endTime = TimeCurrent();

    // 각 각도에 대한 섹터 라인 그리기
    for (int i = 0; i < ArraySize(angles); i++)
    {
        string label = "OppositeGannFan_" + angleNames[i];  // 개체 레이블
        double angle = angles[i];                          // 현재 각도

        // 가격 상쇄 계산(시차 기준)
        double secondsDiff = endTime - extremumTime;
        double priceShift = MathTan(angle * M_PI / 180.0) * secondsDiff / PeriodSeconds();
        double endPrice;

        // 반대 추세의 방향에 따라 종가 계산
        if (!isTrendUp) // 역추세
        {
            endPrice = extremum + priceShift;
        }
        else {
            endPrice = extremum - priceShift;
            angle = -angle; // 하락 추세의 반전 각도
        }

        // 추세선 개체 만들기
        if (ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice)) {
            // 추세선 속성 설정
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Opposite Gann Fan " + angleNames[i]);
        }
        else {
            Print("Failed to create Opposite Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//| 차트 이벤트 핸들러 함수 &nbsp nbsp; & & nbsp; |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,                  // 이벤트 ID
const long & lparam,            // 긴 정수 매개변수
                  const double & dparam,          // 배정밀도 매개변수
                  const string & sparam)         // 문자열 매개변수
{
    // 차트 변경 시 개체 다시 그리기
    if (id == CHARTEVENT_CHART_CHANGE || id == CHARTEVENT_CLICK) {
        // 극단을 다시 찾아 벤 팬 라인을 그립니다.
        int rates_total = Bars(_Symbol, PERIOD_CURRENT);
        double high[], low[];
        datetime time[];
        ArraySetAsSeries(high, true);
        ArraySetAsSeries(low, true);
        ArraySetAsSeries(time, true);
        CopyHigh(_Symbol, PERIOD_CURRENT, 0, rates_total, high);
        CopyLow(_Symbol, PERIOD_CURRENT, 0, rates_total, low);
        CopyTime(_Symbol, PERIOD_CURRENT, 0, rates_total, time);

        FindExtremums(rates_total, high, low, time);
        DrawGannFan(extremumPrice, extremumTime);
        DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);
    }
}
새로운 기능: MQL5의 커스텀 인디케이터 새로운 기능: MQL5의 커스텀 인디케이터
MetaTrader5와 MQL5의 새로운 기능 전체를 나열하지는 않겠습니다. 종류도 많은 데다가, 별도의 설명이 필요한 기능들도 있거든요. 객체 지향 프로그래밍을 이용한 코드 작성법 또한 다음에 알아보도록 하겠습니다. 다른 기능들과 함께 설명하기에는 조금 어려운 이야기일 수 있으니까요. 이 글에서는 인디케이터와 인디케이터의 구조, 드로잉 타입과 프로그래밍 디테일을 MQL4와 비교해 볼게요. 초보자 분들께 많은 도움이 되면 좋겠고 기존에 사용하시던 개발자 분들도 뭔가 새로운 걸 얻어 가실 수 있길 바랍니다.
MQL5에서 테이블 모델 구현: MVC 개념 적용 MQL5에서 테이블 모델 구현: MVC 개념 적용
이 글에서는 MVC(모델-뷰-컨트롤러) 아키텍처 패턴을 사용하여 MQL5에서 테이블 모델을 개발하는 프로세스에 대해 살펴보겠습니다. 우리는 이를 통해 데이터 논리, 표현, 제어를 분리하고, 구조화되고 유연하며 확장 가능한 코드를 작성할 수 있습니다. 연결 리스트를 사용하여 데이터를 저장하는 것을 포함하여 테이블 모델을 구축하기 위한 클래스를 구현해 볼 것입니다.
새 MetaTrader 와 MQL5를 소개해드립니다 새 MetaTrader 와 MQL5를 소개해드립니다
본 문서는 MetaTrader5의 간략 리뷰입니다. 짧은 시간 내에 시스템의 모든 세부 사항을 안내해드리기는 어렵습니다 - 테스트는 2009.09.09에 시작되었습니다. 이는 상징적인 일자로, 전 이것이 행운의 숫자가 될거라 믿어 의심치않습니다. 제가 새 MetaTrader 5 터미널과 MQL5 베타버전을 받은지 며칠이 지났습니다. 아직 모든 기능을 사용해본 것은 아니지만, 벌써부터 감명깊네요.
경제 예측: 파이썬의 잠재력 살펴보기 경제 예측: 파이썬의 잠재력 살펴보기
세계 은행 경제 데이터를 예측에 어떻게 사용할 수 있을까요? AI 모델과 경제학을 결합하면 어떤 일이 일어날까요?