This script is designed to create a specialized visual representation of market price movements known as a Renko chart. Unlike traditional charts that plot price based on time intervals (e.g., every minute or hour), this tool filters out "market noise" by focusing solely on price movement magnitude.
Core Logic Overview
The primary goal of the script is to convert standard price action into a series of uniform boxes (bricks). Each box represents a fixed price change. For a new brick to appear, the price must move a specific distance in one direction; if the price moves back within the range of the current brick, the chart remains unchanged.
Key Functionalities
- Fixed Box Movement: The user can define a "Box Size." The script monitors the live market and only draws a new price level once the market has moved by that specific amount. This creates a clean, step-like visual where every movement is of equal significance.
- Directional Recognition: The script tracks whether the current trend is bullish (upward) or bearish (downward).
- If the price continues in the current direction, it extends the existing "brick."
- If the price reverses and moves enough to surpass the previous brick's boundary, the script identifies a trend reversal.
- Dynamic Reversal Handling: When a trend reversal occurs, the script automatically handles the transition by:
- Creating a new directional brick.
- Adjusting the history of the bricks to maintain a consistent sequence.
- Updating the visual colors (typically switching between Blue for up-movements and Red for down-movements) to clearly signal a change in market sentiment.
- Real-Time Synchronization: The script is designed to stay updated with the live "Bid" price. It constantly recalculates the current position of the price relative to the last completed brick.
- Visual Management:
- Automatic Scaling: It manages the placement of objects on the chart, ensuring that as new bricks are formed, they appear in the correct chronological order.
- Time Shifting: To ensure the boxes remain aligned with the price action, the script can shift existing visual elements to accommodate the passage of time on the main chart.
- Reference Lines: It includes a silver horizontal line that tracks the current Bid price, allowing the user to see how close the current market action is to completing the next brick.
Summary for the User
Essentially, this script cleans up your view of the market. Instead of seeing every tiny fluctuation, it only shows you "meaningful" movements. It treats price action as a series of bricks: once a brick is finished, the next one begins in the new direction, providing a clear visual history of trend changes and momentum.
// Ticker Renko Box.mq4
// Èíäèêàòîð
#property copyright "mandorr@gmail.com"
#property indicator_separate_window
#property indicator_buffers 2
extern int BoxSize=5; // Ðàçìåð êèðïè÷à
extern int BarWidth=5; // Øèðèíà ëèíèè áàðà
int win_index;
int box_size;
int price_prev;
int tickers;
int bar_size;
int bar_high[];
int bar_low [];
int bar_dir [];
double box_range;
double box_backlash; // çàçîð
double buffer0 [];
double buffer1 [];
datetime time0;
void init() {
SetIndexBuffer(0,buffer0);
SetIndexBuffer(1,buffer1);
SetIndexStyle (0,DRAW_NONE);
SetIndexStyle (1,DRAW_NONE);
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
SetIndexLabel (0,"High");
SetIndexLabel (1,"Low");
SetIndexDrawBegin(0,0);
SetIndexDrawBegin(1,0);
IndicatorDigits(Digits);
for (int i=0; i<=1000; i++) {
buffer0[i]=0.0;
buffer1[i]=0.0;
}
box_size=MathMax(1,BoxSize);
box_range=box_size*Point;
box_backlash=Point; // çàçîð
time0=0;
price_prev=0;
tickers=0;
bar_size=0;
}
void deinit() {
ObjectsDeleteAll(win_index);
}
void start() {
int i, j, price, box_count, obj_total;
bool reverse;
string obj_name, win_name;
double high, low;
double price1, price2;
datetime time1, time2, time_shift;
price=MathRound(Bid/Point);
if (price==0) {return;}
if (price==price_prev) {return;}
tickers++;
win_name="Renko ("+BoxSize+")"+" Ticker ("+tickers+")";
IndicatorShortName(win_name);
win_index=WindowFind(win_name);
if (bar_size==0) {
bar_size=1;
time0=Time[0];
ArrayResize(bar_high,1);
ArrayResize(bar_low ,1);
ArrayResize(bar_dir, 1);
price_prev=10*(price/10); // ïðèâÿçêà ê öåíå, êðàòíîé 10 ïóíêòîâ
bar_high[0]=price_prev+box_size;
bar_low [0]=price_prev;
bar_dir [0]=1;
}
price_prev=price;
// Ïåðåìåùåíèå îáúåêòîâ îêíà íà 1 áàð âïðàâî, êîãäà ïîÿâëÿåòñÿ íîâûé áàð îñíîâíîãî ãðàôèêà
if (time0!=Time[0]) {
time0=Time[0];
obj_total=ObjectsTotal();
time_shift=Time[0]-Time[1];
for (i=0; i<obj_total; i++) {
obj_name=ObjectName(i);
if (ObjectFind(obj_name)!=win_index) {continue;}
if (obj_name=="Win"+win_index+"_Bid") {continue;}
price1=ObjectGet(obj_name,OBJPROP_PRICE1);
time1=ObjectGet(obj_name,OBJPROP_TIME1);
ObjectMove(obj_name,0,time1+time_shift,price1);
price2=ObjectGet(obj_name,OBJPROP_PRICE2);
time2=ObjectGet(obj_name,OBJPROP_TIME2);
ObjectMove(obj_name,1,time2+time_shift,price2);
}
}
box_count=0;
reverse=false;
if ((price>bar_high[0]) && (bar_dir[0]>0)) {
box_count=(price-bar_high[0])/box_size;
bar_high[0]=bar_high[0]+box_count*box_size;
}
if ((price<bar_low[0]) && (bar_dir[0]<0)) {
box_count=(bar_low[0]-price)/box_size;
bar_low[0]=bar_low[0]-box_count*box_size;
}
if ((price>bar_low[0]) && (bar_dir[0]<0)) {
box_count=(price-bar_low[0])/box_size;
if (box_count>1) {reverse=true;}
}
if ((price<bar_high[0]) && (bar_dir[0]>0)) {
box_count=(bar_high[0]-price)/box_size;
if (box_count>1) {reverse=true;}
}
if (reverse) {
bar_size++;
ArrayResize(bar_high,bar_size);
ArrayResize(bar_low ,bar_size);
ArrayResize(bar_dir ,bar_size);
for (i=bar_size-1; i>0; i--) {
bar_high[i]=bar_high[i-1];
bar_low [i]=bar_low [i-1];
bar_dir [i]=bar_dir [i-1];
}
if (bar_dir[1]<0) {
bar_high[0]=bar_low[1]+box_count*box_size;
bar_low [0]=bar_low[1]+box_size;
bar_dir [0]=1;
}
if (bar_dir[1]>0) {
bar_high[0]=bar_high[1]-box_size;
bar_low [0]=bar_high[1]-box_count*box_size;
bar_dir [0]=-1;
}
// Ïåðåìåùåíèå îáúåêòîâ îêíà íà 1 áàð âëåâî
obj_total=ObjectsTotal();
time_shift=Time[0]-Time[1];
for (i=0; i<obj_total; i++) {
obj_name=ObjectName(i);
if (ObjectFind(obj_name)!=win_index) {continue;}
if (obj_name=="Win"+win_index+"_Bid") {continue;}
price1=ObjectGet(obj_name,OBJPROP_PRICE1);
time1=ObjectGet(obj_name,OBJPROP_TIME1);
ObjectMove(obj_name,0,time1-time_shift,price1);
price2=ObjectGet(obj_name,OBJPROP_PRICE2);
time2=ObjectGet(obj_name,OBJPROP_TIME2);
ObjectMove(obj_name,1,time2-time_shift,price2);
}
}
for (i=0; i<bar_size; i++) {
buffer0[i]=bar_high[i]*Point;
buffer1[i]=bar_low [i]*Point;
}
buffer0[bar_size]=0.0;
buffer1[bar_size]=0.0;
high=bar_high[0]*Point;
low =bar_low [0]*Point;
time1=Time[0];
time2=Time[0];
box_count=(bar_high[0]-bar_low[0])/box_size;
color bar_color;
if (bar_dir[0]<0) {bar_color=Red;} else {bar_color=Blue;}
for (i=0; i<box_count; i++) {
price1=low+i*box_range;
price2=low+(i+1)*box_range-box_backlash;
if (i==box_count-1) {price2=low+(i+1)*box_range;} // ñàìûé âåðõíèé êèðïè÷ áåç çàçîðà
obj_name="Win"+win_index+"_Bar"+(bar_size-1)+"_Box"+i;
if (ObjectFind(obj_name)!=win_index) {
ObjectCreate(obj_name,OBJ_TREND,win_index,time1,price1,time2,price2);
}
ObjectSet(obj_name,OBJPROP_TIME1,time1);
ObjectSet(obj_name,OBJPROP_TIME2,time2);
ObjectSet(obj_name,OBJPROP_PRICE1,price1);
ObjectSet(obj_name,OBJPROP_PRICE2,price2);
ObjectSet(obj_name,OBJPROP_STYLE,DRAW_LINE);
ObjectSet(obj_name,OBJPROP_WIDTH,BarWidth);
ObjectSet(obj_name,OBJPROP_RAY,false);
ObjectSet(obj_name,OBJPROP_COLOR,bar_color);
}
obj_name="Win"+win_index+"_Bid";
if (ObjectFind(obj_name)!=win_index) {
ObjectCreate(obj_name,OBJ_HLINE,win_index,time1,Bid);
}
ObjectSet(obj_name,OBJPROP_PRICE1,Bid);
ObjectSet(obj_name,OBJPROP_STYLE,DRAW_LINE);
ObjectSet(obj_name,OBJPROP_WIDTH,1);
ObjectSet(obj_name,OBJPROP_COLOR,Silver);
}
// End
Comments