レジスタンスラインサポートラインをMT4で好きな色で実装する方法

はじめまして。私自身は投資事で生計を立てています。
投資事というと、プログラミングとは縁遠いように思えますが、実はMT4を使う時、プログラミングが書けると勝率も上がります。

実は投資とプログラミングは密接に関わりがあるんだなと実感しています。

今回はMT4でレジスタンスラインとサポートラインを自作できるプログラミングコードを紹介します。

チャートの色との対比で自分好みのレジサポラインを引きたいという方も多いはず。

なお、今回紹介するソースコードは自己責任でお使いください。


#property copyright ""
#property link      ""
#property indicator_chart_window

extern int MaxLmt      = 1000;
extern int MaxCrsLv    = 10;
extern int LineWidth   = 0;
extern int LineStyle   = 0;
extern int TmPeriod    = 0;
extern double MaxR     = 0.001;
extern color LineColor = White;

int LIndex        = 0; 
double p1Num      = 0.0;
double p2Num      = 0.0;
datetime TMaxI    = 0;
color  Colors[]   = {Red,Maroon,Sienna,OrangeRed,Purple,Indigo,DarkViolet,MediumBlue,DarkSlateGray};
int    Widths[]   = {1,2,3,4,5,6,7,8,9};
string Alphabet[] = {"i","h","g","f","e","d","c","b","a"};
int CrsBarCnt[];
bool CrsBarMin[];

#define MxLine 1000
string LName[MxLine];

double GetPrLow(int i)
{
  return (iLow(NULL,TmPeriod,i));
}
double GetPrHigh(int i)
{
  return (iHigh(NULL,TmPeriod,i));
}

int GetPeriod2Int(int tp)
{
  switch (tp)
  {
    case PERIOD_M1  : return(0);
    case PERIOD_M5  : return(1);
    case PERIOD_M15 : return(2);
    case PERIOD_M30 : return(3);
    case PERIOD_H1  : return(4);
    case PERIOD_H4  : return(5);
    case PERIOD_D1  : return(6);
    case PERIOD_W1  : return(7);
    case PERIOD_MN1 : return(8);
  }      
  return (0);
}

string GetPeriod2AlpthabetString(int tp)
{
  return (Alphabet[GetPeriod2Int(tp)]);
}

int init()
{
  if (TmPeriod == 0)
  {
    TmPeriod = Period();
  }

  if (TmPeriod != 0 && LineWidth == 0)
  {
    if (GetPeriod2Int(TmPeriod) - GetPeriod2Int(Period()) >= 0)
    {
      LineWidth = Widths[GetPeriod2Int(TmPeriod) - GetPeriod2Int(Period())];
    }
    else
    {
      LineWidth = 0;
      if (LineStyle == 0)
      {
        LineStyle = STYLE_DASH;
      }
    }
  }

  if (TmPeriod != 0 && LineColor == White)
  {
    LineColor = Colors[GetPeriod2Int(TmPeriod)];
  }
  return(0);
}

int deinit()
{
  for (int i = 0; i < LIndex; i++)
  {
    ObjectDelete(LName[i]);
  }
  return(0);
}

int start()
{
   int counted_bars = IndicatorCounted();
   int limit        = MathMin(Bars - counted_bars, MaxLmt);   
   double p1        = GetPrLow(Lowest(NULL,TmPeriod,MODE_LOW,limit,0));
   double p2        = GetPrHigh(Highest(NULL,TmPeriod,MODE_HIGH,limit,0));
   
   if (p1Num != p1 || p2Num != p2)
   {
       ArrayResize(CrsBarCnt, (p2-p1) * 10000);
       ArrayResize(CrsBarMin, (p2-p1) * 10000);
       if (p1Num != p1 && p1Num != 0.0)
       {
         ArrayCopy(CrsBarCnt,CrsBarCnt, 0, (p1Num-p1) * 10000);
         ArrayCopy(CrsBarMin,CrsBarMin, 0, (p1Num-p1) * 10000);
       }
       p1Num = p1;
       p2Num = p2;
   }
   
   for (double d = p1; d <= p2; d += 0.0001)
   {
       int di = (d-p1) * 10000;
       for (int i = 1; i < limit; i++)
       {
         if (d > GetPrLow(i) && d < GetPrHigh(i))
         {
           CrsBarCnt[di]++;
         }
       }

       if (Time[limit] != TMaxI && TMaxI != 0)
       {
         if (d > GetPrLow(iBarShift(NULL,0,TMaxI)) && d < GetPrHigh(iBarShift(NULL,0,TMaxI)))
         {
           CrsBarCnt[di]--;
         }
       }
   }
   TMaxI = Time[limit]-1;

   double l = MaxR * 10000;
   for (d = p1 + MaxR; d <= p2 - MaxR; d += 0.0001)
   {
        di = (d-p1) * 10000;
        if (!CrsBarMin[di]
            && CrsBarCnt[ArrayMaximum(CrsBarCnt,2*l,di-l)]-CrsBarCnt[ArrayMinimum(CrsBarCnt,2*l,di-l)]>MaxCrsLv
            && CrsBarCnt[di]  ==CrsBarCnt[ArrayMinimum(CrsBarCnt,2*l,di-l)]
            && CrsBarCnt[di-1]!=CrsBarCnt[ArrayMinimum(CrsBarCnt,2*l,di-l)])
        {
          CrsBarMin[di] = true;
          LName[LIndex] = GetPeriod2AlpthabetString(TmPeriod) + TmPeriod + "_" + d;
          
          ObjectCreate(LName[LIndex],OBJ_HLINE    ,0,0,d);
          ObjectSet(LName[LIndex],   OBJPROP_COLOR,LineColor);
          ObjectSet(LName[LIndex],   OBJPROP_WIDTH,LineWidth);
          ObjectSet(LName[LIndex],   OBJPROP_STYLE,LineStyle);
          LIndex++;
        }

        if (CrsBarMin[di] && CrsBarCnt[di] != CrsBarCnt[ArrayMinimum(CrsBarCnt, 2 * l, di - l)])
        {
          CrsBarMin[di] = false;
          ObjectDelete(GetPeriod2AlpthabetString(TmPeriod) + TmPeriod + "_" + d);
        }
          
   }
   return(0);
}


※なお、レジサポラインの色変更の詳細は、以下の私のブログでもっと詳しく紹介しています。

https://ankomochi-highlow.com/resistance-support/