HYROLEAN

hyrKagiZag.mq5

Mar 21st, 2026 (edited)
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // hyrKagiZag.mq5 ( MT5半自動移植版 by Claude )
  2. // Copyright 2026 hyrolean
  3. // Converted from URL:: https://pastebin.com/5j7EjYEp
  4. //=======================================================================
  5. // ----- properties -----
  6. #property copyright "2026, (c)hyrolean"
  7. #property link      "https://pastebin.com/vpxeAGpj"
  8. #property version   "1.13"
  9.  
  10.   // version 1.13
  11.   //  - fixed atrArray direction to match Series price arrays (ArraySetAsSeries true)
  12.  
  13.   // version 1.12
  14.   //  - added ArraySetAsSeries() codes to OnCalculate()
  15.  
  16.   // version 1.11
  17.   //  - bugfix on updating new extremum values among previous-current timelines
  18.  
  19.   // version 1.10
  20.   //  - supported the feature of progressive shift price multiplied by ATR
  21.  
  22.  
  23. #property indicator_chart_window
  24. #property indicator_buffers 3
  25. #property indicator_plots   1
  26. #property indicator_type1   DRAW_SECTION
  27. #property indicator_color1  clrYellow
  28. #property indicator_width1  1
  29.  
  30. // ----- parameters -----
  31. input double ShiftPrice   = 100;    // Shift price in points
  32. input bool   ATRMultiplying = true; // ATR shift price multiplying enabled
  33. input double ATRMultiplier  = 0.025;// ATR shift price multiplier
  34. input int    ATRPeriod      = 14;   // ATR period
  35.  
  36. // ----- buffers -----
  37. double ExtKagizagBuffer[];
  38. double ExtHighBuffer[];
  39. double ExtLowBuffer[];
  40.  
  41. // ----- global -----
  42. int ExtLevel = 3;
  43. int atrHandle = INVALID_HANDLE;
  44.  
  45. //-----------------------------------------------------------------------
  46. int OnInit()
  47. {
  48.     // number of indicator buffers
  49.     IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
  50.  
  51.     // setup buffers
  52.     SetIndexBuffer(0, ExtKagizagBuffer, INDICATOR_DATA);
  53.     SetIndexBuffer(1, ExtHighBuffer,    INDICATOR_CALCULATIONS);
  54.     SetIndexBuffer(2, ExtLowBuffer,     INDICATOR_CALCULATIONS);
  55.     ArraySetAsSeries(ExtKagizagBuffer, true);
  56.     ArraySetAsSeries(ExtHighBuffer, true);
  57.     ArraySetAsSeries(ExtLowBuffer, true);
  58.  
  59.     // draw style
  60.     PlotIndexSetInteger(0, PLOT_DRAW_TYPE,  DRAW_SECTION);
  61.     PlotIndexSetDouble (0, PLOT_EMPTY_VALUE, 0.0);
  62.     PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
  63.  
  64.     // indicator short name
  65.     if(ATRMultiplying) {
  66.         IndicatorSetString(INDICATOR_SHORTNAME,
  67.             "KagiZag(" + string(ShiftPrice) + "," +
  68.             string(ATRMultiplier) + "," + string(ATRPeriod) + ")");
  69.     } else {
  70.         IndicatorSetString(INDICATOR_SHORTNAME,
  71.             "KagiZag(" + string(ShiftPrice) + ")");
  72.     }
  73.  
  74.     // ATR handle
  75.     if(ATRMultiplying) {
  76.         atrHandle = iATR(_Symbol, PERIOD_CURRENT, ATRPeriod);
  77.         if(atrHandle == INVALID_HANDLE) {
  78.             Print("Failed to create ATR handle");
  79.             return(INIT_FAILED);
  80.         }
  81.     }
  82.  
  83.     return(INIT_SUCCEEDED);
  84. }
  85.  
  86. //-----------------------------------------------------------------------
  87. void OnDeinit(const int reason)
  88. {
  89.     if(atrHandle != INVALID_HANDLE)
  90.         IndicatorRelease(atrHandle);
  91. }
  92.  
  93. //-----------------------------------------------------------------------
  94. int OnCalculate(const int rates_total,
  95.                 const int prev_calculated,
  96.                 const datetime &time[],
  97.                 const double   &open[],
  98.                 const double   &high[],
  99.                 const double   &low[],
  100.                 const double   &close[],
  101.                 const long     &tick_volume[],
  102.                 const long     &volume[],
  103.                 const int      &spread[])
  104. {
  105.     int    i, pos, opos = -1, numExt, extMode = 0;
  106.     double curLow = 0.0, curHigh = 0.0;
  107.     double deltaLow = 0.0, deltaHigh = 0.0;
  108.     double shift = ShiftPrice * _Point;
  109.  
  110.     ArraySetAsSeries(high,true);
  111.     ArraySetAsSeries(low,true);
  112.     ArraySetAsSeries(open,true);
  113.  
  114.     if(prev_calculated == 0) {
  115.         // 初回計算
  116.         InitializeAll();
  117.         pos = rates_total;
  118.     } else {
  119.         // 直近の極値(ExtLevel個)を探して再計算開始位置を決定
  120.         for(i = numExt = 0; numExt < ExtLevel && i < rates_total; i++) {
  121.             if(ExtKagizagBuffer[i] != 0.0)
  122.                 numExt++;
  123.         }
  124.         if(!numExt) {
  125.             // 極値が見つからない(初回相当)
  126.             InitializeAll();
  127.             pos = rates_total;
  128.         } else {
  129.             // 極値が見つかった
  130.             pos = i - 1;
  131.             if(ExtLowBuffer[pos]!= 0.0) {
  132.                 // 直近極値は安値
  133.                 curLow  = ExtLowBuffer[pos];
  134.                 extMode = 1; // 安値を追いかけるモード
  135.             } else {
  136.                 // 直近極値は高値
  137.                 curHigh  = ExtHighBuffer[pos];
  138.                 extMode  = -1; // 高値を追いかけるモード
  139.             }
  140.             // 直前の確定済み極値より新しいバッファデータをリセット
  141.             for(i = pos - 1; i >= 0; i--) {
  142.                 ExtKagizagBuffer[i] = 0.0;
  143.                 ExtLowBuffer[i]     = 0.0;
  144.                 ExtHighBuffer[i]    = 0.0;
  145.             }
  146.         }
  147.     }
  148.  
  149.     double atrArray[];
  150.     if(ATRMultiplying) {
  151.         if(CopyBuffer(atrHandle, 0, 0, pos, atrArray) <= 0)
  152.             return(0);
  153.         ArraySetAsSeries(atrArray, true); // high/low/openと方向を揃える(index 0=最新)
  154.     }
  155.  
  156.     // メインループ
  157.     for(i = pos - 1; i >= 0; i--) {
  158.         if(ATRMultiplying) {
  159.             if(rates_total - i < ATRPeriod) continue;
  160.             shift = ShiftPrice * atrArray[i] * ATRMultiplier;
  161.         }
  162.  
  163.         switch(extMode) {
  164.         case 0: // 初回(まだどちらのモードでもない)
  165.             deltaHigh = high[i] - open[pos - 1];
  166.             deltaLow  = open[pos - 1] - low[i];
  167.             if(deltaHigh >= deltaLow) { // 上方向優先
  168.                 if(deltaHigh >= shift) {
  169.                     curLow  = open[pos - 1];
  170.                     ExtKagizagBuffer[pos - 1] = curLow;
  171.                     ExtLowBuffer[pos - 1]     = curLow;
  172.                     curHigh = high[i];
  173.                     pos     = i;
  174.                     ExtKagizagBuffer[pos] = curHigh;
  175.                     ExtHighBuffer[pos]    = curHigh;
  176.                     extMode = -1; // 高値を追いかけるモードへ
  177.                 }
  178.             } else { // 下方向優先
  179.                 if(deltaLow >= shift) {
  180.                     curHigh = open[pos - 1];
  181.                     ExtKagizagBuffer[pos - 1] = curHigh;
  182.                     ExtHighBuffer[pos - 1]    = curHigh;
  183.                     curLow = low[i];
  184.                     pos    = i;
  185.                     ExtKagizagBuffer[pos] = curLow;
  186.                     ExtLowBuffer[pos]     = curLow;
  187.                     extMode = 1; // 安値を追いかけるモードへ
  188.                 }
  189.             }
  190.             break;
  191.  
  192.         case 1: // 安値を追いかけるモード(高値への転換待ち)
  193.             deltaHigh = high[i] - curLow;
  194.             deltaLow  = curLow  - low[i];
  195.             if(deltaHigh > deltaLow) { // 上方向
  196.                 if(deltaHigh >= shift) { // 高値側へ転換
  197.                     curHigh = high[i];
  198.                     opos    = pos;
  199.                     pos     = i;
  200.                     ExtKagizagBuffer[pos] = curHigh;
  201.                     ExtHighBuffer[pos]    = curHigh;
  202.                     extMode = -1; // 高値を追いかけるモードへ
  203.                     break;
  204.                 }
  205.             }
  206.             if(deltaLow >= 0) { // 安値更新
  207.                 curLow = low[i];
  208.                 if(opos >= 0) { // 直前の高値ピーク(高値)を更新確認
  209.                     int ih = IndexOfHighest(high, pos, opos);
  210.                     if(curHigh <= high[ih]) {
  211.                         // 更新前の直前ピーク(高値)より現在の高値側が高い
  212.                         curHigh = high[ih];
  213.                         ExtKagizagBuffer[opos] = 0.0;
  214.                         ExtHighBuffer[opos]    = 0.0;
  215.                         opos = ih;
  216.                         ExtKagizagBuffer[ih] = curHigh;
  217.                         ExtHighBuffer[ih]    = curHigh;
  218.                     }
  219.                 }
  220.                 if(opos != pos) ExtKagizagBuffer[pos] = 0.0;
  221.                 ExtLowBuffer[pos] = 0.0;
  222.                 pos = i;
  223.                 ExtKagizagBuffer[pos] = curLow;
  224.                 ExtLowBuffer[pos]     = curLow;
  225.             }
  226.             break;
  227.  
  228.         case -1: // 高値を追いかけるモード(安値への転換待ち)
  229.             deltaHigh = high[i] - curHigh;
  230.             deltaLow  = curHigh - low[i];
  231.             if(deltaLow > deltaHigh) { // 下方向
  232.                 if(deltaLow >= shift) { // 安値側へ転換
  233.                     curLow = low[i];
  234.                     opos   = pos;
  235.                     pos    = i;
  236.                     ExtKagizagBuffer[pos] = curLow;
  237.                     ExtLowBuffer[pos]     = curLow;
  238.                     extMode = 1; // 安値を追いかけるモードへ
  239.                     break;
  240.                 }
  241.             }
  242.             if(deltaHigh >= 0) { // 高値更新
  243.                 curHigh = high[i];
  244.                 if(opos >= 0) { // 直前の安値ピーク(安値)を更新確認
  245.                     int il = IndexOfLowest(low, pos, opos);
  246.                     if(curLow >= low[il]) {
  247.                         // 更新前の直前ピーク(安値)より現在の安値側が低い
  248.                         curLow = low[il];
  249.                         ExtKagizagBuffer[opos] = 0.0;
  250.                         ExtLowBuffer[opos]     = 0.0;
  251.                         opos = il;
  252.                         ExtKagizagBuffer[il] = curLow;
  253.                         ExtLowBuffer[il]     = curLow;
  254.                     }
  255.                 }
  256.                 if(opos != pos) ExtKagizagBuffer[pos] = 0.0;
  257.                 ExtHighBuffer[pos] = 0.0;
  258.                 pos = i;
  259.                 ExtKagizagBuffer[pos] = curHigh;
  260.                 ExtHighBuffer[pos]    = curHigh;
  261.             }
  262.             break;
  263.         }
  264.     }
  265.  
  266.     return(rates_total);
  267. }
  268.  
  269. //-----------------------------------------------------------------------
  270. void InitializeAll()
  271. {
  272.     ArrayInitialize(ExtKagizagBuffer, 0.0);
  273.     ArrayInitialize(ExtHighBuffer,    0.0);
  274.     ArrayInitialize(ExtLowBuffer,     0.0);
  275. }
  276. //-----------------------------------------------------------------------
  277. int IndexOfLowest(const double &array[],const int si,const int ei)
  278. {
  279.   double v = array[si];
  280.   int r=si;
  281.   for(int i=si+1;i<=ei;i++) {
  282.     if(v>array[i]) { r=i ; v = array[i]; }
  283.   }
  284.   return r ;
  285. }
  286. //-----------------------------------------------------------------------
  287. int IndexOfHighest(const double &array[],const int si,const int ei)
  288. {
  289.   double v = array[si];
  290.   int r=si;
  291.   for(int i=si+1;i<=ei;i++) {
  292.     if(v<array[i]) { r=i ; v = array[i]; }
  293.   }
  294.   return r ;
  295. }
  296. //-----------------------------------------------------------------------
  297.  
Tags: Mt5
Advertisement
Add Comment
Please, Sign In to add comment