FanSimple8

This script functions as a multi-timeframe technical analysis tool designed to track market trends and price positioning relative to specific moving averages. It provides a visual dashboard that synthesizes data from various timeframes simultaneously, allowing a user to see the "big picture" of the market's direction at a glance.

Core Functionality

Multi-Timeframe Trend Analysis The script monitors multiple timeframes (ranging from 1-minute charts up to weekly charts) concurrently. For each timeframe selected by the user, it calculates a series of Exponential Moving Averages (EMAs). It then analyzes these averages to determine the market's "Fan" status:

  • Upward Trend: When the moving averages are arranged in a specific ascending order.
  • Downward Trend: When the moving averages are arranged in a specific descending order.
  • Neutral/Mixed: When the averages are tangled or do not form a clear directional sequence.

Price Positioning Tracking In addition to trend direction, the script monitors the current market price relative to these moving averages. It identifies whether the price is currently trading above or below the average lines on each respective timeframe, providing an immediate visual cue of the price's location within the trend.

Dynamic Visual Dashboard Instead of just drawing lines on a chart, the script generates a text-based status board on the screen. This dashboard displays:

  • The current trend status for every active timeframe.
  • Symbols (such as arrows or circles) that indicate whether the price is currently "on" or "off" the moving averages.
  • Customizable colors and icons to make these signals easily distinguishable.

Live Tracking and Animation The script includes a sophisticated tracking system that allows users to monitor specific moments in time:

  • Time Tracking: Users can set a specific point in time, and the script will calculate the market status at that exact moment.
  • Sliding Mechanism: The indicator can "slide" with the live price action. As new candles form, the tracking point moves automatically, updating the dashboard in real-time to reflect the most current market conditions.
  • Audio Alerts: The script can be configured to play a specific sound effect whenever the tracking point moves or shifts, providing an audible notification of new data updates.

Summary for the User

This tool acts as a "command center" for your trading screen. Rather than forcing you to switch back and forth between different charts to see what is happening on the 1-hour, 4-hour, or Daily timeframes, it pulls all that data into one organized list. It tells you instantly which timeframes are trending up, which are trending down, and exactly where the price sits in relation to those trends at any given second.

Price Data Components
Series array that contains close prices for each bar
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It plays sound alerts
13 Views
0 Downloads
0 Favorites
FanSimple8
#include <stdlib.mqh>

/******************************************************************************/
#property indicator_chart_window

#property indicator_buffers 8

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/* Çäåñü ìîæíî èñïðàâèòü çíà÷åíèÿ, ýòè çíà÷åíèÿ èñïîëüçóþòñÿ ïî óìîë÷àíèþ ïðè ïîäêëþ÷åíèè èíäèêàòîðà */

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/* Öâåòà íàáîðà ñðåäíèõ (âñòàâ êóðñîðîì íà èìåíè öâåòà, íàæàòü F1 è óâèäåòü èìåíà îñòàëüíûõ öâåòîâ) */
#property indicator_color1 OrangeRed
#property indicator_color2 Orange
#property indicator_color3 Yellow
#property indicator_color4 DodgerBlue
#property indicator_color5 Aqua
#property indicator_color6 Magenta
#property indicator_color7 Gray
#property indicator_color8 White

/******************************************************************************
  Indicator parameters
*/

/* Îáùèé ðóáèëüíèê îòîáðàæåíèÿ ïðàâèëüíîñòè âååðà, ïîçâîëÿåò îòðóáèòü ðàçîì îòîáðàæåíèå íàáîðà âñåõ ïåðèîäîâ */
extern bool DisplayFanStatus = true;

/* Îáùèé ðóáèëüíèê îòîáðàæåíèÿ ñðåäíèõ, ïîçâîëÿåò îòðóáèòü ðàçîì îòîáðàæåíèå íàáîðà ñðåäíèõ */
extern bool DisplayFan = true;

/* Çíà÷åíèÿ ïåðèîäîâ íàáîðà timeframe'îâ â ïîðÿäêå ñëåäîâàíèÿ ñëåâà íàïðàâî (âîçìîæíû ïîâòîðåíèÿ, 0-âûå è íåïðàâèëüíûå çíà÷åíèÿ âêëþ÷åíû â íàáîð íå áóäóò) */
extern int Timeframe1 = PERIOD_M1;
extern int Timeframe2 = PERIOD_M5;
extern int Timeframe3 = PERIOD_M15;
extern int Timeframe4 = PERIOD_H1;
extern int Timeframe5 = PERIOD_H4;
extern int Timeframe6 = PERIOD_D1;
extern int Timeframe7 = PERIOD_W1;
extern int Timeframe8 = 0;
extern int Timeframe9 = 0;

