JC - Line Break Alert5
Download scriptThis script is designed for traders who need to be notified the exact moment a market price crosses or breaks through a specific level. It acts as an automated monitoring system that watches price movements and triggers various alerts based on your predefined rules.
Core Functionality
The tool allows you to establish "price boundaries" on your trading chart. You can choose between two primary ways of using these levels:
- Line Mode: Monitors a single price level. It detects whenever the market price moves from below to above (or vice versa) that specific point.
- Channel Mode: Monitors two separate price levels, effectively creating a "zone" or channel. It alerts you specifically when the price breaks out of the top boundary or drops below the bottom boundary.
Key Features
Dynamic Manual Interaction Unlike many static indicators, this script is interactive. You can manually move the lines on your chart to adjust your target prices in real-time. The script is smart enough to recognize these manual movements; if you drag a line to a new position, it automatically updates its internal logic and resets its alert status so it can monitor the new level immediately.
Customizable Notifications When a price breach occurs, the script can notify you in four different ways (which can be turned on or off individually):
- Sound Alerts: Plays a specific audio file (like a beep or alarm) to grab your attention.
- Pop-up Alerts: Displays an instant message box on your trading screen stating which symbol and period the break occurred on, along with the specific price.
- Visual Alerts: Places a clear "ALERT!" text label directly on the chart near the price level where the breach happened.
- Email Notifications: Sends a detailed email to your connected device (if configured), ensuring you don't miss a move even if you aren't looking at the screen.
Smart Automation Logic To prevent "alert fatigue," the script includes a one-time alert system. Once a price crosses a line, it triggers the notification once and then enters a "deactivated" state. It will only trigger again if you manually move the line or reset the parameters. This ensures you aren't bombarded with repeated sounds every time the price wobbles slightly around your target.
Persistence and Memory The script includes an automatic saving system. It can remember your custom price levels and chosen modes by saving them to a file. When you reopen your chart, the tool can restore these settings automatically so you don't have to manually re-draw your lines every time you restart your platform.
//+------------------------------------------------------------------+
//| JC - Line Break Alert.mq4 |
//| Juan Carlos Christensen. |
//| http://www.eumefinancial.com |
//|Modified on June 8, 2007 by Hartono Setiono |
//|Movable Price Level Setting by Line |
//|Store & Restore Setting to File |
//+------------------------------------------------------------------+
#property copyright "Juan Carlos Christensen."
#property link "http://www.eumefinancial.com"
#include <stdlib.mqh>
#include <stderror.mqh>
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Lime
#property indicator_width1 2
//---- input parameters
extern double Price1 = 0.0000;
extern double Price2 = 0.0000;
extern string Modes = "0- Line; 1- Channel";
extern int Mode = 1;
extern bool UseSoundAlert = True;
extern string SoundFile = "alert.wav";
extern int PlaySoundNTimes = 1;
extern bool UseAlertPopUp = True;
extern bool UseVisualAlert = True;
extern bool UseTickMode = True;
extern bool UseSendMail = False;
extern bool DeactivateOnAlert = True;
extern color price1_color = Lime;
extern color price2_color = Red;
extern color alert_color_up = DarkOrange;
extern color alert_color_dn = DarkOrange;
extern int alert_font_size = 18;
bool DidBreakout = False;
double LastPrice;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
if(Price1==0 && Price2==0) RestoreSetting();
LastPrice=Bid;
CreateLine("price1",price1_color,Price1);
if(Mode==1) CreateLine("price2",price2_color,Price2);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
if(Price1!=0 && Price2!=0) StoreSetting();
ObjectDelete("price1");
ObjectDelete("price2");
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//----
double aPrice1=ObjectGet("price1",OBJPROP_PRICE1);
if(GetLastError()==4202) CreateLine("price1",price1_color,Price1);
if(aPrice1!=0 && aPrice1 != Price1)
{
Price1=aPrice1;
Print("Price1 Changed:",Price1);
DidBreakout=false;
ObjectDelete("alert1");
}
if(Mode==1)
{
double aPrice2=ObjectGet("price2",OBJPROP_PRICE1);
if(GetLastError()==4202) CreateLine("price2",price2_color,Price2);
if(aPrice2!=0 && aPrice2 != Price2)
{
Price2=aPrice2;
Print("Price2 Changed:",Price2);
DidBreakout=false;
ObjectDelete("alert2");
}
}
if(Price1<Price2 && Mode==1)
{
aPrice1=Price1;
Price1=Price2;
Price2=aPrice1;
ObjectSet("price1",OBJPROP_PRICE1,Price1);
ObjectSet("price2",OBJPROP_PRICE1,Price2);
}
switch(Mode)
{
case 0:
CrossingPrice1Only();
break;
case 1:
ChannelBreakOut();
break;
default:
CrossingPrice1Only();
}
//----
return(0);
}
//+------------------------------------------------------------------+
void CrossingPrice1Only()
{
double CurrentPrice=Bid;
if(((LastPrice < Price1) && (CurrentPrice >= Price1)) || ((LastPrice > Price1) && (CurrentPrice <= Price1)) && !DidBreakout)
{
if(DeactivateOnAlert) DidBreakout = True;
if(UseSoundAlert)
for(int x=0;x<=PlaySoundNTimes;x++)
PlaySound(SoundFile);
if(UseAlertPopUp)
Alert(Symbol()," ",Period(),"Price Crossing Alert Line at ", Price1); //Symbol()," ",Period()," @ ",Bid
if(UseVisualAlert)
ShowVisualAlert("alert1", Price1 + 8 * Point, alert_color_up);
if(UseSendMail)
SendMail("Price Crossing Alert Line at " + Price1 + "!", "This is an email from the JC - Line Break Alert indicator. Price is crossing your alert line at " + Price1 + "!");
}
}
//+------------------------------------------------------------------+
void ChannelBreakOut()
{
double CurrentPrice=Bid;
if((LastPrice < Price1) && (CurrentPrice >= Price1) && !DidBreakout)
{
if(DeactivateOnAlert) DidBreakout = True;
if(UseSoundAlert)
for(int x=0;x<=PlaySoundNTimes;x++) PlaySound(SoundFile);
if(UseAlertPopUp)
Alert(Symbol()," ",Period(),"Price Breaking Up at ", Price1);
if(UseVisualAlert)
ShowVisualAlert("alert1", Price1+8*Point, alert_color_up);
if(UseSendMail)
SendMail("Channel Breaking Up at " + Price1 + "!", "This is an email from the JC - Line Break Alert indicator. Price broke up your channel alert line at " + Price1 + "!");
}
if((LastPrice > Price2) && (CurrentPrice <= Price2) && !DidBreakout)
{
if(DeactivateOnAlert) DidBreakout = True;
if(UseSoundAlert)
for(x=0;x<=PlaySoundNTimes;x++)
PlaySound(SoundFile);
if(UseAlertPopUp)
Alert(Symbol()," ",Period(),"Price Breaking Down at ", Price2);
if(UseVisualAlert)
ShowVisualAlert("alert2", Price2-1*Point, alert_color_dn);
if(UseSendMail)
SendMail("Channel Breaking Down at " + Price2 + "!", "This is an email from the JC - Line Break Alert indicator. Price broke down your channel alert line at " + Price2 + "!");
}
}
void ShowVisualAlert(string aName, double aPrice, color aColor)
{
Print("Show Visual Alert!");
ObjectCreate(aName, OBJ_TEXT, 0, Time[5], aPrice);
Print(ErrorDescription(GetLastError()));
ObjectSetText(aName, "ALERT!", alert_font_size, "Arial", aColor);
//ObjectSet(aName, OBJPROP_WIDTH, 2);
Print(ErrorDescription(GetLastError()));
}
//+------------------------------------------------------------------+
void CreateLine(string aName, color aColor, double aPrice)
{
ObjectCreate(aName, OBJ_HLINE, 0, Time[0],aPrice);
ObjectSet(aName, OBJPROP_COLOR, aColor);
ObjectSet(aName, OBJPROP_STYLE, STYLE_DASH);
}
void StoreSetting()
{
int myhandle;
Print("Store Setting :",Symbol(),":",Price1,":",Price2,":",Mode);
myhandle=FileOpen("LineBreak_"+Symbol()+".SET", FILE_BIN|FILE_WRITE|FILE_READ);
if(myhandle>0)
{
FileSeek(myhandle,0,0);
FileWriteDouble(myhandle, Price1);
FileWriteDouble(myhandle, Price2);
FileWriteInteger(myhandle, Mode);
FileClose(myhandle);
}
}
void RestoreSetting()
{
int myhandle, aMode, err;
double aPrice1, aPrice2;
myhandle=FileOpen("LineBreak_"+Symbol()+".SET", FILE_BIN|FILE_WRITE|FILE_READ);
if(myhandle>0)
{
FileSeek(myhandle,0,0);
aPrice1=FileReadDouble(myhandle);
err=GetLastError();
if(err==0) { aPrice2=FileReadDouble(myhandle); err=GetLastError();}
if(err==0) { aMode=FileReadInteger(myhandle); err=GetLastError();}
FileClose(myhandle);
}
if(err==0){Mode=aMode; Price1=aPrice1; Price2=aPrice2;}
Print("Restore Setting :",Symbol(),":",err,":",aPrice1,":",aPrice2,":",aMode);
}
Comments