615 líneas
46 KiB
MQL5
615 líneas
46 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|