Fisher_m11_002
Download scriptTechnical Overview: Fisher_m11 Indicator
The Fisher_m11 is a specialized technical analysis tool designed to help traders identify trend direction and momentum in financial markets. Instead of plotting price directly, this indicator converts market movements into a visual "oscillator" that distinguishes between upward and downward trends based on price location relative to recent volatility.
Core Logic and Methodology
The script operates by analyzing specific windows of time (defined by the RangePeriods setting) to determine where the current price sits within the recent high and low boundaries. The logic follows a multi-step transformation process:
- Relative Position Mapping: The tool identifies the highest high and lowest low over a set period. It then calculates where the current mid-price sits within that range. This result is normalized into a value between -1 and +1, effectively "mapping" the price location to a consistent scale regardless of how much the actual price moves.
- Double Smoothing: To prevent the indicator from reacting too wildly to minor market noise, the script applies two distinct layers of smoothing:
- Price Smoothing: This stabilizes the raw position data derived from the market's highs and lows.
- Index Smoothing: This further refines the final resulting "Fisher Index" to ensure a fluid transition between trend changes.
- Logarithmic Transformation: The script uses a logarithmic calculation on the smoothed location values. This mathematical approach is intended to accentuate trend acceleration, making it easier to see when momentum is strengthening or weakening.
Visual Representation
The indicator provides a clean, binary visual output in a separate window below the main price chart:
- Upward Trends: When the calculated index value is positive, the indicator displays a Lime (Green) histogram. This signals that the price momentum is currently leaning toward the upper end of the established range.
- Downward Trends: When the index value is negative, the indicator switches to a Red histogram, signaling that momentum is leaning toward the lower end of the range.
Key Parameters for Customization
Users can fine-tune the sensitivity of the tool using three primary inputs:
- Range Periods: Determines how far back the script looks to find the highest highs and lowest lows (the "look-back" window).
- Price Smoothing: Controls how much weight is given to new price data versus previous data during the initial mapping phase.
- Index Smoothing: Controls the final fluidity of the indicator's line, helping to filter out small fluctuations for a clearer trend view.
Summary for Traders
The Fisher_m11 is designed for traders who want to see "momentum trends" rather than just price action. By filtering out market noise through double smoothing and logarithmic scaling, it provides a clear visual signal: green for bullish momentum and red for bearish momentum, based on where the price currently resides within its recent volatility boundaries.
//+------------------------------------------------------------------+
//| 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 2
#property indicator_width3 2
int LeftNum1=56;
int LeftNum2=56;
extern int RangePeriods=10;
extern double PriceSmoothing=0.67; // =0.67 bei Fisher_m10
extern double IndexSmoothing=0.50; // =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