Author: Copyright � 23.07.2006 MartinG
Fisher_m11

This script is a specialized technical analysis tool designed to help traders visualize market momentum and trend direction. It processes historical price data to create a visual "Fisher" indicator, which highlights whether the current market sentiment is leaning toward an upward or downward move.

Core Logic and Workflow

The indicator operates by analyzing specific price movements over a defined timeframe (the "Range") and then applying a multi-layered smoothing process to filter out market noise. Here is the step-by-step logic:

1. Identifying Market Boundaries The script first looks back at a specific number of bars to identify the highest high and the lowest low within that period. By establishing these boundaries, it determines the "Greatest Range" of the current price action.

2. Calculating Relative Price Position Once the boundaries are known, the script finds the midpoint of the current price bar. It then calculates where this midpoint sits relative to the high and low of the range. This is converted into a numerical value:

  • A position near the top of the range results in a higher positive number.
  • A position near the bottom of the range results in a lower negative number.
  • This allows the script to see not just if the price is moving, but how "strongly" it is positioned within its recent history.

3. Dual-Layer Smoothing To prevent the indicator from reacting too wildly to minor, insignificant price flickers (market noise), the script applies two distinct layers of smoothing:

  • Price Smoothing: The initial relative position is blended with previous data points based on a user-defined factor. This ensures that a single erratic candle doesn't cause a massive jump in the indicator.
  • Index Smoothing: After the first calculation, the resulting "Fisher Index" undergoes a second round of smoothing. This creates a fluid, continuous line that clearly reveals the underlying trend.

4. Trend Identification and Visual Output The final step is the translation of these numbers into a visual histogram:

  • Upward Trend: If the final calculated value is positive (above zero), the script identifies an upward trend and displays a Lime-colored histogram.
  • Downward Trend: If the final value is negative (below zero), the script identifies a downward trend and displays a Red-colored histogram.

Summary for the User

In simple terms, this tool acts as a "momentum filter." It takes the raw movement of price, calculates where the price is sitting relative to its recent highs and lows, and smooths out the "jitter" of the market. The result is a clean visual cue: when the histogram is Lime, the momentum is technically bullish; when it is Red, the momentum is technically bearish.

Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
11 Views
0 Downloads
0 Favorites
Fisher_m11
//+------------------------------------------------------------------+
//|                                                   Fisher_m11.mq4 |
//|                                   Copyright © 23.07.2006 MartinG |
//|                                http://home.arcor.de/cam06/fisher |
//+------------------------------------------------------------------+
#property copyright "Copyright © 23.07.2006 MartinG"
#property link      "http://home.arcor.de/cam06/fisher"

#property indicator_separate_window
//#property indicator_minimum -1
//#property indicator_maximum 1
#property indicator_buffers 3
#property indicator_color2 Lime
#property indicator_color3 Red
#property indicator_width2 4
#property indicator_width3 4

int   LeftNum1=56;
int   LeftNum2=56;

extern int     RangePeriods=10;
extern double  PriceSmoothing=0.3;    // =0.67 bei Fisher_m10 
extern double  IndexSmoothing=0.3;    // =0.50 bei Fisher_m10

string         ThisName="Fisher_m11";
int            DrawStart;

