ASCTrend_Sound_MTF
Download scriptOverview of Script Logic
This script is designed as a specialized trading indicator for MetaTrader. Its primary purpose is to identify specific momentum shifts and trend reversals in the market by analyzing price movements and historical volatility. Instead of just looking at where the price is currently, it calculates several factors to determine "strength" before triggering an alert for a potential trade.
Core Analysis Logic
The script operates using a multi-step verification process to filter out market noise and identify high-probability signals:
1. Volatility and Range Calculation
The indicator first calculates the average price range over a specific lookback period (defined by the myPeriod setting). By understanding the "normal" size of price candles in the current market, the script can distinguish between standard movements and significant price breaks.
2. Dynamic Movement Detection (MRO Analysis) The logic employs a unique method to detect "True" movements. It scans recent history to find specific gaps or jumps in price that exceed a multiple of the average range. It looks for two specific types of movement:
- Significant changes between opening and closing prices.
- Sudden gaps between current prices and prices from a few bars back. Depending on which of these "True" movements it finds first, it adjusts a secondary calculation variable to determine how the market is behaving.
3. Momentum Filtering (WPR Integration) The script utilizes the Williams Percent Range (WPR) as a foundation but modifies it significantly. It takes the results from the "Movement Detection" step above to influence the WPR value. This means the indicator isn't just reading a standard momentum oscillator; it is using your specific market volatility to decide which "level" of the oscillator is most relevant at that moment.
4. Signal Generation and Filtering Once the modified momentum value is calculated, the script looks for specific breaches:
- Sell Signals: Triggered when the momentum value drops below a certain lower threshold and then recovers back into a middle "buffer zone."
- Buy Signals: Triggered when the momentum value rises above an upper threshold and then returns back into that same middle "buffer zone."
Notification System
To ensure the user receives actionable information without manual monitoring, the script includes several automated features:
- Visual Markers: It places specific arrow icons on the chart to indicate where it has detected a potential Buy or Sell entry.
- Audio and Email Alerts: If enabled, the script will trigger an audible "Alert" sound and can also send an automated email notification containing the current price (Ask/Bid), date, time, and the specific symbol being traded.
- Intelligent Alert Timing: The script includes logic to prevent "alert spam." It uses internal timers and global variables to ensure that it only notifies you once per period, preventing multiple notifications for the same signal during a single candle's movement.
//+------------------------------------------------------------------+
//| ASCTrend_Sound_MTF |
//| |
//| MODIFIED BY Avery T. Horton, Jr. aka TheRumpledOne |
//| |
//| Copyright © 2008, Avery T. Horton, Jr. aka TheRumpledOne |
//| |
//| PO BOX 43575, TUCSON, AZ 85733 |
//| |
//| GIFTS AND DONATIONS ACCEPTED |
//| |
//| therumpldone@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, Avery T. Horton, Jr. aka TRO"
#property link "http://www.therumpldone.com/"
//+-------------------------------------------------------------------+
//| ASCTrendExpert snd e-mail.mq4 |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//| Made/Modified by Alejandro Galindo |
//| |
//| You are free to use it |
//| |
//| If you want and if this work/modification is helpful to you |
//| send me a PayPal donation to ag@elcactus.com |
//| any help is apreciated :) |
//| Thanks. |
//+-------------------------------------------------------------------+
//| Original Version ASCTrend1sig_noSound.mq4
//| Ramdass - Conversion only
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Magenta
#property indicator_color2 Aqua
//---- input parameters
extern int myPeriod=60;
extern int RISK=3;
extern int CountBars=300;
extern int SoundON=1;
extern int EmailON=0;
//---- buffers
double val1[];
double val2[];
int flagval1 = 0;
int flagval2 = 0;
double open, high, low, close, open1, high1, low1, close1, close3 ;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator line
IndicatorBuffers(2);
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,234);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,233);
SetIndexBuffer(0,val1);
SetIndexBuffer(1,val2);
GlobalVariableSet("AlertTime"+Symbol()+myPeriod,CurTime());
GlobalVariableSet("SignalType"+Symbol()+myPeriod,OP_SELLSTOP);
//----
return(0);
}
int deinit()
{
GlobalVariableDel("AlertTime"+Symbol()+myPeriod);
GlobalVariableDel("SignalType"+Symbol()+myPeriod);
return(0);
}
//+------------------------------------------------------------------+
//| ASCTrend1sig |
//+------------------------------------------------------------------+
int start()
{
if (CountBars>=1000) CountBars=950;
SetIndexDrawBegin(0,Bars-CountBars+11+1);
SetIndexDrawBegin(1,Bars-CountBars+11+1);
int i,shift,counted_bars=IndicatorCounted();
int Counter,i1,value10,value11;
double value1,x1,x2;
double value2,value3;
double TrueCount,Range,AvgRange,MRO1,MRO2;
double Table_value2[1000];
double tmp=0;
value10=3+RISK*2;
x1=67+RISK;
x2=33-RISK;
value11=value10;
//----
if(Bars<=11+1) return(0);
//---- initial zero
if(counted_bars<11+1)
{
for(i=1;i<=0;i++) val1[CountBars-i]=0.0;
for(i=1;i<=0;i++) val2[CountBars-i]=0.0;
}
//----
shift=CountBars-11-1;
while(shift>=0)
{
Counter=shift;
Range=0.0;
AvgRange=0.0;
high = iHigh(NULL,myPeriod,Counter);
low = iLow(NULL,myPeriod,Counter);
// for (Counter=shift; Counter<=shift+9; Counter++) AvgRange=AvgRange+MathAbs(High[Counter]-Low[Counter]);
for (Counter=shift; Counter<=shift+9; Counter++) AvgRange=AvgRange+MathAbs(high-low);
Range=AvgRange/10;
Counter=shift;
TrueCount=0;
while (Counter<shift+9 && TrueCount<1)
{
open = iOpen(NULL,myPeriod,Counter);
close1 = iClose(NULL,myPeriod,Counter+1);
// if (MathAbs(Open[Counter]-Close[Counter+1])>=Range*2.0) TrueCount=TrueCount+1;
if (MathAbs(open-close1)>=Range*2.0) TrueCount=TrueCount+1;
Counter=Counter+1;
}
if (TrueCount>=1) {MRO1=Counter;} else {MRO1=-1;}
Counter=shift;
TrueCount=0;
while (Counter<shift+6 && TrueCount<1)
{
close = iClose(NULL,myPeriod,Counter);
close3 = iClose(NULL,myPeriod,Counter+3);
// if (MathAbs(Close[Counter+3]-Close[Counter])>=Range*4.6) TrueCount=TrueCount+1;
if (MathAbs(close3-close)>=Range*4.6) TrueCount=TrueCount+1;
Counter=Counter+1;
}
if (TrueCount>=1) {MRO2=Counter;} else {MRO2=-1;}
if (MRO1>-1) {value11=3;} else {value11=value10;}
if (MRO2>-1) {value11=4;} else {value11=value10;}
// value2=100-MathAbs(iWPR(NULL,0,value11,shift)); // PercentR(value11=9)
value2=100-MathAbs(iWPR(NULL,myPeriod,value11,shift)); // PercentR(value11=9)
Table_value2[shift]=value2;
val1[shift]=0;
val2[shift]=0;
value3=0;
if (value2<x2)
{i1=1;
while (Table_value2[shift+i1]>=x2 && Table_value2[shift+i1]<=x1){i1++;}
if (Table_value2[shift+i1]>x1)
{
high = iHigh(NULL,myPeriod,shift);
// value3=High[shift]+Range*0.5;
value3=high+Range*0.5;
if (shift == 1 && flagval1==0){ flagval1=1; flagval2=0; }
val1[shift]=value3;
}
}
if (value2>x1)
{i1=1;
while (Table_value2[shift+i1]>=x2 && Table_value2[shift+i1]<=x1){i1++;}
if (Table_value2[shift+i1]<x2)
{
low = iLow(NULL,myPeriod,shift);
// value3=Low[shift]-Range*0.5;
value3=low-Range*0.5;
if (shift == 1 && flagval2==0) { flagval2=1; flagval1=0; }
val2[shift]=value3;
}
}
shift--;
}
if (flagval1==1 && CurTime() > GlobalVariableGet("AlertTime"+Symbol()+myPeriod) && GlobalVariableGet("SignalType"+Symbol()+myPeriod)!=OP_BUY) {
if (SoundON==1) Alert("SELL signal at Ask=",Ask,", Bid=",Bid,", Date=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime())," Symbol=",Symbol()," Period=",myPeriod);
if (EmailON==1) SendMail("SELL signal alert","SELL signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+myPeriod);
tmp = CurTime() + (myPeriod-MathMod(Minute(),myPeriod))*60;
GlobalVariableSet("AlertTime"+Symbol()+myPeriod,tmp);
GlobalVariableSet("SignalType"+Symbol()+myPeriod,OP_BUY);
}
if (flagval2==1 && CurTime() > GlobalVariableGet("AlertTime"+Symbol()+myPeriod) && GlobalVariableGet("SignalType"+Symbol()+myPeriod)!=OP_SELL) {
if (SoundON==1) Alert("BUY signal at Ask=",Ask,", Bid=",Bid,", Time=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime())," Symbol=",Symbol()," Period=",myPeriod);
if (EmailON==1) SendMail("BUY signal alert","BUY signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+myPeriod);
tmp = CurTime() + (myPeriod-MathMod(Minute(),myPeriod))*60;
GlobalVariableSet("AlertTime"+Symbol()+myPeriod,tmp);
GlobalVariableSet("SignalType"+Symbol()+myPeriod,OP_SELL);
}
return(0);
}
//+------------------------------------------------------------------+
Comments