Variator

Technical Logic Overview: MA Variator Indicator

This script is designed to analyze price action by tracking the momentum and movement of a Moving Average (MA). Instead of simply plotting a standard moving average line, this tool identifies specific states of market activity—categorizing them into upward trends, downward trends, or neutral "flat" periods—and highlights potential transition points where these trends shift.

Core Analytical Logic

The indicator operates through three primary stages of calculation:

1. Moving Average Differentiation The script first calculates a standard Moving Average based on the closing prices of the market. However, it goes a step further by "differentiating" this data. In simple terms, it measures the change between consecutive moving average values to determine the velocity and direction of the trend rather than just the price level.

2. Trend Categorization (The Variator) By evaluating the rate of change over a specific window of time, the script classifies every market bar into one of three distinct states:

  • Upward Movement: Triggered when the moving average increases by a predefined amount. This suggests bullish momentum.
  • Downward Movement: Triggered when the moving average decreases by a predefined amount. This suggests bearish momentum.
  • Flat/Neutral: Occurs when the movement stays within a narrow range, indicating a lack of significant momentum or a consolidation phase.

The script then visually marks these states on your chart using specific indicators (arrows/points) to represent these three conditions clearly.

3. Transition Identification Beyond simply identifying trends, the logic includes a sophisticated "Inversion" check. It looks for specific price action signatures that occur during active trends:

  • Bearish Inversion: If the market is in an identified upward trend, the script monitors for a specific "cross" where the current candle closes higher than it opened, while the previous candle opened lower than it closed (or vice versa).
  • Bullish Inversion: Conversely, if the market is in a downward trend, it looks for the opposite price action behavior to identify a potential shift.

Summary of Functionality

Essentially, this tool acts as a momentum filter. It filters out "noise" by ignoring minor fluctuations and focuses on significant movements of the Moving Average. By categorizing the market into Up, Down, or Flat states and looking for specific candle behaviors within those states, it provides a visual map of where the trend is established and where the price action might be attempting to reverse.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
3 Views
0 Downloads
0 Favorites
Variator
//---- indicator settings
#property  indicator_chart_window
#property  indicator_buffers 4
#property  indicator_color1  White
#property  indicator_color2  Red
#property  indicator_color3  Blue
#property  indicator_color4  Violet

//---- indicator parameters
extern int ma_period=12;
extern int ma_method=MODE_SMA ;
extern int ma_varpip=2 ;
extern int ma_periodpip=4 ;

//---- indicator buffers
double VariatorFlat[] ;
double VariatorUp[] ;
double VariatorDown[] ;
double Trans[] ;

//Differentiate a buffer
void differentiate(double buff[], double& res[]) 
{
   ArrayResize(res, ArraySize(buff)) ;
   ArrayInitialize(res, 0) ;
   
   for(int var=0 ; var<ArraySize(buff)-1 ; var++)
   {
      res[var] = buff[var]-buff[var+1] ;
   }
}

//Compute variation on a buffer at index for period
double getVar(double buff[], int index, int period)
{
   double res=0 ;
   
   for(int i=index ; i<index+period && i<ArraySize(buff)-1 ; i++)
   {
      res += buff[i]-buff[i+1] ;
   }
   return(res) ;
}

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
//---- drawing settings
   SetIndexBuffer(0, VariatorFlat) ;
   SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 1) ;
   SetIndexEmptyValue(0, 0.0) ;
   
   SetIndexBuffer(1, VariatorUp) ;
   SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID, 1) ;
   SetIndexEmptyValue(1, 0.0) ;

   SetIndexBuffer(2, VariatorDown) ;
   SetIndexStyle(2, DRAW_ARROW, STYLE_SOLID, 1) ;
   SetIndexEmptyValue(2, 0.0) ;

   SetIndexBuffer(3, Trans) ;
   SetIndexStyle(3, DRAW_ARROW, STYLE_SOLID, 3) ;

//---- indicator buffers mapping

//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("MA variator") ;
   SetIndexLabel(0, "MA variator") ;

//---- initialization done

   return(0) ;   
}

//+------------------------------------------------------------------+
//| Moving Averages variation                                        |
//+------------------------------------------------------------------+
int start()
{
   double maclose[] ;
   double madiff[] ;
   double vopen[] ;
   double vclose[] ;
   
   double pipval ;
   static int value=0 ;

   int limit ;
   int counted_bars ;
   
   if(Bars<=ma_period+ma_periodpip) 
      return(0) ;
   counted_bars = IndicatorCounted() ;
   if(counted_bars>0) 
      counted_bars-- ;
   limit = Bars-counted_bars ;

   //----------------------------------------------------------
   //Création des buffers
   ArrayResize(maclose, ArraySize(VariatorUp)) ;
   ArrayInitialize(maclose, 0) ;
   ArrayResize(madiff, ArraySize(VariatorUp)) ;
   ArrayInitialize(madiff, 0) ;
   
   for(int i=0 ; i<limit ; i++)
      maclose[i] = iMA(NULL, 0, ma_period, 0, ma_method, PRICE_CLOSE, i) ;
   differentiate(maclose, madiff) ;

   ArrayCopySeries(vopen, MODE_OPEN) ;
   ArrayCopySeries(vclose, MODE_CLOSE) ;
 
   
   //----------------------------------------------------------
   //Compute indicator
   i = Bars-counted_bars-1 ;
   while(i>=0)
   {
      double var ;
      int v=0 ;
         
      //MA variator
      var = getVar(maclose, i, ma_periodpip) ;
      if(var>=Point*ma_varpip)
      {
         v = 1 ;
         VariatorUp[i] = maclose[i] ;
         VariatorFlat[i] = 0 ;
         VariatorDown[i] = 0 ;
      }   
      else if(var<=-Point*ma_varpip)
      {
         v = 2 ;
         VariatorUp[i] = 0 ;
         VariatorFlat[i] = 0 ;
         VariatorDown[i] = maclose[i] ;
      }   
      else
      {
         v = 0 ;
         VariatorUp[i] = 0 ;
         VariatorFlat[i] = maclose[i] ;
         VariatorDown[i] = 0 ;
      }      
      
      //Inversion indicator
      if(VariatorUp[i]!=0)
      {
         if(vopen[i]>vclose[i] && vopen[i+1]<vclose[i+1])
         {
            Trans[i] = vclose[i] ;
         }
         else
         {
            Trans[i] = 0 ;
         }      
      }
      else if(VariatorDown[i]!=0)
      {
         if(vopen[i]<vclose[i] && vopen[i+1]>vclose[i+1])
         {
            Trans[i] = vclose[i] ;
         }
         else
         {
            Trans[i] = 0 ;
         }      
      }
      else
      {
         Trans[i] = 0 ;
      }      
            
      i-- ;
   }
 
//   value++ ;
//   Print(value, " ", Symbol(), " ", Period()) ;
   Print(VariatorUp[0], " ", VariatorFlat[0], " ", VariatorDown[0]) ;
   return(0);
  }
//+------------------------------------------------------------------+

Comments