//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(4);

   SetIndexLabel(0,"Fish");
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexStyle(3,DRAW_NONE);
   SetIndexBuffer(3,ExtMapBuffer4);

   string Text=ThisName;
   Text=Text+"  (rPeriods "+RangePeriods;
   Text=Text+", pSmooth "+DoubleToStr(PriceSmoothing,2);
   Text=Text+", iSmooth "+DoubleToStr(IndexSmoothing,2);
   Text=Text+")  ";
   IndicatorShortName(Text);
   
   SetIndexLabel(1,NULL);
   SetIndexLabel(2,NULL);

   
   DrawStart=2*RangePeriods+4;             // DrawStart= BarNumber calculated from left to right
   SetIndexDrawBegin(1,DrawStart);
   SetIndexDrawBegin(2,DrawStart);
   
   if (PriceSmoothing>=1.0)
      {
      PriceSmoothing=0.9999;
      Alert("Fish61: PriceSmothing factor has to be smaller 1!");
      }
   if (PriceSmoothing<0)
      {
      PriceSmoothing=0;
      Alert("Fish61: PriceSmothing factor mustn''t be negative!");
      }

   if (IndexSmoothing>=1.0)
      {
      IndexSmoothing=0.9999;
      Alert("Fish61: PriceSmothing factor has to be smaller 1!");
      }
   if (IndexSmoothing<0)
      {
      IndexSmoothing=0;
      Alert("Fish61: PriceSmothing factor mustn''t be negative!");
      }

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   if (Bars<DrawStart)
      {
      Alert("Fish84: Not enough Bars loaded to calculate FisherIndicator with RangePeriods=",RangePeriods);
      return(-1);
      }
//----   
   int    counted_bars=IndicatorCounted();
   if (counted_bars<0) return(-1);
   if (counted_bars>0) counted_bars--;
//----
   int Position=Bars-counted_bars;        // Position = BarPosition calculated from right to left
   int LeftNum1=Bars-Position;            // when more bars are loaded the Position of a bar changes but not its LeftNum
   if (LeftNum1<RangePeriods+1)Position=Bars-RangePeriods-1;
   
   while(Position>=0)
      {
      CalculateCurrentBar(Position); 
      Position--;
      }

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

//+------------------------------------------------------------------+
//| Single Bar Calculation function                                  |
//+------------------------------------------------------------------+
int CalculateCurrentBar(int pos)
  {
   double  LowestLow, HighestHigh, GreatestRange, MidPrice;
   double  PriceLocation, SmoothedLocation, FishIndex, SmoothedFish;
//----
   LowestLow = Low[Lowest(NULL,0,MODE_LOW,RangePeriods,pos)];
   HighestHigh = High[Highest(NULL,0,MODE_HIGH,RangePeriods,pos)];
   if (HighestHigh-LowestLow<0.1*Point)HighestHigh=LowestLow+0.1*Point;
   GreatestRange=HighestHigh-LowestLow;
   MidPrice = (High[pos]+Low[pos])/2;
   

// PriceLocation in current Range 
   if (GreatestRange!=0)
      {
      PriceLocation=(MidPrice-LowestLow)/GreatestRange;
      PriceLocation= 2.0*PriceLocation - 1.0;           // ->  -1 < PriceLocation < +1
      }
// Smoothing of PriceLocation
   ExtMapBuffer4[pos]=PriceSmoothing*ExtMapBuffer4[pos+1]+(1.0-PriceSmoothing)*PriceLocation;
   SmoothedLocation=ExtMapBuffer4[pos];
   if (SmoothedLocation> 0.99) SmoothedLocation= 0.99; // verhindert, dass MathLog unendlich wird
   if (SmoothedLocation<-0.99) SmoothedLocation=-0.99; // verhindert, dass MathLog minuns unendlich wird
   
   
// FisherIndex
   if(1-SmoothedLocation!=0) FishIndex=MathLog((1+SmoothedLocation)/(1-SmoothedLocation));
   else Alert("Fisher129: Unerlaubter Zustand bei Bar Nummer ",Bars-pos);

// Smoothing of FisherIndex
   ExtMapBuffer1[pos]=IndexSmoothing*ExtMapBuffer1[pos+1]+(1.0-IndexSmoothing)*FishIndex;
   if (Bars-pos<DrawStart)ExtMapBuffer1[pos]=0;
   SmoothedFish=ExtMapBuffer1[pos];
         

   if (SmoothedFish>0)     // up trend
      {
      ExtMapBuffer2[pos]=SmoothedFish;
      ExtMapBuffer3[pos]=0;
      }
   else                          // else down trend
      {
      ExtMapBuffer2[pos]=0;
      ExtMapBuffer3[pos]=SmoothedFish;
      }      
//----
   return(0);
  }


//+------------------------------------------------------------------+

Comments