Zephra Adaptive ATR V1.3 (Non-Repaint) MetaTrader 5 Indicator

The Zephra Adaptive ATR V1.3 (Non-Repaint) is a technical indicator designed to combine the adaptability of a moving average with the volatility measurement of the Average True Range (ATR). By adjusting to changing market conditions, it offers a dynamic way to view price trends and potential price ranges. This version of the indicator ensures that signals are non-repainting, providing a stable view of market data without altering past signals. It is primarily used to monitor both trend direction and price volatility through an adaptive moving average and channel boundaries calculated using the ATR.

// Property definitions for indicator
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   3
#property indicator_label1  "Adaptive EMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrPaleVioletRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_label2  "Channel up"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrDarkGray
#property indicator_style2  STYLE_DOT
#property indicator_label3  "Channel down"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrDarkGray
#property indicator_style3  STYLE_DOT

// Input parameters for customization
input int inpPeriod = 20;                          // Period for calculation
input ENUM_APPLIED_PRICE inpPrice = PRICE_TYPICAL; // Applied price type
input double inpMultiplier = 1;                    // Multiplier for channel width

// Buffers for storing calculated data
double val[], chanup[], chandn[], atr[];
double m_fastEnd, m_slowEnd;
int m_period;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                          |
//+------------------------------------------------------------------+
int OnInit()
{
   // Initialize buffers
   SetIndexBuffer(0, val, INDICATOR_DATA);
   SetIndexBuffer(1, chanup, INDICATOR_DATA);
   SetIndexBuffer(2, chandn, INDICATOR_DATA);
   SetIndexBuffer(3, atr, INDICATOR_CALCULATIONS);
   
   // Set period and adaptive range (fast/slow end for Adaptive EMA)
   m_period = (inpPeriod > 1) ? inpPeriod : 1;
   m_fastEnd = MathMax(m_period / 2.0, 1);
   m_slowEnd = m_period * 5;
   
   // Set indicator short name
   IndicatorSetString(INDICATOR_SHORTNAME, "Adaptive ATR channel(" + (string)m_period + ")");
   
   return (INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function (main calculation loop)       |
//+------------------------------------------------------------------+
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[])
{
   // Define a structure for storing price and noise data
   struct sEfrStruct
   {
      double price;
      double difference;
      double noise;
   };

   // Static array to store calculation data
   static sEfrStruct m_array[];
   static int m_arraySize = -1;

   // Resize array if necessary
   if (m_arraySize < rates_total)
   {
      m_arraySize = ArrayResize(m_array, rates_total + 500);
      if (m_arraySize < rates_total) return (0); // Return if not enough memory
   }

   // Start calculating from where the previous calculation left off
   int i = prev_calculated - 1;
   if (i < 0) i = 0;

   // Calculation loop for each candle
   for (; i < rates_total && !_StopFlag; i++)
   {
      // Set the price according to the input price type
      double _price;
      _setPrice(inpPrice, _price, i);
      m_array[i].price = _price;

      // Calculate price difference (absolute value)
      m_array[i].difference = (i > 0) ? MathAbs(m_array[i].price - m_array[i - 1].price) : 0;

      // Calculate noise and signal
      double signal = 0;
      if (i > m_period)
      {
         signal = MathAbs(m_array[i].price - m_array[i - m_period].price);
         m_array[i].noise = m_array[i - 1].noise + m_array[i].difference - m_array[i - m_period].difference;
      }
      else
      {
         m_array[i].noise = m_array[i].difference;
         for (int k = 1; k < m_period && i >= k; k++)
         {
            m_array[i].noise += m_array[i - k].difference;
         }
      }

      // Calculate Efficiency Ratio (EFR) and Average Period
      double efratio = (m_array[i].noise != 0) ? signal / m_array[i].noise : 1;
      double averagePeriod = (m_array[i].noise != 0) ? ((signal / m_array[i].noise) * (m_slowEnd - m_fastEnd)) + m_fastEnd : m_period;

      // Calculate ATR, EMA (val), Channel Up and Down
      atr[i] = (i > 0) ? atr[i - 1] + (2.0 / (1.0 + averagePeriod)) * ((high[i] - low[i]) - atr[i - 1]) : (high[i] - low[i]);
      val[i] = (i > 0) ? val[i - 1] + (2.0 / (1.0 + averagePeriod)) * (_price - val[i - 1]) : (_price);
      chanup[i] = val[i] + inpMultiplier * atr[i];
      chandn[i] = val[i] - inpMultiplier * atr[i];
   }

   return (rates_total);
}

//+------------------------------------------------------------------+
//| Helper macro for setting the price based on selected price type   |
//+------------------------------------------------------------------+
#define _setPrice(_priceType, _target, _index) \
   { \
      switch (_priceType) \
      { \
         case PRICE_CLOSE:    _target = close[_index]; break; \
         case PRICE_OPEN:     _target = open[_index]; break; \
         case PRICE_HIGH:     _target = high[_index]; break; \
         case PRICE_LOW:      _target = low[_index]; break; \
         case PRICE_MEDIAN:   _target = (high[_index] + low[_index]) / 2.0; break; \
         case PRICE_TYPICAL:  _target = (high[_index] + low[_index] + close[_index]) / 3.0; break; \
         case PRICE_WEIGHTED: _target = (high[_index] + low[_index] + close[_index] * 2) / 4.0; break; \
         default:             _target = 0; \
      } \
   }

What Is the Zephra Adaptive ATR?

The Zephra Adaptive ATR indicator dynamically calculates a moving average line, surrounded by two additional lines (upper and lower channels), which show potential price fluctuations. This approach allows you to see both the central price movement (the moving average) and the range within which the price may vary (the channels based on ATR).

  • Adaptive EMA (Exponential Moving Average): The moving average in this indicator isn’t fixed. It adapts to price changes, becoming more reactive during volatile periods and smoothing out when the market is calm. This adaptability ensures the moving average reflects current market conditions without lagging too far behind.
  • ATR Channels: The indicator plots two dotted lines (referred to as Channel up and Channel down) that form a price channel. These lines are calculated using the ATR, which measures the market’s volatility. The channel expands when volatility increases and contracts when the market is more stable.
See also  Bizzwill Adx Cross Arrow (Non-Repaint) MetaTrader 5 Indicator

Now that we have a basic idea, let’s dive into the different components of this indicator.

Key Inputs and Parameters

Before we explore how the indicator works, it’s essential to understand the inputs you can adjust to tailor the indicator to your specific needs.

  • Period: This is a key parameter that defines the length of time used to calculate the moving average and ATR. The default value is set to 20, which means it looks back 20 bars or candles to make calculations. You can increase or decrease this value depending on how sensitive you want the indicator to be.
  • Price Type: The indicator allows you to select the price type on which the calculations are based. These could include options like Close Price, Open Price, or more complex price types like Typical Price (the average of high, low, and close prices). The default setting uses Typical Price to get a balanced representation of price movement.
  • Multiplier: The multiplier adjusts the width of the ATR-based channel. By default, it’s set to 1, which means the channel width is directly proportional to the ATR. Increasing the multiplier will widen the channel, and decreasing it will narrow the channel.

How the Zephra Adaptive ATR Works

Price Calculation

The first step in the Zephra Adaptive ATR’s process is to calculate the price for each period. Based on the chosen price type (whether it’s the close price, open price, or typical price), the indicator will continuously update its view of the price as new bars are formed on the chart.

See also  Adeptive WPR Signal (Non-Repaint) MetaTrader 5 Indicator

Noise and Signal Difference

The indicator uses a concept called noise and signal difference to measure the efficiency of price movement over time.

  • Noise is calculated as the sum of price differences between consecutive bars. It helps the indicator understand the unpredictability of price movement.
  • Signal difference measures the absolute price movement over a set period. This difference helps identify whether price is trending in a particular direction or fluctuating in a range.

Efficiency Ratio

The Efficiency Ratio (EFR) is derived from the relationship between signal and noise. If the price is consistently moving in a single direction, the efficiency ratio will be higher. Conversely, if the price fluctuates back and forth without a clear trend, the ratio will be lower. This EFR helps the indicator adjust the sensitivity of the moving average.

Adaptive Moving Average

Once the efficiency ratio is determined, the indicator uses this information to adjust the moving average dynamically. This is where the term “adaptive” comes in—the moving average’s speed adjusts based on how volatile the market is.

For example:

  • In trending markets with high efficiency, the moving average reacts faster.
  • In sideways or choppy markets, the moving average slows down to reduce noise.

ATR-Based Channel

The next step involves calculating the ATR (Average True Range). The ATR measures the volatility of the market by looking at the range between the high and low prices of each period. The channel up and channel down lines are then plotted by adding and subtracting a multiple of the ATR to the adaptive moving average.

  • Channel up: This is the upper boundary of the channel, created by adding the ATR (multiplied by the input multiplier) to the adaptive moving average.
  • Channel down: This is the lower boundary, created by subtracting the ATR from the adaptive moving average.
See also  Hybrid Vision FX Indicator (Non-Repaint) MetaTrader 5 Indicator

These channels visually represent the potential price range, helping traders see whether the price is within or outside of its typical volatility range.

Practical Application of Zephra Adaptive ATR

The Zephra Adaptive ATR can be useful in various market conditions. Since it adapts to both price trends and volatility, it offers flexibility for traders who need an indicator that adjusts with the market.

  • Trend identification: The adaptive moving average helps identify when the market is in a strong trend. If the price stays above the moving average and the channels are widening, it indicates a strong uptrend.
  • Volatility awareness: The ATR channels give traders an idea of the market’s volatility. When the price approaches or breaks through the upper or lower channel lines, it suggests that volatility is higher than normal.

Conclusion

The Zephra Adaptive ATR is a versatile indicator that combines the power of an adaptive moving average with the flexibility of ATR-based price channels. By adjusting to market conditions, it provides traders with a clearer view of both trend direction and potential volatility. This indicator isn’t a “one-size-fits-all” tool, but for those looking to understand both price movement and volatility in a single glance, it can be quite useful. The adaptability ensures that it doesn’t get bogged down in sideways markets, making it a reliable option for various trading styles.

Leave a Comment