MACD_Signals
Download scriptThis custom indicator is designed to analyze market trends by utilizing a modified version of the Moving Average Convergence Divergence (MACD) strategy. Rather than providing a standard MACD reading, this script applies a specific mathematical normalization to ensure that historical data remains consistent and comparable across different price levels.
Core Logic and Visuals
The tool operates by calculating a normalized MACD value, which it then maps onto a visual histogram in a separate window. This histogram helps traders visualize the current momentum of the market. Additionally, the script identifies specific "turning points" where the momentum shifts from upward to downward (or vice versa) and marks these occurrences with visual arrows directly on the main price chart.
Technical Filtering and Signal Generation
To filter out market "noise" and avoid false signals caused by minor price fluctuations, the script employs several sophisticated logic layers:
- Momentum Tracking: The script monitors the direction of the normalized MACD. It tracks how long the momentum continues in a single direction (e.g., a continuous climb or drop).
- Significant Peak Detection: It utilizes a "Sequence" parameter to determine what constitutes a meaningful movement. A signal is only prioritized if a momentum shift occurs after a sustained period of movement, helping to distinguish between a major trend change and a temporary pause.
- Pattern Recognition: The logic looks for specific historical patterns regarding price peaks. It compares current values against previous highs and lows to validate the strength of a reversal. If a peak meets these specific criteria—such as being significantly higher or lower than previous levels within a certain timeframe—the script confirms the signal.
User Experience Features
The script is designed with practical trading utilities in mind:
- Visual Alerts: When a validated buy or sell pattern is detected, the script can automatically place an arrow on the chart at the specific price point of the candle where the pattern was confirmed.
- Notifications: It includes an optional alert system that can trigger a pop-up notification in the trading platform to grab the trader's attention immediately upon a signal.
- Clean Chart Management: There is a built-in cleanup function that ensures that if the indicator is removed from the chart, the generated arrows are automatically deleted, keeping the workspace organized.
In summary, this tool acts as a filtered momentum oscillator. It smooths out raw price data into a readable histogram and only highlights high-probability reversal points by cross-referencing current momentum with historical peak behavior.
//+------------------------------------------------------------------+
//| MyMACD_V2.mq4 |
//| Copyright © 2008, TheXpert |
//| theforexpert@gmail.com |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 SkyBlue
#property indicator_color2 FireBrick
#property indicator_width1 2
#property indicator_width2 2
extern string Copyright = "Copyright (c) TheXpert, mailto:TheForEXpert@gmail.com";
extern string _1 = "Ïàðàìåòðû äëÿ MACD";
extern int MaFast = 5;
extern int MaSlow = 73;
extern int MaSignal = 13;
extern string _2 = "Ïðèìåíÿåìàÿ öåíà (0, 1 ... 6)";
extern int Price = 3;
extern string _3 = "Ìèíèìàëüíîå ðàññòîÿíèå â áàðàõ äî ïðåäûäóùåé çíà÷èìîé âåðøèíû, ïðè êîòîðîì âåðøèíà ñ÷èòàåòñÿ çíà÷èìîé";
extern int Sequence = 17;
extern string _4 = "Ðèñîâàòü èëè íåò ñèãíàëüíûå ñòðåëêè";
extern bool DrawArrows = true;
extern string _5 = "Óäàëÿòü èëè íåò ñòðåëêè ïðè óäàëåíèè èíäèêàòîðà";
extern bool DeleteArrows = true;
extern string _6 = "Ñèãíàëèòü èëè íåò àëåðòîì ïðè óñòàíîâêå ñòðåëêè";
extern bool UseAlert = false;
#define NONE 0
#define UP 1
#define DN -1
int Direction = NONE;
double Last = 0;
datetime LastTime;
//---- buffers
double UpValue[];
double DnValue[];
double PatternSignal[];
double Signal[];
double SignalDirection[];
string symbol;
int Length = 0;
int Prev = 0;
int PrevPrev = 0;
int PrevPrevPrev = 0;
double PrevValue = 0;
double PrevPrevValue = 0;
double PrevPrevPrevValue = 0;
double LastSignalValue = 0;
int LastSignal = 0;
bool IsLastSignal = false;
void PushBack(int Now, double NowValue)
{
if (Prev == Now)
{
PrevValue = NowValue;
}
else
{
PrevPrevPrev = PrevPrev;
PrevPrevPrevValue = PrevPrevValue;
PrevPrev = Prev;
PrevPrevValue = PrevValue;
Prev = Now;
PrevValue = NowValue;
}
}
int init()
{
IndicatorBuffers(5);
IndicatorShortName("-=<MyMACD>=-");
SetIndexBuffer(0, UpValue);
SetIndexBuffer(1, DnValue);
SetIndexBuffer(2, SignalDirection);
SetIndexBuffer(3, PatternSignal);
SetIndexBuffer(4, Signal);
SetIndexStyle(0, DRAW_HISTOGRAM);
SetIndexStyle(1, DRAW_HISTOGRAM);
symbol = Symbol();
LastTime = Time[0];
return(0);
}
int start()
{
if (LastTime > Time[0])
{
return(0);
}
LastTime = Time[0];
int ToCount = Bars - IndicatorCounted();
bool dataIsLoaded = false;
while (!dataIsLoaded)
{
double price = 0;
int error = 0;
dataIsLoaded = true;
for (int i = ToCount - 2; i >= 0; i--)
{
price = Open[i];
error = GetLastError();
if (4066 == error)
{
Sleep(1000);
dataIsLoaded = false;
break;
}
}
}
for (i = ToCount - 2; i >= 0; i--)
{
double ma = iMA(symbol, 0, MaSlow, 0, MODE_EMA, Price, i + 1);
if(ma == 0 || ma == EMPTY_VALUE) continue;
// íà äîëãîé èñòîðèè çíà÷åíèÿ ìîãóò ìåíÿòüñÿ â ðàçû, çíà÷èò è àìïëèòóäà MACD òîæå, ÷òîáû
// ñäåëàòü ïîâåäåíèå îäèíàêîâûì íà âñåé èñòîðèè, äåëèì íà ñãëàæåííóþ òåêóùóþ öåíó.
double now = iMACD(symbol, 0, MaFast, MaSlow, MaSignal, Price, MODE_SIGNAL, i + 1)/ma;
UpValue[i + 1] = now;
Signal[i + 1] = 0;
SignalDirection[i + 1] = SignalDirection[i + 2];
PatternSignal[i + 1] = 0;
if (Last == 0)
{
Last = now;
continue;
}
if (Direction == NONE)
{
if (Last > now) Direction = DN;
if (Last < now) Direction = UP;
Last = now;
Length = 1;
continue;
}
if ((now - Last)*Direction > 0)
{
Last = now;
Length++;
Signal[i + 1] = 0;
continue;
}
if ((now - Last)*Direction < 0)
{
Direction = -Direction;
Signal[i + 1] = Direction*UpValue[i + 1];
Last = now;
if (Prev == 0)
{
PushBack(Direction, now);
Length = 1;
continue;
}
else
{
if (IsLastSignal)
{
if (Length > Sequence)
{
PushBack(LastSignal, LastSignalValue);
PushBack(Direction, now);
IsLastSignal = false;
}
else
{
LastSignal = Direction;
LastSignalValue = now;
Length = 1;
continue;
}
}
else
{
if (Length > Sequence)
{
PushBack(Direction, now);
}
else
{
LastSignal = Direction;
LastSignalValue = now;
IsLastSignal = true;
Length = 1;
continue;
}
}
Length = 1;
// çàäàíèå ïàòòåðíîâ.
if ( Prev == 1
&& PrevValue > PrevPrevPrevValue) PatternSignal[i + 1] = 1;
if ( Prev == -1
&& PrevValue < PrevPrevPrevValue) PatternSignal[i + 1] = -1;
if ( Prev == 1
&& PrevValue > -0.1*PrevPrevValue) PatternSignal[i + 1] = 1;
if ( Prev == -1
&& PrevValue < -0.1*PrevPrevValue) PatternSignal[i + 1] = -1;
if (PatternSignal[i + 1] != 0)
{
if (PatternSignal[i + 1] > 0)
{
if (DrawArrows)
{
string name = "MyMACD_Arrow #" + Time[i + 1];
ObjectCreate(name, OBJ_ARROW, 0, Time[i], Open[i]);
ObjectSet(name, OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
}
if (UseAlert && i == 0)
{
Alert("Ñèãíàë íà ïîêóïêó");
}
SignalDirection[i + 1] = 1;
}
if (PatternSignal[i + 1] < 0)
{
if (DrawArrows)
{
name = "MyMACD_Arrow #" + Time[i + 1];
ObjectCreate(name, OBJ_ARROW, 0, Time[i], Open[i]);
ObjectSet(name, OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
}
if (UseAlert && i == 0)
{
Alert("Ñèãíàë íà ïðîäàæó");
}
SignalDirection[i + 1] = -1;
}
}
}
}
}
for (i = ToCount - 2; i >= 0; i--)
{
DnValue[i + 1] = EMPTY_VALUE;
if (SignalDirection[i + 1] == -1)
{
DnValue[i + 1] = UpValue[i + 1];
}
}
return(0);
}
int deinit ()
{
if (!DeleteArrows) return (0);
for (int i = ObjectsTotal() - 1; i >= 0; i--)
{
string name = ObjectName(i);
if (StringFind(name, "MyMACD_Arrow") != -1)
{
ObjectDelete(name);
}
}
}
Comments