기고글 토론 "MQL5를 사용하여 캔들 스틱 패턴을 감지하는 방법" - 페이지 2

 
Mohamed Abdelmaaboud #:
의견 주셔서 감사합니다. 먼저 원하는 방식으로 할 수 있다는 점을 명확히해야합니다. 감지하고 표시 할 수있는 지표가 될 수도 있고 원하는 경우 거래와 같은 필요한 조치를 취할 수있는 EA가 될 수도 있고 고급 EA로 결합 할 수도 있습니다. 올바르게 실행되면 모두 하나의 EA로 차트에 첨부됩니다. 여기에는 진실이나 거짓이 없으며, 여기서 목적은 이러한 유형의 캔들 스틱 패턴을 코딩하는 방법을 공유하는 교육용 일 뿐이며, 그러면 여러분 자신의 캔들 스틱 패턴을 직접 사용할 수 있습니다.

그래서 모든 것을 하나의 EA로 결합했습니다. 하지만 인디케이터로 작성하려고 하면 터미널에서 여전히 전문가 조언으로 로드됩니다. 코드에서 무언가를 변경해야하지만 정확히 무엇인지 잘 모르겠습니다. 또한 시간 프레임을 다른 프레임으로 변경하면 신호가 차트에 남아 있고 새 프레임의 동일한 위치에있는 막대와 일치하지 않는다는 점에서 개선이 필요하다는 것을 알았습니다. 이상적으로는 변경할 때 신호가 감지된 차트주기에만 삭제하거나 저장해야 합니다. 수집 한 코드를 올려서 조정하거나 최적화 할 수있는 사항을 확인하기 위해 모든 전문가 고문에서 하나로 복사했지만 코드에서 여러 번 반복하지 않도록 처음에 일부 변수를 선언 할 수 있다고 생각합니다.

//+------------------------------------------------------------------+
//|패턴-인디크.mq5 |
//|저작권 2023,VIKTOR |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023,VIKTOR"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 초기화 기능 |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+ createObj1 = 도지|
//+ createObj2 = Hammer|
//+ createObj3 = Engulfing|
//+ createObj4 = 피어싱|
//+ createObj5 = Star|
//+ createObj6 = threeInside|
//+------------------------------------------------------------------+
void OnTick()
  {
   getDoji();
   getHammer(0.07,0.7);
   getEngulfing();
   getPiercing();
   getStar(0.5);
   getthreeInside();
  }
int getDoji()
  {
   datetime time  =iTime  (_Symbol,PERIOD_CURRENT,1);
   double   open  =iOpen  (_Symbol,PERIOD_CURRENT,1);
   double   high  =iHigh  (_Symbol,PERIOD_CURRENT,1);
   double   low   =iLow   (_Symbol,PERIOD_CURRENT,1);
   double   close =iClose (_Symbol,PERIOD_CURRENT,1);
   
//Doji
   if(open==close)
     {
      createObj1a(time,low,217, clrBlack,"Doji");
        {
         return 1;
        }
     }
   return 0;
  }
