Vizion-Trading-EA/Experts/gtp3.mq5

497 lines
40 KiB
MQL5
Raw Permalink Normal View History

<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Vizion_MFIB_MA_Stoch_Panel_FIXED.mq5
//| FIXED for MQL5: no RGB(), uses XSIZE/YSIZE for OBJ_RECTANGLE_LABEL
//| Signals/labels + RR>=1:5 SL/TP projection using:
//| - EMAs: 7,14,21,50,140,230,500,1400
//| - Stochastic timing labels
//| - Moving Fibs from ATH/ATL (dynamic), with 0.32 stack BOTH directions
//| - SL uses MFIB + EMA14 (structural invalidation)
//| - TP uses nearest MFIB levels; walks levels until RR>=1:5
//| No trading. Draw-only.
//+------------------------------------------------------------------+
#property strict
#property version "1.11"
//-------------------------- 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)
input int InpEvalBars = 6; // Bars to evaluate reclaim/reject
input double InpRR_Min = 5.0; // Minimum Risk:Reward
input double InpSL_BufferPoints = 80; // SL buffer (points)
input bool InpDrawMFIBLines = true; // Draw MFIB + SL/TP lines
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;
// Panel size
input int InpPanelW = 520;
input int InpPanelH = 260;
//-------------------------- 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;
// Ratios: includes extensions so we can reach RR>=1:5 using structure
double g_ratios[] = {0.0, 0.32, 0.382, 0.5, 0.618, 0.705, 0.786, 1.0, 1.272, 1.618};
double g_bullLevels[64]; int g_bullCount=0;
double g_bearLevels[64]; int g_bearCount=0;
double g_mfib032_low = EMPTY_VALUE; // ATL + range*0.32
double g_mfib032_high = EMPTY_VALUE; // ATH - range*0.32 (ATL + range*0.68)
double g_ath = EMPTY_VALUE;
double g_atl = EMPTY_VALUE;
//-------------------------- Helpers ---------------------------------
color RGBc(const int r,const int g,const int b)
{
int rr = MathMax(0, MathMin(255, r));
int gg = MathMax(0, MathMin(255, g));
int bb = MathMax(0, MathMin(255, b));
return (color)(rr | (gg<<8) | (bb<<16));
}
bool ObjExists(const string name){ return (ObjectFind(0,name) >= 0); }
double AbsD(const double v){ return (v < 0 ? -v : v); }
double GetLast(const int handle, const int bufferIndex=0, const int shift=0)
{
double buf[];
if(CopyBuffer(handle, bufferIndex, shift, 1, buf) != 1) return EMPTY_VALUE;
return buf[0];
}
bool TouchedWithin(const double high,const double low,const double level,const double tolPrice)
{
return (high >= (level - tolPrice) && low <= (level + tolPrice));
}
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, (long)RGBc(18,18,18));
ObjectSetInteger(0, PANEL_BG, OBJPROP_COLOR, (long)RGBc(60,60,60));
ObjectSetInteger(0, PANEL_BG, OBJPROP_BACK, true);
ObjectSetInteger(0, PANEL_BG, OBJPROP_XSIZE, InpPanelW);
ObjectSetInteger(0, PANEL_BG, OBJPROP_YSIZE, InpPanelH);
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_SELECTABLE, false);
ObjectSetInteger(0, obj, OBJPROP_HIDDEN, true);
}
ObjectSetString (0, obj, OBJPROP_TEXT, text);
ObjectSetInteger(0, obj, OBJPROP_COLOR, (long)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, (long)col);
ObjectSetInteger(0, obj, OBJPROP_STYLE, style);
ObjectSetInteger(0, obj, OBJPROP_WIDTH, 1); // OK for HLINE
}
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, (long)col);
}
double ClosestLevel(const double price,const double &levels[],const 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(const double price,const double &levels[],const int count)
{
double best = EMPTY_VALUE;
for(int i=0;i<count;i++)
if(levels[i] > price && (best==EMPTY_VALUE || levels[i] < best)) best = levels[i];
return best;
}
double NextLevelDown(const double price,const double &levels[],const int count)
{
double best = EMPTY_VALUE;
for(int i=0;i<count;i++)
if(levels[i] < price && (best==EMPTY_VALUE || levels[i] > best)) best = levels[i];
return best;
}
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 = iHighest(_Symbol, InpTF, MODE_HIGH, scanBars, 0);
int loIdx = iLowest (_Symbol, InpTF, MODE_LOW, scanBars, 0);
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;
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];
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();
if(!BuildMFIB()) return;
double tolPrice = InpTolPoints * _Point;
double slBuf = InpSL_BufferPoints * _Point;
double c0 = iClose(_Symbol, InpTF, 0);
double h0 = iHigh (_Symbol, InpTF, 0);
double l0 = iLow (_Symbol, InpTF, 0);
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;
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);
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 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 (both directions)
bool touchLow032 = TouchedWithin(h0, l0, g_mfib032_low, tolPrice);
bool touchHigh032 = TouchedWithin(h0, l0, g_mfib032_high, tolPrice);
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; }
// MA structure
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);
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));
// Suggestion (signals-only)
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(suggestLong && suggestShort)
{
if(macroBull || gravityBull) suggestShort=false;
else if(macroBear || gravityBear) suggestLong=false;
}
// Risk management: SL via EMA14+closest MFIB, TP via nearest MFIB until RR>=1:5
double entry = c0;
double entryLevel = EMPTY_VALUE;
if(suggestLong) entryLevel = ClosestLevel(entry, g_bullLevels, g_bullCount);
if(suggestShort) entryLevel = ClosestLevel(entry, g_bearLevels, g_bearCount);
double sl = EMPTY_VALUE;
if(suggestLong && entryLevel!=EMPTY_VALUE) sl = MathMin(e14, entryLevel) - slBuf;
if(suggestShort && entryLevel!=EMPTY_VALUE) sl = MathMax(e14, entryLevel) + slBuf;
double tp = EMPTY_VALUE;
double rr = 0.0;
bool rrOK = false;
if(sl!=EMPTY_VALUE)
{
double risk = AbsD(entry - sl);
if(risk > (2*_Point))
{
if(suggestLong)
{
double cand = NextLevelUp(entry, g_bullLevels, g_bullCount);
while(cand!=EMPTY_VALUE)
{
rr = AbsD(cand - entry) / risk;
if(rr >= InpRR_Min){ tp=cand; rrOK=true; break; }
cand = NextLevelUp(cand + _Point, g_bullLevels, g_bullCount);
}
}
else if(suggestShort)
{
double cand = NextLevelDown(entry, g_bearLevels, g_bearCount);
while(cand!=EMPTY_VALUE)
{
rr = AbsD(entry - cand) / risk;
if(rr >= InpRR_Min){ tp=cand; rrOK=true; break; }
cand = NextLevelDown(cand - _Point, g_bearLevels, g_bearCount);
}
}
}
}
// Draw key lines
if(InpDrawMFIBLines)
{
PutHLine("MFIB032_LOW", g_mfib032_low, ColInfo, STYLE_DOT);
PutHLine("MFIB032_HIGH", g_mfib032_high, ColInfo, STYLE_DOT);
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);
}
// Panel
int x=InpX, y=InpY;
int dy=InpFontSize+4;
PutLabel("HDR","VIZION MFIB + MA + STOCH PANEL (FIXED) | SL/TP via MFIB + EMA14 | No trading", x,y,ColInfo); y+=dy;
PutLabel("MFIBMODE", StringFormat("MFIB MODE: %s | ATL=%.5f ATH=%.5f", mfibMode, g_atl, g_ath), x,y,mfibModeCol); y+=dy;
string mfib032Txt = StringFormat("MFIB 0.32 STACK: %s | LOW032=%.5f HIGH032=%.5f",
(touchLow032||touchHigh032) ? (touchLow032&&touchHigh032 ? "TOUCH (BOTH)" : (touchLow032?"TOUCH (LOW)":"TOUCH (HIGH)")) : "NO CONTACT",
g_mfib032_low, g_mfib032_high);
PutLabel("MFIB032", mfib032Txt, x,y, (touchLow032||touchHigh032)?ColBull:ColDim ); y+=dy;
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;
PutLabel("MICRO", StringFormat("MICRO (7/14/21): %s", microBull?"BULL ALIGN":(microBear?"BEAR ALIGN":"MIXED")),
x,y, microBull?ColBull:(microBear?ColBear:ColWarn)); y+=dy;
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("FLOW", StringFormat("FLOW (140/230): %s", sessionBull?"ABOVE (UP)":(sessionBear?"BELOW (DOWN)":"INSIDE (RISK)")),
x,y, sessionBull?ColBull:(sessionBear?ColBear:ColWarn)); y+=dy;
PutLabel("MACRO", StringFormat("MACRO (500): %s", macroBull?"ABOVE":(macroBear?"BELOW":"AT/PIVOT")),
x,y, macroBull?ColBull:(macroBear?ColBear:ColWarn)); y+=dy;
PutLabel("GRAV", StringFormat("GRAVITY (1400): %s", gravityBull?"ABOVE":(gravityBear?"BELOW":"AT/PIVOT")),
x,y, gravityBull?ColBull:(gravityBear?ColBear:ColWarn)); y+=dy;
PutLabel("DOM", StringFormat("DOMINANCE: %s", fullBull?"FULL BULL STACK":(fullBear?"FULL BEAR STACK":"NOT FULL STACK")),
x,y, fullBull?ColBull:(fullBear?ColBear:ColWarn)); y+=dy;
PutLabel("CHOP", chop?"WARNING: MA CHOP (7-50 tangled)":"CHOP: No", x,y, chop?ColWarn:ColInfo); y+=dy;
string stTxt = StringFormat("STOCH K=%.1f D=%.1f | ", k0, d0);
color stCol = ColDim;
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;
string sigTxt="SIGNAL: ";
color sigCol=ColDim;
if((suggestLong || suggestShort) && !rrOK){ sigTxt += suggestLong?"LONG BIAS (RR BLOCKED)":"SHORT BIAS (RR BLOCKED)"; 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;
string rrTxt;
color rrCol = rrOK ? ColBull : ((suggestLong||suggestShort)?ColWarn:ColDim);
if(sl!=EMPTY_VALUE && tp!=EMPTY_VALUE)
rrTxt = StringFormat("ENTRY=%.5f SL=%.5f TP=%.5f | RR=%.2f (min 1:%.1f)", entry, sl, tp, rr, InpRR_Min);
else if(sl!=EMPTY_VALUE)
rrTxt = StringFormat("ENTRY=%.5f SL=%.5f TP=n/a | RR=%.2f (min 1:%.1f)", entry, sl, rr, InpRR_Min);
else
rrTxt = StringFormat("ENTRY=%.5f SL/TP=n/a | RR=n/a (min 1:%.1f)", entry, InpRR_Min);
PutLabel("RISK", rrTxt, x,y,rrCol); y+=dy;
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);
}
}
//+------------------------------------------------------------------+