Urban_Towers
Download scriptThe Urban Towers script is a sophisticated visual technical analysis tool designed to identify market structure, trend momentum, and key price levels on a trading chart. It automates the process of analyzing moving averages and price action to highlight potential breakout zones and structural shifts.
Here is a detailed breakdown of the logic used by the script:
1. Dynamic Moving Average Ribbon
The foundation of the script is a "ribbon" consisting of six different Moving Averages (MA). Instead of using just one average, the script calculates several simultaneously with increasing periods. This allows the tool to visualize the "flow" of the market:
- Trend Identification: By comparing these moving averages against each other, the script determines the prevailing momentum.
- Volatility Mapping: The ribbon helps define the current trading range and the strength of the current price movement.
2. Trend Strength Analysis
The script doesn't just look at whether a price is up or down; it calculates a specific "Trend Count." It evaluates the relationship between the primary moving averages over a set number of previous bars. This helps filter out "noise" (minor fluctuations) and ensures that the script only reacts when there is a consistent, confirmed trend in place.
3. Advanced Price Action Filtering
To provide more accurate signals, the script looks for specific geometric patterns in price movement. It validates trades based on three main criteria:
- Structural Sequence: It checks if the "Highs" or "Lows" of recent bars are moving in a consistent direction (e.g., three consecutive higher highs).
- Moving Average Boundaries: The script identifies the highest and lowest points of the Moving Average ribbon at any given moment. It looks for instances where the price "breaks out" of these boundaries.
- Price Confirmation: A signal is only generated if the current candle closes decisively beyond a previous high or low, confirming that the momentum has shifted significantly enough to be actionable.
4. Visual Signaling and Level Mapping
Once the logic confirms a trend shift or breakout, the script provides immediate visual feedback:
- Directional Arrows: It places distinct arrows on the chart (Green for upward momentum, Red for downward) to highlight the exact moment a condition is met.
- Horizontal Support/Resistance Levels: The script automatically draws horizontal lines at key price points. These "Levels" act as visual anchors, showing where the market has established a new floor or ceiling following a trend change.
5. Automated Order Management (CloseBy)
The script includes an integrated logic for managing existing positions. It is programmed to monitor open trades and can automatically execute a "Close By" command. This is used to synchronize the closing of opposing positions (e.g., closing a Buy position using a Sell position) when specific volume and magic number criteria are met, helping to manage risk and clear the chart of overlapping orders.
Summary for the User
In short, this script acts as an intelligent filter. It ignores minor market fluctuations by requiring a multi-layered confirmation of Moving Average alignment, Price Action sequence, and Boundary breakouts. When all these factors align, it marks the level on your chart and provides a clear visual cue for the current market direction.
//+------------------------------------------------------------------+
//| +++Urban_Towers.mq4 |
//| Copyright © 2010, XrustSolution. |
//| mail: xrustx@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, XrustSolution."
#property link "mail: xrustx@gmail.com"
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 DodgerBlue
#property indicator_color2 DodgerBlue
#property indicator_color3 DodgerBlue
#property indicator_color4 Green
#property indicator_color5 Green
#property indicator_color8 Green
#property indicator_color6 Aqua
#property indicator_color7 Red
//+------------------------------------------------------------------+
extern int Start_Period_Ma = 9;
extern int Step_Period_Ma = 2;
extern int Ma_Price = 0;
extern int Ma_Metod = 1;
extern bool Show_Ma = true;
extern int Trand_back_count = 3;
//+------------------------------------------------------------------+
//---- buffers
double ma1[];
double ma2[];
double ma3[];
double ma4[];
double ma5[];
double ma6[];
double up[];
double dn[];
int draw = 0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
if(!Show_Ma){draw = 12;}
SetIndexStyle(0,draw);
SetIndexLabel(0,"MA1");
SetIndexBuffer(0,ma1);
SetIndexStyle(1,draw);
SetIndexLabel(0,"MA2");
SetIndexBuffer(1,ma2);
SetIndexStyle(2,draw);
SetIndexLabel(0,"MA3");
SetIndexBuffer(2,ma3);
SetIndexStyle(3,draw);
SetIndexLabel(0,"MA4");
SetIndexBuffer(3,ma4);
SetIndexStyle(4,draw);
SetIndexLabel(0,"MA5");
SetIndexBuffer(4,ma5);
SetIndexStyle(7,draw);
SetIndexLabel(0,"MA6");
SetIndexBuffer(7,ma6);
SetIndexStyle(5,DRAW_ARROW,EMPTY,2);
SetIndexArrow(5,233);
SetIndexBuffer(5,up);
SetIndexEmptyValue(5,0.0);
SetIndexStyle(6,DRAW_ARROW,EMPTY,2);
SetIndexArrow(6,234);
SetIndexBuffer(6,dn);
SetIndexEmptyValue(6,0.0);
//----
return(0);
}
//+------------------------------------------------------------------+
void deinit(){
for(int i=ObjectsTotal();i>=0;i--){
string nm = ObjectName(i);
if(StringSubstr(nm,0,5) == "Level"){ObjectDelete(nm);}
}
CloseBy(0);
return;}
//+------------------------------------------------------------------+
int start(){
int counted_bars=IndicatorCounted();
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
if(counted_bars == 0){ArrayInitialize(dn,0);ArrayInitialize(up,0);}
//----
for(int i = limit;i>=0;i--){
ma1[i] = iMA(Symbol(),Period(),Start_Period_Ma,0,Ma_Metod,Ma_Price,i);
ma2[i] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma,0,Ma_Metod,Ma_Price,i);
ma3[i] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*2,0,Ma_Metod,Ma_Price,i);
ma4[i] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*3,0,Ma_Metod,Ma_Price,i);
ma5[i] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*4,0,Ma_Metod,Ma_Price,i);
ma6[i] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*5,0,Ma_Metod,Ma_Price,i);
int trand = Trand(i,Trand_back_count);
if(trand>0){
if(High[i+3]>High[i+2]&&High[i+2]>High[i+1]){
if(High[i+3]>hi_lo(true,i+3)&&High[i+2]>hi_lo(true,i+2)&&High[i+1]>hi_lo(true,i+1)){
if(Low[i+2]<=hi_lo(true,i+2)||Low[i+1]<=hi_lo(true,i+1)){
if(Close[i]>High[i+1]){
SetLevel(true,i,High[i+1]);
up[i]=Low[i]-10*Point;
}
}
}
}
}
if(trand<0){
if(Low[i+3]<Low[i+2]&&Low[i+2]<Low[i+1]){
if(Low[i+3]<hi_lo(false,i+3)&&Low[i+2]<hi_lo(false,i+2)&&Low[i+1]<hi_lo(false,i+1)){
if(High[i+2]>=hi_lo(false,i+2)||High[i+1]>=hi_lo(false,i+1)){
if(Close[i]<Low[i+1]){
SetLevel(false,i,Low[i+1]);
dn[i]=High[i]+10*Point;
}
}
}
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
void SetLevel(bool bs,int co,double pr){color cl;
if(bs){cl = Blue;}else{cl = Red;}
string nm = "Level_"+Time[co];
if(ObjectFind(nm)!=0){ObjectCreate(nm,2,0,0,0,0,0);}
ObjectSet(nm,OBJPROP_TIME1,Time[co]+Period()*60*4);
ObjectSet(nm,OBJPROP_TIME2,Time[co+1]);
ObjectSet(nm,OBJPROP_PRICE1,pr);
ObjectSet(nm,OBJPROP_PRICE2,pr);
ObjectSet(nm,OBJPROP_COLOR,cl);
ObjectSet(nm,OBJPROP_WIDTH,2);
ObjectSet(nm,OBJPROP_STYLE,0);
ObjectSet(nm,OBJPROP_RAY,false);
return;
}
//+------------------------------------------------------------------+
double hi_lo(bool hl,int i){double pr[6],hi,lo;
pr[0] = iMA(Symbol(),Period(),Start_Period_Ma,0,Ma_Metod,Ma_Price,i);
pr[1] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma,0,Ma_Metod,Ma_Price,i);
pr[2] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*2,0,Ma_Metod,Ma_Price,i);
pr[3] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*3,0,Ma_Metod,Ma_Price,i);
pr[4] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*4,0,Ma_Metod,Ma_Price,i);
pr[5] = iMA(Symbol(),Period(),Start_Period_Ma+Step_Period_Ma*5,0,Ma_Metod,Ma_Price,i);
ArraySort(pr,WHOLE_ARRAY,0,MODE_DESCEND);
hi = pr[ArrayMaximum(pr)];
lo = pr[ArrayMinimum(pr)];
if(lo==0){lo = pr[ArrayMinimum(pr)-1];}
if(lo==0){lo = pr[ArrayMinimum(pr)-1];}
if(lo==0){lo = pr[ArrayMinimum(pr)-1];}
if(hl){return(hi);}else{return(lo);}
}
//+------------------------------------------------------------------+
int Trand(int pos,int co){int tr=0;
for(int i = pos;i<pos + co;i++){
if(ma1[i]>ma2[i+1]){tr++;}
if(ma1[i]<ma2[i+1]){tr--;}
}
return(tr);
}
bool CloseBy(int mn){int ticket=0,typ=-1;
for(int i=OrdersTotal();i>=0;i--){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
if(OrderSymbol() == Symbol()){
if(OrderLots() == 0.1){
if(OrderMagicNumber()==mn){
ticket = OrderTicket();
typ = OrderType();
break;
}
}
}
}
}
return;
if(ticket == 0){return(false);}
for(i=OrdersTotal();i>=0;i--){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
if(OrderSymbol() == Symbol()){
if(OrderLots() == 0.1/2){
if(OrderTicket()!=ticket){
if(OrderMagicNumber()==mn){
if(typ==0&&OrderType()==1){
if(OrderCloseBy(OrderTicket(),ticket,Green)){
return(true);
}else{return(false);}
}
if(typ==1&&OrderType()==0){
if(OrderCloseBy(OrderTicket(),ticket,Green)){
return(true);
}
}
}
}
}
}
}
}
return(false);
}
Comments