MACD Crossover Arrows & Alert
Download scriptOverview
The MACD Crossover Arrows & Alert tool is a technical analysis indicator designed to help traders identify momentum shifts in the financial markets. It automates the process of spotting "crossovers" between two specific moving average lines—the MACD Main line and the Signal line—and provides visual cues and notifications when these events occur.
How It Works
1. Trend Detection (The MACD Logic) The script calculates the Moving Average Convergence Divergence (MACD) based on three user-adjustable settings: Fast, Slow, and Smoothing periods. By comparing the Main line against the Signal line, the tool looks for specific "crossover" moments:
- Bullish Signal: When the Main line moves from below to above the Signal line.
- Bearish Signal: When the Main line moves from above to below the Signal line.
2. Visual Alerts (On-Chart Arrows) Instead of making you watch the lines constantly, the script identifies these crossover points and places an arrow directly on your price chart:
- An arrow appears below the candle for upward crossovers.
- An arrow appears above the candle for downward crossovers. The tool includes a variety of customizable styles, allowing you to choose different shapes (such as thick, thin, hollow, or diagonal arrows) to match your personal preference for chart clarity.
3. Smart Positioning To ensure that the arrows do not overlap with the price candles, the script calculates the "average range" of recent price movement. It then places the arrows at a calculated distance away from the high and low of the candle, keeping your workspace clean and readable.
4. Real-Time Notifications Beyond visual cues, the script can proactively notify you of market activity:
- Pop-up Alerts: You can enable on-screen alerts that trigger instantly when a crossover occurs on a new price bar.
- Email Notifications: For traders who are away from their desks, the tool can be configured to send an automated email alert whenever a signal is detected.
Key Features
- Customizable Visuals: Choose from 10 different arrow types to suit your viewing style.
- Multi-Platform Alerts: Supports both instant desktop notifications and remote email alerts.
- Dynamic Range Calculation: Automatically adjusts the distance of the arrows based on current market volatility.
- Timeframe Awareness: The alert messages automatically include information about which timeframe (e.g., M15, H1, D1) the signal is occurring on, helping you stay organized across multiple charts.
//+------------------------------------------------------------------+
//| MACD Crossover Arrows & Alert |
//| Copyright © 2006 Written by PussyGalore |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 DodgerBlue
#property indicator_width1 3
#property indicator_color2 Magenta
#property indicator_width2 3
extern int MACD_Fast = 12;
extern int MACD_Slow = 26;
extern int MACD_Slowing = 9;
extern int Bars_Count= 20000;
extern string note1 = "Arrow Type";
extern string note2 = "0=Thick, 1=Thin, 2=Hollow, 3=Round";
extern string note3 = "4=Fractal, 5=Diagonal Thin";
extern string note4 = "6=Diagonal Thick, 7=Diagonal Hollow";
extern string note5 = "8=Thumb, 9=Finger";
extern int ArrowType=2;
extern string note6 = "--------------------------------------------";
extern string note7 = "turn on Alert = true; turn off = false";
extern bool AlertOn = true;
extern string note8 = "--------------------------------------------";
extern string note9 = "send Email Alert = true; turn off = false";
extern bool SendAnEmail=false;
double CrossUp[];
double CrossDown[];
string AlertPrefix, MA1short_name, MA2short_name;
string GetTimeFrameStr() {
switch(Period())
{
case 1 : string TimeFrameStr="M1"; break;
case 5 : TimeFrameStr="M5"; break;
case 15 : TimeFrameStr="M15"; break;
case 30 : TimeFrameStr="M30"; break;
case 60 : TimeFrameStr="H1"; break;
case 240 : TimeFrameStr="H4"; break;
case 1440 : TimeFrameStr="D1"; break;
case 10080 : TimeFrameStr="W1"; break;
case 43200 : TimeFrameStr="MN1"; break;
default : TimeFrameStr=Period();
}
return (TimeFrameStr);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
if (ArrowType == 0) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 233);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 234);
}
else if (ArrowType == 1) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 225);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 226);
}
else if (ArrowType == 2) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 241);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 242);
}
else if (ArrowType == 3) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 221);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 222);
}
else if (ArrowType == 4) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 217);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 218);
}
else if (ArrowType == 5) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 228);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 230);
}
else if (ArrowType == 6) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 236);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 238);
}
else if (ArrowType == 7) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 246);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 248);
}
else if (ArrowType == 8) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 67);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 68);
}
else if (ArrowType == 9) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 71);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 72);
}
SetIndexBuffer(0, CrossUp);
SetIndexBuffer(1, CrossDown);
AlertPrefix=Symbol()+" ("+GetTimeFrameStr()+"): ";
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
bool NewBar()
{
static datetime lastbar;
datetime curbar = Time[0];
if(lastbar!=curbar)
{
lastbar=curbar;
return (true);
}
else
{
return(false);
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
int limit, i, counter;
double macdnow, macd_signow, macdprevious, macd_sigprevious, macdafter, macd_sigafter;
double Range, AvgRange;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(i = 0; i <= limit; i++) {
counter=i;
Range=0;
AvgRange=0;
for (counter=i ;counter<=i+9;counter++)
{
AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
}
Range=AvgRange/10;
macdnow = iMACD(Symbol(), Period(), MACD_Fast, MACD_Slow, MACD_Slowing, PRICE_CLOSE, MODE_MAIN, i);
macdprevious = iMACD(Symbol(), Period(), MACD_Fast, MACD_Slow, MACD_Slowing, PRICE_CLOSE, MODE_MAIN, i+1);
macdafter = iMACD(Symbol(), Period(), MACD_Fast, MACD_Slow, MACD_Slowing, PRICE_CLOSE, MODE_MAIN, i-1);
macd_signow = iMACD(Symbol(), Period(), MACD_Fast, MACD_Slow, MACD_Slowing, PRICE_CLOSE, MODE_SIGNAL, i);
macd_sigprevious = iMACD(Symbol(), Period(), MACD_Fast, MACD_Slow, MACD_Slowing, PRICE_CLOSE, MODE_SIGNAL, i+1);
macd_sigafter = iMACD(Symbol(), Period(), MACD_Fast, MACD_Slow, MACD_Slowing, PRICE_CLOSE, MODE_SIGNAL, i-1);
if ((macdnow > macd_signow) && (macdprevious < macd_sigprevious) && (macdafter > macd_sigafter)) {
CrossUp[i] = Low[i] - Range*1.5;
if (AlertOn && NewBar()) {
Alert(AlertPrefix + "MACD ("+MACD_Fast+","+MACD_Slow+","+MACD_Slowing+") crosses UP");
}
if (SendAnEmail && NewBar()) {
SendMail(AlertPrefix, "MACD ("+MACD_Fast+","+MACD_Slow+","+MACD_Slowing+") crosses UP");
}
}
else if ((macdnow < macd_signow) && (macdprevious > macd_sigprevious) && (macdafter < macd_sigafter)) {
CrossDown[i] = High[i] + Range*1.5;
if (AlertOn && NewBar()) {
Alert(AlertPrefix + "MACD ("+MACD_Fast+","+MACD_Slow+","+MACD_Slowing+") crosses DOWN");
}
if (SendAnEmail && NewBar()) {
SendMail(AlertPrefix, "MACD ("+MACD_Fast+","+MACD_Slow+","+MACD_Slowing+") crosses DOWN");
}
}
}
return(0);
}
Comments