aNina_v1m

This script is a technical analysis tool designed to identify potential trading opportunities by analyzing price volatility and trend direction relative to moving averages. It generates visual signals on your chart to help navigate market momentum.

Core Logic Overview

The logic operates by calculating the "energy" or range of price movement over a specific period. Instead of just looking at where the price is, it evaluates how much the price has fluctuated and identifies whether that volatility suggests a sustained trend or a temporary fluctuation.

1. Volatility Analysis (The Foundation)

The script first calculates a dynamic range based on the highest highs and lowest lows over a user-defined window. It creates three distinct "levels" of market sentiment:

  • Minimum Range: Represents conservative price movement.
  • Maximum Range: Represents high-volatility price movement.
  • Mid Range: The average balance between the two.

2. Trend Identification

The script uses these ranges to determine the current "Trend State." It compares current closing prices against calculated boundaries. By tracking whether the price is consistently breaking through these volatility thresholds, it categorizes the market into bullish (upward), bearish (downward), or neutral states.

3. Signal Generation

The primary objective of the script is to identify specific "cross-over" moments where momentum shifts significantly. It looks for instances where the trend sentiment changes from one state to another.

  • Buy Signals: These are triggered when a bullish momentum shift occurs, specifically when the script detects that price movement is shifting toward the higher end of the volatility spectrum while remaining in a favorable position relative to a 50-period Exponential Moving Average (EMA).
  • Sell Signals: These are triggered when a bearish momentum shift occurs, identifying where the price is moving toward the lower end of the volatility spectrum, provided it aligns with the downward trajectory of the EMA.

4. Filter Mechanisms

To reduce "noise" and prevent false signals, the script employs two main filters:

  • The Moving Average Filter: It checks the distance between the current price and the 50-period EMA. A signal is considered "High Quality" only if the price is on the correct side of this average.
  • The Cross Confirmation: The script specifically looks for a mathematical "flip" (a cross-over) in the momentum buffers, ensuring that you are entering the trade at the point of transition rather than simply following an exhausted trend.

Visual Indicators

  • Arrows: The script places visual markers (arrows) on the chart to highlight where the logic identifies a potential entry or exit point.
  • Trend Lines: It maps out the calculated momentum levels in a separate window, allowing you to see the "flow" of the market volatility independently of the price candles.
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
aNina_v1m
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Green
#property indicator_color4 DeepSkyBlue
#property indicator_color5 Yellow

#property indicator_minimum 0
#property indicator_maximum 1
//---- input parameters
extern int PeriodWATR=10;
extern double Kwatr=1.0000;
extern int HighLow=0;
extern int cbars = 0;
extern int from  = 0;
extern int maP  = 50;

#property indicator_width1 1
#property indicator_width2 0
#property indicator_width3 0
#property indicator_width4 1

