Author: Copyright 2012, Rone.
0 Views
0 Downloads
0 Favorites
Kagi
//+------------------------------------------------------------------+
//|                                                         Kagi.mq5 |
//|                                            Copyright 2012, Rone. |
//|                                            rone.sergey@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Rone."
#property link      "rone.sergey@gmail.com"
#property version   "1.00"
#property description "The Kagi chart."
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 9
#property indicator_plots   4
//--- plot Yang
#property indicator_label1  "Yang"
#property indicator_type1   DRAW_HISTOGRAM2
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- plot Yin
#property indicator_label2  "Yin"
#property indicator_type2   DRAW_HISTOGRAM2
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//--- plot BendTop
#property indicator_label3  "BendTop"
#property indicator_type3   DRAW_COLOR_LINE
#property indicator_color3  clrRed,clrBlue
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2
//--- plot BendBottom
#property indicator_label4  "BendBottom"
#property indicator_type4   DRAW_COLOR_LINE
#property indicator_color4  clrRed,clrBlue
#property indicator_style4  STYLE_SOLID
#property indicator_width4  2
//---
enum REVERSAL_MODE {
   PIPS,    // In pips
   PERCENT  // In percentage
};
//--- input parameters
input REVERSAL_MODE  InpMode = PIPS;      // Reversal
input int            InpPips = 100;       // Reversal in pips
input double         InpPercent = 0.5;    // Reversal in %
//--- indicator buffers
double         YangBuffer1[];
double         YangBuffer2[];
double         YinBuffer1[];
double         YinBuffer2[];
double         BendTopBuffer[];
double         BendTopColors[];
double         BendBottomBuffer[];
double         BendBottomColors[];
double         KagiBuffer[];
//--- global variables
int            kagiShift;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {   
//--- indicator buffers mapping
   SetIndexBuffer(0, YangBuffer1, INDICATOR_DATA);
   SetIndexBuffer(1, YangBuffer2, INDICATOR_DATA);
   SetIndexBuffer(2, YinBuffer1, INDICATOR_DATA);
   SetIndexBuffer(3, YinBuffer2, INDICATOR_DATA);
   SetIndexBuffer(4, BendTopBuffer, INDICATOR_DATA);
   SetIndexBuffer(5, BendTopColors, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(6, BendBottomBuffer, INDICATOR_DATA);
   SetIndexBuffer(7, BendBottomColors, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(8, KagiBuffer, INDICATOR_CALCULATIONS);
//---
   for ( int i = 0; i < 4; i++ ) {
      PlotIndexSetDouble(i, PLOT_EMPTY_VALUE, 0.0);
   }
//---
   IndicatorSetInteger(INDICATOR_LEVELS, 1);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR, clrGray);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE, STYLE_SOLID);
//---
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
//---
   string modeData = (InpMode == PIPS) ? (string)InpPips+" pips" : DoubleToString(InpPercent, 2)+"%";
   IndicatorSetString(INDICATOR_SHORTNAME, "Kagi ("+modeData+")");
//---
   return(0);
}
//+------------------------------------------------------------------+
//| Get Reversal Value function                                      |
//+------------------------------------------------------------------+
double getReversal(double price) {
//---
   if ( InpMode == PIPS ) {
      return(InpPips*_Point);
   }
   return(NormalizeDouble((price/100)*InpPercent, _Digits));
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
//---
   int shift = 1;
   bool up, yang;
   double localMin, localMax;
   double reversal = getReversal(price[0]);
//---
   for ( ; MathAbs(price[shift]-price[0]) < reversal; shift++ );
//---
   KagiBuffer[0] = KagiBuffer[1] = price[0];
   KagiBuffer[2] = price[shift];
   kagiShift = 2;
   if ( price[shift] > price[0] ) {
      up = true;
      yang = true;
      localMin = price[0];
      localMax = price[shift];
   } else {
      up = false;
      yang = false;
      localMin = price[shift];
      localMax = price[0];
   }
//---
   for ( int bar = shift; bar < rates_total && !IsStopped(); bar++ ) {
      double curPrice = price[bar];
      
      reversal = getReversal(KagiBuffer[kagiShift]);
      if ( up ) {
         if ( curPrice > KagiBuffer[kagiShift] ) {
            KagiBuffer[kagiShift] = curPrice;
         } else if ( curPrice < KagiBuffer[kagiShift] - reversal ) {
            kagiShift += 1;
            KagiBuffer[kagiShift] = KagiBuffer[kagiShift-1];
            kagiShift += 1;
            KagiBuffer[kagiShift] = curPrice;
            up = false;
         }
      } else {
         if ( curPrice < KagiBuffer[kagiShift] ) {
            KagiBuffer[kagiShift] = curPrice;
         } else if ( curPrice > KagiBuffer[kagiShift] + reversal ) {
            kagiShift += 1;
            KagiBuffer[kagiShift] = KagiBuffer[kagiShift-1];
            kagiShift += 1;
            KagiBuffer[kagiShift] = curPrice;
            up = true;
         }
      }
   }
//---
   for ( int i = 1; i <= kagiShift; i++ ) {
      int bar = rates_total - kagiShift - 1 + i;
      double cur = KagiBuffer[i];
      double prev = KagiBuffer[i-1];
      //---
      if ( yang ) {
         YinBuffer1[bar] = YinBuffer2[bar] = 0.0;
         BendTopColors[bar] = BendBottomColors[bar] = 1;
         if ( cur > prev ) {
            YangBuffer1[bar] = localMin = prev;
            YangBuffer2[bar] = localMax = cur;
            //---
            BendTopBuffer[bar] = cur;
            BendBottomBuffer[bar] = prev;
         } else if ( cur < prev ) {
            if ( cur < localMin ) {
               YangBuffer1[bar] = localMax = prev;
               YangBuffer2[bar] = YinBuffer1[bar] = localMin;
               YinBuffer2[bar] = localMin = cur;
               yang = false;
               //---
               BendTopBuffer[bar] = prev;
               BendBottomBuffer[bar] = cur;
            } else {
               YangBuffer1[bar] = localMax = prev;
               YangBuffer2[bar] = localMin = cur;
               //---
               BendTopBuffer[bar] = prev;
               BendBottomBuffer[bar] = cur;
            }
         } else {
            YangBuffer1[bar] = YangBuffer2[bar] = 0.0;
            //---
            if ( cur == localMin ) {
               BendTopBuffer[bar] = 0.0;
               BendBottomBuffer[bar] = cur;
            } else {
               BendTopBuffer[bar] = cur;
               BendBottomBuffer[bar] = 0.0;
            }
         }
      } else {
         YangBuffer1[bar] = YangBuffer2[bar] = 0.0;
         BendTopColors[bar] = BendBottomColors[bar] = 0;
         if ( cur < prev ) {
            YinBuffer1[bar] = localMax = prev;
            YinBuffer2[bar] = localMin = cur;
            //---
            BendTopBuffer[bar] = prev;
            BendBottomBuffer[bar] = cur;
         } else if ( cur > prev ) {
            if ( cur > localMax ) {
               YinBuffer1[bar] = localMin = prev;
               YinBuffer2[bar] = YangBuffer1[bar] = localMax;
               YangBuffer2[bar] = localMax = cur;
               yang = true;
               //---
               BendTopBuffer[bar] = cur;
               BendBottomBuffer[bar] = prev;
            } else {
               YinBuffer1[bar] = localMin = prev;
               YinBuffer2[bar] = localMax = cur;
               //---
               BendTopBuffer[bar] = cur;
               BendBottomBuffer[bar] = prev;
            }
         } else {
            YinBuffer1[bar] = YinBuffer2[bar] = 0.0;
            //---
            if ( cur == localMin ) {
               BendTopBuffer[bar] = 0.0;
               BendBottomBuffer[bar] = cur;
            } else {
               BendTopBuffer[bar] = cur;
               BendBottomBuffer[bar] = 0.0;   
            }
         }
      }
   }
//---
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, price[rates_total-1]);  
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---