FX_FISH_2MA
Download scriptThis indicator is designed to provide visual analysis of market momentum and price trends by combining a custom mathematical oscillator with moving averages. It focuses on identifying specific "turning points" where the market sentiment shifts from one direction to another.
Core Logic and Calculations
1. The Momentum Oscillator (The "Fish") The primary logic of the script revolves around a proprietary calculation that measures price position relative to its recent highs and lows over a specific period.
- Relative Position: The script first identifies the highest high and lowest low within a set timeframe. It then calculates where the current price sits within that range.
- Smoothing: This relative position is processed through a weighted formula to create a normalized value.
- Logarithmic Transformation: To make the data more readable and responsive, the script applies a logarithmic calculation to this value. This results in an oscillator (referred to as "Fish" in the logic) that fluctuates above and below a zero line, representing upward or downward momentum.
2. Moving Averages (The Trend Filters) While the oscillator handles short-term sentiment, the script also calculates two distinct moving averages:
- Primary Average (MA1): This is calculated based on the "Fish" values to smooth out the initial oscillator data.
- Secondary Average (MA2): This is a "moving average of a moving average." By calculating a second average based on the first one, the script creates a much smoother trend line that filters out market noise and highlights the broader price direction.
Visual Outputs and Signals
The indicator displays several components simultaneously to help a trader visualize the market:
- Histogram: The oscillator values are plotted as a histogram. When the value is positive, it appears in one color; when negative, it switches to another, providing an immediate visual cue of momentum shifts.
- Trend Lines: The script draws two lines on the chart representing the primary and secondary moving averages, allowing you to see the "flow" of the trend.
- Automated Labels: If enabled in the settings, the script identifies three specific types of events directly on the chart:
- Buy Signals: Triggered when the oscillator exceeds a specific momentum threshold while simultaneously showing a downward curve in its previous movement.
- Sell Signals: Triggered when the oscillator drops below a negative threshold while showing an upward curve in its previous movement.
- Exit Points: These appear when the momentum switches polarity (e.g., moving from positive to negative), suggesting that a trend may be losing steam and it might be time to close a position.
Summary for the User
In simple terms, this tool looks at where the price is currently "living" compared to its recent history. It converts that position into a momentum score (the Fish). It then smooths that score twice to create clear trend lines. By watching where the histogram crosses certain levels and where the labels appear, you can identify potential areas of high momentum or exhaustion.
// FX_FISH_2MA
#property copyright "Copyright © 2005, Kiko Segui"
#property link "webtecnic@terra.es"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 MidnightBlue
#property indicator_color2 Maroon
#property indicator_color3 Red
#property indicator_color4 Lime
#property indicator_color5 White
double buffer1[];
double buffer2[];
double buffer3[];
double MA1buffer[];
double MA2buffer[];
extern int period=10;
extern int price=0; // 0 or other = (H+L)/2
// 1 = Open
// 2 = Close
// 3 = High
// 4 = Low
// 5 = (H+L+C)/3
// 6 = (O+C+H+L)/4
// 7 = (O+C)/2
extern bool Mode_Fast= False;
extern bool Signals= False;
extern int MA1period=9, MA2period=45;
extern string TypeHelp = "SMA- 0, EMA - 1, SMMA - 2, LWMA- 3";
extern string TypeHelp2 = "John Hyden settings TypeMA1=0, TypeMA2=3";
extern int TypeMA1=0;
extern int TypeMA2=3;
int init()
{
SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,4);
SetIndexBuffer(0,buffer1);
SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,4);
SetIndexBuffer(1,buffer2);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2);
SetIndexLabel(2,"line");
SetIndexBuffer(2,buffer3);
SetIndexStyle(3,DRAW_LINE);
SetIndexLabel(3,"MA1 "+MA1period);
SetIndexStyle(4,DRAW_LINE,STYLE_DOT);
SetIndexLabel(4,"MA2 "+MA2period);
SetIndexBuffer(3,MA1buffer);
SetIndexBuffer(4,MA2buffer);
return(0);
}
int deinit()
{
int i;
double tmp;
for (i=0;i<Bars;i++)
{
ObjectDelete("SELL SIGNAL: "+DoubleToStr(i,0));
ObjectDelete("BUY SIGNAL: "+DoubleToStr(i,0));
ObjectDelete("EXIT: "+DoubleToStr(i,0));
}
return(0);
}
double Value=0,Value1=0,Value2=0,Fish=0,Fish1=0,Fish2=0;
int buy=0,sell=0;
int start()
{
int counted_bars=IndicatorCounted();
int i;
int barras;
double _price;
double tmp;
double MinL=0;
double MaxH=0;
double Threshold=1.2;
if(counted_bars>0) counted_bars--;
//barras = Bars;ç
barras = Bars-counted_bars;
if (Mode_Fast)
barras = 100;
i = 0;
while(i<barras)
{
MaxH = High[Highest(NULL,0,MODE_HIGH,period,i)];
MinL = Low[Lowest(NULL,0,MODE_LOW,period,i)];
switch (price)
{
case 1: _price = Open[i]; break;
case 2: _price = Close[i]; break;
case 3: _price = High[i]; break;
case 4: _price = Low[i]; break;
case 5: _price = (High[i]+Low[i]+Close[i])/3; break;
case 6: _price = (Open[i]+High[i]+Low[i]+Close[i])/4; break;
case 7: _price = (Open[i]+Close[i])/2; break;
default: _price = (High[i]+Low[i])/2; break;
}
Value = 0.33*2*((_price-MinL)/(MaxH-MinL)-0.5) + 0.67*Value1;
Value=MathMin(MathMax(Value,-0.999),0.999);
Fish = 0.5*MathLog((1+Value)/(1-Value))+0.5*Fish1;
buffer1[i]= 0;
buffer2[i]= 0;
if ( (Fish<0) && (Fish1>0))
{
if (Signals)
{
ObjectCreate("EXIT: "+DoubleToStr(i,0),OBJ_TEXT,0,Time[i],_price);
ObjectSetText("EXIT: "+DoubleToStr(i,0),"EXIT AT "+DoubleToStr(_price,4),7,"Arial",White);
}
buy = 0;
}
if ((Fish>0) && (Fish1<0))
{
if (Signals)
{
ObjectCreate("EXIT: "+DoubleToStr(i,0),OBJ_TEXT,0,Time[i],_price);
ObjectSetText("EXIT: "+DoubleToStr(i,0),"EXIT AT "+DoubleToStr(_price,4),7,"Arial",White);
}
sell = 0;
}
if (Fish>=0)
{
buffer1[i] = Fish;
buffer3[i]= Fish;
}
else
{
buffer2[i] = Fish;
buffer3[i]= Fish;
}
tmp = i;
if ((Fish<-Threshold) &&
(Fish>Fish1) &&
(Fish1<=Fish2))
{
if (Signals)
{
ObjectCreate("SELL SIGNAL: "+DoubleToStr(i,0),OBJ_TEXT,0,Time[i],_price);
ObjectSetText("SELL SIGNAL: "+DoubleToStr(i,0),"SELL AT "+DoubleToStr(_price,4),7,"Arial",Red);
}
sell = 1;
}
if ((Fish>Threshold) &&
(Fish<Fish1) &&
(Fish1>=Fish2))
{
if (Signals)
{
ObjectCreate("BUY SIGNAL: "+DoubleToStr(i,0),OBJ_TEXT,0,Time[i],_price);
ObjectSetText("BUY SIGNAL: "+DoubleToStr(i,0),"BUY AT "+DoubleToStr(_price,4),7,"Arial",Lime);
}
buy=1;
}
Value1 = Value;
Fish2 = Fish1;
Fish1 = Fish;
i++;
}
for(i=0; i<barras; i++)
MA1buffer[i]=iMAOnArray(buffer3,Bars,MA1period,0,TypeMA1,i);
for(i=0; i<barras; i++)
MA2buffer[i]=iMAOnArray(MA1buffer,Bars,MA2period,0,TypeMA2,i);
return(0);
}
//+------------------------------------------------------------------+
Comments