//---- indicator buffers
double LineMinBuffer[];
double LineMidBuffer[];
double LineBuyBuffer[];
double LineSellBuffer[];
double LineExitBuffer[];
double Ma50[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
  int init()
  {
   string short_name;
   IndicatorBuffers(6);
//---- indicator line
   SetIndexStyle(4,DRAW_LINE);
   SetIndexStyle(3,DRAW_LINE);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexStyle(0,DRAW_ARROW);
   
   SetIndexStyle(5,DRAW_NONE);
   SetIndexEmptyValue(5,0);
   
   SetIndexEmptyValue(2,0);
   SetIndexArrow(2,233);
   SetIndexEmptyValue(3,0);
   SetIndexArrow(1,234);
   SetIndexEmptyValue(4,0);
   SetIndexArrow(0,252);//159 174
  
   
   SetIndexBuffer(4,LineMinBuffer);
   SetIndexBuffer(3,LineMidBuffer);
   SetIndexBuffer(2,LineBuyBuffer);
   SetIndexBuffer(1,LineSellBuffer);
   SetIndexBuffer(0,LineExitBuffer);
   SetIndexBuffer(5,Ma50);

   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
   short_name="Nina ("+PeriodWATR+", "+DoubleToStr(Kwatr,4)+", "+HighLow+")";
   IndicatorShortName(short_name);
//----
   SetIndexDrawBegin(0,PeriodWATR);
   SetIndexDrawBegin(1,PeriodWATR);

//----
   return(0);
  }

int last_update = 0;
int last = 0;

int start(){
   if(last==Bars) return (0);
   last = Bars;

   int limit = cbars;
   
   if(limit==0 || limit>Bars) limit = Bars;
   //last_update = Bars;
      
   int      i,shift,TrendMin,TrendMax,TrendMid;
   double   SminMin0,SmaxMin0,SminMin1,SmaxMin1,SumRange,dK,WATR0,WATRmax,WATRmin,WATRmid;
   double   SminMax0,SmaxMax0,SminMax1,SmaxMax1,SminMid0,SmaxMid0,SminMid1,SmaxMid1;
   double   linemin,linemax,linemid,Stoch1,Stoch2,bsmin,bsmax;
   	
   int StepSizeMin,StepSizeMax,StepSizeMid;
   double min,max,mid,h,l,c;
   	
   int b = 0;	
   int last = 0,ma = 0,last_ma = 0;
   //ArrayInitialize(Ma50,0);
   //ArrayInitialize(LineBuyBuffer,0);
   //ArrayInitialize(LineSellBuffer,0);
   Print(limit);
   
   for(shift=limit-1;shift>=from;shift--){	
	  SumRange=0;
	  for (i=PeriodWATR-1;i>=from;i--){ 
         dK = 1+1.0*(PeriodWATR-i)/PeriodWATR;
         SumRange+= dK*MathAbs(High[i+shift]-Low[i+shift]);
         }
	  WATR0 = SumRange/PeriodWATR;
	
	  WATRmax=MathMax(WATR0,WATRmax);
	  if (shift==limit-1-PeriodWATR) WATRmin=WATR0;
	  WATRmin=MathMin(WATR0,WATRmin);
	
	  StepSizeMin=MathRound(Kwatr*WATRmin/Point);
	  StepSizeMax=MathRound(Kwatr*WATRmax/Point);
	  StepSizeMid=MathRound(Kwatr*0.5*(WATRmax+WATRmin)/Point);
	  
     min = Kwatr*WATRmin;
     max = Kwatr*WATRmax;
     mid = Kwatr*0.5*(WATRmax+WATRmin);
	  
	  //b = iBarShift(Symbol(),tPeriod,Time[shift]);
	  c = Close[shift];//iClose(Symbol(),tPeriod,b);
	  h = High[shift];//iHigh(Symbol(),tPeriod,b)
	  l = Low[shift];//iLow(Symbol(),tPeriod,b)
	  
	  if (HighLow>0){
	    SmaxMin0=l+2*min;
	    SminMin0=h-2*min;
	  
	    SmaxMax0=l+2*max;
	    SminMax0=h-2*max;
	  
	    SmaxMid0=l+2*mid;
	    SminMid0=h-2*mid;
	  
	    if(c>SmaxMin1) TrendMin=1; 
	    if(c<SminMin1) TrendMin=-1;
	  
	    if(c>SmaxMax1) TrendMax=1; 
	    if(c<SminMax1) TrendMax=-1;
	  
	    if(c>SmaxMid1) TrendMid=1; 
	    if(c<SminMid1) TrendMid=-1;
	    }
	 
	  if (HighLow == 0){
	    SmaxMin0=c+2*min;
	    SminMin0=c-2*min;
	  
	    SmaxMax0=c+2*max;
	    SminMax0=c-2*max;
	  
	    SmaxMid0=c+2*mid;
	    SminMid0=c-2*mid;
	  
	    if(c>SmaxMin1) TrendMin=1; 
	    if(c<SminMin1) TrendMin=-1;
	  
	    if(c>SmaxMax1) TrendMax=1; 
	    if(c<SminMax1) TrendMax=-1;
	  
	    if(c>SmaxMid1) TrendMid=1; 
	    if(c<SminMid1) TrendMid=-1;
	    }
	 	
	  if(TrendMin>0 && SminMin0<SminMin1) SminMin0=SminMin1;
	  if(TrendMin<0 && SmaxMin0>SmaxMin1) SmaxMin0=SmaxMin1;
		
	  if(TrendMax>0 && SminMax0<SminMax1) SminMax0=SminMax1;
	  if(TrendMax<0 && SmaxMax0>SmaxMax1) SmaxMax0=SmaxMax1;
	  
	  if(TrendMid>0 && SminMid0<SminMid1) SminMid0=SminMid1;
	  if(TrendMid<0 && SmaxMid0>SmaxMid1) SmaxMid0=SmaxMid1;
	  
	  
	  if (TrendMin>0) linemin=SminMin0+min;
	  if (TrendMin<0) linemin=SmaxMin0-min;
	  
	  if (TrendMax>0) linemax=SminMax0+max;
	  if (TrendMax<0) linemax=SmaxMax0-max;
	  
	  if (TrendMid>0) linemid=SminMid0+mid;
	  if (TrendMid<0) linemid=SmaxMid0-mid;
	  
	  bsmin=linemax-max;
	  bsmax=linemax+max;
	  Stoch1=(linemin-bsmin)/(bsmax-bsmin);
	  Stoch2=(linemid-bsmin)/(bsmax-bsmin);
	  
	  LineMinBuffer[shift]=Stoch1;
	  LineMidBuffer[shift]=Stoch2;
	  
	  
	  SminMin1=SminMin0;
	  SmaxMin1=SmaxMin0;
	  
	  SminMax1=SminMax0;
	  SmaxMax1=SmaxMax0;
	  
	  SminMid1=SminMid0;
	  SmaxMid1=SmaxMid0;

     Ma50[shift] = iMA(NULL,0,50,0,MODE_EMA,PRICE_CLOSE,shift);
     if(is_inside(shift)) last_ma = shift;
     
	  if(
	     is_cross(shift)
	     ){
	     last = 0;
	     LineExitBuffer[shift] = LineMidBuffer[shift];   
	     // BUY or SELL
        if(LineMinBuffer[shift]-LineMidBuffer[shift]>0){
            if(/*last_ma == shift || */(last_ma!=0 && Ma50[last_ma]-Open[shift]<0)){
               // VERY GOOD SIGNAL - BEST TRADE
               LineBuyBuffer[shift] = LineMinBuffer[shift]+0.1;
	            if(last_ma == shift && MathAbs(Ma50[last_ma]-Open[shift])/Point < 20) LineExitBuffer[shift] = LineMidBuffer[shift];
               }
            else if(last_ma!=0){
               last = shift;
               }
            }
        else if(LineMinBuffer[shift]-LineMidBuffer[shift]<0){
            if(/*last_ma == shift || */(last_ma!=0 && Ma50[last_ma]-Open[shift]>0)){
               // VERY GOOD SIGNAL - BEST TRADE
               LineSellBuffer[shift] = LineMinBuffer[shift]-0.1;
	            if(last_ma == shift && MathAbs(Ma50[last_ma]-Open[shift])/Point < 20) LineExitBuffer[shift] = LineMinBuffer[shift];
               }
            else if(last_ma!=0){
               last = -shift;
               }
            } 
	     }
	   else{
	     if(last>0 && Open[shift]-Ma50[shift]>0/* && last_ma==shift+1*/){
	        LineBuyBuffer[shift] = LineMidBuffer[shift]-0.1;
	        last = 0;
	        }
	     else if(last<0 && Open[shift]-Ma50[shift]<0/* && last_ma==shift+1*/){
	        LineSellBuffer[shift] = LineMidBuffer[shift]+0.1;
	        last = 0;
	        }
	     }
	   }
	return(0);	
 }

bool is_inside(int shift){
   return (
      (Close[shift] - Ma50[shift])*(Open[shift] - Ma50[shift])<0
      //Ma50[shift]>MathMin(Close[shift],Open[shift]) && Ma50[shift]<MathMax(Close[shift],Open[shift])
      );
}

bool is_cross(int shift){
   return 
      (
      (LineMinBuffer[shift]-LineMidBuffer[shift])*(LineMinBuffer[shift+1]-LineMidBuffer[shift+1])<0 
      //|| (LineMinBuffer[shift+1]-LineMidBuffer[shift+1]==0 && LineMinBuffer[shift]-LineMidBuffer[shift]!=0)
      
      //(LineMinBuffer[shift+1]<=0.0 && LineMinBuffer[shift]==0.0 && LineMidBuffer[shift+1]==0.0 && LineMidBuffer[shift]>=0.0) ||
      //(LineMinBuffer[shift+1]==0.0 && LineMinBuffer[shift]<=0.0 && LineMidBuffer[shift+1]>=0.0 && LineMidBuffer[shift]==0.0) 
      );
}


Comments