Vigiar
1
0
Derivar
Você já tinha feito uma derivação do repositório displacement-order-blocks, anteriormente
0
displacement-order-blocks/mql4/Indicators/DisplacementOrderBlocks/DzDraw.mqh
Allan Niñal Allan Niñal 90f38abc9c Free source regenerated: Pro-only code removed from the engine, debug log added
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 12:15:21 +08:00
//+------------------------------------------------------------------+
//| DzDraw.mqh |
//| Copyright 2026, Allan Niñal |
//| https://www.allanninal.dev/mql5 |
//+------------------------------------------------------------------+
//| Draws a CDzEngine's zones on the chart: rectangles (fresh filled,|
//| tested outlined, broken grey up to the bar that broke them), the |
//| middle line, a short label and the broken swing. Objects share |
//| one prefix and are rebuilt only when a bar closes. |
//| MT4 edition: MT4 fills a rectangle only when it is drawn in the |
//| background, so OBJPROP_BACK follows the fill (else as MT5). |
//+------------------------------------------------------------------+
// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0 (see LICENSE)
#property strict
#ifndef DZDRAW_MQH
#define DZDRAW_MQH
#include "DzEngine.mqh"
#include "ObjSync.mqh"
int g_dz_fail=0; // objects the chart refused in the current pass
struct SDzStyle
{
bool fill,show_tested,show_broken,midline,labels,swings,show_filtered;
int draw_bars,max_zones,extend;
color dem,sup,broken,outline;
};
void DzRect(const string name,const datetime t1,const double top,const datetime t2,const double bot,const color clr,
const bool fill,const ENUM_LINE_STYLE style,const string tip)
{
if(!OsPlace(name,OBJ_RECTANGLE,2,t1,top,t2,bot))
{
g_dz_fail++;
return;
}
OsInt(name,OBJPROP_COLOR,clr);
OsInt(name,OBJPROP_FILL,fill);
OsInt(name,OBJPROP_STYLE,style);
OsInt(name,OBJPROP_BACK,fill);
OsInt(name,OBJPROP_WIDTH,1);
OsStr(name,OBJPROP_TOOLTIP,tip);
}
void DzSeg(const string name,const datetime t1,const double p1,const datetime t2,const double p2,const color clr,
const ENUM_LINE_STYLE style,const string tip)
{
if(!OsPlace(name,OBJ_TREND,2,t1,p1,t2,p2))
{
g_dz_fail++;
return;
}
OsInt(name,OBJPROP_COLOR,clr);
OsInt(name,OBJPROP_STYLE,style);
OsInt(name,OBJPROP_RAY_RIGHT,false);
OsInt(name,OBJPROP_BACK,true);
OsStr(name,OBJPROP_TOOLTIP,tip);
}
void DzText(const string name,const datetime t,const double p,const string text,const color clr,const ENUM_ANCHOR_POINT anchor)
{
if(!OsPlace(name,OBJ_TEXT,1,t,p,0,0))
{
g_dz_fail++;
return;
}
OsStr(name,OBJPROP_TEXT,text);
OsInt(name,OBJPROP_COLOR,clr);
OsInt(name,OBJPROP_FONTSIZE,8);
OsInt(name,OBJPROP_ANCHOR,anchor);
}
string DzStateText(const SDzZone &z)
{
if(z.state==DZ_FRESH)
return("fresh");
if(z.state==DZ_TESTED)
return(z.retests>1 ? StringFormat("tested, %d entries",z.retests) : "tested");
if(z.state==DZ_BROKEN)
return("broken");
return("dropped (zone limit)");
}
//--- a small corner label with the validated market structure after the last closed bar
void DzTrendLabel(const string name,CDzEngine &e,const string tfname,const ENUM_BASE_CORNER corner,const int x,const int y,
const color clr,const int digits)
{
if(e.done<1)
return;
string tx=StringFormat("%sValidated trend: %s (validated %s %s)",tfname!="" ? tfname+" " : "",e.Trend()>0 ? "up" : "down",
e.Trend()>0 ? "low" : "high",DoubleToString(e.ValidLevel(),digits));
if(!OsPlace(name,OBJ_LABEL,1,0,0,0,0))
{
g_dz_fail++;
return;
}
OsInt(name,OBJPROP_CORNER,corner);
OsInt(name,OBJPROP_ANCHOR,(corner==CORNER_RIGHT_UPPER || corner==CORNER_RIGHT_LOWER) ? ANCHOR_RIGHT_UPPER : ANCHOR_LEFT_UPPER);
OsInt(name,OBJPROP_XDISTANCE,x);
OsInt(name,OBJPROP_YDISTANCE,y);
OsInt(name,OBJPROP_COLOR,clr);
OsInt(name,OBJPROP_FONTSIZE,9);
OsStr(name,OBJPROP_TEXT,tx);
}
//--- draw the zones of one engine; `t` = bar times of the series it ran on. `tfname` != "" marks a higher timeframe.
int DzDrawEngine(CDzEngine &e,const datetime &t[],const string pfx,const string tfname,const datetime from_t,
const datetime right_t,const int budget,const SDzStyle &st,const int digits)
{
int drawn=0;
bool htf=(tfname!="");
for(int z=e.nz-1; z>=0 && drawn<budget; z--)
{
if(t[e.zones[z].born]<from_t)
break; // zones are stored in birth order: all older ones are out too
int s=e.zones[z].state;
bool shown=e.zones[z].ok; // false: left out by the trend or reward-to-risk option
if(s==DZ_DROPPED || (s==DZ_TESTED && !st.show_tested) || (s==DZ_BROKEN && !st.show_broken) || (!shown && !st.show_filtered))
continue;
bool dem=(e.zones[z].dir>0),live=(e.zones[z].end<0);
color clr=(!shown || s==DZ_BROKEN ? st.broken : (htf ? st.outline : (dem ? st.dem : st.sup)));
datetime t2=(live ? right_t : t[e.zones[z].end]);
string tip=StringFormat("%s%s zone %s - %s, made %s, %s",htf ? tfname+" " : "",dem ? "Demand" : "Supply",
DoubleToString(e.zones[z].bot,digits),DoubleToString(e.zones[z].top,digits),
TimeToString(t[e.zones[z].born]),DzStateText(e.zones[z]));
tip+=StringFormat(", validated trend %s, reward-to-risk %.1f",e.zones[z].trend>0 ? "up" : "down",e.zones[z].rr);
if(!shown)
tip+=" - left out by the trend / reward-to-risk option";
string nm=StringFormat("%sZ%d",pfx,z);
bool fill=(st.fill && !htf && s==DZ_FRESH && shown);
DzRect(nm,t[e.zones[z].t0],e.zones[z].top,t2,e.zones[z].bot,clr,fill,!shown ? STYLE_DOT : (s==DZ_TESTED ? STYLE_DASH : STYLE_SOLID),tip);
if(st.midline && shown)
DzSeg(nm+"m",t[e.zones[z].t0],e.zones[z].mid,t2,e.zones[z].mid,clr,STYLE_DOT,tip);
if(st.labels && shown)
{
string lb=(htf ? tfname+" " : "")+(dem ? "D" : "S")+(e.zones[z].retests>1 ? "x"+IntegerToString(e.zones[z].retests) : "");
DzText(nm+"l",t[e.zones[z].t0],dem ? e.zones[z].bot : e.zones[z].top,lb,clr,dem ? ANCHOR_LEFT_UPPER : ANCHOR_LEFT_LOWER);
}
drawn++;
}
int shown=0;
if(st.swings && !htf)
for(int b=e.nb-1; b>=0 && shown<budget; b--)
{
if(t[e.breaks[b].at]<from_t)
break;
if(e.breaks[b].zone<0 || !e.zones[e.breaks[b].zone].ok)
continue;
bool up=(e.breaks[b].dir>0);
DzSeg(StringFormat("%sB%d",pfx,b),t[e.breaks[b].frm],e.breaks[b].level,t[e.breaks[b].at],e.breaks[b].level,
up ? st.dem : st.sup,STYLE_DOT,up ? "Swing high closed through with displacement" : "Swing low closed through with displacement");
shown++;
}
return(drawn);
}
#endif
//+------------------------------------------------------------------+