FX_FISH_2MA_v2

Author: Copyright � 2005, Kiko Segui
FX_FISH_2MA_v2

This script is a technical analysis indicator designed for the MetaTrader platform to help traders identify potential trend directions and momentum shifts in financial markets. It combines custom mathematical modeling with classic moving average smoothing to provide visual cues on price action.

Core Logic Overview

The primary function of the script is to calculate a specialized "momentum oscillator" (referred to in the code as the "Fish" value). Instead of simply looking at current price, it evaluates where the current price sits relative to the recent high and low extremes within a specific timeframe.

By measuring this relative position and applying a logarithmic smoothing formula, the script generates a dynamic value that oscillates above and below a zero baseline. This helps in identifying whether the market is currently leaning toward an aggressive upward move or a downward move.

Key Components & Visuals

The indicator produces several distinct visual elements on your chart:

  • Trend Histograms: The script uses colored bars (SteelBlue and Orange) to represent positive and negative momentum. These provide an immediate visual sense of the "strength" of the current price movement.
  • Moving Average Overlay: It calculates two different types of moving averages based on the smoothed momentum data. These lines act as a secondary filter, helping to confirm that a trend has sufficient stability before acting on it.
  • Dynamic Price Reference: The logic can be customized to calculate its primary data point from various sources, such as the standard closing price, the opening price, or a balanced average of the high and low points of a candle.

Signal Generation

The script is designed to identify specific "turning points" based on three main conditions:

  1. Buy Signals: When the momentum value exceeds a specific strength threshold and shows a distinct upward curvature (meaning it is moving faster than its previous trends), the script identifies a potential entry point for a long position.
  2. Sell Signals: Conversely, when momentum drops below a negative threshold and shows an accelerating downward curve, the script flags a potential entry for a short position.
  3. Exit Cues: The logic also monitors for "momentum exhaustion." If the momentum value flips from positive to negative (or vice versa), it suggests that the current move may be losing steam, providing a visual prompt to consider exiting an existing trade.

Summary for the User

In plain terms, this tool acts as a "momentum filter." It looks at how hard the market is pushing in one direction compared to its recent history. When that push becomes exceptionally strong and consistent, it marks a potential signal; when that push starts to weaken or reverse, it provides an exit warning. By layering moving averages over these signals, it aims to reduce "noise" and help traders focus on sustained market trends.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
7 Views
0 Downloads
0 Favorites
FX_FISH_2MA_v2
//+------------------------------------------------------------------+
//|                 FX_FISH_2MA                                      |
//|                 Copyright © 1999-2007, MetaQuotes Software Corp. |
//|                 http://www.metaquotes.ru                         |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Kiko Segui"
#property link      "webtecnic@terra.es"
//----
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 SteelBlue
#property indicator_color2 Orange
#property indicator_color3 Black
#property indicator_color4 Blue
#property indicator_color5 Red
//----
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,1,SteelBlue);
   SetIndexBuffer(0,buffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,1,Orange);
   SetIndexBuffer(1,buffer2);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexLabel(2,"line");
   SetIndexBuffer(2,buffer3);
   SetIndexStyle(3,DRAW_LINE);
   SetIndexLabel(3,"MA1 "+MA1period);
   SetIndexStyle(4,DRAW_LINE);
   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