This script is designed as a visual trading tool for the MetaTrader platform, specifically created to identify potential market turning points by analyzing price momentum. Rather than simply following price trends, it looks for specific patterns of acceleration and deceleration in the market's "heartbeat."
Core Mechanics
The logic operates through three primary layers:
1. Data Smoothing (The Foundation) The script begins by calculating two distinct types of moving averages based on closing prices. It compares a "Fast" moving average against a "Slow" moving average to determine the raw momentum of the market. It then takes that momentum and smooths it again with a third "Signal" line. By comparing these values, the script can distinguish between minor price noise and significant trend shifts.
2. Momentum Analysis (The Comparison) Instead of looking at just one point in time, the script examines a sequence of recent data points. It calculates the difference between the current momentum and several previous bars to determine how quickly the market is moving. It seeks "divergence" or specific changes in direction—essentially checking if the speed of the move is increasing, decreasing, or reversing compared to where it was just a few moments ago.
3. Signal Generation (The Execution) The script looks for very specific geometric patterns in this momentum data. It triggers an alert (visualized as an arrow on your chart) when the momentum meets specific "strength" thresholds defined by the user settings.
- Buy Signals: The script identifies a bullish shift when the momentum shows a specific upward curve or recovery that exceeds a pre-defined intensity level.
- Sell Signals: Conversely, it detects a bearish shift when the momentum demonstrates a specific downward drop or exhaustion that surpasses its respective intensity threshold.
User Customization
The logic is designed to be flexible. Users can adjust the "Fast," "Slow," and "Signal" periods to change how sensitive the script is to price movement, as well as fine-tune the "DivCalc" (Division Calculation) values. These latter values act as filters; higher values require a more aggressive momentum shift before an arrow appears on the chart, while lower values make the script more sensitive to smaller market fluctuations.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
// you are free to use and improve, however I would appreciate you send me your versions at gideonsmolders(@)gmail.com
//ATTENTION: error messages: zero divide
#property copyright "Gideon Smolders,2005"
#property link "gideonsmolders(@)gmail.com"
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Olive
#property indicator_color2 FireBrick
//---- indicator parameters
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;
extern double DivCalc1=0.3;
extern double DivCalc2=0.35;
extern double DivCalc3=0.45;
extern double DivCalc4=0.60;
//---- indicator buffers
double ind_buffer1a[];
double ind_buffer1b[];
double ind_buffer2[];
double ind_buffer3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- 2 additional buffers are used for counting.
IndicatorBuffers(4);
//---- drawing settings
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,108);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,108);
//---- 3 indicator buffers mapping
if(!SetIndexBuffer(0,ind_buffer1a) &&
!SetIndexBuffer(1,ind_buffer1b) &&
!SetIndexBuffer(2,ind_buffer2) &&
!SetIndexBuffer(3,ind_buffer3))
Print("cannot set indicator buffers!");
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("MACDsignalsv0.2("+FastEMA+","+SlowEMA+","+SignalSMA+")");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Moving Average |
//+------------------------------------------------------------------+
int start()
{
int limit;
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;
//---- macd counted in the 1-st additional buffer
for(int i=0; i<limit; i++)
ind_buffer2[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
-iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd additional buffer
for(i=0; i<limit; i++)
ind_buffer3[i]=iMAOnArray(ind_buffer2,Bars,SignalSMA,0,MODE_SMA,i);
//---- main loop
double value=0;
double prev1_value=0;
double prev2_value=0;
double prev3_value=0;
double prev4_value=0;
double div_value1=0;
double div_value2=0;
double div_value3=0;
double div1=0;
double div2=0;
double div3=0;
for(i=0; i<limit; i++)
{
ind_buffer1a[i]=0.0;
ind_buffer1b[i]=0.0;
value=ind_buffer2[i]-ind_buffer3[i];
prev1_value=ind_buffer2[i+1]-ind_buffer3[i+1];
prev2_value=ind_buffer2[i+2]-ind_buffer3[i+2];
prev3_value=ind_buffer2[i+3]-ind_buffer3[i+3];
prev4_value=ind_buffer2[i+4]-ind_buffer3[i+4];
if(prev1_value != 0) div_value1=MathAbs(div1/prev1_value); else div_value1 = 0;
if(prev2_value != 0) div_value1=MathAbs(div2/prev2_value); else div_value2 = 0;
if(prev3_value != 0) div_value1=MathAbs(div3/prev3_value); else div_value3 = 0;
div1=value-prev1_value;
div2=value-prev2_value;
div3=value-prev3_value;
if ((value>prev1_value && prev1_value<prev2_value && prev2_value<prev3_value && div_value1>DivCalc1) ||
(value>prev1_value && prev1_value>prev2_value && prev2_value<prev3_value && div_value2>DivCalc2) ||
(value>prev1_value && (prev1_value<prev2_value || prev1_value>prev2_value) && prev2_value>prev3_value && prev3_value<prev4_value && div_value3>DivCalc3) ||
(value>prev1_value && prev1_value>prev2_value && prev2_value>prev3_value && div_value1>DivCalc4) ) ind_buffer1a[i]=Low[i]-2*Point;
if ((value<prev1_value && prev1_value>prev2_value && prev2_value>prev3_value && div_value1>DivCalc1) ||
(value<prev1_value && prev1_value<prev2_value && prev2_value>prev3_value && div_value2>DivCalc2) ||
(value<prev1_value && (prev1_value>prev2_value || prev1_value<prev2_value) && prev2_value<prev3_value && prev3_value>prev4_value && div_value3>DivCalc3) ||
(value<prev1_value && prev1_value<prev2_value && prev2_value<prev3_value && div_value2>DivCalc4)) ind_buffer1b[i]=High[i]+2*Point;
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
Comments