This tool functions as a multi-market "Scanning Dashboard" designed to help traders quickly identify momentum trends across a wide variety of currency pairs and different timeframes simultaneously. Instead of forcing you to click on every single chart individually, it aggregates that data into a single visual display.
Core Functionality
The script monitors 24 specific currency pairs (such as AUDUSD, EURJPY, etc.) and evaluates them across four distinct timeframes: 1 Minute (M1), 5 Minutes (M5), 15 Minutes (M15), and 1 Hour (H1).
How the Logic Works
The system operates by analyzing Moving Averages (MA)—which are mathematical averages of price over specific periods. It tracks four different moving averages for every single currency pair at once.
1. Trend Identification The script looks for a "stacking" order of these moving averages to determine the direction of the market:
- Bullish Alignment: If the fastest moving average is above the second, and the second is above the third, and so on (descending order), the tool identifies an upward trend.
- Bearish Alignment: If the fastest moving average is below the others in a descending chain, it identifies a downward trend.
2. Consolidation Detection Beyond just knowing if the market is going up or down, the script features a "Channel" logic. It measures the distance between the fastest and slowest moving averages:
- If the averages are aligned in a trend but are very close to each other (within a specific price range), the tool flags this as Consolidated.
- This helps traders distinguish between a strong, explosive move and a tight, simmering trend where the market might be preparing to break out.
Visual Representation
The dashboard uses a color-coded system to relay this information instantly:
- Green/Lime: Indicates a Bullish (Upward) trend. If it turns into a specific shade of Lime, it signals that the trend is "Consolidated" (tightly grouped).
- Crimson/Red: Indicates a Bearish (Downward) trend. A specific shade of Red signals that the bearish trend is "Consolidated."
- Gray: Indicates that no clear trend alignment has been met or that the monitoring toggle is turned off.
Summary for the User
Essentially, this script acts as an automated "scout." It constantly sweeps through dozens of market combinations, checks if the price momentum is trending up or down, and alerts you via a color-coded grid whether those trends are strong, weak, or currently consolidating. This allows a trader to see at a glance which markets are showing the most consistent movement across multiple timeframes.
//+------------------------------------------------------------------+
//| MA Scan.mq4 |
//| Copyright © 2010, Simon Kaufmann |
//| |
//+------------------------------------------------------------------+
// best placed on a 1 minute chart to get most frequent updates
#property copyright "Copyright © 2010, Simon Kaufmann"
#property link ""
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 1
extern string MA_Settings = "----------------------------------------------------------------------";
extern int MA1 = 13;
extern int MA2 = 21;
extern int MA3 = 34;
extern int MA4 = 55;
extern string Channel_Settings = "----------------------------------------------------------------------";
extern int Channel = 3;
extern string GUI_Settings = "----------------------------------------------------------------------";
extern color textcolor = Snow;
extern int textsize = 8;
extern color Long_Consolidated = Lime;
extern color Short_Consolidated = Red;
extern color Long = Green;
extern color Short = Crimson;
bool Monitor = true;
string objprefix = "MA-SCAN-";
string indi_name = "MA Scan";
string symbol[] = {
"AUDCAD", "AUDCHF","AUDJPY","AUDNZD","AUDUSD","CADJPY","CHFJPY","EURAUD","EURCAD","EURCHF","EURGBP","EURJPY","EURNZD","EURUSD","GBPCAD","GBPCHF","GBPJPY","GBPNZD","GBPUSD","NZDCHF","NZDJPY","NZDUSD","USDCAD","USDCHF","USDJPY"};
string tf_text[] = {"M1", "M5", "M15", "H1"};
int timeframe[] = {PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_H1};
int window;
static bool done;
int xoffset=75;
int yoffset=20;
int x, y, spacingx, spacingy;
datetime ctime, prevtime;
double iMA1,iMA2,iMA3,iMA4;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
IndicatorShortName(indi_name);
string AddChar = StringSubstr(Symbol(),6,4);
for (int cc = 0; cc <= ArraySize(symbol); cc++)
{
symbol[cc] = StringConcatenate(symbol[cc], AddChar);
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
deleteObjects();
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
initGraph();
scan();
done = true;
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator delete objects function |
//+------------------------------------------------------------------+
void deleteObjects()
{
for(int i=ObjectsTotal();i >= 0;i--)
{
if(StringSubstr(ObjectName(i),0,StringLen(objprefix))==objprefix)
ObjectDelete(ObjectName(i));
}
}
//----------------------------------------
void initGraph()
{
if (done) { return; }
spacingx = textsize*7;
spacingy = textsize+8;
// draw up table of symbols and tf_text
for (int i = 0; i < ArraySize(symbol); i++)
{
x = xoffset+(spacingx*i);
objectCreate(symbol[i],x, 5, symbol[i],textsize,"Arial",textcolor);
for (int j = 0; j < ArraySize(timeframe); j++)
{
objectReset(symbol[i]+DoubleToStr(timeframe[j],0),x+10,y,Gray);
}
}
// draw timeframe headers
for (int k = 0; k < ArraySize(timeframe); k++)
{
y = yoffset + (spacingy*k);
objectCreate(tf_text[k],15,y,tf_text[k],textsize,"Arial",textcolor);
}
done = true;
}
//+------------------------------------------------------------------+
void objectCreate(string name,int x,int y,string text="-",int size=42,
string font="Arial",color colour=CLR_NONE)
{
ObjectCreate(objprefix+name,OBJ_LABEL,WindowFind(indi_name),0,0);
ObjectSet(objprefix+name,OBJPROP_CORNER,0);
ObjectSet(objprefix+name,OBJPROP_COLOR,colour);
ObjectSet(objprefix+name,OBJPROP_XDISTANCE,x);
ObjectSet(objprefix+name,OBJPROP_YDISTANCE,y);
ObjectSetText(objprefix+name,text,size,font,colour);
}
void objectReset(string name,int i,int j,color colour=CLR_NONE)
{
x = xoffset+(spacingx*i); y = yoffset+(spacingy*j);
if (ObjectFind(name)>0) { ObjectDelete(name); }
objectCreate(name,x+10,y,CharToStr(152),textsize,"Wingdings 2",colour);
}
//----------------------------------------
void scan()
{
ctime = Time[0];
if (ctime == prevtime) { return(0); }
prevtime = ctime;
// loop through array of symbols
for ( int i = 0; i< ArraySize(symbol); i++)
{
// loop through timeframes
for (int j = 0; j < ArraySize(timeframe); j++)
{
iMA1 = iMA(symbol[i],timeframe[j],MA1,0,MODE_EMA,PRICE_CLOSE,0);
iMA2 = iMA(symbol[i],timeframe[j],MA2,0,MODE_EMA,PRICE_CLOSE,0);
iMA3 = iMA(symbol[i],timeframe[j],MA3,0,MODE_EMA,PRICE_CLOSE,0);
iMA4 = iMA(symbol[i],timeframe[j],MA4,0,MODE_EMA,PRICE_CLOSE,0);
double point =MarketInfo(symbol[i],MODE_POINT);
double digits =MarketInfo(symbol[i],MODE_DIGITS);
double mult=(digits==3 || digits==5)*10+(digits==2 || digits==4);
double ChannelWidth = NormalizeDouble(Channel*point*mult,digits);
// If MA are within a certain range of each other
if ( Monitor == True )
{
if (iMA1 > iMA2 && iMA2 > iMA3 && iMA3 > iMA4) { objectReset(symbol[i]+DoubleToStr(timeframe[j],0),i,j,Green); }
if ((iMA1 > iMA2 && iMA2 > iMA3 && iMA3 > iMA4)&&(MathAbs(iMA1-iMA4)<ChannelWidth)) { objectReset(symbol[i]+DoubleToStr(timeframe[j],0),i,j,Lime); }
if (iMA4 > iMA3 && iMA3 > iMA2 && iMA2 > iMA1) { objectReset(symbol[i]+DoubleToStr(timeframe[j],0),i,j,Crimson); }
if ((iMA4 > iMA3 && iMA3 > iMA2 && iMA2 > iMA1)&&(MathAbs(iMA1-iMA4)<ChannelWidth)) { objectReset(symbol[i]+DoubleToStr(timeframe[j],0),i,j,Red); }
}
else
{
objectReset(symbol[i]+DoubleToStr(timeframe[j],0),i,j,Gray);
}
}
}
}
Comments