/* Äàòà è âðåìÿ, äëÿ êîòîðîãî èíäèöèðóåòñÿ ïðàâèëüíîñòü âååðà */
extern datetime TrackingTime = 0;

/* Ðèñîâàòü ëè âåðòèêàëüíóþ ëèíèþ ÷åðåç îòñëåæèâàåìûé áàð */
extern bool Tracking = false;

/* Ñäâèãàåì ëè òî÷êó ñëåæåíèÿ ñ îáðàçîâíèåì ñëåäóùåãî áàðà */
extern bool Sliding = true;

/* Èìÿ ôàéëà çâóêà, âîñïðîèçâîäèìîãî ïðè ñäâèãå òî÷êè ñëåæåíèÿ */
extern string SlidingSound = "";

/* Çíà÷åíèÿ ïåðèîäîâ íàáîðà ñðåäíèõ, ñîñòàâëÿþùèõ âååð, ïðàâèëüíîñòü êîòîðîãî îòñëåæèâàåòñÿ (0-âûå è íåïðàâèëüíûå çíà÷åíèÿ âêëþ÷åíû â íàáîð íå áóäóò) */
extern int MA1 = 233;
extern int MA2 = 144;
extern int MA3 = 55;
extern int MA4 = 21;
extern int MA5 = 5;
extern int MA6 = 0;
extern int MA7 = 0;
extern int MA8 = 0;

/* Èíäèâèäóàëüíûé ðóáèëüíèê îòîáðàæåíèÿ íà êàæäóþ ñðåäíþþ */
extern bool DisplayMA1 = true;
extern bool DisplayMA2 = true;
extern bool DisplayMA3 = true;
extern bool DisplayMA4 = true;
extern bool DisplayMA5 = true;
extern bool DisplayMA6 = true;
extern bool DisplayMA7 = true;
extern bool DisplayMA8 = true;

/* Èìÿ ôîíòà ñèìâîëîâ */
extern string FontName = "Wingdings";

/* Ðàçìåð ñèìâîëîâ */
extern int FontSize = 12;

/* Ñèìâîëû íàðèñîâàííîãî è ñò¸ðòîãî óêàçàòåëÿ ïîëîæåíèÿ öåíû îòíîñèòåëüíî âååðà */
extern int PriceOnSymbol = 108; // Circle
extern int PriceOffSymbol = 32; // Space

/* Öâåòà íàðèñîâàííîãî óêàçàòåëÿ ïîëîæåíèÿ öåíû îòíîñèòåëüíî âååðà */
extern color PriceColor = LimeGreen;

/* Ñèìâîëû óêàçàòåëÿ ïðàâèëüíîñòè âååðà */
extern int FanWrongSymbol = 117; // Diamond
extern int FanUpSymbol = 233; // Up Arrow
extern int FanDownSymbol = 234; // Down Arrow

/* Öâåòà óêàçàòåëÿ ïðàâèëüíîñòè âååðà */
extern color FanWrongColor = DarkGray;
extern color FanUpColor = DodgerBlue;
extern color FanDownColor = OrangeRed;

/* Ñìåùåíèå âëåâî (X) è âïðàâî (Y) îò ïðàâîãî âåðõíåãî óãëà */
extern int X = 0;
extern int Y = 0;

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/******************************************************************************
  Tracking vertical line label and color
*/
#define TRACKING_NAME "Áàð, îòñëåæèâàåìûé èíäèêàòîðîì FanSimple"
#define TRACKING_COLOR DarkGray

/******************************************************************************/
string RowName[3] = { "Öåíà âûøå âååðà",
                      "Ñòàòóñ âååðà",
                      "Öåíà íèæå âååðà" };

/******************************************************************************/
/******************************************************************************/
/******************************************************************************

/*** À âîò ñþäà ëàçèòü óæå íå ñëåäóåò **** À âîò ñþäà ëàçèòü óæå íå ñëåäóåò ***/
/*** À âîò ñþäà ëàçèòü óæå íå ñëåäóåò **** À âîò ñþäà ëàçèòü óæå íå ñëåäóåò ***/
/*** À âîò ñþäà ëàçèòü óæå íå ñëåäóåò **** À âîò ñþäà ëàçèòü óæå íå ñëåäóåò ***/