void createObj1a(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getHammer(double smallShadowRatio, double longShadowRatio)
  {
//가격 데이터에 대한 변수 만들기 - 시가, 고가, 저가, 종가
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double candleSize=high-low;
//녹색 망치
   if(open<close)
     {
      if(high-close < candleSize*smallShadowRatio)
        {
         if(open-low>candleSize*longShadowRatio)
            createObj2(time,low,217, clrGreen,"Hammer");
           {
            return 1;
           }
        }
     }
//빨간 망치
   if(open>close)
     {
      if(high-open<candleSize*smallShadowRatio)
        {
         if(close-low>candleSize*longShadowRatio)
            createObj2(time,high,218,clrRed,"Hammer");
           {
            return 1;
           }
        }
     }
//녹색 역 망치
   if(open<close)
     {
      if(open-low < candleSize*smallShadowRatio)
        {
         if(high-close>candleSize*longShadowRatio)
            createObj2(time,low,217, clrGreen,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
//빨간색 인버스 해머
   if(open>close)
     {
      if(close-low < candleSize*smallShadowRatio)
        {
         if(high-open>candleSize*longShadowRatio)
            createObj2(time,high,218, clrRed,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
   return 0;
  }
void createObj2(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getEngulfing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(high>high2&&low<low2)
           {
            if(close>open2&&open<close2)
              {
               createObj3(time,low,217, clrGreen,"Bullish Engulfing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(high>high2&&low<low2)
           {
            if(close<open2&&open>close2)
              {
               createObj3(time,high,218, clrRed,"Bearish Engulfing");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj3(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getPiercing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double candleSize2=high2-low2;
   double candleMidPoint2=high2-(candleSize2/2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(open<low2)
           {
            if(close>candleMidPoint2&&close<high2)
              {
               createObj4(time,low,217, clrGreen,"Piercing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(open>high2)
           {
            if(close<candleMidPoint2&&close>low2)
              {
               createObj4(time,high,218, clrRed,"Dark Cloud");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj4(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getStar(double middleCandleRatio)
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   double candleSize=high-low;
   double candleSize2=high2-low2;
   double candleSize3=high3-low3;
   if(open<close)
     {
      if(open3>close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj5(time,low,217, clrGreen,"Morning Star");
              {
               return 1;
              }
           }
        }
     }
   if(open>close)
     {
      if(open3<close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj5(time,high,218, clrRed,"Evening Star");
              {
               return -1;
              }
           }
        }
     }
   return 0;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void createObj5(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getthreeInside()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   if(open3>close3)
     {
      if(open2<close2)
        {
         if(open2>low3&&close2<high3)
           {
            if(open<close&&open>open2&&open<close2)
              {
               if(close>high3)
                 {
                  createObj6(time,low,217, clrGreen,"3 Inside Up");
                    {
                     return 1;
                    }
                 }
              }
           }
        }
     }
   if(open3<close3)
     {
      if(open2>close2)
        {
         if(open2<high3&&close2>low3)
           {
            if(open>close&&open<open2&&open>close2)
              {
               if(close<low3)
                 {
                  createObj6(time,high,218, clrRed,"3 Inside Down");
                    {
                     return -1;
                    }
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj6(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
 
FINANSE-BOND #:

그렇게 해서 모두 하나의 EA로 병합했습니다. 하지만 인디케이터로 쓰려고 하면 터미널에서 여전히 Expert Advisor로 로드됩니다. 코드에서 무언가를 변경해야하지만 그것이 무엇인지 모르겠고 그것에 대해 잘 모릅니다. 또한 시간 프레임을 다른 프레임으로 변경하면 신호가 차트에 남아 있고 새 프레임의 동일한 위치에있는 막대와 일치하지 않는다는 점에서 개선이 필요하다는 것을 알았습니다. 이상적으로는 변경할 때 신호가 감지된 차트주기에만 삭제하거나 저장해야 합니다. 수집 한 코드를 올려서 조정하거나 최적화 할 수있는 사항을 확인하기 위해 모든 전문가 고문에서 하나로 복사했지만 코드에서 여러 번 반복하지 않도록 처음에 일부 변수를 선언 할 수 있다고 생각합니다.

전문가 고문과 지표는 약간 다른 이벤트 핸들러가 있고 지표가 캔들 스틱 패턴과 관련하여 차트 자체 또는 별도의 창에 선을 그릴 수있는 기능이 있다는 점에서만 다르며 이러한 유형의 코드는 다른 경우에는 완전히 중복되며 이러한 단계로 코드의 가능성을 제한 할뿐입니다. 여기에는 올바른 지표 구성 패러다임이 필요합니다. 저는 오래 전에 이것을 깨달았고 지표를 거의 작성하지 않았고 모든 것을 전문가 고문 형태로 실행했습니다. 게다가이 코드는 향후 거래에 매우 쉽게 적응할 수 있으며 코드를주의 깊게 살펴보면 객체 작업이 있음을 알 수 있는데 왜 지표의 기능에 자신을 제한해야합니까? 당신이 사람의 마음을 파헤치고있는 것이 맞습니다.

 

나는 요점에 도달하지 못했고, 코드에 강하지 않다고 썼기 때문에 사용자로서의 결론을 공유하고 반복되는 일부 변수를 선언하는 위치와 방법을 모르는 코드에서 약간의 것을 잘라달라고 요청했습니다. 또한 최근에 외부 지표에 대한 전문가 조언을 작성하는 비디오를 보았습니다. 그래서 지표를 만들면 Expert Advisor에서 지표를 참조하고 데이터를 가져올 수 있다고 말했습니다. 가능하다면 수정할 수 있을까요?

 
전문가 어드바이저이므로 매수 및 매도 주문을 코드에 추가하세요.
 
매우 유용한 정보
 
Cyril Bassey #:
매우 도움이 되었습니다.

의견을 보내주셔서 감사합니다.

 
통찰력 주셔서 감사합니다, 아주 좋은 게시물.
Engulfing 캔들 스틱 감지와 관련하여 궁금한 점이 있는데
if(close>open2&&open<close2)
조건과
if(close<open2&&open>close2)
을 사용하셨습니다. 갭이 있을 때만 해당되는 조건이 있습니다. 갭이 얼마나 자주 발생하나요? 다음과 같이 코드화할 것으로 예상했는데요
if(close>open2&&open<=close2)
와 조건
if(close<open2&&open>=close2)
을 사용해야 합니다. 정상적인 조건에서는 바 1의 시가와 바 2의 종가가 정확히 같기 때문입니다. 시장 가격 차이가 있을 때만 잉글리쉬 패턴을 감지하는 코드입니다.
그래서 제 질문은 바 2와 바 1의 종가와 시가가 같지 않을 때 패턴이 유효하지 않다고 생각하는지 궁금합니다.
 
좋은 기사. mql5에서 객체 패턴을 만드는 방법을 이해하는 데 매우 유용합니다.
 

좋은 정보 감사합니다.

강세와 약세 마루보즈의 조건은 무엇인가요?

 
Sylvanus Phillips #:
강세와 약세 마루보즈의 조건은 무엇인가요?

이런 식입니다: