1153 lines
No EOL
74 KiB
MQL5
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);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+ |