/******************************************************************************/
/******************************************************************************/
/******************************************************************************
  Type of rendering codes
*/
#define is_down    0
#define is_none    1
#define is_up      2

/******************************************************************************/
int Timeframe[9];
string TimeframeNames[9];
int TimeframeInUse = 0;

/******************************************************************************/
int MAs[8];
int Xlat[8];
int MAsInUse = 0;

/******************************************************************************/
double MA1Buf[], MA2Buf[], MA3Buf[], MA4Buf[], MA5Buf[], MA6Buf[], MA7Buf[], MA8Buf[];

/******************************************************************************/
string LabelName(int i, int j) { return(RowName[j] + "(" + (i + 1) + "): " + TimeframeNames[i]); }

/******************************************************************************/
int symcolor[3][2];
int syms[3][2];

/******************************************************************************/
void UpdateFanStatus(int i, int how)
{
  string s = " ";

  ObjectSetText(LabelName(i, 1), StringSetChar(s, 0, symcolor[how][0]), FontSize, FontName, symcolor[how][1]);
}

/******************************************************************************/
void UpdatePriceStatus(int i, int how)
{
  string s = " ";

  ObjectSetText(LabelName(i, 0), StringSetChar(s, 0, syms[how][0]), FontSize, FontName, PriceColor);
  ObjectSetText(LabelName(i, 2), StringSetChar(s, 0, syms[how][1]), FontSize, FontName, PriceColor);
}

/******************************************************************************/
void InitTimeframe(int &P[], int PV)
{
  if(PV != 0)
  {
    switch(PV)
    {
    case PERIOD_M1:  TimeframeNames[TimeframeInUse] = "M1";  break;
    case PERIOD_M5:  TimeframeNames[TimeframeInUse] = "M5";  break;
    case PERIOD_M15: TimeframeNames[TimeframeInUse] = "M15"; break;
    case PERIOD_M30: TimeframeNames[TimeframeInUse] = "M30"; break;
    case PERIOD_H1:  TimeframeNames[TimeframeInUse] = "H1";  break;
    case PERIOD_H4:  TimeframeNames[TimeframeInUse] = "H4";  break;
    case PERIOD_D1:  TimeframeNames[TimeframeInUse] = "D1";  break;
    case PERIOD_W1:  TimeframeNames[TimeframeInUse] = "W1";  break;
    case PERIOD_MN1: TimeframeNames[TimeframeInUse] = "MN1"; break;
    default: return;
    }

    P[TimeframeInUse] = PV; TimeframeInUse++;
  }
}

/******************************************************************************/
void InitMAs(int &P[], int MA) { if(MA > 0) { P[MAsInUse] = MA; MAsInUse++; } }

