CCI_Sound_Email
Download scriptThis script functions as a specialized financial analysis tool designed to help traders identify extreme price movements relative to recent averages. It automates the calculation of the Commodity Channel Index (CCI) and provides real-time notifications when the market reaches specific "overbought" or "oversold" thresholds.
Core Logic and Workflow
1. Data Processing The script constantly monitors current market prices, specifically focusing on the relationship between the high, low, and closing prices of a candle. To establish a baseline, it calculates a Simple Moving Average (SMA) over a user-defined period (defaulting to 14). This represents the "normal" price behavior for that timeframe.
2. Measuring Volatility and Deviation Once the average price is established, the script measures how much the actual price deviates from that average. It specifically looks at the "Standard Deviation"—essentially calculating how far the current price has strayed from the norm. This helps the tool distinguish between a normal price fluctuation and an aggressive, unusual move.
3. Calculating the Index The final value shown on your chart is produced by dividing the price deviation by the standard deviation. This creates a normalized score:
- When the price moves significantly higher than usual, the indicator climbs toward a positive threshold (High).
- When the price drops significantly lower than usual, it falls toward a negative threshold (Low).
4. Automated Alert System The script is equipped with an intelligent notification system that triggers only when the indicator crosses specific boundaries:
- Upper Threshold: If the index reaches or exceeds a high limit (default 100), it signifies a potential overbought condition.
- Lower Threshold: If the index falls to or below a low limit (default -100), it signifies a potential oversold condition.
5. Notification Delivery To ensure you don't miss these moments, the script can be configured to perform three actions simultaneously when a threshold is breached:
- Visual/Audio: It plays a specific sound file on your computer.
- Email Alerts: It automatically sends an email containing the specific asset name, timeframe, current price, and exact date/time of the breach.
- State Management: The logic includes a " Played" memory. This ensures that you only receive one notification per breach, preventing the system from sending constant emails or sounds while the price stays in an extreme zone; it resets automatically once the price returns to normal levels.
User Customization
The script is designed to be flexible, allowing you to adjust the look-back period for calculations, toggle sound and email alerts on or off, and define your own specific high and low numerical boundaries for the indicators.
//+------------------------------------------------------------------+
//| CCI.mq4 |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
#property link "Sound & email added by cja"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 LightSeaGreen
//---- input parameters
extern int CCIPeriod=14;
extern bool SendEmail = false;
extern bool SoundAlert_ON = false;
extern string SoundFile ="alert2.wav";
extern int CCIHigh=100;
extern int CCILow=-100;
int PlayedSoundH = False;
int PlayedSoundL = False;
//---- buffers
double CCIBuffer[];
double RelBuffer[];
double DevBuffer[];
double MovBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- 3 additional buffers are used for counting.
IndicatorBuffers(4);
SetIndexBuffer(1, RelBuffer);
SetIndexBuffer(2, DevBuffer);
SetIndexBuffer(3, MovBuffer);
//---- indicator lines
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,CCIBuffer);
SetLevelValue(0,CCIHigh);
SetLevelValue(1,CCILow);
SetLevelStyle(2,0,DarkSlateGray);
//---- name for DataWindow and indicator subwindow label
string Alert1="",Alert2="";
if(SendEmail==true)Alert1="ON";
if(SendEmail==false)Alert1="OFF";
if(SoundAlert_ON==true)Alert2="ON";
if(SoundAlert_ON==false)Alert2="OFF";
short_name="CCI( "+CCIPeriod+" ) [ Sound Alert "+Alert2+" ] [ Email Alert "+Alert1+" ]";
IndicatorShortName(short_name);
SetIndexLabel(0,short_name);
//----
SetIndexDrawBegin(0,CCIPeriod);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Commodity Channel Index |
//+------------------------------------------------------------------+
int start()
{
int i,k,counted_bars=IndicatorCounted();
double price,sum,mul;
if(Bars<=CCIPeriod) return(0);
//---- initial zero
if(counted_bars<1)
{
for(i=1;i<=CCIPeriod;i++) CCIBuffer[Bars-i]=0.0;
for(i=1;i<=CCIPeriod;i++) DevBuffer[Bars-i]=0.0;
for(i=1;i<=CCIPeriod;i++) MovBuffer[Bars-i]=0.0;
}
//---- last counted bar will be recounted
int limit=Bars-counted_bars;
if(counted_bars>0) limit++;
//---- moving average
for(i=0; i<limit; i++)
MovBuffer[i]=iMA(NULL,0,CCIPeriod,0,MODE_SMA,PRICE_TYPICAL,i);
//---- standard deviations
i=Bars-CCIPeriod+1;
if(counted_bars>CCIPeriod-1) i=Bars-counted_bars-1;
mul=0.015/CCIPeriod;
while(i>=0)
{
sum=0.0;
k=i+CCIPeriod-1;
while(k>=i)
{
price=(High[k]+Low[k]+Close[k])/3;
sum+=MathAbs(price-MovBuffer[i]);
k--;
}
DevBuffer[i]=sum*mul;
i--;
}
i=Bars-CCIPeriod+1;
if(counted_bars>CCIPeriod-1) i=Bars-counted_bars-1;
while(i>=0)
{
price=(High[i]+Low[i]+Close[i])/3;
RelBuffer[i]=price-MovBuffer[i];
i--;
}
//---- cci counting
i=Bars-CCIPeriod+1;
if(counted_bars>CCIPeriod-1) i=Bars-counted_bars-1;
while(i>=0)
{
if(DevBuffer[i]==0.0) CCIBuffer[i]=0.0;
else CCIBuffer[i]=RelBuffer[i]/DevBuffer[i];
i--;
}
if(CCIBuffer[0]<CCIHigh){PlayedSoundH = False;}
if(CCIBuffer[0]>CCILow){PlayedSoundL = False;}
if(CCIBuffer[0]>=CCIHigh && PlayedSoundH == False){if(SoundAlert_ON==true)
PlaySound(SoundFile); if (SendEmail==true)SendMail("CCI "+Symbol()+" M"+Period()+"","CCI Xrossed @ Level "+CCIHigh+"\n"+Symbol()+" M"+Period()+"\n"+"Price "+DoubleToStr(Bid,Digits)+"\n"
+"Time = "+TimeToStr(TimeLocal(),TIME_SECONDS)+"\n"+"Date = "+TimeToStr(TimeLocal(),TIME_DATE)+"");
{
PlayedSoundH = True;}
if(CCIBuffer[0]<=CCILow && PlayedSoundL == False){if(SoundAlert_ON==true)
PlaySound(SoundFile); if (SendEmail==true)SendMail("CCI "+Symbol()+" M"+Period()+"","CCI Xrossed @ Level "+CCILow+"\n"+Symbol()+" M"+Period()+"\n"+"Price "+DoubleToStr(Bid,Digits)+"\n"
+"Time = "+TimeToStr(TimeLocal(),TIME_SECONDS)+"\n"+"Date = "+TimeToStr(TimeLocal(),TIME_DATE)+"");
{
PlayedSoundL = True;}
}}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments