诚信为本
量力而为
当前位置:峰汇在线 > MetaTrader 4 > MT4指标 > 正文

MT4经典之字形通道指标 Channel_ZZ.mq4

Channel_ZZ指标创建之字形通道并提升相关形态。

图表:Channel_ZZ指标

源码:

//+------------------------------------------------------------------+
//|                                                    Channel_ZZ.mq4|
//|                                        Copyright @2008, Tinytjan |
//+------------------------------------------------------------------+
#property copyright "Copyright @2008, Tinytjan"
#property link      "http://www.125808047.com/"

extern string _1 = "1";
extern int SmoothPeriod = 1;
extern string _2 = "2";
extern int ChannelWidth = 150;
extern string _3 = "3";
extern int FontSize = 10;
extern string _4 = "4";
extern string FontName = "Arial Black";
extern string _5 = "4";
extern bool DrawChannel = true;

#property indicator_chart_window
#property indicator_buffers 3

#property indicator_color1 LightGray
#property indicator_width1 3

#property indicator_color2 Orange
#property indicator_color3 Orange

double ZZ[];
double UpChannel[];
double DownChannel[];

double SmoothedMaxValues[];
double SmoothedMinValues[];

string symbol;

#define UP 1
#define DN -1
#define NONE 0

int Direction;

datetime StartMax;
datetime EndMax;
datetime StartMin;
datetime EndMin;

datetime StartDraw;
datetime EndDraw;
double StartDrawValue;
double EndDrawValue;

datetime StartChannel;
datetime EndChannel;
double StartChannelValue;
double EndChannelValue;

int Counter;
int Length;
int LastLength;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   IndicatorShortName("-=<Channel ZZ>=-");

   IndicatorBuffers(5);
   
   SetIndexBuffer(0, ZZ);
   SetIndexBuffer(1, UpChannel);
   SetIndexBuffer(2, DownChannel);
   SetIndexBuffer(3, SmoothedMaxValues);
   SetIndexBuffer(4, SmoothedMinValues);
   
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE, STYLE_DASH);
   SetIndexStyle(2, DRAW_LINE, STYLE_DASH);
   
   symbol = Symbol();
   
   Direction = NONE;
   Counter = 0;

   StartMax = 0;
   EndMax = 0;
   StartMin = 0;
   EndMin = 0;
   
   Length = 0;
   LastLength = EMPTY_VALUE;
   Comment("www.125808047.com");
   return(INIT_SUCCEEDED);
}

   void OnDeinit(const int reason)
{
   for (int i = 0; i <= Counter; i++)
   {
      ObjectDelete("Stats" + i);
   }
}
//+------------------------------------------------------------------+
//| 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[])
  {
   int ToCount = Bars - IndicatorCounted();
   
   for (int i = ToCount - 1; i >= 0; i--)
   {
      SmoothedMaxValues[i] = iMA(symbol, 0, SmoothPeriod, 0, MODE_EMA, PRICE_HIGH, i);
      SmoothedMinValues[i] = iMA(symbol, 0, SmoothPeriod, 0, MODE_EMA, PRICE_LOW, i);
      
      RePaintChannels(i);
      
      if (Direction == NONE)
      {
         CheckInit(i);
         continue;
      }
      
      if (Direction == UP)      
      {
         CheckUp(i);
      }
      else
      {
         CheckDown(i);
      }
   }
   return(0);
}
//+------------------------------------------------------------------+

void CheckInit(int offset)
{
   if (StartMax == 0 || StartMin == 0)
   {
      if (StartMax == 0) StartMax = Time[offset];
      if (StartMin == 0) StartMin = Time[offset];
      
      return;
   }
   
   if (Direction == NONE)
   {
      double maxValue = SmoothedMaxValues[iBarShift(symbol, 0, StartMax)];
      double minValue = SmoothedMinValues[iBarShift(symbol, 0, StartMin)];
      
      double nowMax = SmoothedMaxValues[offset];
      double nowMin = SmoothedMaxValues[offset];
      
      if (nowMax > maxValue && Time[offset] > StartMax)
      {
         EndMax = Time[offset];
         StartMin = Time[offset];
         Direction = UP;
         
         StartDraw = StartMax;
         EndDraw = EndMax;
         StartDrawValue = maxValue;
         EndDrawValue = nowMax;
         
         StartChannel = StartMax;
         EndChannel = EndMax;
         StartChannelValue = maxValue;
         EndChannelValue = nowMax;
         
         Length = NormalizeDouble((nowMax - maxValue)/Point, 0);
         
         RePaint();
      }
      else if (nowMin > minValue && Time[offset] > StartMin)
      {
         EndMin = Time[offset];
         StartMax = Time[offset];
         Direction = DN;

         StartDraw = StartMin;
         EndDraw = EndMin;
         StartDrawValue = minValue;
         EndDrawValue = nowMin;

         StartChannel = StartMin;
         EndChannel = EndMin;
         StartChannelValue = minValue;
         EndChannelValue = nowMin;

         Length = NormalizeDouble((minValue - nowMin)/Point, 0);

         RePaint();
      }
   }
}

void CheckUp(int offset)
{
   int startIndex = iBarShift(symbol, 0, StartMax);
   int endIndex = iBarShift(symbol, 0, EndMax);

   double endMaxValue = SmoothedMaxValues[endIndex];
      
   if (endMaxValue < SmoothedMaxValues[offset])
   {
      endMaxValue = SmoothedMaxValues[offset];
      EndMax = Time[offset];

      EndDraw = EndMax;
      EndDrawValue = endMaxValue;

      EndChannel = EndMax;
      EndChannelValue = endMaxValue;
      
      double endMinValue = SmoothedMinValues[iBarShift(symbol, 0, EndMin)];
      Length = NormalizeDouble((endMaxValue - endMinValue)/Point, 0);

      RePaint();
   }
   else 
   {  
      double startMaxValue = SmoothedMaxValues[startIndex];
      double startMinValue = SmoothedMinValues[iBarShift(symbol, 0, StartMin)];
      
      double nowMaxValue = endMaxValue;
      if (startIndex - endIndex != 0)
      {
         nowMaxValue += (endMaxValue - startMaxValue)/(startIndex - endIndex)*(endIndex - offset);
      }

      double nowMinValue = SmoothedMinValues[offset];
      
      if (nowMaxValue - nowMinValue > ChannelWidth*Point)
      {
         if (EndMax != offset)
         {
            StartMin = Time[offset];
            EndMin = Time[offset];
            Direction = DN;

            StartDraw = EndMax;
            EndDraw = EndMin;
            StartDrawValue = endMaxValue;
            EndDrawValue = nowMinValue;

            StartChannel = EndMin;
            EndChannel = EndMin;
            StartChannelValue = nowMinValue;
            EndChannelValue = nowMinValue;

            Counter++;

            LastLength = Length;
            Length = NormalizeDouble((endMaxValue - nowMinValue)/Point, 0);

            RePaint();
         }
      }
   }
}

void CheckDown(int offset)
{
   int startIndex = iBarShift(symbol, 0, StartMin);
   int endIndex = iBarShift(symbol, 0, EndMin);

   double endMinValue = SmoothedMinValues[endIndex];
      
   if (endMinValue > SmoothedMinValues[offset])
   {
      endMinValue = SmoothedMinValues[offset];
      EndMin = Time[offset];

      EndDraw = EndMin;
      EndDrawValue = endMinValue;

      EndChannel = EndMin;
      EndChannelValue = endMinValue;

      double endMaxValue = SmoothedMaxValues[iBarShift(symbol, 0, EndMax)];
      Length = NormalizeDouble((endMaxValue - endMinValue)/Point, 0);

      RePaint();
   }
   else 
   {  
      double startMinValue = SmoothedMinValues[startIndex];
      double startMaxValue = SmoothedMaxValues[iBarShift(symbol, 0, StartMax)];
      
      double nowMinValue = endMinValue;
      if (startIndex - endIndex != 0)
      {
         nowMinValue += (endMinValue - startMinValue)/(startIndex - endIndex)*(endIndex - offset);
      }

      double nowMaxValue = SmoothedMaxValues[offset];
      
      if (nowMaxValue - nowMinValue > ChannelWidth*Point)
      {
         if (EndMin != offset)
         {
            EndMax = Time[offset];
            StartMax = Time[offset];
            Direction = UP;

            StartDraw = EndMin;
            EndDraw = EndMax;
            StartDrawValue = endMinValue;
            EndDrawValue = nowMaxValue;

            StartChannel = EndMax;
            EndChannel = EndMax;
            StartChannelValue = nowMaxValue;
            EndChannelValue = nowMaxValue;

            Counter++;

            LastLength = Length;
            Length = NormalizeDouble((nowMaxValue - endMinValue)/Point, 0);

            RePaint();
         }
      }
   }
}

void RePaint()
{
   double pos = EndDrawValue;
   if (Direction == UP) pos += 15*Point;
   
   string id = "Stats" + Counter;
   
   string text;
   if (LastLength != 0)
      text = text + DoubleToStr((0.0001 + Length)/(0.0001 + LastLength), 2);
   text = text + "(" + Length + ")";
   
   if (ObjectFind(id) == -1)
   {
      ObjectCreate(id, OBJ_TEXT, 0, EndDraw, pos);
      ObjectSet(id, OBJPROP_COLOR, Yellow);
   }

   ObjectMove(id, 0, EndDraw, pos);
   ObjectSetText(id, text, FontSize, FontName);

   int start = iBarShift(symbol, 0, StartDraw);
   int end = iBarShift(symbol, 0, EndDraw);
   
   if (start == end)
   {
      ZZ[end] = EndDrawValue;
      return;
   }
   
   double preValue = (EndDrawValue - StartDrawValue)/(end - start);
   
   for (int i = start; i >= end; i--)
   {
      ZZ[i] = StartDrawValue + preValue*(i - start);
   }
}

void RePaintChannels(int offset)
{
   if (Direction == NONE) return;
   if (!DrawChannel) return;
   
   int start = iBarShift(symbol, 0, StartChannel);
   int end = iBarShift(symbol, 0, EndChannel);
   
   if (start == end)
   {
      if (Direction == UP)
      {
         UpChannel[start] = StartChannelValue;
         DownChannel[start] = StartChannelValue - ChannelWidth*Point;
      }
      else
      {
         DownChannel[start] = StartChannelValue;
         UpChannel[start] = StartChannelValue + ChannelWidth*Point;
      }
      
      for(int i = start - 1; i >= offset; i--)
      {
         DownChannel[i] = DownChannel[i + 1];
         UpChannel[i] = UpChannel[i + 1];
      }
      return;
   }
   
   double preValue = (EndChannelValue - StartChannelValue)/(end - start);

   if (Direction == UP)
   {
      for (i = start - 1; i >= offset; i--)
      {
         UpChannel[i] = StartChannelValue + preValue*(i - start);
         DownChannel[i] = UpChannel[i] - ChannelWidth*Point;
      }
   }
   else if (Direction == DN)
   {
      for (i = start; i >= offset; i--)
      {
         DownChannel[i] = StartChannelValue + preValue*(i - start);
         UpChannel[i] = DownChannel[i] + ChannelWidth*Point;
      }
   }
}
打赏
版权所有转载请注明标题及链接:峰汇在线 » MT4经典之字形通道指标 Channel_ZZ.mq4
上一篇:
下一篇:
分享到: 更多 (0)

如您觉得此文不错请扫码打赏!

支付宝扫一扫打赏

微信扫一扫打赏