/******************************************************************************/
int init()
{
  int i, j;

  if(DisplayFanStatus)
  {
    syms[0][0] = PriceOffSymbol; syms[0][1] = PriceOnSymbol;
    syms[1][0] = PriceOffSymbol; syms[1][1] = PriceOffSymbol;
    syms[2][0] = PriceOnSymbol; syms[2][1] = PriceOffSymbol;

    InitTimeframe(Timeframe, Timeframe1); InitTimeframe(Timeframe, Timeframe2); InitTimeframe(Timeframe, Timeframe3); InitTimeframe(Timeframe, Timeframe4);
    InitTimeframe(Timeframe, Timeframe5); InitTimeframe(Timeframe, Timeframe6); InitTimeframe(Timeframe, Timeframe7); InitTimeframe(Timeframe, Timeframe8);
    InitTimeframe(Timeframe, Timeframe9);

    InitMAs(MAs, MA1); InitMAs(MAs, MA2); InitMAs(MAs, MA3); InitMAs(MAs, MA4);
    InitMAs(MAs, MA5); InitMAs(MAs, MA6); InitMAs(MAs, MA7); InitMAs(MAs, MA8);

    for(i = 0; i < MAsInUse; i++) Xlat[i] = i;

    for(i = 0; i < MAsInUse - 1; i++)
      for(j = i + 1; j < MAsInUse; j++)
        if(MAs[Xlat[i]] > MAs[Xlat[j]]) { int k = Xlat[j]; Xlat[j] = Xlat[i]; Xlat[i] = k; }

    for(i = 0; i < TimeframeInUse; i++)
      for(j = 0; j < 3; j++)
      {
        string s = LabelName(i, j);

        ObjectCreate(s, OBJ_LABEL, 0, 0, 0);   
        ObjectSet(s, OBJPROP_XDISTANCE, (TimeframeInUse - i - 1) * 13 * FontSize / 10 + 2 * FontSize / 10 + X);
        ObjectSet(s, OBJPROP_YDISTANCE, j * 16 * FontSize / 10 + 3 * FontSize / 10 + Y);
        ObjectSet(s, OBJPROP_BACK, true);
        ObjectSet(s, OBJPROP_CORNER, 1);
        ObjectSetText(s, " ", FontSize, FontName, Black);
      }

    if(Tracking)
    {
      ObjectCreate(TRACKING_NAME, OBJ_VLINE, 0, TrackingTime, 0);
      ObjectSet(TRACKING_NAME, OBJPROP_COLOR, TRACKING_COLOR);
    }
  }

  if(DisplayFan)
  {
    string IndicatorName = "FanSimple(";

    symcolor[0][0] = FanDownSymbol; symcolor[0][1] = FanDownColor;
    symcolor[1][0] = FanWrongSymbol; symcolor[1][1] = FanWrongColor;
    symcolor[2][0] = FanUpSymbol; symcolor[2][1] = FanUpColor;

    if(DisplayMA1 && MA1 > 0) IndicatorName = IndicatorName + MA1; if(DisplayMA2 && MA2 > 0) IndicatorName = IndicatorName + ", " + MA2;
    if(DisplayMA3 && MA3 > 0) IndicatorName = IndicatorName + ", " + MA3; if(DisplayMA4 && MA4 > 0) IndicatorName = IndicatorName + ", " + MA4;
    if(DisplayMA5 && MA5 > 0) IndicatorName = IndicatorName + ", " + MA5; if(DisplayMA6 && MA6 > 0) IndicatorName = IndicatorName + ", " + MA6;
    if(DisplayMA7 && MA7 > 0) IndicatorName = IndicatorName + ", " + MA7; if(DisplayMA8 && MA8 > 0) IndicatorName = IndicatorName + ", " + MA8;

    IndicatorShortName(IndicatorName + ")");

    IndicatorBuffers(8);

    SetIndexBuffer(0, MA1Buf); SetIndexBuffer(1, MA2Buf); SetIndexBuffer(2, MA3Buf); SetIndexBuffer(3, MA4Buf);
    SetIndexBuffer(4, MA5Buf); SetIndexBuffer(5, MA6Buf); SetIndexBuffer(6, MA7Buf); SetIndexBuffer(7, MA8Buf);

    SetIndexLabel(0, "Âååð, " + MA1 + "-ÿ ñðåäíÿÿ"); SetIndexLabel(1, "Âååð, " + MA2 + "-ÿ ñðåäíÿÿ");
    SetIndexLabel(2, "Âååð, " + MA3 + "-ÿ ñðåäíÿÿ"); SetIndexLabel(3, "Âååð, " + MA4 + "-ÿ ñðåäíÿÿ");
    SetIndexLabel(4, "Âååð, " + MA5 + "-ÿ ñðåäíÿÿ"); SetIndexLabel(5, "Âååð, " + MA6 + "-ÿ ñðåäíÿÿ");
    SetIndexLabel(6, "Âååð, " + MA7 + "-ÿ ñðåäíÿÿ"); SetIndexLabel(7, "Âååð, " + MA8 + "-ÿ ñðåäíÿÿ");

    for(i = 0; i < 7; i++)
    {
      SetIndexStyle(i, DRAW_LINE);
      SetIndexEmptyValue(i, 0);
    }

    ArraySetAsSeries(MA1Buf, true); ArraySetAsSeries(MA2Buf, true); ArraySetAsSeries(MA3Buf, true); ArraySetAsSeries(MA4Buf, true);
    ArraySetAsSeries(MA5Buf, true); ArraySetAsSeries(MA6Buf, true); ArraySetAsSeries(MA7Buf, true); ArraySetAsSeries(MA8Buf, true);

    for(i = Bars - 1; i >= 0; i--)
    {
      MA1Buf[i] = 0; MA2Buf[i] = 0; MA3Buf[i] = 0; MA4Buf[i] = 0; MA5Buf[i] = 0; MA6Buf[i] = 0; MA7Buf[i] = 0; MA8Buf[i] = 0;
    }
  }

  return(0);
}

