外汇指标
MT4经典之字形通道指标 Channel
回复:0  浏览:272
  • 楼主admin 圈主
  • 2019-05-05 05:06
Channel_ZZ指标创建之字形通道并提升相关形态。

QQ截图20180302120214.png

  1. //+------------------------------------------------------------------+
  2. //|                                                    Channel_ZZ.mq4|
  3. //|                                        Copyright @2008, Tinytjan |
  4. //+------------------------------------------------------------------+
  5. #property copyright "Copyright @2008, Tinytjan"
  6. #property link      "http://www.eazhijia.com/"

  7. extern string _1 = "1";
  8. extern int SmoothPeriod = 1;
  9. extern string _2 = "2";
  10. extern int ChannelWidth = 150;
  11. extern string _3 = "3";
  12. extern int FontSize = 10;
  13. extern string _4 = "4";
  14. extern string FontName = "Arial Black";
  15. extern string _5 = "4";
  16. extern bool DrawChannel = true;

  17. #property indicator_chart_window
  18. #property indicator_buffers 3

  19. #property indicator_color1 LightGray
  20. #property indicator_width1 3

  21. #property indicator_color2 Orange
  22. #property indicator_color3 Orange

  23. double ZZ[];
  24. double UpChannel[];
  25. double DownChannel[];

  26. double SmoothedMaxValues[];
  27. double SmoothedMinValues[];

  28. string symbol;

  29. #define UP 1
  30. #define DN -1
  31. #define NONE 0

  32. int Direction;

  33. datetime StartMax;
  34. datetime EndMax;
  35. datetime StartMin;
  36. datetime EndMin;

  37. datetime StartDraw;
  38. datetime EndDraw;
  39. double StartDrawValue;
  40. double EndDrawValue;

  41. datetime StartChannel;
  42. datetime EndChannel;
  43. double StartChannelValue;
  44. double EndChannelValue;

  45. int Counter;
  46. int Length;
  47. int LastLength;
  48. //+------------------------------------------------------------------+
  49. //| Custom indicator initialization function                         |
  50. //+------------------------------------------------------------------+
  51. int onInit(void)
  52.   {
  53.    IndicatorShortName("-=<Channel ZZ>=-");

  54.    IndicatorBuffers(5);
  55.    
  56.    SetIndexBuffer(0, ZZ);
  57.    SetIndexBuffer(1, UpChannel);
  58.    SetIndexBuffer(2, DownChannel);
  59.    SetIndexBuffer(3, SmoothedMaxValues);
  60.    SetIndexBuffer(4, SmoothedMinValues);
  61.    
  62.    SetIndexStyle(0, DRAW_LINE);
  63.    SetIndexStyle(1, DRAW_LINE, STYLE_DASH);
  64.    SetIndexStyle(2, DRAW_LINE, STYLE_DASH);
  65.    
  66.    symbol = Symbol();
  67.    
  68.    Direction = NONE;
  69.    Counter = 0;

  70.    StartMax = 0;
  71.    EndMax = 0;
  72.    StartMin = 0;
  73.    EndMin = 0;
  74.    
  75.    Length = 0;
  76.    LastLength = EMPTY_VALUE;
  77.    Comment("www.eazhijia.com");
  78.    return(INIT_SUCCEEDED);
  79. }

  80.    void onDeinit(const int reason)
  81. {
  82.    for (int i = 0; i <= Counter; i++)
  83.    {
  84.       ObjectDelete("Stats" + i);
  85.    }
  86. }
  87. //+------------------------------------------------------------------+
  88. //| Custom indicator iteration function                              |
  89. //+------------------------------------------------------------------+
  90. int onCalculate(const int rates_total,
  91.                 const int prev_calculated,
  92.                 const datetime &time[],
  93.                 const double &open[],
  94.                 const double &high[],
  95.                 const double &low[],
  96.                 const double &close[],
  97.                 const long &tick_volume[],
  98.                 const long &volume[],
  99.                 const int &spread[])
  100.   {
  101.    int ToCount = Bars - IndicatorCounted();
  102.    
  103.    for (int i = ToCount - 1; i >= 0; i--)
  104.    {
  105.       SmoothedMaxValues[i] = iMA(symbol, 0, SmoothPeriod, 0, MODE_EMA, PRICE_HIGH, i);
  106.       SmoothedMinValues[i] = iMA(symbol, 0, SmoothPeriod, 0, MODE_EMA, PRICE_LOW, i);
  107.       
  108.       RePaintChannels(i);
  109.       
  110.       if (Direction == NONE)
  111.       {
  112.          CheckInit(i);
  113.          continue;
  114.       }
  115.       
  116.       if (Direction == UP)      
  117.       {
  118.          CheckUp(i);
  119.       }
  120.       else
  121.       {
  122.          CheckDown(i);
  123.       }
  124.    }
  125.    return(0);
  126. }
  127. //+------------------------------------------------------------------+

  128. void CheckInit(int offset)
  129. {
  130.    if (StartMax == 0 || StartMin == 0)
  131.    {
  132.       if (StartMax == 0) StartMax = Time[offset];
  133.       if (StartMin == 0) StartMin = Time[offset];
  134.       
  135.       return;
  136.    }
  137.    
  138.    if (Direction == NONE)
  139.    {
  140.       double maxValue = SmoothedMaxValues[iBarShift(symbol, 0, StartMax)];
  141.       double minValue = SmoothedMinValues[iBarShift(symbol, 0, StartMin)];
  142.       
  143.       double nowMax = SmoothedMaxValues[offset];
  144.       double nowMin = SmoothedMaxValues[offset];
  145.       
  146.       if (nowMax > maxValue && Time[offset] > StartMax)
  147.       {
  148.          EndMax = Time[offset];
  149.          StartMin = Time[offset];
  150.          Direction = UP;
  151.          
  152.          StartDraw = StartMax;
  153.          EndDraw = EndMax;
  154.          StartDrawValue = maxValue;
  155.          EndDrawValue = nowMax;
  156.          
  157.          StartChannel = StartMax;
  158.          EndChannel = EndMax;
  159.          StartChannelValue = maxValue;
  160.          EndChannelValue = nowMax;
  161.          
  162.          Length = NormalizeDouble((nowMax - maxValue)/Point, 0);
  163.          
  164.          RePaint();
  165.       }
  166.       else if (nowMin > minValue && Time[offset] > StartMin)
  167.       {
  168.          EndMin = Time[offset];
  169.          StartMax = Time[offset];
  170.          Direction = DN;

  171.          StartDraw = StartMin;
  172.          EndDraw = EndMin;
  173.          StartDrawValue = minValue;
  174.          EndDrawValue = nowMin;

  175.          StartChannel = StartMin;
  176.          EndChannel = EndMin;
  177.          StartChannelValue = minValue;
  178.          EndChannelValue = nowMin;

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

  180.          RePaint();
  181.       }
  182.    }
  183. }

  184. void CheckUp(int offset)
  185. {
  186.    int startIndex = iBarShift(symbol, 0, StartMax);
  187.    int endIndex = iBarShift(symbol, 0, EndMax);

  188.    double endMaxValue = SmoothedMaxValues[endIndex];
  189.       
  190.    if (endMaxValue < SmoothedMaxValues[offset])
  191.    {
  192.       endMaxValue = SmoothedMaxValues[offset];
  193.       EndMax = Time[offset];

  194.       EndDraw = EndMax;
  195.       EndDrawValue = endMaxValue;

  196.       EndChannel = EndMax;
  197.       EndChannelValue = endMaxValue;
  198.       
  199.       double endMinValue = SmoothedMinValues[iBarShift(symbol, 0, EndMin)];
  200.       Length = NormalizeDouble((endMaxValue - endMinValue)/Point, 0);

  201.       RePaint();
  202.    }
  203.    else
  204.    {  
  205.       double startMaxValue = SmoothedMaxValues[startIndex];
  206.       double startMinValue = SmoothedMinValues[iBarShift(symbol, 0, StartMin)];
  207.       
  208.       double nowMaxValue = endMaxValue;
  209.       if (startIndex - endIndex != 0)
  210.       {
  211.          nowMaxValue += (endMaxValue - startMaxValue)/(startIndex - endIndex)*(endIndex - offset);
  212.       }

  213.       double nowMinValue = SmoothedMinValues[offset];
  214.       
  215.       if (nowMaxValue - nowMinValue > ChannelWidth*Point)
  216.       {
  217.          if (EndMax != offset)
  218.          {
  219.             StartMin = Time[offset];
  220.             EndMin = Time[offset];
  221.             Direction = DN;

  222.             StartDraw = EndMax;
  223.             EndDraw = EndMin;
  224.             StartDrawValue = endMaxValue;
  225.             EndDrawValue = nowMinValue;

  226.             StartChannel = EndMin;
  227.             EndChannel = EndMin;
  228.             StartChannelValue = nowMinValue;
  229.             EndChannelValue = nowMinValue;

  230.             Counter++;

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

  233.             RePaint();
  234.          }
  235.       }
  236.    }
  237. }

  238. void CheckDown(int offset)
  239. {
  240.    int startIndex = iBarShift(symbol, 0, StartMin);
  241.    int endIndex = iBarShift(symbol, 0, EndMin);

  242.    double endMinValue = SmoothedMinValues[endIndex];
  243.       
  244.    if (endMinValue > SmoothedMinValues[offset])
  245.    {
  246.       endMinValue = SmoothedMinValues[offset];
  247.       EndMin = Time[offset];

  248.       EndDraw = EndMin;
  249.       EndDrawValue = endMinValue;

  250.       EndChannel = EndMin;
  251.       EndChannelValue = endMinValue;

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

  254.       RePaint();
  255.    }
  256.    else
  257.    {  
  258.       double startMinValue = SmoothedMinValues[startIndex];
  259.       double startMaxValue = SmoothedMaxValues[iBarShift(symbol, 0, StartMax)];
  260.       
  261.       double nowMinValue = endMinValue;
  262.       if (startIndex - endIndex != 0)
  263.       {
  264.          nowMinValue += (endMinValue - startMinValue)/(startIndex - endIndex)*(endIndex - offset);
  265.       }

  266.       double nowMaxValue = SmoothedMaxValues[offset];
  267.       
  268.       if (nowMaxValue - nowMinValue > ChannelWidth*Point)
  269.       {
  270.          if (EndMin != offset)
  271.          {
  272.             EndMax = Time[offset];
  273.             StartMax = Time[offset];
  274.             Direction = UP;

  275.             StartDraw = EndMin;
  276.             EndDraw = EndMax;
  277.             StartDrawValue = endMinValue;
  278.             EndDrawValue = nowMaxValue;

  279.             StartChannel = EndMax;
  280.             EndChannel = EndMax;
  281.             StartChannelValue = nowMaxValue;
  282.             EndChannelValue = nowMaxValue;

  283.             Counter++;

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

  286.             RePaint();
  287.          }
  288.       }
  289.    }
  290. }

  291. void RePaint()
  292. {
  293.    double pos = EndDrawValue;
  294.    if (Direction == UP) pos += 15*Point;
  295.    
  296.    string id = "Stats" + Counter;
  297.    
  298.    string text;
  299.    if (LastLength != 0)
  300.       text = text + DoubleToStr((0.0001 + Length)/(0.0001 + LastLength), 2);
  301.    text = text + "(" + Length + ")";
  302.    
  303.    if (ObjectFind(id) == -1)
  304.    {
  305.       ObjectCreate(id, OBJ_TEXT, 0, EndDraw, pos);
  306.       ObjectSet(id, OBJPROP_COLOR, Yellow);
  307.    }

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

  310.    int start = iBarShift(symbol, 0, StartDraw);
  311.    int end = iBarShift(symbol, 0, EndDraw);
  312.    
  313.    if (start == end)
  314.    {
  315.       ZZ[end] = EndDrawValue;
  316.       return;
  317.    }
  318.    
  319.    double prevalue = (EndDrawValue - StartDrawValue)/(end - start);
  320.    
  321.    for (int i = start; i >= end; i--)
  322.    {
  323.       ZZ[i] = StartDrawValue + prevalue*(i - start);
  324.    }
  325. }

  326. void RePaintChannels(int offset)
  327. {
  328.    if (Direction == NONE) return;
  329.    if (!DrawChannel) return;
  330.    
  331.    int start = iBarShift(symbol, 0, StartChannel);
  332.    int end = iBarShift(symbol, 0, EndChannel);
  333.    
  334.    if (start == end)
  335.    {
  336.       if (Direction == UP)
  337.       {
  338.          UpChannel[start] = StartChannelValue;
  339.          DownChannel[start] = StartChannelValue - ChannelWidth*Point;
  340.       }
  341.       else
  342.       {
  343.          DownChannel[start] = StartChannelValue;
  344.          UpChannel[start] = StartChannelValue + ChannelWidth*Point;
  345.       }
  346.       
  347.       for(int i = start - 1; i >= offset; i--)
  348.       {
  349.          DownChannel[i] = DownChannel[i + 1];
  350.          UpChannel[i] = UpChannel[i + 1];
  351.       }
  352.       return;
  353.    }
  354.    
  355.    double prevalue = (EndChannelValue - StartChannelValue)/(end - start);

  356.    if (Direction == UP)
  357.    {
  358.       for (i = start - 1; i >= offset; i--)
  359.       {
  360.          UpChannel[i] = StartChannelValue + prevalue*(i - start);
  361.          DownChannel[i] = UpChannel[i] - ChannelWidth*Point;
  362.       }
  363.    }
  364.    else if (Direction == DN)
  365.    {
  366.       for (i = start; i >= offset; i--)
  367.       {
  368.          DownChannel[i] = StartChannelValue + prevalue*(i - start);
  369.          UpChannel[i] = DownChannel[i] + ChannelWidth*Point;
  370.       }
  371.    }
  372. }