Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // hyrKagiZag.mq5 ( MT5半自動移植版 by Claude )
- // Copyright 2026 hyrolean
- // Converted from URL:: https://pastebin.com/5j7EjYEp
- //=======================================================================
- // ----- properties -----
- #property copyright "2026, (c)hyrolean"
- #property link "https://pastebin.com/vpxeAGpj"
- #property version "1.13"
- // version 1.13
- // - fixed atrArray direction to match Series price arrays (ArraySetAsSeries true)
- // 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 3
- #property indicator_plots 1
- #property indicator_type1 DRAW_SECTION
- #property indicator_color1 clrYellow
- #property indicator_width1 1
- // ----- 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 atrHandle = INVALID_HANDLE;
- //-----------------------------------------------------------------------
- int OnInit()
- {
- // number of indicator buffers
- IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
- // setup buffers
- SetIndexBuffer(0, ExtKagizagBuffer, INDICATOR_DATA);
- SetIndexBuffer(1, ExtHighBuffer, INDICATOR_CALCULATIONS);
- SetIndexBuffer(2, ExtLowBuffer, INDICATOR_CALCULATIONS);
- ArraySetAsSeries(ExtKagizagBuffer, true);
- ArraySetAsSeries(ExtHighBuffer, true);
- ArraySetAsSeries(ExtLowBuffer, true);
- // draw style
- PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_SECTION);
- PlotIndexSetDouble (0, PLOT_EMPTY_VALUE, 0.0);
- PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
- // indicator short name
- if(ATRMultiplying) {
- IndicatorSetString(INDICATOR_SHORTNAME,
- "KagiZag(" + string(ShiftPrice) + "," +
- string(ATRMultiplier) + "," + string(ATRPeriod) + ")");
- } else {
- IndicatorSetString(INDICATOR_SHORTNAME,
- "KagiZag(" + string(ShiftPrice) + ")");
- }
- // ATR handle
- if(ATRMultiplying) {
- atrHandle = iATR(_Symbol, PERIOD_CURRENT, ATRPeriod);
- if(atrHandle == INVALID_HANDLE) {
- Print("Failed to create ATR handle");
- return(INIT_FAILED);
- }
- }
- return(INIT_SUCCEEDED);
- }
- //-----------------------------------------------------------------------
- void OnDeinit(const int reason)
- {
- if(atrHandle != INVALID_HANDLE)
- IndicatorRelease(atrHandle);
- }
- //-----------------------------------------------------------------------
- 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;
- }
- }
- }
- double atrArray[];
- if(ATRMultiplying) {
- if(CopyBuffer(atrHandle, 0, 0, pos, atrArray) <= 0)
- return(0);
- ArraySetAsSeries(atrArray, true); // high/low/openと方向を揃える(index 0=最新)
- }
- // メインループ
- for(i = pos - 1; i >= 0; i--) {
- if(ATRMultiplying) {
- if(rates_total - i < ATRPeriod) continue;
- shift = ShiftPrice * atrArray[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 = IndexOfHighest(high, pos, opos);
- 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 = IndexOfLowest(low, pos, opos);
- 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);
- }
- //-----------------------------------------------------------------------
- int IndexOfLowest(const double &array[],const int si,const int ei)
- {
- double v = array[si];
- int r=si;
- for(int i=si+1;i<=ei;i++) {
- if(v>array[i]) { r=i ; v = array[i]; }
- }
- return r ;
- }
- //-----------------------------------------------------------------------
- int IndexOfHighest(const double &array[],const int si,const int ei)
- {
- double v = array[si];
- int r=si;
- for(int i=si+1;i<=ei;i++) {
- if(v<array[i]) { r=i ; v = array[i]; }
- }
- return r ;
- }
- //-----------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment