i-Example-Add

Author: ��� ����� �. aka KimIV
i-Example-Add

This script is a versatile technical analysis tool designed for the MetaTrader 4 platform. Its primary purpose is to scan market price data and identify specific trading opportunities based on various behaviors of the MACD (Moving Average Convergence Divergence) indicator.

Instead of providing just one type of signal, the script acts as a multi-functional "engine" that allows users to switch between different logic types to find buy and sell entries.

Core Logic Modules

The script evaluates price action using five distinct logic modes:

1. Signal Line Crossovers This is a standard momentum strategy. It looks for instances where the "Signal Line" and the "Main Line" of the MACD cross each other. When the signal line moves from below to above the main line, it suggests upward momentum (Buy); conversely, moving from above to below suggests downward momentum (Sell).

2. Main Line Turns This logic focuses on the direction of the main trend line itself. It identifies "turning points" where the main line reaches a peak or a valley and begins to reverse direction. By detecting these structural shifts in the primary trend, it aims to identify trend reversals before they fully manifest.

3. Signal Line Turns Similar to the logic above, this specifically monitors the "Signal Line." It looks for when this secondary line hits an extreme point and pivots backward. This is often used to identify exhaustion in current price momentum.

4. Main Line Divergences This is a more advanced technical analysis method. The script compares the movement of the actual market price against the movement of the MACD main line over a specific number of bars.

  • If the price makes a "lower low" but the indicator makes a "higher low," it identifies a Bullish Divergence, suggesting the downward trend is losing strength.
  • If the price makes a "higher high" but the indicator makes a "lower high," it identifies a Bearish Divergence, suggesting the upward trend is weakening.

5. Signal Line Divergences This applies the exact same sophisticated divergence logic described above, but uses the MACD Signal Line instead of the Main Line. This provides an additional layer of confirmation for traders who prefer to base their entries on secondary momentum signals.

Key Features and User Experience

  • Dynamic Visuals: The script automatically places visual markers (arrows) on the chart to highlight buy and sell opportunities. It also adjusts the spacing of these arrows based on the timeframe you are viewing (e.g., smaller gaps on 1-minute charts, larger gaps on daily charts) to ensure the screen remains clean and readable.
  • Dynamic Information: The tool includes a messaging system that displays a text comment on the chart. This tells the user exactly which type of signal is currently being active or identified based on the settings selected.
  • Customizable Sensitivity: Users can adjust several "External Parameters," such as the periods for fast and slow moving averages. Changing these values allows the user to make the script more sensitive (reacting to small price wiggles) or more stable (reacting only to major market moves).
  • Batch Processing: The script is capable of scanning through a large history of bars (defaulting to 1,000) to populate the chart with historical signals, allowing traders to see how these strategies would have performed in the past.
Indicators Used
MACD Histogram
9 Views
0 Downloads
0 Favorites
i-Example-Add
//+------------------------------------------------------------------+
//|                                                    i-Example.mq4 |
//|                                           Êèì Èãîðü Â. aka KimIV |
//|                                              http://www.kimiv.ru |
//|                                                                  |
//| 04.09.2005  Ïðèìåð óíèâåðñàëüíîãî èíäèêàòîðà                     |
//+------------------------------------------------------------------+
#property copyright "Êèì Èãîðü Â. aka KimIV"
#property link      "http://www.kimiv.ru"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 LightBlue
#property indicator_color2 Salmon
#property indicator_color3 LightBlue
#property indicator_color4 Salmon

//------- Ãëîáàëüíûå ïåðåìåííûå --------------------------------------

//------- Ïîêëþ÷åíèå âíåøíèõ ìîäóëåé ---------------------------------
//#include <f-KimIV.mqh>       // Áèáëèîòåêà äîïîëíèòåëüíûõ ôóíêöèé
//#include <s-MACD.mqh>   // Ñèãíàëüíûé ìîäóëü


//------- Âíåøíèå ïàðàìåòðû èíäèêàòîðà -------------------------------
extern int NumberOfBars = 1000;   // Êîëè÷åñòâî áàðîâ îáñ÷¸òà (0-âñå)
extern int idIndicator   = 1;     // Èäåíòèôèêàòîð èíäèêàòîðà
extern int FastEMAPeriod = 5;     // Ïåðèîä áûñòðîãî ÌÀ
extern int SlowEMAPeriod = 34;    // Ïåðèîä ìåäëåííîãî ÌÀ
extern int MACDSMAPeriod = 5;     // Ïåðèîä MACD ÌÀ
extern int BarsForCheck  = 20;    // Êîëè÷åñòâî áàðîâ äëÿ ïîèñêà äèâåðãåíöèé
int  ArrowInterval;

//------- Áóôåðû èíäèêàòîðà ------------------------------------------
double SigBuy[];
double SigSell[];
double SigExitBuy[];
double SigExitSell[];


//+------------------------------------------------------------------+
//| Ãëàâíàÿ ôóíêöèÿ ïîëó÷åíèÿ ñèãíàëîâ (âûçûâàåòñÿ èç ñîâåòíèêà)     |
//| Ïàðàìåòðû:                                                       |
//|   id - èäåíòèôèêàòîð èíäèêàòîðà                                  |
//|   nb - íîìåð áàðà                                                |
//|   ms - ìàññèâ ñèãíàëîâ (èñõîäÿùèõ)                               |
//|        0. Ñèãíàë íà ïîêóïêó                                      |
//|        1. Ñèãíàë íà ïðîäàæó                                      |
//|        2. Ñèãíàë íà âûõîä èç ïîêóïêè                             |
//|        3. Ñèãíàë íà âûõîä èç ïðîäàæè                             |
//|        4. Èäåíòèôèêàòîð èíäèêàòîðà, äàâøåãî ñèãíàë               |
//+------------------------------------------------------------------+
void GetSignals(int id, int nb, double& ms[]) {
  if (id==1) CrossingSignalMain(nb, ms);
  if (id==2) TurnMain(nb, ms);
  if (id==3) TurnSignal(nb, ms);
  if (id==4) DivergenceMACDMain(nb, ms);
  if (id==5) DivergenceMACDSignal(nb, ms);
}

//+------------------------------------------------------------------+
//| Âîçâðàùàåò íàèìåíîâàíèå ñèãíàëà                                  |
//| Ïàðàìåòðû:                                                       |
//|   id - èäåíòèôèêàòîð èíäèêàòîðà                                  |
//+------------------------------------------------------------------+
string GetNameSignal(int id) {
  switch (id) {
    case 1: return("Ïåðåñå÷åíèå ñèãíàëüíîé è îñíîâíîé ëèíèé MACD");
    case 2: return("Ðàçâîðîò îñíîâíîé ëèíèé MACD");
    case 3: return("Ðàçâîðîò ñèãíàëüíîé ëèíèé MACD");
    case 4: return("Äèâåðãåíöèÿ MACD îñíîâíîé ëèíèè");
    case 5: return("Äèâåðãåíöèÿ MACD ñèãíàëüíîé ëèíèè");
    default: return("íå âûáðàí èíäèêàòîð");
  }
}

//+------------------------------------------------------------------+
//| Ïåðåñå÷åíèå ñèãíàëüíîé è îñíîâíîé ëèíèé MACD                     |
//| Ïàðàìåòðû:                                                       |
//|   nb - íîìåð áàðà                                                |
//|   ms - ìàññèâ ñèãíàëîâ                                           |
//+------------------------------------------------------------------+
void CrossingSignalMain(int nb, double& ms[]) {
  double s1, s2, m1, m2;

  s1 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+1);
  s2 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+2);
  m1 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+1);
  m2 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+2);

  // Ñèãíàë íà ïîêóïêó
  if (s1<m1 && m2<s2) {
    ms[0] = Low[nb] - ArrowInterval * Point;
    ms[4] += 1;
  }

  // Ñèãíàë íà ïðîäàæó
  if (s1>m1 && m2>s2) {
    ms[1] = High[nb] + ArrowInterval * Point;
    ms[4] += 1;
  }
}

//+------------------------------------------------------------------+
//| Ðàçâîðîò îñíîâíîé ëèíèé MACD                                     |
//| Ïàðàìåòðû:                                                       |
//|   nb - íîìåð áàðà                                                |
//|   ms - ìàññèâ ñèãíàëîâ                                           |
//+------------------------------------------------------------------+
void TurnMain(int nb, double& ms[]) {
  double m1, m2, m3, m4;

  m1 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+1);
  m2 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+2);
  m3 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+3);
  m4 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+4);

  // Ñèãíàë íà ïîêóïêó
  if (m4>m3 && m3>m2 && m2+Point<m1) {
    ms[0] = Low[nb] - ArrowInterval * Point;
    ms[4] += 2;
  }

  // Ñèãíàë íà ïðîäàæó
  if (m4<m3 && m3<m2 && m2-Point>m1) {
    ms[1] = High[nb] + ArrowInterval * Point;
    ms[4] += 2;
  }
}

//+------------------------------------------------------------------+
//| Ðàçâîðîò ñèãíàëüíîé ëèíèé MACD                                   |
//| Ïàðàìåòðû:                                                       |
//|   nb - íîìåð áàðà                                                |
//|   ms - ìàññèâ ñèãíàëîâ                                           |
//+------------------------------------------------------------------+
void TurnSignal(int nb, double& ms[]) {
  double s1, s2, s3, s4;

  s1 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+1);
  s2 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+2);
  s3 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+3);
  s4 = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+4);

  // Ñèãíàë íà ïîêóïêó
  if (s4>s3 && s3>s2 && s2<s1) {
    ms[0] = Low[nb] - ArrowInterval * Point;
    ms[4] += 3;
  }

  // Ñèãíàë íà ïðîäàæó
  if (s4<s3 && s3<s2 && s2>s1) {
    ms[1] = High[nb] + ArrowInterval * Point;
    ms[4] += 3;
  }
}

//+------------------------------------------------------------------+
//| Äèâåðãåíöèè MACD îñíîâíîé ëèíèè                                  |
//| Ïàðàìåòðû:                                                       |
//|   nb - íîìåð áàðà                                                |
//|   ms - ìàññèâ ñèãíàëîâ                                           |
//+------------------------------------------------------------------+
void DivergenceMACDMain(int nb, double& ms[]) {
  double mu1, mu2, md1, md2;
  double pu1, pu2, pd1, pd2;
  double tt[];
  int    sh;

  ArrayResize(tt, BarsForCheck);
  // Çàïîëíåíèå ìàññèâà òî÷åê.
	for (sh=0; sh<BarsForCheck; sh++) {
		tt[sh] = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_MAIN, nb+sh);
 	}
  // Îïðåäåëåíèå êëþ÷åâûõ òî÷åê.
 	mu1=0; mu2=0; pu1=0; pu2=0;
	for (sh=0; sh<BarsForCheck; sh++) {
		if (tt[sh+1]<tt[sh+2] && tt[sh+2]>tt[sh+3]) {
			if (mu1!=0 && mu2==0) {
			  mu2 = tt[sh+1];
			  pu2 = High[nb+sh];
			}
			if (mu1==0 && tt[1]<tt[2] && tt[2]>tt[3]) {
			  mu1 = tt[sh+1];
			  pu1 = High[nb+sh];
			}
		}
	}
 	md1=0; md2=0; pd1=0; pd2=0;
	for (sh=0; sh<BarsForCheck; sh++) {
		if (tt[sh+1]>tt[sh+2] && tt[sh+2]<tt[sh+3]) {
			if (md1!=0 && md2==0) {
			  md2 = tt[sh+1];
			  pd2 = Low[nb+sh];
			}
			if (md1==0 && tt[1]>tt[2] && tt[2]<tt[3]) {
  			md1 = tt[sh+1];
			  pd1 = Low[nb+sh];
			}
		}
	}

  // Ñèãíàë íà ïîêóïêó
  if (pd1<pd2 && md1>md2 && md1<0 && md2<0) {
    ms[0] = Low[nb] - ArrowInterval * Point;
    ms[4] += 4;
  }

  // Ñèãíàë íà ïðîäàæó
  if (pu1>pu2 && mu1<mu2 && mu1>0 && mu2>0) {
    ms[1] = High[nb] + ArrowInterval * Point;
    ms[4] += 4;
  }
}

//+------------------------------------------------------------------+
//| Äèâåðãåíöèè MACD ñèãíàëüíîé ëèíèè                                |
//| Ïàðàìåòðû:                                                       |
//|   nb - íîìåð áàðà                                                |
//|   ms - ìàññèâ ñèãíàëîâ                                           |
//+------------------------------------------------------------------+
void DivergenceMACDSignal(int nb, double& ms[]) {
  double mu1, mu2, md1, md2;
  double pu1, pu2, pd1, pd2;
  double tt[];
  int    sh;

  ArrayResize(tt, BarsForCheck);
  // Çàïîëíåíèå ìàññèâà òî÷åê.
	for (sh=0; sh<BarsForCheck; sh++) {
		tt[sh] = iMACD(NULL, 0, FastEMAPeriod, SlowEMAPeriod, MACDSMAPeriod, PRICE_CLOSE, MODE_SIGNAL, nb+sh);
 	}
  // Îïðåäåëåíèå êëþ÷åâûõ òî÷åê.
 	mu1=0; mu2=0; pu1=0; pu2=0;
	for (sh=0; sh<BarsForCheck; sh++) {
		if (tt[sh+1]<tt[sh+2] && tt[sh+2]>tt[sh+3]) {
			if (mu1!=0 && mu2==0) {
			  mu2 = tt[sh+1];
			  pu2 = High[nb+sh];
			}
			if (mu1==0 && tt[1]<tt[2] && tt[2]>tt[3]) {
			  mu1 = tt[sh+1];
			  pu1 = High[nb+sh];
			}
		}
	}
 	md1=0; md2=0; pd1=0; pd2=0;
	for (sh=0; sh<BarsForCheck; sh++) {
		if (tt[sh+1]>tt[sh+2] && tt[sh+2]<tt[sh+3]) {
			if (md1!=0 && md2==0) {
			  md2 = tt[sh+1];
			  pd2 = Low[nb+sh];
			}
			if (md1==0 && tt[1]>tt[2] && tt[2]<tt[3]) {
  			md1 = tt[sh+1];
			  pd1 = Low[nb+sh];
			}
		}
	}

  // Ñèãíàë íà ïîêóïêó
  if (pd1<pd2 && md1>md2 && md1<0 && md2<0) {
    ms[0] = Low[nb] - ArrowInterval * Point;
    ms[4] += 5;
  }

  // Ñèãíàë íà ïðîäàæó
  if (pu1>pu2 && mu1<mu2 && mu1>0 && mu2>0) {
    ms[1] = High[nb] + ArrowInterval * Point;
    ms[4] += 5;
  }
}
//+------------------------------------------------------------------+


