Vizion-Trading-EA/Scripts/gtp3.mq5

616 lines
46 KiB
MQL5
Raw Permalink Normal View History

<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Vizion_MFIB_MA_Stoch_Panel.mq5
//| Signals/labels + Risk/Reward (>=1:5) projection using:
//| - EMAs: 7,14,21,50,140,230,500,1400
//| - Stochastic timing labels
//| - Moving Fibs from ATH/ATL (dynamic), with 0.32 "stack" in BOTH directions
//| - SL uses MFIB + EMA14 (structural invalidation)
//| - TP uses nearest MFIB levels; auto-walks levels until RR>=1:5
//| This EA DOES NOT place trades. It only draws colored labels/levels.
//+------------------------------------------------------------------+
#property strict
#property version "1.10"
#property description "MFIB+MA+Stoch signals panel + RR>=1:5 SL/TP projection. No trading."
//-------------------------- Inputs ----------------------------------
input ENUM_TIMEFRAMES InpTF = PERIOD_CURRENT; // Timeframe
input int InpMFIB_LookbackBars = 12000; // MFIB ATH/ATL scan bars (0 = all available)
input double InpTolPoints = 30; // Touch tolerance (points) for level interactions
input int InpEvalBars = 6; // Recent bars to evaluate for reclaim/reject patterns
input double InpRR_Min = 5.0; // Minimum Risk:Reward
input double InpSL_BufferPoints = 80; // SL buffer (points) beyond structural level
input bool InpDrawMFIBLines = true; // Draw MFIB key lines + projected SL/TP
input bool InpShowCandleTag = true; // Show last-candle tag text
input int InpCorner = 0; // Panel corner (0=TL,1=TR,2=BL,3=BR)
input int InpX = 10; // Panel X offset
input int InpY = 14; // Panel Y offset
input int InpFontSize = 12; // Font size
// Stochastic inputs
input int InpStochK = 14;
input int InpStochD = 3;
input int InpStochSlowing = 3;
input ENUM_MA_METHOD InpStochMethod = MODE_SMA;
input ENUM_STO_PRICE InpStochPriceField = STO_LOWHIGH;
// Colors
input color ColBull = clrLime;
input color ColBear = clrTomato;
input color ColWarn = clrGold;
input color ColInfo = clrSilver;
input color ColDim = clrGray;
//-------------------------- Globals ---------------------------------
string PFX = "VIZ_MFIB_";
string PANEL_BG = "VIZ_PANEL_BG";
int hE7=-1, hE14=-1, hE21=-1, hE50=-1, hE140=-1, hE230=-1, hE500=-1, hE1400=-1;
int hStoch=-1;
// Key MFIB ratios (structure + targets). Includes extensions to help hit RR>=1:5
double g_ratios[] = {0.0, 0.32, 0.382, 0.5, 0.618, 0.705, 0.786, 1.0, 1.272, 1.618};
// Cached MFIB levels (bull direction: ATL -> ATH -> extensions above ATH)
double g_bullLevels[64];
int g_bullCount = 0;
// Cached MFIB levels (bear direction: ATH -> ATL -> extensions below ATL)
double g_bearLevels[64];
int g_bearCount = 0;
// Special: 0.32 in either direction = two  stack levels inside range
double g_mfib032_low = EMPTY_VALUE; // ATL + range*0.32
double g_mfib032_high = EMPTY_VALUE; // ATH - range*0.32 (i.e., ATL + range*0.68)
double g_ath = EMPTY_VALUE;
double g_atl = EMPTY_VALUE;
//-------------------------- Helpers ---------------------------------
bool ObjExists(const string name)
{
return (ObjectFind(0, name) >= 0);
}
void PutPanelBG()
{
if(!ObjExists(PANEL_BG))
{
ObjectCreate(0, PANEL_BG, OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, PANEL_BG, OBJPROP_CORNER, InpCorner);
ObjectSetInteger(0, PANEL_BG, OBJPROP_XDISTANCE, InpX-6);
ObjectSetInteger(0, PANEL_BG, OBJPROP_YDISTANCE, InpY-6);
ObjectSetInteger(0, PANEL_BG, OBJPROP_BGCOLOR, (color)RGB(18,18,18));
ObjectSetInteger(0, PANEL_BG, OBJPROP_COLOR, (color)RGB(60,60,60));
ObjectSetInteger(0, PANEL_BG, OBJPROP_BACK, true);
ObjectSetInteger(0, PANEL_BG, OBJPROP_WIDTH, 520);
ObjectSetInteger(0, PANEL_BG, OBJPROP_HEIGHT, 260);
ObjectSetInteger(0, PANEL_BG, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, PANEL_BG, OBJPROP_HIDDEN, true);
}
}
void PutLabel(const string shortName, const string text, const int x, const int y, const color col)
{
string obj = PFX + "LBL_" + shortName;
if(!ObjExists(obj))
{
ObjectCreate(0, obj, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, obj, OBJPROP_CORNER, InpCorner);
ObjectSetInteger(0, obj, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, obj, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, obj, OBJPROP_FONTSIZE, InpFontSize);
ObjectSetString(0, obj, OBJPROP_FONT, "Consolas");
ObjectSetInteger(0, obj, OBJPROP_BACK, false);
ObjectSetInteger(0, obj, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, obj, OBJPROP_HIDDEN, true);
}
ObjectSetString(0, obj, OBJPROP_TEXT, text);
ObjectSetInteger(0, obj, OBJPROP_COLOR, col);
}
void PutHLine(const string shortName, const double price, const color col, const ENUM_LINE_STYLE style=STYLE_SOLID)
{
string obj = PFX + "HLINE_" + shortName;
if(!ObjExists(obj))
{
ObjectCreate(0, obj, OBJ_HLINE, 0, 0, price);
ObjectSetInteger(0, obj, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, obj, OBJPROP_HIDDEN, true);
}
ObjectSetDouble(0, obj, OBJPROP_PRICE, price);
ObjectSetInteger(0, obj, OBJPROP_COLOR, col);
ObjectSetInteger(0, obj, OBJPROP_STYLE, style);
ObjectSetInteger(0, obj, OBJPROP_WIDTH, 1);
}
void PutCandleTag(const string text, const color col)
{
string obj = PFX + "CANDLE_TAG";
datetime t = iTime(_Symbol, InpTF, 0);
double p = iClose(_Symbol, InpTF, 0);
if(!ObjExists(obj))
{
ObjectCreate(0, obj, OBJ_TEXT, 0, t, p);
ObjectSetInteger(0, obj, OBJPROP_FONTSIZE, 10);
ObjectSetString(0, obj, OBJPROP_FONT, "Consolas");
ObjectSetInteger(0, obj, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, obj, OBJPROP_HIDDEN, true);
}
ObjectMove(0, obj, 0, t, p);
ObjectSetString(0, obj, OBJPROP_TEXT, text);
ObjectSetInteger(0, obj, OBJPROP_COLOR, col);
}
double GetLast(int handle, int bufferIndex=0, int shift=0)
{
double buf[];
if(CopyBuffer(handle, bufferIndex, shift, 1, buf) != 1) return EMPTY_VALUE;
return buf[0];
}
bool TouchedWithin(double high, double low, double level, double tolPrice)
{
return (high >= (level - tolPrice) && low <= (level + tolPrice));
}
double AbsD(double v){ return (v < 0 ? -v : v); }
// Find closest MFIB bull-level to price
double ClosestLevel(double price, const double &levels[], int count)
{
if(count <= 0) return EMPTY_VALUE;
double best = levels[0];
double bd = AbsD(price - best);
for(int i=1;i<count;i++)
{
double d = AbsD(price - levels[i]);
if(d < bd){ bd = d; best = levels[i]; }
}
return best;
}
double NextLevelUp(double price, const double &levels[], int count)
{
double best = EMPTY_VALUE;
for(int i=0;i<count;i++)
{
if(levels[i] > price)
{
if(best == EMPTY_VALUE || levels[i] < best) best = levels[i];
}
}
return best;
}
double NextLevelDown(double price, const double &levels[], int count)
{
double best = EMPTY_VALUE;
for(int i=0;i<count;i++)
{
if(levels[i] < price)
{
if(best == EMPTY_VALUE || levels[i] > best) best = levels[i];
}
}
return best;
}
int iHighestHigh(const string sym, ENUM_TIMEFRAMES tf, int bars)
{
return iHighest(sym, tf, MODE_HIGH, bars, 0);
}
int iLowestLow(const string sym, ENUM_TIMEFRAMES tf, int bars)
{
return iLowest(sym, tf, MODE_LOW, bars, 0);
}
// Build MFIB levels from ATH/ATL
bool BuildMFIB()
{
int barsAvail = Bars(_Symbol, InpTF);
if(barsAvail < 200) return false;
int scanBars = InpMFIB_LookbackBars;
if(scanBars <= 0 || scanBars > barsAvail) scanBars = barsAvail;
int hiIdx = iHighestHigh(_Symbol, InpTF, scanBars);
int loIdx = iLowestLow(_Symbol, InpTF, scanBars);
if(hiIdx < 0 || loIdx < 0) return false;
g_ath = iHigh(_Symbol, InpTF, hiIdx);
g_atl = iLow(_Symbol, InpTF, loIdx);
double range = g_ath - g_atl;
if(range <= 0) return false;
g_mfib032_low = g_atl + range * 0.32;
g_mfib032_high = g_ath - range * 0.32; // ATL + range*0.68
// Bull levels: ATL + range*ratio
g_bullCount = 0;
for(int i=0;i<ArraySize(g_ratios) && g_bullCount < 64;i++)
g_bullLevels[g_bullCount++] = g_atl + range * g_ratios[i];
// Bear levels: ATH - range*ratio (extensions below ATL for ratio>1)
g_bearCount = 0;
for(int j=0;j<ArraySize(g_ratios) && g_bearCount < 64;j++)
g_bearLevels[g_bearCount++] = g_ath - range * g_ratios[j];
return true;
}
void Cleanup()
{
int total = ObjectsTotal(0);
for(int i=total-1;i>=0;i--)
{
string name = ObjectName(0, i);
if(StringFind(name, PFX) == 0) ObjectDelete(0, name);
}
ObjectDelete(0, PANEL_BG);
}
//-------------------------- Init/Deinit ------------------------------
int OnInit()
{
ENUM_TIMEFRAMES tf = InpTF;
hE7 = iMA(_Symbol, tf, 7, 0, MODE_EMA, PRICE_CLOSE);
hE14 = iMA(_Symbol, tf, 14, 0, MODE_EMA, PRICE_CLOSE);
hE21 = iMA(_Symbol, tf, 21, 0, MODE_EMA, PRICE_CLOSE);
hE50 = iMA(_Symbol, tf, 50, 0, MODE_EMA, PRICE_CLOSE);
hE140 = iMA(_Symbol, tf, 140, 0, MODE_EMA, PRICE_CLOSE);
hE230 = iMA(_Symbol, tf, 230, 0, MODE_EMA, PRICE_CLOSE);
hE500 = iMA(_Symbol, tf, 500, 0, MODE_EMA, PRICE_CLOSE);
hE1400 = iMA(_Symbol, tf, 1400, 0, MODE_EMA, PRICE_CLOSE);
hStoch = iStochastic(_Symbol, tf, InpStochK, InpStochD, InpStochSlowing, InpStochMethod, InpStochPriceField);
if(hE7<0 || hE14<0 || hE21<0 || hE50<0 || hE140<0 || hE230<0 || hE500<0 || hE1400<0 || hStoch<0)
return INIT_FAILED;
PutPanelBG();
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
Cleanup();
}
//-------------------------- Main -------------------------------------
void OnTick()
{
PutPanelBG();
// Build MFIB (dynamic)
if(!BuildMFIB())
return;
double tolPrice = InpTolPoints * _Point;
double slBuf = InpSL_BufferPoints * _Point;
// Prices
double c0 = iClose(_Symbol, InpTF, 0);
double h0 = iHigh(_Symbol, InpTF, 0);
double l0 = iLow(_Symbol, InpTF, 0);
// EMA values
double e7 = GetLast(hE7);
double e14 = GetLast(hE14);
double e21 = GetLast(hE21);
double e50 = GetLast(hE50);
double e140 = GetLast(hE140);
double e230 = GetLast(hE230);
double e500 = GetLast(hE500);
double e1400 = GetLast(hE1400);
if(e14==EMPTY_VALUE || e1400==EMPTY_VALUE) return;
// Stoch values (buffer 0 = main %K, buffer 1 = signal %D)
double k0 = GetLast(hStoch, 0, 0);
double d0 = GetLast(hStoch, 1, 0);
double k1 = GetLast(hStoch, 0, 1);
double d1 = GetLast(hStoch, 1, 1);
bool stochOS = (k0 <= 20.0);
bool stochOB = (k0 >= 80.0);
bool stochBullCross = (k1 < d1 && k0 > d0);
bool stochBearCross = (k1 > d1 && k0 < d0);
// Reset logic (simple + effective)
bool stochBullReset = (k1 > 80.0 && k0 >= 40.0 && k0 <= 55.0 && k0 > k1);
bool stochBearReset = (k1 < 20.0 && k0 >= 45.0 && k0 <= 60.0 && k0 < k1);
bool stoch50Hold = (k0 >= 50.0 && k0 <= 60.0 && k0 > k1);
bool stoch50Fail = (k0 <= 50.0 && k0 >= 40.0 && k0 < k1);
// ---------- EMA14 Magnet logic (touch/reclaim/reject) over last N bars ----------
bool touched14=false, reclaimed14=false, rejected14=false;
for(int i=0;i<MathMax(1,InpEvalBars);i++)
{
double hi = iHigh(_Symbol, InpTF, i);
double lo = iLow(_Symbol, InpTF, i);
double cl = iClose(_Symbol, InpTF, i);
double e14i = GetLast(hE14, 0, i);
if(e14i==EMPTY_VALUE) continue;
if(TouchedWithin(hi, lo, e14i, tolPrice)) touched14 = true;
if(lo < e14i - tolPrice && cl > e14i + tolPrice) reclaimed14 = true;
if(hi > e14i + tolPrice && cl < e14i - tolPrice) rejected14 = true;
}
// ---------- MFIB 0.32 stack logic in BOTH directions ----------
bool touchLow032 = TouchedWithin(h0, l0, g_mfib032_low, tolPrice);
bool touchHigh032 = TouchedWithin(h0, l0, g_mfib032_high, tolPrice);
// MFIB mode:
// - BULL MODE if above upper 0.32 (the "bear 0.32" level) => strong structural bull
// - BEAR MODE if below lower 0.32 (the "bull 0.32" level) => strong structural bear
// - TRANSITION if between
string mfibMode = "TRANSITION";
color mfibModeCol = ColWarn;
if(c0 >= g_mfib032_high){ mfibMode="BULL MODE"; mfibModeCol=ColBull; }
else if(c0 <= g_mfib032_low){ mfibMode="BEAR MODE"; mfibModeCol=ColBear; }
// MFIB interaction label around 0.32 stack
string mfib032Txt = "MFIB 0.32 STACK: ";
color mfib032Col = ColWarn;
if(touchLow032 || touchHigh032)
{
// determine hold/reject by last close relative to touched level(s)
mfib032Txt += (touchLow032 && touchHigh032) ? "TOUCH (BOTH)" : (touchLow032 ? "TOUCH (LOW)" : "TOUCH (HIGH)");
mfib032Col = ColBull;
}
else
{
mfib032Txt += "NO CONTACT";
mfib032Col = ColDim;
}
// ---------- MA structure labels ----------
bool microBull = (e7 > e14 && e14 > e21);
bool microBear = (e7 < e14 && e14 < e21);
bool intradayBull = (e21 > e50);
bool intradayBear = (e21 < e50);
bool sessionBull = (c0 > e140 && c0 > e230);
bool sessionBear = (c0 < e140 && c0 < e230);
bool macroBull = (c0 > e500);
bool macroBear = (c0 < e500);
bool gravityBull = (c0 > e1400);
bool gravityBear = (c0 < e1400);
bool fullBull = (e7>e14 && e14>e21 && e21>e50 && e50>e140 && e140>e230 && e230>e500 && e500>e1400);
bool fullBear = (e7<e14 && e14<e21 && e21<e50 && e50<e140 && e140<e230 && e230<e500 && e500<e1400);
// MA chop (7..50 tangled)
double minMicro = MathMin(MathMin(e7,e14), MathMin(e21,e50));
double maxMicro = MathMax(MathMax(e7,e14), MathMax(e21,e50));
bool chop = ((maxMicro - minMicro) < (tolPrice * 6.0));
// ---------- Determine "direction suggestion" (signals-only, no trading) ----------
// Your logic: break/reject at MFIB or EMA14/50 with Stoch confirmation.
// We'll suggest LONG if MFIB mode bullish OR price is reclaiming EMA14 + Stoch supports.
bool suggestLong =
(mfibMode=="BULL MODE" && (microBull || intradayBull) && !macroBear && !gravityBear) ||
(reclaimed14 && (stochOS || stochBullCross || stochBullReset || stoch50Hold));
bool suggestShort =
(mfibMode=="BEAR MODE" && (microBear || intradayBear) && !macroBull && !gravityBull) ||
(rejected14 && (stochOB || stochBearCross || stochBearReset || stoch50Fail));
// If both, prefer macro/gravity
if(suggestLong && suggestShort)
{
if(macroBull || gravityBull) suggestShort = false;
else if(macroBear || gravityBear) suggestLong = false;
}
// ---------- Risk Management: SL/TP projection using MFIB + EMA14 ----------
string rrTxt="RR: n/a";
color rrCol=ColDim;
double entry = c0;
double entryLevel = EMPTY_VALUE;
// For entry-level: use closest MFIB level (bullLevels if long, bearLevels if short)
if(suggestLong) entryLevel = ClosestLevel(entry, g_bullLevels, g_bullCount);
if(suggestShort) entryLevel = ClosestLevel(entry, g_bearLevels, g_bearCount);
// Structural SL based on EMA14 + MFIB level
double sl = EMPTY_VALUE;
if(suggestLong && entryLevel!=EMPTY_VALUE)
sl = MathMin(e14, entryLevel) - slBuf;
else if(suggestShort && entryLevel!=EMPTY_VALUE)
sl = MathMax(e14, entryLevel) + slBuf;
// TP selection: nearest MFIB levels (walk up/down until RR>=InpRR_Min)
double tp = EMPTY_VALUE;
bool rrOK = false;
double rr = 0.0;
if(sl != EMPTY_VALUE)
{
double risk = AbsD(entry - sl);
if(risk > (2*_Point))
{
if(suggestLong)
{
// walk through bull levels above entry
double candidate = NextLevelUp(entry, g_bullLevels, g_bullCount);
while(candidate != EMPTY_VALUE)
{
rr = AbsD(candidate - entry) / risk;
if(rr >= InpRR_Min){ tp = candidate; rrOK=true; break; }
// move to next above candidate by temporarily treating candidate as price
candidate = NextLevelUp(candidate + _Point, g_bullLevels, g_bullCount);
}
}
else if(suggestShort)
{
// walk through bear levels below entry (bearLevels descend; we just pick next down numerically)
double candidate = NextLevelDown(entry, g_bearLevels, g_bearCount);
while(candidate != EMPTY_VALUE)
{
rr = AbsD(entry - candidate) / risk;
if(rr >= InpRR_Min){ tp = candidate; rrOK=true; break; }
candidate = NextLevelDown(candidate - _Point, g_bearLevels, g_bearCount);
}
}
}
}
if(rrOK)
{
rrTxt = StringFormat("RR VALID (>=1:%.1f): %.2f", InpRR_Min, rr);
rrCol = ColBull;
}
else if(suggestLong || suggestShort)
{
rrTxt = StringFormat("RR FAIL (<1:%.1f): %.2f (NO TRADE)", InpRR_Min, rr);
rrCol = ColWarn;
}
// ---------- Draw MFIB lines + projected SL/TP ----------
if(InpDrawMFIBLines)
{
PutHLine("MFIB032_LOW", g_mfib032_low, ColInfo, STYLE_DOT);
PutHLine("MFIB032_HIGH", g_mfib032_high, ColInfo, STYLE_DOT);
// Highlight mode anchor
if(mfibMode=="BULL MODE") PutHLine("MFIB_MODE", g_mfib032_high, ColBull, STYLE_DASH);
else if(mfibMode=="BEAR MODE") PutHLine("MFIB_MODE", g_mfib032_low, ColBear, STYLE_DASH);
if(sl!=EMPTY_VALUE) PutHLine("SL", sl, ColBear, STYLE_SOLID);
if(tp!=EMPTY_VALUE) PutHLine("TP", tp, ColBull, STYLE_SOLID);
}
// ---------- Build panel text ----------
int x=InpX, y=InpY;
int dy=InpFontSize+4;
PutLabel("HDR", "VIZION MFIB + MA + STOCH PANEL (Signals-only) | SL/TP via MFIB + EMA14", x, y, ColInfo); y += dy;
// MFIB mode + 0.32 stack
PutLabel("MFIBMODE", StringFormat("MFIB MODE (ATH/ATL): %s | ATL=%.5f ATH=%.5f", mfibMode, g_atl, g_ath), x, y, mfibModeCol); y += dy;
PutLabel("MFIB032", StringFormat("%s | LOW032=%.5f HIGH032=%.5f", mfib032Txt, g_mfib032_low, g_mfib032_high), x, y, mfib032Col); y += dy;
// EMA14 magnet
string magTxt="EMA14 MAGNET: ";
color magCol=ColWarn;
if(reclaimed14){ magTxt += "RECLAIM"; magCol=ColBull; }
else if(rejected14){ magTxt += "REJECT"; magCol=ColBear; }
else if(touched14){ magTxt += "HOLD/TOUCH"; magCol=ColBull; }
else { magTxt += "NO CONTACT"; magCol=ColDim; }
PutLabel("MAG", magTxt, x, y, magCol); y += dy;
// Micro
string microTxt="MICRO (7>14>21): ";
color microCol=ColWarn;
if(microBull){ microTxt+="BULL ALIGN"; microCol=ColBull; }
else if(microBear){ microTxt+="BEAR ALIGN"; microCol=ColBear; }
else { microTxt+="MIXED"; microCol=ColWarn; }
PutLabel("MICRO", microTxt, x, y, microCol); y += dy;
// Intraday/session/macro/gravity
PutLabel("INTRA", StringFormat("INTRADAY (21 vs 50): %s", intradayBull?"BULL CONTROL":(intradayBear?"BEAR CONTROL":"NEUTRAL")),
x, y, intradayBull?ColBull:(intradayBear?ColBear:ColWarn)); y += dy;
PutLabel("SESS", StringFormat("FLOW (140/230): %s", sessionBull?"ABOVE (FLOW UP)":(sessionBear?"BELOW (FLOW DOWN)":"INSIDE (CHOP RISK)")),
x, y, sessionBull?ColBull:(sessionBear?ColBear:ColWarn)); y += dy;
PutLabel("MACRO", StringFormat("MACRO (500): %s", macroBull?"ABOVE (BULL BIAS)":(macroBear?"BELOW (BEAR BIAS)":"AT (PIVOT)")),
x, y, macroBull?ColBull:(macroBear?ColBear:ColWarn)); y += dy;
PutLabel("GRAV", StringFormat("GRAVITY (1400): %s", gravityBull?"ABOVE (SUPPORT)":(gravityBear?"BELOW (CAP)":"AT (PIVOT)")),
x, y, gravityBull?ColBull:(gravityBear?ColBear:ColWarn)); y += dy;
// Dominance + Chop
string domTxt="DOMINANCE: ";
color domCol=ColWarn;
if(fullBull){ domTxt+="FULL BULL STACK"; domCol=ColBull; }
else if(fullBear){ domTxt+="FULL BEAR STACK"; domCol=ColBear; }
else { domTxt+="NOT FULL STACK"; domCol=ColWarn; }
PutLabel("DOM", domTxt, x, y, domCol); y += dy;
PutLabel("CHOP", chop ? "WARNING: MA CHOP ZONE (7-50 tangled)" : "CHOP: No (clean enough)",
x, y, chop?ColWarn:ColInfo); y += dy;
// Stoch labels
string stTxt = StringFormat("STOCH K=%.1f D=%.1f | ", k0, d0);
color stCol = ColInfo;
if(stochOS) { stTxt += "OS HOLD"; stCol = ColBull; }
else if(stochOB) { stTxt += "OB REJECT"; stCol = ColBear; }
else if(stochBullCross) { stTxt += "BULL CROSS"; stCol = ColBull; }
else if(stochBearCross) { stTxt += "BEAR CROSS"; stCol = ColBear; }
else if(stochBullReset) { stTxt += "BULL RESET"; stCol = ColBull; }
else if(stochBearReset) { stTxt += "BEAR RESET"; stCol = ColBear; }
else if(stoch50Hold) { stTxt += "50 HOLD"; stCol = ColBull; }
else if(stoch50Fail) { stTxt += "50 FAIL"; stCol = ColBear; }
else { stTxt += "NEUTRAL"; stCol = ColDim; }
PutLabel("STOCH", stTxt, x, y, stCol); y += dy;
// Suggestion + Risk box
string sigTxt="SIGNAL: ";
color sigCol=ColDim;
if((suggestLong || suggestShort) && !rrOK)
{
sigTxt += suggestLong ? "LONG BIAS (blocked by RR)" : "SHORT BIAS (blocked by RR)";
sigCol = ColWarn;
}
else if(suggestLong && rrOK)
{
sigTxt += "LONG CONFIRMED";
sigCol = ColBull;
}
else if(suggestShort && rrOK)
{
sigTxt += "SHORT CONFIRMED";
sigCol = ColBear;
}
else
{
sigTxt += "NO TRADE";
sigCol = ColDim;
}
PutLabel("SIG", sigTxt, x, y, sigCol); y += dy;
// SL/TP/RR display
string sltpTxt;
color sltpCol = rrOK ? ColBull : ColWarn;
if(sl!=EMPTY_VALUE && tp!=EMPTY_VALUE)
sltpTxt = StringFormat("ENTRY=%.5f SL=%.5f TP=%.5f | %s", entry, sl, tp, rrTxt);
else if(sl!=EMPTY_VALUE)
sltpTxt = StringFormat("ENTRY=%.5f SL=%.5f TP=n/a | %s", entry, sl, rrTxt);
else
sltpTxt = StringFormat("ENTRY=%.5f SL/TP=n/a | %s", entry, rrTxt);
PutLabel("RISK", sltpTxt, x, y, sltpCol); y += dy;
// Candle tag (optional)
if(InpShowCandleTag)
{
if(suggestLong && rrOK) PutCandleTag("LONG CONFIRMED", ColBull);
else if(suggestShort && rrOK)PutCandleTag("SHORT CONFIRMED", ColBear);
else if(reclaimed14) PutCandleTag("MAGNET RECLAIM", ColBull);
else if(rejected14) PutCandleTag("MAGNET REJECT", ColBear);
else if(touchLow032 || touchHigh032) PutCandleTag("MFIB 0.32 TOUCH", ColInfo);
else PutCandleTag(" ", ColDim);
}
}
//+------------------------------------------------------------------+