Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // hyrKagiZag.mq4
- // Copyright 2026 hyrolean
- //===========================================================================
- //----- properties -----
- #property copyright "2026, (c)hyrolean"
- #property link "https://pastebin.com/5j7EjYEp"
- #property version "1.12"
- #property strict
- // version 1.12
- // - added ArraySetAsSeries() codes to OnCalculate()
- // version 1.11
- // - bugfix on updating new extremum values among previous-current timelines
- // version 1.10
- // - supported the feature of progressive shift price multiplied by ATR
- #property indicator_chart_window
- #property indicator_buffers 1
- #property indicator_color1 clrYellow
- //----- parameters -----
- input double ShiftPrice = 100 ; // Shift price in points
- input bool ATRMultiplying = true ; // ATR shift price multiplying enabled
- input double ATRMultiplier = 0.025 ; // ATR shift price multiplier
- input int ATRPeriod = 14 ; // ATR period
- //----- buffers -----
- double ExtKagizagBuffer[];
- double ExtHighBuffer[];
- double ExtLowBuffer[];
- //----- global -----
- int ExtLevel=3;
- //---------------------------------------------------------------------------
- int OnInit()
- {
- // number of indicator buffers
- IndicatorBuffers(3); // Kagizag, High, Low
- // setup the drawing style of primary buffer as section
- SetIndexStyle(0,DRAW_SECTION);
- // setup buffers
- SetIndexBuffer(0,ExtKagizagBuffer);
- SetIndexBuffer(1,ExtHighBuffer);
- SetIndexBuffer(2,ExtLowBuffer);
- SetIndexEmptyValue(0,0.0);
- // setup the indicator short name
- if(ATRMultiplying) {
- IndicatorShortName("KagiZag("+string(ShiftPrice)+","
- +string(ATRMultiplier)+","+string(ATRPeriod)+")");
- }else {
- IndicatorShortName("KagiZag("+string(ShiftPrice)+")");
- }
- return(INIT_SUCCEEDED);
- }
- //---------------------------------------------------------------------------
- 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 i, pos, opos=-1, numExt, extMode=0 ;
- double curLow=0.0, curHigh=0.0 ;
- double deltaLow=0.0, deltaHigh=0.0 ;
- double shift = ShiftPrice*Point ;
- ArraySetAsSeries(high,true);
- ArraySetAsSeries(low,true);
- ArraySetAsSeries(open,true);
- if(prev_calculated==0) { // 初期状態
- InitializeAll();
- pos = rates_total ;
- }else {
- // 近傍の有効頂点数(ExtLevelまでの)を数える
- for(i=numExt=0;numExt<ExtLevel&&i<rates_total;i++) {
- if(ExtKagizagBuffer[i]!=0.0)
- numExt++;
- }
- if(!numExt) {
- // 頂点ナシ(初期状態)
- InitializeAll();
- pos = rates_total ;
- }else {
- // 頂点がみつかった
- pos = i-1 ;
- if(ExtLowBuffer[pos]!=0.0) { // 頂点は、谷に位置する
- curLow = ExtLowBuffer[pos] ;
- extMode = 1 ; // 山を見つけるモード
- }else { // 頂点は、山に位置する
- curHigh = ExtHighBuffer[pos] ;
- extMode = -1 ; // 谷を見つけるモード
- }
- // 頂点再列挙の事前処理として近傍の頂点データを抹消しておく
- for(i=pos-1;i>=0;i--) {
- ExtKagizagBuffer[i]=0.0;
- ExtLowBuffer[i]=0.0;
- ExtHighBuffer[i]=0.0;
- }
- }
- }
- // メイン処理
- for(i=pos-1;i>=0;i--) {
- if(ATRMultiplying) {
- if(rates_total-i<ATRPeriod) continue;
- shift = ShiftPrice * iATR(NULL,0,ATRPeriod,i) * ATRMultiplier ;
- }
- switch(extMode) { // 頂点検出モード(山と谷のどちらのピークであるか)
- case 0: // どちらのモードでもない(初期状態)
- deltaHigh = high[i]-open[pos-1] ;
- deltaLow = open[pos-1]-low[i] ;
- if(deltaHigh>=deltaLow) { // 上昇気味
- if(deltaHigh>=shift) { // 初期価格から上にシフト
- curLow = open[pos-1] ;
- ExtKagizagBuffer[pos-1]=curLow;
- ExtLowBuffer[pos-1]=curLow;
- curHigh = high[i] ;
- pos = i ;
- ExtKagizagBuffer[pos] = curHigh ;
- ExtHighBuffer[pos] = curHigh ;
- extMode = -1 ; // 谷を見つけるモードに移行
- }
- }else { // 下降気味
- if(deltaLow>=shift) { // 初期価格から下にシフト
- curHigh = open[pos-1] ;
- ExtKagizagBuffer[pos-1]=curHigh;
- ExtHighBuffer[pos-1]=curHigh;
- curLow = low[i] ;
- pos = i ;
- ExtKagizagBuffer[pos] = curLow ;
- ExtLowBuffer[pos] = curLow ;
- extMode = 1 ; // 山を見つけるモードに移行
- }
- }
- break;
- case 1: // 山を見つけるモード ( 谷側に価格が進行中 )
- deltaHigh = high[i] - curLow ;
- deltaLow = curLow - low[i] ;
- if(deltaHigh>deltaLow) { // 上昇気味
- if(deltaHigh>=shift) { // 谷底から上にシフト
- curHigh = high[i] ;
- opos = pos ;
- pos = i ;
- ExtKagizagBuffer[pos] = curHigh ;
- ExtHighBuffer[pos] = curHigh ;
- extMode = -1 ; // 谷を見つけるモードに移行
- break;
- }
- }
- if(deltaLow>=0) { // 最安値更新
- curLow = low[i] ;
- if(opos>=0) { // ひとつ前のポジション(山)が有効
- int ih = iHighest(NULL,0,MODE_HIGH,opos-pos,pos) ;
- if(curHigh<=high[ih]) { // 現在からひとつ前までの最高値が前の山より高い
- // ひとつ前のポジション(山)を更新
- curHigh=high[ih];
- ExtKagizagBuffer[opos] = 0.0 ;
- ExtHighBuffer[opos]=0.0;
- opos=ih;
- ExtKagizagBuffer[ih]=curHigh;
- ExtHighBuffer[ih]=curHigh;
- }
- }
- if(opos!=pos) ExtKagizagBuffer[pos]=0.0;
- ExtLowBuffer[pos]=0.0;
- pos=i;
- ExtKagizagBuffer[pos]=curLow;
- ExtLowBuffer[pos]=curLow;
- }
- break;
- case -1: // 谷を見つけるモード ( 山側に価格が進行中 )
- deltaHigh = high[i] - curHigh ;
- deltaLow = curHigh - low[i] ;
- if(deltaLow>deltaHigh) { // 下降気味
- if(deltaLow>=shift) { // 山頂から下にシフト
- curLow = low[i] ;
- opos = pos ;
- pos = i ;
- ExtKagizagBuffer[pos] = curLow ;
- ExtLowBuffer[pos] = curLow ;
- extMode = 1 ; // 山を見つけるモードに移行
- break;
- }
- }
- if(deltaHigh>=0) { // 最高値更新
- curHigh = high[i] ;
- if(opos>=0) { // ひとつ前のポジション(谷)が有効
- int il = iLowest(NULL,0,MODE_LOW,opos-pos,pos) ;
- if(curLow>=low[il]) { // 現在からひとつ前までの最安値が前の谷より低い
- // ひとつ前のポジション(谷)を更新
- curLow=low[il];
- ExtKagizagBuffer[opos] = 0.0 ;
- ExtLowBuffer[opos]=0.0;
- opos=il;
- ExtKagizagBuffer[il]=curLow;
- ExtLowBuffer[il]=curLow;
- }
- }
- if(opos!=pos) ExtKagizagBuffer[pos]=0.0;
- ExtHighBuffer[pos]=0.0;
- pos=i;
- ExtKagizagBuffer[pos]=curHigh;
- ExtHighBuffer[pos]=curHigh;
- }
- break;
- }
- }
- return(rates_total);
- }
- //---------------------------------------------------------------------------
- void InitializeAll()
- {
- ArrayInitialize(ExtKagizagBuffer,0.0);
- ArrayInitialize(ExtHighBuffer,0.0);
- ArrayInitialize(ExtLowBuffer,0.0);
- }
- //---------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment