The FX_FISH indicator is a technical analysis tool designed to help traders identify market momentum and potential reversal points by calculating price fluctuations relative to recent highs and lows. It functions as a visual oscillator, providing clear signals for entering or exiting trades based on the "strength" of the current price movement.
How the Logic Works
1. Price Selection and Normalization The script begins by analyzing the price action over a specific number of candles (the period). It determines the highest high and the lowest low within that timeframe to establish a range. It then selects a specific price point—such as the closing price, opening price, or an average of the high/low—to evaluate where the current market is sitting relative to that range.
2. Momentum Calculation The core logic transforms this relative position into a numerical value. By comparing the current price against the extremes (the highs and lows), the script calculates how "stretched" the market is. This raw value is then processed through a smoothing formula to prevent erratic jumps, ensuring that the resulting data flows smoothly rather than reacting violently to minor price flickers.
3. The "Fish" Oscillator To make the data easier to interpret for human traders, the script applies a logarithmic transformation to the smoothed values. This creates the "Fish" value, which is displayed in a separate window on your chart:
- Green (Lime) Histogram: Represents upward momentum or positive price pressure.
- Red Histogram: Represents downward momentum or negative price pressure.
Trading Signals and Visual Aids
The script doesn't just show a graph; it actively monitors for specific conditions to generate on-screen labels:
- Buy Signals: When the momentum pushes significantly high (exceeding a specific threshold) and begins to turn downward, the script identifies a peak and marks a "BUY" signal.
- Sell Signals: When the momentum drops significantly low and begins to turn upward, the script identifies a trough and marks a "SELL" signal.
- Exit Alerts: The logic also monitors for "crosses." If the indicator flips from positive to negative (or vice versa), it identifies a shift in trend strength and provides an "EXIT" label, suggesting that the previous move may have exhausted its energy.
Customization Options
The script allows for flexibility depending on your trading style:
- Speed: You can toggle a "Fast Mode" to limit the amount of historical data processed, making the indicator react more quickly to recent changes.
- Price Source: You can choose which specific price point (e.g., Close, Open, High, Low) the logic should base its calculations on.
- Visuals: Users can turn the on-screen text signals on or off depending on whether they prefer a clean chart or active alerts.
// FX_FISH
#property copyright "Copyright © 2005, Kiko Segui"
#property link "webtecnic@terra.es"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_level1 0
#property indicator_level2 0.30
#property indicator_level3 -0.30
double buffer1[];
double buffer2[];
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;
int init()
{
SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,2,Lime);
SetIndexBuffer(0,buffer1);
SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,2,Red);
SetIndexBuffer(1,buffer2);
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 i;
int barras;
double _price;
double tmp;
double MinL=0;
double MaxH=0;
double Threshold=1.2;
barras = 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;
}
else
{
buffer2[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++;
}
return(0);
}
//+------------------------------------------------------------------+
Comments