/******************************************************************************/
int deinit()
{
  for(int i = 0; i < TimeframeInUse; i++)
    for(int j = 0; j < 3; j++)
      ObjectDelete(LabelName(i, j));

  if(Tracking)
    ObjectDelete(TRACKING_NAME);

  return(0);
}

/******************************************************************************/
int start()
{
  int i;
  datetime NewTrackingTime = TrackingTime;

  static datetime time = 0;

  if(time == 0)
  {
    if(TrackingTime == 0)
      TrackingTime = Time[0];

    i = ((TimeDay(TrackingTime) * 24 + TimeHour(TrackingTime)) * 60 + TimeMinute(TrackingTime)) * 60 + TimeSeconds(TrackingTime);
    TrackingTime -= i;

    i /= 60;
    i -= i % Period();

    TrackingTime += i * 60;

    if(Tracking)
      ObjectSet(TRACKING_NAME, OBJPROP_TIME1, TrackingTime);
    else
      NewTrackingTime = TrackingTime;
  }

  if(Tracking)
    NewTrackingTime = ObjectGet(TRACKING_NAME, OBJPROP_TIME1);

  /* Ïîëüçîâàòåëü ñäâèíóë òî÷êó ñëåæåíèÿ èëè òî÷êà ñëåæåíèÿ - ïîñëåäíèé áàð èëè ïîÿâèëñÿ íîâûé áàð */
  if(NewTrackingTime != TrackingTime || (CurTime() - TrackingTime) / 60  < Period() || time != Time[0])
  {
    if(DisplayFanStatus)
      for(i = 0; i < TimeframeInUse; i++)
      {
        bool Up = true, Down = true;
        bool PriceUp = true, PriceDown = true;

        int LocalShift = iBarShift(Symbol(), Timeframe[i], NewTrackingTime + (Period() - 1) * 60);

        double PrevMA = 0;

        for(int j = 0; j < MAsInUse; j++)
        {
          double MA = iMA(Symbol(), Timeframe[i], MAs[Xlat[j]], 0, MODE_EMA, PRICE_CLOSE, LocalShift);

          if(j > 0) { if(Up && PrevMA < MA) Up = false; if(Down && PrevMA > MA) Down = false; }

          if(PriceUp && MA > iClose(Symbol(), Timeframe[i], LocalShift)) PriceUp = false;
          if(PriceDown && MA < iClose(Symbol(), Timeframe[i], LocalShift)) PriceDown = false;

          PrevMA = MA;
        }

        if(Up) UpdateFanStatus(i, is_up); else if(Down) UpdateFanStatus(i, is_down); else UpdateFanStatus(i, is_none);
        if(PriceUp) UpdatePriceStatus(i, is_up); else if(PriceDown) UpdatePriceStatus(i, is_down); else UpdatePriceStatus(i, is_none);
      }

    if(DisplayFan)
      for(i = Bars - IndicatorCounted() - 1; i >= 0; i--)
      {
        if(DisplayMA1 && MA1 > 0) MA1Buf[i] = iMA(Symbol(), 0, MA1, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA2 && MA2 > 0) MA2Buf[i] = iMA(Symbol(), 0, MA2, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA3 && MA3 > 0) MA3Buf[i] = iMA(Symbol(), 0, MA3, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA4 && MA4 > 0) MA4Buf[i] = iMA(Symbol(), 0, MA4, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA5 && MA5 > 0) MA5Buf[i] = iMA(Symbol(), 0, MA5, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA6 && MA6 > 0) MA6Buf[i] = iMA(Symbol(), 0, MA6, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA7 && MA7 > 0) MA7Buf[i] = iMA(Symbol(), 0, MA7, 0, MODE_EMA, PRICE_CLOSE, i);
        if(DisplayMA8 && MA8 > 0) MA8Buf[i] = iMA(Symbol(), 0, MA8, 0, MODE_EMA, PRICE_CLOSE, i);
      }

    if(time != Time[0])
    {
      if(Sliding && time != 0)
        NewTrackingTime += Time[0] - time;

      time = Time[0];
    }

    if(Tracking && NewTrackingTime != TrackingTime)
      ObjectSet(TRACKING_NAME, OBJPROP_TIME1, NewTrackingTime);

    if(StringLen(SlidingSound) != 0 && NewTrackingTime != TrackingTime)
      PlaySound(SlidingSound);

    TrackingTime = NewTrackingTime;
  }

  return(0);
}

Comments