This indicator is designed to help traders quickly identify the current state of a market—specifically, whether a currency pair or asset is currently trending (moving with strength in a specific direction) or ranging (moving sideways without a clear trend).
By providing a visual summary across multiple timeframes simultaneously, the tool helps you determine which trading strategy is most appropriate for the current environment. For example, it suggests using moving averages when a strong trend is detected and oscillators when the market is consolidating in a range.
Core Logic and Functionality
Multi-Timeframe Analysis The script calculates specific technical data for three primary timeframes: 1 Hour, 4 Hours, and 1 Day. It looks at these intervals to give you a "big picture" view of the market's health, allowing you to see if short-term movements are aligned with or contradicting long-term trends.
Trend Strength & Direction Detection The indicator uses specific mathematical values to categorize the market into three distinct states:
- Ranging State: If the market strength is low, the indicator identifies the price action as "ranging." This serves as a warning that standard trend-following strategies might not be effective.
- Weak Trend: When the market begins to show some movement but hasn't reached full momentum, it identifies a developing upward or downward trend.
- Strong Trend: When the market reaches a high level of momentum, the indicator clearly distinguishes between a "Strong Up" and a "Strong Down" movement.
Visual Communication Instead of just showing raw numbers, the script translates this data into easy-to-read visual cues on your chart:
- Color Coding: The indicator dynamically changes colors based on market conditions. For instance, it uses specific colors to highlight upward momentum versus downward momentum, while using a different color to signal a non-trending (ranging) state.
- Directional Icons: It places specific symbols (arrows and squiggly lines) next to the timeframe data. These icons represent the "mood" of the market:
- Arrows point up or down to show the direction of the trend.
- Squiggly Lines indicate that the market is currently ranging.
Smart Alerts The script includes a built-in notification system. If it detects a significant shift in momentum (specifically on shorter timeframes), it can trigger an alert to notify you of the change in market direction instantly, helping you react faster to price action.
Summary for the Trader
The primary goal of this logic is to provide "at-a-glance" situational awareness. It removes the guesswork by telling you:
- Is it moving? (Trending vs. Ranging)
- Which way is it moving? (Up vs. Down)
- How fast is it moving? (Weak vs. Strong)
By monitoring all three timeframes at once, you can make more informed decisions about whether to take a trade, stay on the sidelines, or switch your technical tools based on the current market "weather."
//+------------------------------------------------------------------+
//| Trending or Ranging? |
//| ToR_1.02.mq4 |
//| Copyright © 2007 Tom Balfe |
//| |
//| This indicator shows you whether a pair is trending or ranging. |
//| For trending markets use moving averages and for ranging |
//| market use oscillators. |
//| |
//| It shows ADX values for multiple timeframes to help you |
//| decide which trading technique to use. |
//| Sometimes you'll see short-term trends against the H4 |
//| and D1 trend. |
//| |
//| It's up to you whether you trade in a ranging market. It seems |
//| to me that trading with the long-term trend is best. |
//| Having said that, the reason why I made this indicator is to |
//| to let the trader decide at a glance what to do, or even to |
//| do nothing. Staying out of a market is a position too. |
//| |
//| If you want to chat about FOREX my friends and I made an IRC |
//| channel on Undernet called #forex. |
//| |
//| Best of luck in all your trades! |
//| |
//| Version: 1.02 |
//| |
//| Changelog: |
//| 1.02 - added arrows, ranging icon, no zero space state |
//| for icons/arrows, spacing got messed up, now |
//| fixed |
//| 1.01 - unreleased, reduced number of colors, functional |
//| 1.0 - unreleased, too many colors for ADX values |
//| |
//| http://www.forex-tsd.com/members/nittany1.html |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007 Tom Balfe"
#property link "http://www.forex-tsd.com/members/nittany1.html"
#property link "redcarsarasota@yahoo.com"
#property indicator_separate_window
#define labelNames "Tor 1.03"
int spread;
//---- user selectable stuff
extern int SpreadThreshold=6;
extern bool Show_D1_ADX=true;
double alertBar;
double prev;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator short name
IndicatorShortName("ToR 1.03 ("+Symbol()+")");
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
for(int i = 1; i < 7; i++) deleteObject(i);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//---- let's define some stuff
// M5 data
//double adx_m5 = iADX(NULL,5,14,PRICE_CLOSE,0,0);
//double di_p_m5 = iADX(NULL,5,14,PRICE_CLOSE,1,0);
//double di_m_m5 = iADX(NULL,5,14,PRICE_CLOSE,2,0);
// M15 data
//double adx_m15 = iADX(NULL,15,14,PRICE_CLOSE,0,0);
//double di_p_m15 = iADX(NULL,15,14,PRICE_CLOSE,1,0);
//double di_m_m15 = iADX(NULL,15,14,PRICE_CLOSE,2,0);
// M30 data
//double adx_m30 = iADX(NULL,30,14,PRICE_CLOSE,0,0);
//double di_p_m30 = iADX(NULL,30,14,PRICE_CLOSE,1,0);
//double di_m_m30 = iADX(NULL,30,14,PRICE_CLOSE,2,0);
// H1 data
double adx_h1 = iADX(NULL,60,14,PRICE_CLOSE,0,0);
double di_p_h1 = iADX(NULL,60,14,PRICE_CLOSE,1,0);
double di_m_h1 = iADX(NULL,60,14,PRICE_CLOSE,2,0);
// H4 data
double adx_h4 = iADX(NULL,240,14,PRICE_CLOSE,0,0);
double di_p_h4 = iADX(NULL,240,14,PRICE_CLOSE,1,0);
double di_m_h4 = iADX(NULL,240,14,PRICE_CLOSE,2,0);
// D1 data
double adx_d1 = iADX(NULL,1440,14,PRICE_CLOSE,0,0);
double di_p_d1 = iADX(NULL,1440,14,PRICE_CLOSE,1,0);
double di_m_d1 = iADX(NULL,1440,14,PRICE_CLOSE,2,0);
//---- define colors and arrows
color adx_color_m5,adx_color_m15,adx_color_m30,adx_color_h1,adx_color_h4,adx_color_d1;
string adx_arrow_m5,adx_arrow_m15,adx_arrow_m30,adx_arrow_h1,adx_arrow_h4,adx_arrow_d1;
//---- store values into strings
//string adx_value_m5 = adx_m5;
//string adx_value_m15 = adx_m15;
//string adx_value_m30 = adx_m30;
string adx_value_h1 = adx_h1;
string adx_value_h4 = adx_h4;
string adx_value_d1 = adx_d1;
//---- assign colors
//adx_color_m5 = setColor(adx_m5 ,di_p_m5 ,di_m_m5);
//adx_color_m15 = setColor(adx_m15,di_p_m15,di_m_m15);
//adx_color_m30 = setColor(adx_m30,di_p_m30,di_m_m30);
adx_color_h1 = setColor(adx_h1 ,di_p_h1 ,di_m_h1);
adx_color_h4 = setColor(adx_h4 ,di_p_h4 ,di_m_h4);
adx_color_d1 = setColor(adx_d1 ,di_p_d1 ,di_m_d1);
//---- assign arrows
//adx_arrow_m5 = setArrow(adx_m5 ,di_p_m5 ,di_m_m5);
//adx_arrow_m15 = setArrow(adx_m15 ,di_p_m15 ,di_m_m15);
//adx_arrow_m30 = setArrow(adx_m30 ,di_p_m30 ,di_m_m30);
adx_arrow_h1 = setArrow(adx_h1 ,di_p_h1 ,di_m_h1);
adx_arrow_h4 = setArrow(adx_h4 ,di_p_h4 ,di_m_h4);
adx_arrow_d1 = setArrow(adx_d1 ,di_p_d1 ,di_m_d1);
//---- alert
if (prev != 1 && adx_arrow_m5 == "é" && adx_arrow_m15 == "é" && adx_arrow_m5 != "h" && adx_arrow_m15 != "h" && Bars>alertBar) {Alert("5 & 15 min ToR changing to Up on ",Symbol()," ", Period());alertBar = Bars;prev=1;}
if (prev != 2 && adx_arrow_m5 == "ê" && adx_arrow_m15 == "ê" && adx_arrow_m5 != "h" && adx_arrow_m15 != "h" && Bars>alertBar) {Alert("5 & 15 min ToR changing to Down on ",Symbol()," ", Period());alertBar = Bars;prev=2;}
//---- show it
//setLabel(1," 5 Min:",95 ,adx_value_m5 ,adx_color_m5 ,adx_arrow_m5);
//setLabel(2,"15 Min:",228,adx_value_m15,adx_color_m15,adx_arrow_m15);
//setLabel(3,"30 Min:",366,adx_value_m30,adx_color_m30,adx_arrow_m30);
setLabel(4," 1 Hr:",366,adx_value_h1 ,adx_color_h1 ,adx_arrow_h1);
setLabel(5," 4 Hr:",500,adx_value_h4 ,adx_color_h4 ,adx_arrow_h4);
if (Show_D1_ADX)
setLabel(6,"1 day:",642,adx_value_d1 ,adx_color_d1 ,adx_arrow_d1);
else deleteObject(6);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom functions and procedures |
//+------------------------------------------------------------------+
color setColor(double first,double second,double third)
{
color retColor;
if ((first < 23) && (first != 0)) { retColor = LightSkyBlue; }
if ((first >=23) && (second > third)) { retColor = Lime; }
if ((first >=23) && (second < third)) { retColor = Red; }
return(retColor);
}
//
//
// ---- assign arrows
// strong up: { adx_arrow_ = "é"; }
// strong down: { adx_arrow_ = "ê"; }
// up: { adx_arrow_ = "ì"; }
// down: { adx_arrow_ = "î"; }
// range: { adx_arrow_ = "h"; }
// use wingdings for these, the h is squiggly line
//
//
string setArrow(double first, double second, double third)
{
string arrow;
if ( first < 23 && first != 0) { arrow = "h"; }
if ((first >= 23 && first < 28) && (second > third)) { arrow = "ì"; }
if ((first >= 23 && first < 28) && (second < third)) { arrow = "î"; }
if ( first >= 28 && (second > third)) { arrow = "é"; }
if ( first >= 28 && (second < third)) { arrow = "ê"; }
return(arrow);
}
//
//
//
//
//
void setLabel(int name,string text,int x,string value, color theColor, string arrow)
{
setObject(name+"0001",text ,x);
setObject(name+"0002"," ADX "+StringSubstr(value,0,5),x+43 ,theColor);
setObject(name+"0003",arrow ,x+116,theColor,"Wingdings");
}
//
//
//
//
//
void setObject(string name,string text,int x,color theColor = LightSteelBlue, string font = "Lucida Sans Regular")
{
string indNames = "ToR 1.03 ("+Symbol()+")";
int window = WindowFind(indNames);
if (ObjectFind(labelNames+name) == -1)
{
ObjectCreate(labelNames+name,OBJ_LABEL,window,0,0);
ObjectSet(labelNames+name,OBJPROP_CORNER,0);
ObjectSet(labelNames+name,OBJPROP_XDISTANCE,x);
ObjectSet(labelNames+name,OBJPROP_YDISTANCE,2);
}
//
//
//
//
//
ObjectSetText(labelNames+name,text,9,font,theColor);
}
void deleteObject(int name)
{
if (ObjectFind(labelNames+name+"0001") > 0) {
ObjectDelete(labelNames+name+"0001");
ObjectDelete(labelNames+name+"0002");
ObjectDelete(labelNames+name+"0003");
}
}
//+------------------------------------------------------------------+
Comments