안녕하세요, 트레이더 여러분! 오늘은 MetaTrader 4에서 모든 시간 프레임의 현재 추세를 한눈에 볼 수 있는 그래픽 지표에 대해 소개해 드리려고 합니다.
이 지표는 기울기 방향 추세 지표를 기반으로 하며, 이미 여러 형태로 공개된 바 있습니다. 하지만 이번에 소개할 지표는 모든 시간 프레임을 한 개의 그래픽 패널에서 동시에 보여주는 유일한 버전입니다.
더 많은 결과를 보고 싶다면 이곳를 클릭해 보세요.
저는 이 지표를 활용하여 모든 시간 프레임을 보여주는 그래픽 패널로 만들었으며, 원래 코드에서 몇 가지 소소한 수정도 진행했습니다. 그 중 하나는 부드럽게 하는 데 사용되는 두 번째 이동 평균 방법을 선택할 수 있도록 한 것입니다. 원래 코드는 두 번째 계산에 선형 가중 평균을 사용했지만, 저의 버전은 사용자가 부드러움의 방법을 선택할 수 있도록 했습니다. 두 가지 계산 모두 선형 가중 평균을 사용할 경우, 지표가 너무 민감해져서 현재 추세에 대해 잘못된 신호를 줄 수 있습니다. 반면에, 단순 평균을 두 번째 평균 방법으로 사용하면 가격이 나아가는 방향을 더 잘 나타내는 추세를 얻을 수 있습니다.
또 다른 변경 사항은 추세의 방향(상승, 하락 또는 보합)뿐만 아니라 그 값도 확인할 수 있게 한 것입니다. 이 내용을 다루는 또 다른 글도 곧 발행할 예정이니 기대해 주세요!
자, 그럼 코드에 대해 간단히 살펴볼까요? 먼저 사용할 객체 이름을 정의합니다. 객체 이름을 인용부호로 묶을 때마다 프로그램에서 공간을 할당하기 때문에, 한 번 정의해 두면 코드에서 공간을 한 번만 사용하게 됩니다.
// 추세 방향 정의#define UPTREND 1#define DOWNTREND -1#define FLATTREND 0// 객체 정의#define TrendPanel "TrendPanel"#define InfoLine1 "InfoLine1"#define InfoLine2 "InfoLine2"#define TrendLabel "추세: M1 M5 M15 M30 H1 H4 D1 W1 MN"#define TrendUp "\233"#define TrendDown "\234"#define TrendFlat "\232"#define TrendUnknown "\251"#define StatObjectError "%s(%d) '%s' 생성 실패. 오류 = %d"
그 다음으로 두 개의 배열을 정의합니다. 하나는 각 9개 시간 프레임의 픽셀 위치를 위한 배열이고, 다른 하나는 시간 프레임을 위한 배열입니다. 이들은 전역 변수로 정의됩니다.
// 전역 변수 정의int TrendPosition[] = { 44, 64, 88, 114, 136, 156, 174, 194, 216 }; int TrendPeriods[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };
우리의 지표 OnInit() 함수는 패널과 그 안의 객체를 생성하는 함수를 호출합니다. 또한 추세를 계산하는 데 사용하는 바(bar)의 수에 대해 간단한 체크를 진행합니다. 3개 미만이면 의미가 없겠죠.
//+------------------------------------------------------------------+//| 사용자 정의 지표 초기화 함수 |//+------------------------------------------------------------------+int OnInit() { // 지표 패널 객체 생성 if(Create_Panel() && BarCount >= 3) return(INIT_SUCCEEDED); else return(INIT_FAILED); }
GetTrend() 함수의 작동 방식에 대한 자세한 설명은 이미 이 사이트에 좋은 문서가 있으므로 넘어가겠습니다. 대신 그래픽을 표시하는 DisplayTrend() 함수에 대해 살펴보겠습니다.
//+------------------------------------------------------------------+//| 모든 시간 프레임의 현재 추세 표시//+------------------------------------------------------------------+void DisplayTrend(void) { int i, cntr, Trend, LastTrend; string str; for(i=1; i<10; i++) { str = "Trend" + DoubleToStr(i, 0); Trend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method); if(Trend == FLATTREND) { // 보합 상태, 마지막 추세 방향 찾기 cntr = 1; do { LastTrend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method, false, cntr++); } while(LastTrend == Trend); ObjectSetText(str, TrendFlat, 8, "WingDings", (LastTrend == UPTREND ? Green : Red)); ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 6); } else { ObjectSetText(str, (Trend == UPTREND ? TrendUp : TrendDown), 8, "WingDings", (Trend == UPTREND ? Green : Red)); ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 5 + (Trend == UPTREND ? 1 : -1)); } } }
기본적으로 TrendPeriods[] 배열을 통해 각 시간 프레임을 반복하면서 각 시간 프레임의 추세 방향에 따라 추세 화살표를 설정합니다. 만약 추세가 보합이라면, 보합이 아닌 첫 번째 방향을 찾아 그 방향의 색깔로 측면 화살표를 표시합니다.
OnInit()의 Create_Panel() 함수는 화면 왼쪽 하단에 고정된 객체를 생성하며 TrendPosition[]를 사용하여 화살표를 적절한 위치에 배치합니다.
//+------------------------------------------------------------------+//| 화면 왼쪽 하단에 추세 패널 생성//+------------------------------------------------------------------+bool Create_Panel(void) { int i; string str; // 추세 지표 창 생성 if(ObjectCreate(TrendPanel, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { ObjectSetInteger(0, TrendPanel, OBJPROP_XDISTANCE, 1); ObjectSetInteger(0, TrendPanel, OBJPROP_YDISTANCE, 29); ObjectSetInteger(0, TrendPanel, OBJPROP_XSIZE, 240); ObjectSetInteger(0, TrendPanel, OBJPROP_YSIZE, 26); ObjectSetInteger(0, TrendPanel, OBJPROP_BGCOLOR, White); ObjectSetInteger(0, TrendPanel, OBJPROP_BORDER_TYPE, 0); ObjectSetInteger(0, TrendPanel, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSetInteger(0, TrendPanel, OBJPROP_COLOR, Red); ObjectSetInteger(0, TrendPanel, OBJPROP_STYLE, STYLE_SOLID); ObjectSetInteger(0, TrendPanel, OBJPROP_WIDTH, 2); ObjectSetInteger(0, TrendPanel, OBJPROP_BACK, false); ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTED, <:class>false); ObjectSetInteger(0, TrendPanel, OBJPROP_HIDDEN, true); ObjectSetString(0, TrendPanel, OBJPROP_TOOLTIP, "\n"); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, TrendPanel, GetLastError()); return(false); } if(ObjectCreate(InfoLine1, OBJ_LABEL, 0, 0, 0)) { ObjectSet(InfoLine1, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSet(InfoLine1, OBJPROP_XDISTANCE, 6); ObjectSet(InfoLine1, OBJPROP_YDISTANCE, 15); ObjectSetInteger(0, InfoLine1, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, InfoLine1, OBJPROP_HIDDEN, true); ObjectSetString(0, InfoLine1, OBJPROP_TOOLTIP, "\n"); ObjectSetText(InfoLine1, TrendLabel, 8, "Arial", Black); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine1, GetLastError()); return(false); } if(ObjectCreate(InfoLine2, OBJ_LABEL, 0, 0, 0)) { ObjectSet(InfoLine2, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSet(InfoLine2, OBJPROP_XDISTANCE, 6); ObjectSet(InfoLine2, OBJPROP_YDISTANCE, 5); ObjectSetInteger(0, InfoLine2, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, InfoLine2, OBJPROP_HIDDEN, true); ObjectSetString(0, InfoLine2, OBJPROP_TOOLTIP, "\n"); ObjectSetText(InfoLine2, " " + DoubleToStr(BarCount, 0) + " / " + DoubleToStr(Method, 0), 8, "Arial", Black); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine2, GetLastError()); return(false); } // 추세 객체 생성 및 현재 추세 표시 for(i=1; i<10; i++) { str = "Trend" + DoubleToStr(i, 0); if(ObjectCreate(str, OBJ_LABEL, 0, 0, 0)) { ObjectSet(str, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSet(str, OBJPROP_XDISTANCE, TrendPosition[i-1]); ObjectSet(str, OBJPROP_YDISTANCE, 5); ObjectSetInteger(0, str, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, str, OBJPROP_HIDDEN, true); ObjectSetString(0, str, OBJPROP_TOOLTIP, "\n"); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, str, GetLastError()); return(false); } } // 현재 추세 표시 DisplayTrend(); // 모든 것이 잘 진행되었습니다 return(true); }
이 함수는 모든 객체를 성공적으로 생성하면 TRUE를 반환하고, 객체 생성 중 오류가 발생하면 FALSE를 반환합니다. 좋은 점은 지표가 콘솔의 EXPERT 탭에서 오류 코드와 오류가 발생한 코드의 줄 번호를 표시한다는 점입니다.
또한, 수신하는 각 새로운 틱마다 추세 지표를 업데이트해야 합니다. 이는 start() 함수에서 DisplayTrend()를 호출하여 수행합니다.
//+------------------------------------------------------------------+//| 사용자 정의 지표 반복 함수 |//+------------------------------------------------------------------+int start() { // 모든 시간 프레임의 현재 추세 표시 DisplayTrend(); return(0); }
마지막으로, 지표를 닫을 때 생성된 모든 객체를 삭제합니다.
//+------------------------------------------------------------------+//| 비활성화 함수 |//+------------------------------------------------------------------+voidOnDeinit(constint reason) { // 지표의 객체 삭제 if(ObjectFind(TrendPanel) >= 0) ObjectDelete(TrendPanel); if(ObjectFind(InfoLine1) >= 0) ObjectDelete(InfoLine1); if(ObjectFind(InfoLine2) >= 0) ObjectDelete(InfoLine2); for(int i=1; i<10; i++) if(ObjectFind("Trend"+DoubleToStr(i, 0)) >= 0) ObjectDelete("Trend"+DoubleToStr(i, 0)); }
이제 화면 왼쪽 하단에 모든 시간 프레임의 현재 추세를 보여주는 멋진 지표 패널이 생겼습니다.
즐거운 트레이딩 되세요!

댓글 0