Author: Copyright � 2005, john@fayandjohn.com
ICWR

Technical Logic Overview: ICWR Indicator

The ICWR indicator is a sophisticated visual analysis tool designed to identify significant structural movements in financial charts. Rather than simply drawing lines over every price fluctuation, it filters out "market noise" to highlight meaningful trends and automatically calculate key technical levels based on those movements.

Here is a breakdown of the logic used by this script:

1. Dynamic Structural Mapping

The script begins by scanning historical price data to identify significant "swing highs" and "swing lows." It does not consider every peak or valley as a valid point. Instead, it uses a multi-step filtering process:

  • Depth & Deviation: It looks back over a specific number of bars (the Depth) to find the lowest or highest points. It only marks a point if the price move is significant enough to meet the "Deviation" threshold.
  • Backstepping: To ensure the integrity of the trend line, the script performs a secondary check on preceding bars. If a new high or low is found, it automatically "cleans up" the immediate surrounding bars to ensure the transition between different price swings is smooth and logical.

2. Trend Verification (Zig-Zag Logic)

Once the raw highs and lows are identified, the script performs a "final cutting" process. This logic ensures that:

  • If a new high is established that is higher than the previous one, the old peak is discarded.
  • Conversely, if a lower high is reached before a new price target is met, it maintains the structural integrity of the current swing.
  • The script prevents "overlapping" signals by ensuring that a new high and a new low cannot be recorded simultaneously in a way that breaks the logical flow of the market trend.

3. Significant Wave Identification

Not every price move is considered a complete "wave." The script utilizes a Required Wave Height parameter (which automatically adjusts based on the timeframe you are viewing). This means:

  • Small, minor fluctuations are ignored.
  • The indicator only triggers a visual update when a price movement exceeds a specific distance from the previous major swing point.

4. Automated Visual Analytics

When a significant move (a "Wave") is confirmed, the script performs three automated actions on your chart:

  • Trend Line Drawing: It draws a solid red trend line connecting the start and end of the most recent significant wave.
  • Dynamic Fibonacci Retracement: It automatically places a green Fibonacci tool over that specific wave.
  • Key Level Calculation: The script calculates several key price levels (specifically 0.25, 0.382, 0.618, and 0.75) based on the height of that movement. These levels are used to help traders identify potential areas where the price might pull back or reverse.

Summary for the User

In simple terms, this script acts as an automated "trend scout." It watches the market, ignores the tiny ups and downs, and only pays attention when a large move happens. When it sees a big move, it draws a line showing you the direction of that move and places a Fibonacci tool on it to show you exactly where the most important mathematical "reversal zones" are located.

Indicators Used
Relative strength index
Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
ICWR
//+------------------------------------------------------------------+
//|                                                   ICWR indicator |
//|                                   Copyright © 2005, John Lotoski |
//|                                       mailto:john@fayandjohn.com |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, john@fayandjohn.com"
#property link      "mailto:john@fayandjohn.com"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Black


//---- indicator parameters
extern int ExtDepth=10;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
extern int RequiredWaveHeight=40;