void _Comment(int id, string Comm, int x=5, int y=15, int fs=9, color cl=Gray) {
  if (!IsTesting()) {
    if (ObjectFind("CommentLabel"+id)==-1) {
      ObjectCreate("CommentLabel"+id, OBJ_LABEL, 0, 0,0);
    }
  	ObjectSet("CommentLabel"+id, OBJPROP_XDISTANCE, x);
   	ObjectSet("CommentLabel"+id, OBJPROP_YDISTANCE, y);
  	ObjectSetText("CommentLabel"+id, Comm, fs, "Arial", cl);
  }
}

//+------------------------------------------------------------------+
//| Óäàëåíèå ñâîèõ êîììåíòàðèåâ                                      |
//| Ïàðàìåòðû:                                                       |
//|   id - èäåíòèôèêàòîð òåêñòîâîé ìåòêè,                            |
//+------------------------------------------------------------------+
void _Comment_Clear(int id) {
  ObjectDelete("CommentLabel"+id);
}

//+------------------------------------------------------------------+
//| Âîçâðàùàåò èíòåðâàë óñòàíîâêè ñèãíàëüíûõ óêàçàòåëåé              |
//+------------------------------------------------------------------+
int GetArrowInterval() {
  int p = Period();

  switch (p) {
    case 1:     return(5);
    case 5:     return(7);
    case 15:    return(10);
    case 30:    return(15);
    case 60:    return(20);
    case 240:   return(30);
    case 1440:  return(80);
    case 10080: return(150);
    case 43200: return(250);
  }
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void init() {
  SetIndexBuffer(0, SigBuy);
  SetIndexStyle (0, DRAW_ARROW);
  SetIndexArrow (0, 233);
  SetIndexEmptyValue(0, EMPTY_VALUE);

  SetIndexBuffer(1, SigSell);
  SetIndexStyle (1, DRAW_ARROW);
  SetIndexArrow (1, 234);
  SetIndexEmptyValue(1, EMPTY_VALUE);

  SetIndexBuffer(2, SigExitBuy);
  SetIndexStyle (2, DRAW_ARROW);
  SetIndexArrow (2, 251);
  SetIndexEmptyValue(2, EMPTY_VALUE);

  SetIndexBuffer(3, SigExitSell);
  SetIndexStyle (3, DRAW_ARROW);
  SetIndexArrow (3, 251);
  SetIndexEmptyValue(3, EMPTY_VALUE);

  ArrowInterval = GetArrowInterval();
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void deinit() {
  _Comment_Clear(1);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
void start() {
  double ms[5];
  int    loopbegin, shift, ids;

 	if (NumberOfBars==0) loopbegin = Bars - 1;
  else loopbegin = NumberOfBars - 1;

  for (shift=loopbegin; shift>=0; shift--) {
    ms[0] = EMPTY_VALUE;
    ms[1] = EMPTY_VALUE;
    ms[2] = EMPTY_VALUE;
    ms[3] = EMPTY_VALUE;
    ms[4] = 0;
    GetSignals(idIndicator, shift, ms);
    SigBuy[shift] = ms[0];
    SigSell[shift] = ms[1];
    SigExitBuy[shift+1] = ms[2];
    SigExitSell[shift+1] = ms[3];
    if (ms[4]!=0 && ms[4]!=ids) ids = ms[4];
    _Comment(1, GetNameSignal(ids), 3, 20);
  }
}
//+------------------------------------------------------------------+

Comments