Vizion-Trading-EA/Experts/gpt5.mq5
2026-02-19 23:19:25 -06:00

1153 lines
No EOL
74 KiB
MQL5

//+------------------------------------------------------------------+
//| QuarterTheory_MFIB_Enhanced.mq5 |
//| MFIB 0.32 + EMA14 Magnet + Stoch Confirmations + Labels |
//| Aggressive Multi-Setup System with Smart Filtering |
//+------------------------------------------------------------------+
#property copyright "MFIB Enhanced System"
#property version "16.00"
#property strict
#include <Trade/Trade.mqh>
CTrade Trade;
//================ INPUT PARAMETERS ==================//
input group "=== GENERAL ==="
input int MagicNumber = 456789;
input double Risk_Per_Trade = 1.2;
input int Min_Active_Entries = 8;
input int Max_Simultaneous_Trades = 20;
input group "=== MOVING FIBS (PRIMARY!) ==="
input int MFIB_Lookback = 200;
input bool Show_MFIB_Levels = true;
input int MFIB_Touch_Buffer = 30; // Buffer in points for level detection
input bool Require_MFIB_Interaction = true; // No MFIB = no trade
input group "=== MA MAGNET SYSTEM ==="
input int MA_1 = 7; // Trigger
input int MA_2 = 14; // MAGNET (Core)
input int MA_3 = 21; // Structure
input int MA_4 = 50; // Structure
input int MA_5 = 140; // Flow
input int MA_6 = 230; // Mean
input int MA_7 = 500; // Macro
input int MA_8 = 1000;
input int MA_9 = 1100;
input int MA_10 = 1400; // Gravity
input int MA_Touch_Buffer = 30;
input int Min_MA14_Crosses = 1; // Using MA14 as primary now
input group "=== STOCHASTIC CONFIRMATION ==="
input int Stoch_K_Period = 5;
input int Stoch_D_Period = 3;
input int Stoch_Slowing = 3;
input bool Use_Stoch_Confirmation = true;
input group "=== TRADE SETUP FILTERS ==="
input bool Allow_Structural_Bounce = true; // Setup 1
input bool Allow_Structural_Break = true; // Setup 2
input bool Allow_Magnet_Snapback = true; // Setup 3
input bool Allow_MFIB_Continuation = true; // Setup 4
input bool Allow_Failed_Break = true; // Setup 5
input bool Allow_Triple_Confluence = true; // Setup 6
input bool Filter_Dead_Zones = true; // Block chop zones
input group "=== RISK MANAGEMENT (800pts → 5000pts) ==="
input double Risk_Reward_Ratio = 6.25; // 800 pts risk → 5000 pts profit
input bool Use_Fib_Based_SLTP = true; // SL/TP to nearest Fib
input int Default_SL_Points = 800; // Default SL distance
input int Default_TP_Points = 5000; // Default TP distance
input int Move_BE_At_Points = 300; // Move to BE
input int Trailing_SL_Points = 500; // Trailing distance
input double Partial_TP_Percent = 25.0; // Close 25% per hit
input group "=== DAILY LIMITS ==="
input double Max_Daily_Loss_Percent = 5.0;
input double Max_Daily_Profit_Percent = 30.0;
input int Max_Trades_Per_Day = 40;
//================ GLOBALS ==================//
int Stoch_Handle;
double Stoch_K_Current = 0;
double Stoch_K_Previous = 0;
double Stoch_K_Old = 0;
// MFIB System
double MFIB_ATH = 0;
double MFIB_ATL = 0;
double MFIB_032 = 0; // Key structural level
double MFIB_0236 = 0;
double MFIB_05 = 0;
double MFIB_0618 = 0;
double MFIB_0786 = 0;
bool MFIB_Bull_Mode = false;
bool MFIB_Bear_Mode = false;
datetime Last_MFIB_Calc = 0;
int MA_Handles[10];
double MA_Current[10];
double MA_Previous[10];
double MA_Old[10];
bool Current_Trend_Bullish = false;
bool Current_Trend_Bearish = false;
bool Previous_Trend_Bullish = false;
bool Previous_Trend_Bearish = false;
datetime Last_Trend_Check = 0;
struct Position
{
ulong ticket;
double entry;
double sl_level;
double tp_level;
double original_lot;
bool is_buy;
bool be_set;
int partials_closed;
string setup_type;
};
Position OpenPositions[];
double DailyStart = 0;
int TodayTrades = 0;
datetime LastDay = 0;
//+------------------------------------------------------------------+
int OnInit()
{
Print("========================================");
Print("MFIB ENHANCED SYSTEM v16.0");
Print("MFIB 0.32 + EMA14 Magnet + Stoch");
Print("6 Setup Types + Smart Filtering");
Print("AGGRESSIVE: 800pts → 5000pts (1:6.25)");
Print("========================================");
Trade.SetExpertMagicNumber(MagicNumber);
Trade.SetDeviationInPoints(50);
Stoch_Handle = iStochastic(_Symbol, PERIOD_CURRENT, Stoch_K_Period, Stoch_D_Period,
Stoch_Slowing, MODE_SMA, STO_LOWHIGH);
if(Stoch_Handle == INVALID_HANDLE)
{
Print("ERROR: Stochastic failed");
return INIT_FAILED;
}
int periods[10] = {MA_1, MA_2, MA_3, MA_4, MA_5, MA_6, MA_7, MA_8, MA_9, MA_10};
for(int i=0; i<10; i++)
{
MA_Handles[i] = iMA(_Symbol, PERIOD_CURRENT, periods[i], 0, MODE_EMA, PRICE_CLOSE);
if(MA_Handles[i] == INVALID_HANDLE)
{
Print("ERROR: MA ", periods[i], " failed");
return INIT_FAILED;
}
}
CalculateMFIB();
if(Show_MFIB_Levels) DrawMFIBLevels();
DailyStart = AccountInfoDouble(ACCOUNT_BALANCE);
Print("MFIB 0.32 Level: ", MFIB_032);
Print("EMA14 Magnet: ENABLED");
Print("Risk:Reward = 1:", Risk_Reward_Ratio, " (800pts → 5000pts)");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
for(int i=0; i<10; i++)
if(MA_Handles[i] != INVALID_HANDLE)
IndicatorRelease(MA_Handles[i]);
if(Stoch_Handle != INVALID_HANDLE)
IndicatorRelease(Stoch_Handle);
ObjectsDeleteAll(0, "MFIB_");
ObjectsDeleteAll(0, "Arrow_");
ObjectsDeleteAll(0, "Label_");
}
//+------------------------------------------------------------------+
//| CALCULATE MOVING FIBS (MFIB)
//+------------------------------------------------------------------+
void CalculateMFIB()
{
// Find ATH and ATL over lookback period
MFIB_ATH = iHigh(_Symbol, PERIOD_CURRENT, 0);
MFIB_ATL = iLow(_Symbol, PERIOD_CURRENT, 0);
for(int i=1; i<=MFIB_Lookback; i++)
{
double h = iHigh(_Symbol, PERIOD_CURRENT, i);
double l = iLow(_Symbol, PERIOD_CURRENT, i);
if(h > MFIB_ATH) MFIB_ATH = h;
if(l < MFIB_ATL) MFIB_ATL = l;
}
double range = MFIB_ATH - MFIB_ATL;
// Calculate key Fib levels (Bull Fib: ATL → ATH)
MFIB_0236 = MFIB_ATL + range * 0.236;
MFIB_032 = MFIB_ATL + range * 0.382; // KEY STRUCTURAL LEVEL
MFIB_05 = MFIB_ATL + range * 0.5;
MFIB_0618 = MFIB_ATL + range * 0.618;
MFIB_0786 = MFIB_ATL + range * 0.786;
// Determine MFIB Mode
double current = (SymbolInfoDouble(_Symbol, SYMBOL_BID) + SymbolInfoDouble(_Symbol, SYMBOL_ASK)) / 2;
if(current > MFIB_032)
MFIB_Bull_Mode = true;
else
MFIB_Bull_Mode = false;
if(current < MFIB_032)
MFIB_Bear_Mode = true;
else
MFIB_Bear_Mode = false;
}
void DrawMFIBLevels()
{
ObjectsDeleteAll(0, "MFIB_");
// Draw key MFIB levels
CreateHLine("MFIB_ATH", MFIB_ATH, clrWhite, STYLE_SOLID, 2, "ATH");
CreateHLine("MFIB_ATL", MFIB_ATL, clrWhite, STYLE_SOLID, 2, "ATL");
CreateHLine("MFIB_0786", MFIB_0786, clrDodgerBlue, STYLE_DOT, 1, "0.786");
CreateHLine("MFIB_0618", MFIB_0618, clrDodgerBlue, STYLE_DOT, 1, "0.618");
CreateHLine("MFIB_05", MFIB_05, clrYellow, STYLE_DOT, 1, "0.5");
CreateHLine("MFIB_032", MFIB_032, clrRed, STYLE_SOLID, 3, "0.32 KEY"); // Most important
CreateHLine("MFIB_0236", MFIB_0236, clrDodgerBlue, STYLE_DOT, 1, "0.236");
}
void CreateHLine(string name, double price, color clr, ENUM_LINE_STYLE style, int width, string label)
{
ObjectCreate(0, name, OBJ_HLINE, 0, 0, price);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_STYLE, style);
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
ObjectSetString(0, name, OBJPROP_TEXT, label);
}
//+------------------------------------------------------------------+
void UpdateMAs()
{
for(int i=0; i<10; i++)
{
MA_Old[i] = MA_Previous[i];
MA_Previous[i] = MA_Current[i];
double curr[1];
if(CopyBuffer(MA_Handles[i], 0, 0, 1, curr) > 0)
MA_Current[i] = curr[0];
}
}
void UpdateStochastic()
{
Stoch_K_Old = Stoch_K_Previous;
Stoch_K_Previous = Stoch_K_Current;
double k_curr[1];
if(CopyBuffer(Stoch_Handle, MAIN_LINE, 0, 1, k_curr) > 0)
Stoch_K_Current = k_curr[0];
}
//+------------------------------------------------------------------+
//| MFIB DETECTION FUNCTIONS
//+------------------------------------------------------------------+
bool IsPriceAtMFIB032(double price)
{
double buffer = MFIB_Touch_Buffer * _Point;
return (MathAbs(price - MFIB_032) <= buffer);
}
string GetMFIBLabel(double price, bool is_bullish)
{
if(!IsPriceAtMFIB032(price)) return "";
if(is_bullish)
{
if(price > MFIB_032)
return "MFIB 0.32 SUPPORT";
else if(price <= MFIB_032 && MA_Current[1] > MFIB_032) // EMA14 above
return "MFIB 0.32 RECLAIM";
}
else
{
if(price < MFIB_032)
return "MFIB 0.32 RESIST";
else if(price >= MFIB_032 && MA_Current[1] < MFIB_032) // EMA14 below
return "MFIB 0.32 REJECT";
}
return "MFIB 0.32 TEST";
}
bool IsMFIBStaircase(bool check_bullish)
{
// Check if price is making higher lows (bull) or lower highs (bear) at MFIB levels
double close_curr = iClose(_Symbol, PERIOD_CURRENT, 0);
double close_prev = iClose(_Symbol, PERIOD_CURRENT, 1);
double close_old = iClose(_Symbol, PERIOD_CURRENT, 2);
if(check_bullish)
return (close_curr > close_prev && close_prev > close_old && MFIB_Bull_Mode);
else
return (close_curr < close_prev && close_prev < close_old && MFIB_Bear_Mode);
}
//+------------------------------------------------------------------+
//| EMA14 MAGNET DETECTION
//+------------------------------------------------------------------+
bool IsPriceAtEMA14(double price)
{
double buffer = MA_Touch_Buffer * _Point;
return (MathAbs(price - MA_Current[1]) <= buffer); // MA_Current[1] = EMA14
}
string GetEMA14Label(double price, bool is_bullish)
{
if(!IsPriceAtEMA14(price)) return "";
double ema14 = MA_Current[1];
double ema14_prev = MA_Previous[1];
if(is_bullish)
{
if(price > ema14 && ema14 > ema14_prev)
return "EMA14 MAGNET HOLD";
else if(price >= ema14 && MA_Previous[1] < ema14)
return "EMA14 MAGNET RECLAIM";
else if(MathAbs(price - ema14) < 50 * _Point)
return "EMA14 COILED SPRING";
}
else
{
if(price < ema14 && ema14 < ema14_prev)
return "EMA14 MAGNET REJECT";
else if(price > ema14 * 1.01) // Extended far from EMA14
return "EMA14 SNAPBACK";
}
return "EMA14 TEST";
}
bool IsMicroBullAlign()
{
// 7 > 14 > 21
return (MA_Current[0] > MA_Current[1] && MA_Current[1] > MA_Current[2]);
}
bool IsMicroBearAlign()
{
// 7 < 14 < 21
return (MA_Current[0] < MA_Current[1] && MA_Current[1] < MA_Current[2]);
}
int CountMA14Crosses(bool check_bullish)
{
int crosses = 0;
// Count how many MAs the EMA14 has crossed
for(int i=2; i<6; i++) // Check against 21, 50, 140, 230
{
if(check_bullish && MA_Current[1] > MA_Current[i])
crosses++;
else if(!check_bullish && MA_Current[1] < MA_Current[i])
crosses++;
}
return crosses;
}
//+------------------------------------------------------------------+
//| STOCHASTIC LABELS
//+------------------------------------------------------------------+
string GetStochLabel(bool is_bullish)
{
if(is_bullish)
{
if(Stoch_K_Current >= 20 && Stoch_K_Current <= 30)
return "STOCH OS HOLD";
else if(Stoch_K_Current >= 40 && Stoch_K_Current <= 50 && Stoch_K_Current > Stoch_K_Previous)
return "STOCH BULL RESET";
else if(Stoch_K_Current >= 50 && Stoch_K_Current > Stoch_K_Previous)
return "STOCH 50 HOLD";
else if(Stoch_K_Current < 70)
return "STOCH STRUCTURAL CONFIRM";
}
else
{
if(Stoch_K_Current >= 80 && Stoch_K_Current <= 100)
return "STOCH OB REJECT";
else if(Stoch_K_Current >= 50 && Stoch_K_Current <= 60 && Stoch_K_Current < Stoch_K_Previous)
return "STOCH BEAR RESET";
else if(Stoch_K_Current <= 50 && Stoch_K_Current < Stoch_K_Previous)
return "STOCH 50 FAIL";
else if(Stoch_K_Current > 30)
return "STOCH STRUCTURAL FAIL";
}
return "STOCH NEUTRAL";
}
bool IsStochOversold()
{
return (Stoch_K_Current >= 20 && Stoch_K_Current <= 30);
}
bool IsStochOverbought()
{
return (Stoch_K_Current >= 80);
}
bool IsStochReset(bool check_bullish)
{
if(check_bullish)
return (Stoch_K_Old >= 80 && Stoch_K_Current >= 40 && Stoch_K_Current <= 50);
else
return (Stoch_K_Old <= 20 && Stoch_K_Current >= 50 && Stoch_K_Current <= 60);
}
//+------------------------------------------------------------------+
//| DEAD ZONE DETECTION
//+------------------------------------------------------------------+
bool IsDeadZone()
{
if(!Filter_Dead_Zones) return false;
// 1. MFIB whipsaw + MA chop
bool mfib_whipsaw = (IsPriceAtMFIB032(iClose(_Symbol, PERIOD_CURRENT, 0)) &&
IsPriceAtMFIB032(iClose(_Symbol, PERIOD_CURRENT, 1)));
// 2. EMA14 flat
double ema14_change = MathAbs(MA_Current[1] - MA_Previous[1]) / _Point;
bool ema14_flat = (ema14_change < 20);
// 3. Stoch in dead zone (40-60)
bool stoch_chop = (Stoch_K_Current >= 40 && Stoch_K_Current <= 60);
// 4. MFIB mode against EMA500
bool mode_conflict = false;
if(MFIB_Bull_Mode && MA_Current[1] < MA_Current[6]) // EMA14 below EMA500
mode_conflict = true;
if(MFIB_Bear_Mode && MA_Current[1] > MA_Current[6]) // EMA14 above EMA500
mode_conflict = true;
if((mfib_whipsaw && ema14_flat) || (ema14_flat && stoch_chop) || mode_conflict)
{
UpdateStatusLabel("DEAD ZONE — NO TRADE", clrOrange);
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| TRADE SETUPS
//+------------------------------------------------------------------+
bool CheckSetup1_StructuralBounce(bool is_buy, string &setup_label)
{
if(!Allow_Structural_Bounce) return false;
double current = (SymbolInfoDouble(_Symbol, SYMBOL_BID) + SymbolInfoDouble(_Symbol, SYMBOL_ASK)) / 2;
bool at_mfib = IsPriceAtMFIB032(current);
bool at_ema14 = IsPriceAtEMA14(current);
bool stoch_ok = IsStochOversold() || IsStochReset(is_buy);
if(at_mfib && (at_ema14 || IsPriceAtHigherMA(current)) && stoch_ok)
{
setup_label = "STRUCTURAL BOUNCE";
return true;
}
return false;
}
bool CheckSetup2_StructuralBreak(bool is_buy, string &setup_label)
{
if(!Allow_Structural_Break) return false;
double close_curr = iClose(_Symbol, PERIOD_CURRENT, 0);
double close_prev = iClose(_Symbol, PERIOD_CURRENT, 1);
bool broke_mfib = false;
bool broke_ema14 = false;
bool held = false;
if(is_buy)
{
broke_mfib = (close_prev < MFIB_032 && close_curr > MFIB_032);
broke_ema14 = (close_prev < MA_Current[1] && close_curr > MA_Current[1]);
held = (close_curr > MFIB_032);
}
else
{
broke_mfib = (close_prev > MFIB_032 && close_curr < MFIB_032);
broke_ema14 = (close_prev > MA_Current[1] && close_curr < MA_Current[1]);
held = (close_curr < MFIB_032);
}
bool stoch_ok = is_buy ? (Stoch_K_Current > 50) : (Stoch_K_Current < 50);
if((broke_mfib || broke_ema14) && held && stoch_ok)
{
setup_label = "STRUCTURAL BREAK & HOLD";
return true;
}
return false;
}
bool CheckSetup3_MagnetSnapback(bool is_buy, string &setup_label)
{
if(!Allow_Magnet_Snapback) return false;
double current = (SymbolInfoDouble(_Symbol, SYMBOL_BID) + SymbolInfoDouble(_Symbol, SYMBOL_ASK)) / 2;
double ema14 = MA_Current[1];
bool extended = is_buy ? (current < ema14 * 0.99) : (current > ema14 * 1.01);
bool stoch_extreme = is_buy ? IsStochOversold() : IsStochOverbought();
bool returning = IsPriceAtEMA14(current) && IsPriceAtMFIB032(current);
if(extended && stoch_extreme && returning)
{
setup_label = "MAGNET SNAPBACK ENTRY";
return true;
}
return false;
}
bool CheckSetup4_MFIBContinuation(bool is_buy, string &setup_label)
{
if(!Allow_MFIB_Continuation) return false;
bool mode_ok = is_buy ? MFIB_Bull_Mode : MFIB_Bear_Mode;
bool ema14_respected = IsPriceAtEMA14(iClose(_Symbol, PERIOD_CURRENT, 0));
bool micro_align = is_buy ? IsMicroBullAlign() : IsMicroBearAlign();
bool stoch_reset = IsStochReset(is_buy);
if(mode_ok && ema14_respected && micro_align && stoch_reset)
{
setup_label = "MFIB MODE CONTINUATION";
return true;
}
return false;
}
bool CheckSetup5_FailedBreak(bool is_buy, string &setup_label)
{
if(!Allow_Failed_Break) return false;
double close_curr = iClose(_Symbol, PERIOD_CURRENT, 0);
double close_prev = iClose(_Symbol, PERIOD_CURRENT, 1);
double close_old = iClose(_Symbol, PERIOD_CURRENT, 2);
bool attempted_break = false;
bool failed = false;
bool stoch_crossed = false;
if(is_buy)
{
// Failed bearish break
attempted_break = (close_old > MFIB_032 && close_prev < MFIB_032);
failed = (close_curr > MFIB_032);
stoch_crossed = (Stoch_K_Previous < 50 && Stoch_K_Current > 50);
}
else
{
// Failed bullish break
attempted_break = (close_old < MFIB_032 && close_prev > MFIB_032);
failed = (close_curr < MFIB_032);
stoch_crossed = (Stoch_K_Previous > 50 && Stoch_K_Current < 50);
}
if(attempted_break && failed && stoch_crossed)
{
setup_label = "FAILED STRUCTURE BREAK";
return true;
}
return false;
}
bool CheckSetup6_TripleConfluence(bool is_buy, string &setup_label)
{
if(!Allow_Triple_Confluence) return false;
double current = (SymbolInfoDouble(_Symbol, SYMBOL_BID) + SymbolInfoDouble(_Symbol, SYMBOL_ASK)) / 2;
bool at_mfib = IsPriceAtMFIB032(current);
bool at_ema14 = IsPriceAtEMA14(current);
bool stoch_extreme = is_buy ? (Stoch_K_Current <= 20) : (Stoch_K_Current >= 80);
// Check for rejection candle
double body_size = MathAbs(iClose(_Symbol, PERIOD_CURRENT, 1) - iOpen(_Symbol, PERIOD_CURRENT, 1));
double wick_size = is_buy ?
(iHigh(_Symbol, PERIOD_CURRENT, 1) - MathMax(iOpen(_Symbol, PERIOD_CURRENT, 1), iClose(_Symbol, PERIOD_CURRENT, 1))) :
(MathMin(iOpen(_Symbol, PERIOD_CURRENT, 1), iClose(_Symbol, PERIOD_CURRENT, 1)) - iLow(_Symbol, PERIOD_CURRENT, 1));
bool rejection_candle = (wick_size > body_size * 1.5);
if(at_mfib && at_ema14 && stoch_extreme && rejection_candle)
{
setup_label = "TRIPLE LEVEL REJECT";
return true;
}
return false;
}
//+------------------------------------------------------------------+
bool IsPriceAtHigherMA(double price)
{
double buffer = MA_Touch_Buffer * _Point;
// Check MA50, MA140, MA230, MA500
int higher_mas[4] = {3, 4, 5, 6};
for(int i=0; i<4; i++)
{
int idx = higher_mas[i];
if(MathAbs(price - MA_Current[idx]) <= buffer)
return true;
}
return false;
}
//+------------------------------------------------------------------+
void UpdateStatusLabel(string status, color clr)
{
ObjectDelete(0, "Label_Status");
ObjectCreate(0, "Label_Status", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, "Label_Status", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, "Label_Status", OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, "Label_Status", OBJPROP_YDISTANCE, 60);
ObjectSetString(0, "Label_Status", OBJPROP_TEXT, status);
ObjectSetInteger(0, "Label_Status", OBJPROP_COLOR, clr);
ObjectSetInteger(0, "Label_Status", OBJPROP_FONTSIZE, 11);
}
void UpdateMFIBModeLabel()
{
ObjectDelete(0, "Label_MFIB_Mode");
ObjectCreate(0, "Label_MFIB_Mode", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_YDISTANCE, 30);
if(MFIB_Bull_Mode)
{
ObjectSetString(0, "Label_MFIB_Mode", OBJPROP_TEXT, "MFIB: BULL MODE ↑");
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_COLOR, clrLime);
}
else if(MFIB_Bear_Mode)
{
ObjectSetString(0, "Label_MFIB_Mode", OBJPROP_TEXT, "MFIB: BEAR MODE ↓");
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_COLOR, clrRed);
}
else
{
ObjectSetString(0, "Label_MFIB_Mode", OBJPROP_TEXT, "MFIB: TRANSITION");
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_COLOR, clrYellow);
}
ObjectSetInteger(0, "Label_MFIB_Mode", OBJPROP_FONTSIZE, 12);
}
//+------------------------------------------------------------------+
void DetermineTrendBias()
{
UpdateMAs();
Previous_Trend_Bullish = Current_Trend_Bullish;
Previous_Trend_Bearish = Current_Trend_Bearish;
int bullish_alignment = 0;
int bearish_alignment = 0;
for(int i=0; i<6; i++)
{
if(i < 5 && MA_Current[i] > MA_Current[i+1])
bullish_alignment++;
if(i < 5 && MA_Current[i] < MA_Current[i+1])
bearish_alignment++;
}
bool ma14_above_ma50 = MA_Current[1] > MA_Current[3];
bool ma14_below_ma50 = MA_Current[1] < MA_Current[3];
if(bullish_alignment >= 3 && ma14_above_ma50)
{
Current_Trend_Bullish = true;
Current_Trend_Bearish = false;
}
else if(bearish_alignment >= 3 && ma14_below_ma50)
{
Current_Trend_Bullish = false;
Current_Trend_Bearish = true;
}
}
bool TrendReversed()
{
if(Previous_Trend_Bullish && Current_Trend_Bearish)
{
Print("===== TREND REVERSAL: BULL → BEAR =====");
return true;
}
if(Previous_Trend_Bearish && Current_Trend_Bullish)
{
Print("===== TREND REVERSAL: BEAR → BULL =====");
return true;
}
return false;
}
void CloseOppositeTrades(bool close_buys)
{
int closed = 0;
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((close_buys && type == POSITION_TYPE_BUY) ||
(!close_buys && type == POSITION_TYPE_SELL))
{
Trade.PositionClose(ticket);
closed++;
}
}
if(closed > 0)
Print("Closed ", closed, " opposite trades on reversal");
}
//+------------------------------------------------------------------+
double FindNearestFibLevel(double price, bool find_below)
{
double levels[] = {MFIB_ATL, MFIB_0236, MFIB_032, MFIB_05, MFIB_0618, MFIB_0786, MFIB_ATH};
double nearest = 0;
double min_distance = 999999;
for(int i=0; i<ArraySize(levels); i++)
{
double level = levels[i];
double distance = MathAbs(price - level);
if(find_below && level < price && distance < min_distance)
{
nearest = level;
min_distance = distance;
}
else if(!find_below && level > price && distance < min_distance)
{
nearest = level;
min_distance = distance;
}
}
return nearest;
}
void CalculateDynamicSLTP(double entry, bool is_buy, double &sl, double &tp)
{
if(Use_Fib_Based_SLTP)
{
sl = FindNearestFibLevel(entry, is_buy);
// If no Fib level found or too close, use 800 points
if(sl == 0 || MathAbs(entry - sl) / _Point < 100)
sl = is_buy ? entry - Default_SL_Points * _Point : entry + Default_SL_Points * _Point;
double sl_distance = MathAbs(entry - sl);
tp = is_buy ? entry + (sl_distance * Risk_Reward_Ratio)
: entry - (sl_distance * Risk_Reward_Ratio);
// Adjust TP to nearest Fib if close
double nearest_tp_fib = FindNearestFibLevel(entry, !is_buy);
if(nearest_tp_fib != 0)
{
double calculated_tp_dist = MathAbs(tp - entry);
double fib_tp_dist = MathAbs(nearest_tp_fib - entry);
// Only snap to Fib if within 15% and Fib level is further than minimum
if(MathAbs(calculated_tp_dist - fib_tp_dist) / calculated_tp_dist < 0.15 &&
fib_tp_dist >= Default_TP_Points * _Point * 0.8)
tp = nearest_tp_fib;
}
// Ensure minimum TP of 5000 points if calculated is less
double min_tp_distance = Default_TP_Points * _Point;
if(MathAbs(tp - entry) < min_tp_distance)
tp = is_buy ? entry + min_tp_distance : entry - min_tp_distance;
}
else
{
// Fallback: use default values
sl = is_buy ? entry - Default_SL_Points * _Point : entry + Default_SL_Points * _Point;
tp = is_buy ? entry + Default_TP_Points * _Point : entry - Default_TP_Points * _Point;
}
}
double GetLotSize(int sl_points)
{
double risk = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Per_Trade / 100.0;
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double lot = risk / ((sl_points * _Point / tickSize) * tickValue);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lot = MathMax(lot, minLot);
lot = MathMin(lot, maxLot);
lot = NormalizeDouble(lot / step, 0) * step;
return lot;
}
bool CheckLimits()
{
MqlDateTime dt;
TimeCurrent(dt);
dt.hour = 0; dt.min = 0; dt.sec = 0;
datetime today = StructToTime(dt);
if(today != LastDay)
{
DailyStart = AccountInfoDouble(ACCOUNT_BALANCE);
TodayTrades = 0;
LastDay = today;
}
if(TodayTrades >= Max_Trades_Per_Day) return false;
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double pl = ((balance - DailyStart) / DailyStart) * 100.0;
if(pl <= -Max_Daily_Loss_Percent || pl >= Max_Daily_Profit_Percent)
return false;
return true;
}
void OpenTrade(bool buy, double price, string setup_type, string details)
{
double sl, tp;
CalculateDynamicSLTP(price, buy, sl, tp);
int sl_points = (int)(MathAbs(price - sl) / _Point);
double lot = GetLotSize(sl_points);
if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return;
string comment = setup_type + " | " + details;
bool result = buy ? Trade.Buy(lot, _Symbol, price, sl, tp, comment)
: Trade.Sell(lot, _Symbol, price, sl, tp, comment);
if(result)
{
TodayTrades++;
ulong ticket = Trade.ResultOrder();
int size = ArraySize(OpenPositions);
ArrayResize(OpenPositions, size+1);
OpenPositions[size].ticket = ticket;
OpenPositions[size].entry = price;
OpenPositions[size].sl_level = sl;
OpenPositions[size].tp_level = tp;
OpenPositions[size].original_lot = lot;
OpenPositions[size].is_buy = buy;
OpenPositions[size].be_set = false;
OpenPositions[size].partials_closed = 0;
OpenPositions[size].setup_type = setup_type;
Print("========== ", setup_type, " ", TodayTrades, " ==========");
Print(buy ? "BUY" : "SELL", " @ ", price);
Print("Details: ", details);
Print("===================================");
string arrow_name = "Arrow_" + IntegerToString(ticket);
ObjectCreate(0, arrow_name, OBJ_ARROW, 0, TimeCurrent(), price);
ObjectSetInteger(0, arrow_name, OBJPROP_COLOR, buy ? clrLime : clrRed);
ObjectSetInteger(0, arrow_name, OBJPROP_ARROWCODE, buy ? 233 : 234);
ObjectSetInteger(0, arrow_name, OBJPROP_WIDTH, 3);
}
}
void ManagePositions()
{
UpdateMAs();
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
int idx = -1;
for(int j=0; j<ArraySize(OpenPositions); j++)
{
if(OpenPositions[j].ticket == ticket)
{
idx = j;
break;
}
}
if(idx == -1) continue;
double entry = OpenPositions[idx].entry;
double sl = PositionGetDouble(POSITION_SL);
bool is_buy = OpenPositions[idx].is_buy;
double current = is_buy ? SymbolInfoDouble(_Symbol, SYMBOL_BID)
: SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double profit_points = is_buy ? (current - entry) / _Point
: (entry - current) / _Point;
if(!OpenPositions[idx].be_set && profit_points >= Move_BE_At_Points)
{
if((is_buy && sl < entry) || (!is_buy && sl > entry))
{
Trade.PositionModify(ticket, entry, 0);
OpenPositions[idx].be_set = true;
Print("BE SET: ", ticket, " @ ", entry);
}
}
double lot = PositionGetDouble(POSITION_VOLUME);
if(IsPriceAtHigherMA(current))
{
if(OpenPositions[idx].partials_closed < 4)
{
double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Partial_TP_Percent / 100.0, 2);
if(close_size > 0 && close_size <= lot)
{
Trade.PositionClosePartial(ticket, close_size);
OpenPositions[idx].partials_closed++;
Print("PARTIAL TP ", OpenPositions[idx].partials_closed, ": Closed ", Partial_TP_Percent, "%");
}
}
}
if(profit_points >= Trailing_SL_Points + 100)
{
double newSL = is_buy ? current - Trailing_SL_Points * _Point
: current + Trailing_SL_Points * _Point;
if((is_buy && newSL > sl + 50 * _Point) ||
(!is_buy && newSL < sl - 50 * _Point))
{
Trade.PositionModify(ticket, newSL, 0);
}
}
}
}
//+------------------------------------------------------------------+
void OnTick()
{
// Update MFIB every 30 minutes
if(TimeCurrent() - Last_MFIB_Calc >= 1800)
{
CalculateMFIB();
if(Show_MFIB_Levels) DrawMFIBLevels();
Last_MFIB_Calc = TimeCurrent();
}
if(TimeCurrent() - Last_Trend_Check >= 5)
{
DetermineTrendBias();
UpdateMFIBModeLabel();
if(TrendReversed())
{
if(Current_Trend_Bullish)
CloseOppositeTrades(false);
else if(Current_Trend_Bearish)
CloseOppositeTrades(true);
}
Last_Trend_Check = TimeCurrent();
}
ManagePositions();
if(!CheckLimits()) return;
// Check for dead zones
if(IsDeadZone()) return;
int buy_count = 0;
int sell_count = 0;
for(int i=0; i<PositionsTotal(); i++)
{
if(PositionGetTicket(i) == 0) continue;
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber)
{
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
buy_count++;
else
sell_count++;
}
}
int total_open = buy_count + sell_count;
if(total_open >= Max_Simultaneous_Trades) return;
bool force_entry = (total_open < Min_Active_Entries);
UpdateMAs();
UpdateStochastic();
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double current = (bid + ask) / 2;
int ma14_crosses_bull = CountMA14Crosses(true);
int ma14_crosses_bear = CountMA14Crosses(false);
// Get labels for display
string mfib_label_bull = GetMFIBLabel(current, true);
string mfib_label_bear = GetMFIBLabel(current, false);
string ema14_label_bull = GetEMA14Label(current, true);
string ema14_label_bear = GetEMA14Label(current, false);
string stoch_label_bull = GetStochLabel(true);
string stoch_label_bear = GetStochLabel(false);
// Check MFIB interaction requirement
bool has_mfib_interaction = (mfib_label_bull != "" || mfib_label_bear != "");
if(Require_MFIB_Interaction && !has_mfib_interaction && !force_entry)
{
UpdateStatusLabel("No MFIB Interaction - Waiting", clrGray);
return;
}
string setup_label = "";
string details = "";
// BUY SETUPS
if(Current_Trend_Bullish || MFIB_Bull_Mode || force_entry)
{
bool buy_signal = false;
// Check all 6 setups
if(CheckSetup1_StructuralBounce(true, setup_label))
{
buy_signal = true;
details = mfib_label_bull + " + " + ema14_label_bull + " + " + stoch_label_bull;
}
else if(CheckSetup2_StructuralBreak(true, setup_label))
{
buy_signal = true;
details = "Break & Hold + " + stoch_label_bull;
}
else if(CheckSetup3_MagnetSnapback(true, setup_label))
{
buy_signal = true;
details = ema14_label_bull + " + " + stoch_label_bull;
}
else if(CheckSetup4_MFIBContinuation(true, setup_label))
{
buy_signal = true;
details = "MFIB Bull Mode + Micro Align + " + stoch_label_bull;
}
else if(CheckSetup5_FailedBreak(true, setup_label))
{
buy_signal = true;
details = "Failed Bear Break + Stoch Cross";
}
else if(CheckSetup6_TripleConfluence(true, setup_label))
{
buy_signal = true;
details = mfib_label_bull + " + " + ema14_label_bull + " + Rejection";
}
// Force entry logic
if(!buy_signal && force_entry && ma14_crosses_bull >= Min_MA14_Crosses && buy_count < sell_count)
{
buy_signal = true;
setup_label = "FORCE ENTRY";
details = "Min trades " + IntegerToString(total_open) + "/" + IntegerToString(Min_Active_Entries);
}
if(buy_signal)
{
OpenTrade(true, ask, setup_label, details);
UpdateStatusLabel(setup_label + " LONG", clrLime);
}
}
// SELL SETUPS
if(Current_Trend_Bearish || MFIB_Bear_Mode || force_entry)
{
bool sell_signal = false;
if(CheckSetup1_StructuralBounce(false, setup_label))
{
sell_signal = true;
details = mfib_label_bear + " + " + ema14_label_bear + " + " + stoch_label_bear;
}
else if(CheckSetup2_StructuralBreak(false, setup_label))
{
sell_signal = true;
details = "Break & Hold + " + stoch_label_bear;
}
else if(CheckSetup3_MagnetSnapback(false, setup_label))
{
sell_signal = true;
details = ema14_label_bear + " + " + stoch_label_bear;
}
else if(CheckSetup4_MFIBContinuation(false, setup_label))
{
sell_signal = true;
details = "MFIB Bear Mode + Micro Align + " + stoch_label_bear;
}
else if(CheckSetup5_FailedBreak(false, setup_label))
{
sell_signal = true;
details = "Failed Bull Break + Stoch Cross";
}
else if(CheckSetup6_TripleConfluence(false, setup_label))
{
sell_signal = true;
details = mfib_label_bear + " + " + ema14_label_bear + " + Rejection";
}
if(!sell_signal && force_entry && ma14_crosses_bear >= Min_MA14_Crosses && sell_count < buy_count)
{
sell_signal = true;
setup_label = "FORCE ENTRY";
details = "Min trades " + IntegerToString(total_open) + "/" + IntegerToString(Min_Active_Entries);
}
if(sell_signal)
{
OpenTrade(false, bid, setup_label, details);
UpdateStatusLabel(setup_label + " SHORT", clrRed);
}
}
}
//+------------------------------------------------------------------+