//---- indicator buffers
double ExtMapBuffer[];
double ExtMapBuffer2[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   IndicatorBuffers(2);

//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
   
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexEmptyValue(0,0.0);
   ArraySetAsSeries(ExtMapBuffer,true);
   ArraySetAsSeries(ExtMapBuffer2,true);
   
//---- indicator short name
   IndicatorShortName("ICWR("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");

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

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+

int deinit()                           // Removes all lines and text
{                                      // from the chart upon removal
                                       // of the indicator
   ObjectDelete("ActiveWave");
   ObjectDelete("Fibo");
   return(0);
}

//+------------------------------------------------------------------+
//| Main function                                                    |
//+------------------------------------------------------------------+
int start()
{
   if(Period()==5) {RequiredWaveHeight=40;}
   if(Period()==240) {RequiredWaveHeight=150;}
   int    shift,back,lasthighpos,lastlowpos,LastActivePos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow,LastActive;
   
   int AWStartPos, AWEndPos;
   double AWStart, AWEnd;
   
   double FiboL, FiboH, FiboLC, FiboLR, FiboHR, FiboHC;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
   {
                                       // The beginning code of this for loop is dedicated
                                       // to finding a low endpoint of a zig-zag
      val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,shift)];
                                       // Start at beginning of data
                                       // - Get low of last depth (12) periods
                                       // - Repeat low search of 12 periods,
                                       //   advancing 1 bar every search (for loop)
      
      if(val==lastlow)                 // If this is not a new low
         val=0.0;                      // - Reset the val marker to dbl 0
      
      else                             // Otherwise, if it is a new low
      { 
         lastlow=val;                  // - Record this new low in lastlow for future reference
         if((Low[shift]-val)>(ExtDeviation*Point)) 
            val=0.0;                   // If the low of the current bar is 6 or
                                       // more pips greater than the lowest low of the last
                                       // depth (12) periods, then reset val to dbl 0.
                                       // Ie: continue the zig because the line is going up
         
         else                          // Otherwise, if the current low is within 6 pips
         {                             // of the lowest low of the last 12 bars
            for(back=1; back<=ExtBackstep; back++)
            {                          // Check back 3 bars, and if each value over those
                                       // three bars is greater than the current lowest low,
                                       // then reset the map buffer value to 0 because
                                       // we have a new lower low.
               res=ExtMapBuffer[shift+back];
               if((res!=0)&&(res>val)) 
                  ExtMapBuffer[shift+back]=0.0; 
            }
         }
      } 

      ExtMapBuffer[shift]=val;         // Set our current bar to 0 (continuation of zig) if:
                                       //    - A new low has not been reached;
                                       //    - The current bar is 6 pips beyond the lowest low
                                       // Set our current bar to the lowest low if:
                                       //    - It is within 6 pips of the lowest low and
                                       //      and go back over the last three bars and set them
                                       //      to continuation of zig as well if they are greater
                                       //      than the new lowest value
      
      
                                       // Same deal for below, except the case is reversed
                                       // and everything is done in terms of trying to find
                                       // the high zig-zag endpoint
      val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)];

      if(val==lasthigh) 
         val=0.0;
      else 
      {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) 
            val=0.0;
         else
         {
            for(back=1; back<=ExtBackstep; back++)
            {
               res=ExtMapBuffer2[shift+back];
               if((res!=0)&&(res<val)) 
                  ExtMapBuffer2[shift+back]=0.0; 
            } 
         }
      }
      ExtMapBuffer2[shift]=val;
   }

   // final cutting 
   lasthigh=-1; 
   lasthighpos=-1;
   lastlow=-1;  
   lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
   {
      curlow=ExtMapBuffer[shift];
      curhigh=ExtMapBuffer2[shift];
      
      if((curlow==0)&&(curhigh==0))    // Break into the next cycle of the loop
         continue;                     // to try and find the next zig-zap endpoint
      
      if(curhigh!=0)                   // If there is a current high, then:
      {
         if(lasthigh>0)                   // If there was a previous high already:
         {
            if(lasthigh<curhigh)          //    - Set the last high to 0 if it is less than the current high
               ExtMapBuffer2[lasthighpos]=0;
            else                          //    - Set the current bar to 0 if it is less than the last high
               ExtMapBuffer2[shift]=0;
         }
         
         if(lasthigh<curhigh || lasthigh<0)
         {                             // If there was no last high or the last high was less than the current high
            lasthigh=curhigh;          //    - Set the current high to be the last high (keep record of it)
            lasthighpos=shift;         //    - Set the current bar to the lasthighpos (keep record of it)
         }
         lastlow=-1;                   // Since we just had a new high, reset the lastlow flag
      }

      if(curlow!=0)                    // If there is a low, then do the same as above, except for the case of lows instead of highs
      {
         if(lastlow>0)
         {
            if(lastlow>curlow) 
               ExtMapBuffer[lastlowpos]=0;
            else 
               ExtMapBuffer[shift]=0;
         }

         if((curlow<lastlow)||(lastlow<0))
         {
            lastlow=curlow;
            lastlowpos=shift;
         } 
         lasthigh=-1;
      }
   }
  
   for(shift=Bars-1; shift>=0; shift--)
   {                                   // Go through all the bars
      if(shift>=Bars-ExtDepth)         // If we are not at the beginning comparison bars,
         ExtMapBuffer[shift]=0.0;      //    then set the low buffer to 0
      else
      {                                // Otherwise:
         res=ExtMapBuffer2[shift];     //    - If the current bar has a high, set the low
         if(res!=0.0)                  //      buffer to contain the high
            ExtMapBuffer[shift]=res;
      }                                // Looks like this function brings the highs into the lows
   }                                   // so that all the zig-zags can be drawn from one function

   LastActive = -1;
   LastActivePos = -1;
      
   for(shift=0; shift<=Bars-ExtDepth; shift++)
   {
      if(ExtMapBuffer[shift]!=0.0)
      {
         if(LastActive > 0)
         {
            if(MathAbs(LastActive - ExtMapBuffer[shift]) >= RequiredWaveHeight*Point)
            {
               AWStartPos = shift;
               AWStart = ExtMapBuffer[shift];
               AWEndPos = LastActivePos;
               AWEnd = LastActive;

               if(ObjectFind("ActiveWave") != 0)
               {
                  ObjectCreate("ActiveWave", OBJ_TREND, 0, Time[AWStartPos], AWStart, Time[AWEndPos], AWEnd);
                  ObjectSet("ActiveWave", OBJPROP_STYLE, STYLE_SOLID);
                  ObjectSet("ActiveWave", OBJPROP_COLOR, Red);               
                  ObjectSet("ActiveWave", OBJPROP_WIDTH, 3);
                  ObjectSet("ActiveWave", OBJPROP_RAY, false);  
               }
               else
               {
                  ObjectMove("ActiveWave", 0, Time[AWStartPos], AWStart);
                  ObjectMove("ActiveWave", 1, Time[AWEndPos], AWEnd);
               }
            
               if(AWStart < AWEnd)
               {
                  FiboL = AWStart;
                  FiboH = AWEnd;
               }
               else
               {
                  FiboL = AWEnd;
                  FiboH = AWStart;
               }
               
               FiboLC = FiboL + (FiboH - FiboL)*0.25;
               FiboLR = FiboL + (FiboH - FiboL)*0.382;
               FiboHR = FiboL + (FiboH - FiboL)*0.618;
               FiboHC = FiboL + (FiboH - FiboL)*0.75;
            
            
               if(ObjectFind("Fibo") != 0)
               {
                  ObjectCreate("Fibo", OBJ_FIBO, 0, Time[AWStartPos], AWStart, Time[AWEndPos], AWEnd);
                  ObjectSet("Fibo", OBJPROP_STYLE, STYLE_SOLID);
                  ObjectSet("Fibo", OBJPROP_COLOR, Green);               
                  ObjectSet("Fibo", OBJPROP_WIDTH, 2);
                  ObjectSet("Fibo", OBJPROP_FIBOLEVELS, 6);
/*                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+0, FiboL);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+1, FiboLC);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+2, FiboLR);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+3, FiboHR);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+4, FiboHC);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+6, FiboH); */
                  
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+0, 0);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+1, 0.25);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+2, 0.382);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+3, 0.618);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+4, 0.75);
                  ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+5, 1);
               }
               else
               {
                  ObjectMove("Fibo", 0, Time[AWStartPos], AWStart);
                  ObjectMove("Fibo", 1, Time[AWEndPos], AWEnd);
               }
               break;
            }
         }
         LastActive = ExtMapBuffer[shift];
         LastActivePos = shift;
      }
   }
/*double rsi=iRSI(Symbol(),1440,14,PRICE_CLOSE,0);
Comment("Daily RSI= ",rsi);*/
}

Comments