2346 lines
No EOL
177 KiB
MQL5
2346 lines
No EOL
177 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| QuarterTheory_VIZION_FINAL_v5.7.mq5 |
|
|
//| WAR SURVIVOR: Aggressive MFIB Partials (25% at each reject) |
|
|
//| Larger Initial Size (2.5x) to survive frequent trailing stops |
|
|
//| All 18 Setups Active | Smart Re-Entry | MFIB .382 Bias |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "QuarterTheory x VIZION"
|
|
#property version "5.70"
|
|
#property strict
|
|
|
|
#include <Trade/Trade.mqh>
|
|
CTrade Trade;
|
|
|
|
//================ INPUT PARAMETERS ==================//
|
|
input group "=== CORE SETTINGS ==="
|
|
input int MagicNumber = 456789;
|
|
input double Risk_Per_Trade = 1.2;
|
|
input int Max_Trades_Per_Setup = 10;
|
|
input int Max_Total_Trades = 100;
|
|
input int Min_Runners_To_Keep = 4;
|
|
|
|
input group "=== MARKET MODE SYSTEM ==="
|
|
input bool Use_Market_Mode_Filter = true;
|
|
input int Mode_Confirmation_Bars = 2;
|
|
input double Chop_ATR_Threshold = 0.5;
|
|
input double Range_Price_Threshold = 0.3;
|
|
|
|
input group "=== REVERSAL CONFIRMATION ==="
|
|
input bool Only_Close_On_Full_Reversal = true;
|
|
input int Reversal_Confirmation_Bars = 3;
|
|
|
|
input group "=== MA SYSTEM ==="
|
|
input int MA_1 = 7;
|
|
input int MA_2 = 14;
|
|
input int MA_3 = 21;
|
|
input int MA_4 = 50;
|
|
input int MA_5 = 140;
|
|
input int MA_6 = 230;
|
|
input int MA_7 = 500;
|
|
input int MA_8 = 1000;
|
|
input int MA_9 = 1100;
|
|
input int MA_10 = 1300;
|
|
input int MA_Touch_Buffer = 100;
|
|
|
|
input group "=== STOCHASTIC ==="
|
|
input int Stoch_K_Period = 5;
|
|
input int Stoch_D_Period = 3;
|
|
input int Stoch_Slowing = 3;
|
|
input double Stoch_Extreme_High = 85.0; // Extreme overbought
|
|
input double Stoch_Extreme_Low = 15.0; // Extreme oversold
|
|
input double Stoch_High = 70.0;
|
|
input double Stoch_Low = 30.0;
|
|
|
|
// STOCHASTIC KEY LEVELS for Pullback Detection
|
|
// OS (Oversold) Levels: <20, 20, 35, 50
|
|
// OB (Overbought) Levels: 50, 65, 80, >80
|
|
// K x D (or D x K) at ANY of these levels = pullback signal
|
|
double Stoch_Levels[7] = {20.0, 35.0, 50.0, 65.0, 80.0}; // Key pivot levels
|
|
|
|
input group "=== MOVING FIBONACCI (ATH/ATL) ==="
|
|
input int MFIB_Lookback = 500; // Moving fib from ATH/ATL over this period
|
|
input bool Use_MFIB_382_Bias = true; // Price > .382 = bull bias, < .382 = bear bias
|
|
|
|
input group "=== FIBONACCI ==="
|
|
input int Lookback_Bars = 200;
|
|
input bool Show_Levels = true;
|
|
input group "=== PRAISE vs WARN AUTHORITY ENGINE ==="
|
|
input bool Use_PraiseWarn_Engine = true;
|
|
|
|
// posture multipliers (applied after War_Survivor_Lot_Multiplier)
|
|
input double Mult_SupremeTrend = 2.0; // P>=3, W<=1
|
|
input double Mult_StrongAware = 1.5; // P=3, W=2
|
|
input double Mult_Neutral = 1.0; // P=1-2,W=1-2
|
|
input double Mult_CounterMode_Cont = 0.5; // P<=1, W>=3 (continuation reduced)
|
|
input double Mult_CounterMode_Counter = 1.0; // counter full size
|
|
input double Mult_Defensive_Counter = 1.0; // counter only
|
|
input bool Pause_Counter_When_P3 = true; // pause counter when praise>=3
|
|
input bool Pause_Cont_When_W3 = true; // pause continuation when warn>=3
|
|
input int Supreme_Trend_TrailPts = 100; // continuation trail becomes 100 in supreme trend
|
|
|
|
input group "=== PRAISE SIGNAL TUNING (NO STOCH) ==="
|
|
input double Magnet_Triple_MaxATR = 0.45; // (ma7-ma21)/ATR must be below this
|
|
input double Magnet_14_21_MaxATR = 0.22; // (ma14-ma21)/ATR must be below this
|
|
input int Praise_Break_BufferPts = 120; // "decisive" distance for break/hold
|
|
input double Express_ATR_Mult = 1.6; // bar displacement >= ATR*X = express
|
|
|
|
input group "=== CONTINUATION TRADE SETTINGS ==="
|
|
input int Continuation_SL_Points = 150;
|
|
input int Continuation_BreakEven_Points = 300;
|
|
input int Continuation_Trail_Points = 300;
|
|
input int Continuation_TP_Points = 4000;
|
|
input int Continuation_Partial_TP = 900;
|
|
input double Continuation_Partial_Percent = 33.0;
|
|
|
|
input group "=== COUNTER-TREND TRADE SETTINGS (Pullback/Retracement/Range/Chop) ==="
|
|
input int Counter_SL_Points = 50; // Tight SL
|
|
input int Counter_BreakEven_Points = 25; // Fast BE
|
|
input int Counter_Trail_Points = 150; // Trail by 150
|
|
input int Counter_TP_Points = 3000; // Open TP for trend expansion
|
|
input int Counter_Partial_TP = 100; // First partial
|
|
input double Counter_Partial_Percent = 50.0; // Close 50% early
|
|
|
|
input group "=== WAR SURVIVOR: AGGRESSIVE MFIB PARTIAL SYSTEM ==="
|
|
input bool Use_MFIB_Partials = true; // Take 25% at each MFIB reject
|
|
input double MFIB_Partial_Percent = 25.0; // 25% per MFIB level
|
|
input int MFIB_Partial_Min_Profit = 30; // Min profit to take MFIB partial (points)
|
|
input double War_Survivor_Lot_Multiplier = 2.5; // Multiply lot size for more survivors
|
|
|
|
input group "=== BAND SNAP DETECTION ==="
|
|
input double Band_Snap_ATR_Multiplier = 2.0;
|
|
|
|
input group "=== RE-ENTRY SETTINGS ==="
|
|
input bool Allow_Re_Entry = true;
|
|
input int Re_Entry_Cooldown_Bars = 5;
|
|
|
|
//================ ENUMS ==================//
|
|
enum MODE_FAMILY
|
|
{
|
|
FAMILY_TRENDING = 0,
|
|
FAMILY_RANGING = 1,
|
|
FAMILY_CHOP = 2,
|
|
FAMILY_TRANSITIONAL = 3
|
|
};
|
|
|
|
enum TREND_BIAS
|
|
{
|
|
BIAS_NEUTRAL = 0,
|
|
BIAS_BULL = 1,
|
|
BIAS_BEAR = -1
|
|
};
|
|
|
|
enum TREND_STRENGTH
|
|
{
|
|
STRENGTH_WEAK = 0,
|
|
STRENGTH_CONFIRMED = 1,
|
|
STRENGTH_STRONG = 2
|
|
};
|
|
|
|
enum PRICE_STATE
|
|
{
|
|
STATE_CONTINUATION = 0,
|
|
STATE_PULLBACK = 1,
|
|
STATE_DEEP_RETRACEMENT = 2,
|
|
STATE_REVERSAL_ATTEMPT = 3,
|
|
STATE_REVERSAL_CONFIRMED = 4,
|
|
|
|
STATE_RANGE_MID_DRIFT = 10,
|
|
STATE_RANGE_EDGE_TEST = 11,
|
|
STATE_RANGE_REJECTION = 12,
|
|
STATE_RANGE_BREAK_ATTEMPT = 13,
|
|
STATE_RANGE_BREAK_CONFIRMED = 14,
|
|
|
|
STATE_CHOP_NOISE = 20,
|
|
STATE_CHOP_VOL_SPIKE = 21,
|
|
STATE_CHOP_SQUEEZE = 22,
|
|
STATE_CHOP_FAKEOUT_LOOP = 23,
|
|
|
|
STATE_UNKNOWN = 99
|
|
};
|
|
|
|
enum SETUP_TYPE
|
|
{
|
|
SETUP_MA14_CROSS = 1,
|
|
SETUP_MA50_BOUNCE = 2,
|
|
SETUP_MA140_BOUNCE = 3,
|
|
SETUP_MA230_BOUNCE = 4,
|
|
SETUP_MA500_TOUCH = 5,
|
|
SETUP_FIB_BREAK = 6,
|
|
SETUP_FIB_RECLAIM = 7,
|
|
SETUP_FIB_REJECT = 8,
|
|
SETUP_MAGNET_WALK = 9,
|
|
SETUP_STAIRCASE_ADV = 10,
|
|
SETUP_CTRL_PULLBACK = 11,
|
|
SETUP_TF_RESET = 12,
|
|
SETUP_MFIB_LADDER = 13,
|
|
SETUP_MFIB_PRESS = 14,
|
|
SETUP_MEAN_REV = 15,
|
|
SETUP_RANGE_ENGINE = 16,
|
|
SETUP_PULLBACK_COUNTER = 17,
|
|
SETUP_RETRACEMENT_COUNTER = 18
|
|
};
|
|
|
|
enum TRADE_CATEGORY
|
|
{
|
|
CATEGORY_CONTINUATION = 0,
|
|
CATEGORY_COUNTER_TREND = 1
|
|
};
|
|
|
|
//================ GLOBALS ==================//
|
|
int Stoch_Handle, ATR_Handle, ADX_Handle;
|
|
|
|
double Stoch_K_Current = 0, Stoch_K_Previous = 0, Stoch_K_Prev2 = 0;
|
|
double Stoch_D_Current = 0;
|
|
|
|
double Current_ATR = 0;
|
|
double Current_ADX = 0;
|
|
|
|
double PriceLevels[7];
|
|
|
|
int MA_Handles[10];
|
|
double MA_Current[10];
|
|
double MA_Previous[10];
|
|
double MA_Prev2[10];
|
|
|
|
// Moving MFIB from ATH to ATL
|
|
double MFIB_High, MFIB_Low;
|
|
double MFIB_Level_236, MFIB_Level_382, MFIB_Level_050;
|
|
double MFIB_Level_618, MFIB_Level_786;
|
|
|
|
// MFIB .382 Bias
|
|
TREND_BIAS MFIB_Bias = BIAS_NEUTRAL;
|
|
|
|
MODE_FAMILY Current_Family = FAMILY_TRANSITIONAL;
|
|
TREND_BIAS Current_Bias = BIAS_NEUTRAL;
|
|
TREND_STRENGTH Current_Strength = STRENGTH_WEAK;
|
|
PRICE_STATE Current_State = STATE_UNKNOWN;
|
|
|
|
MODE_FAMILY Prev_Family = FAMILY_TRANSITIONAL;
|
|
TREND_BIAS Prev_Bias = BIAS_NEUTRAL;
|
|
TREND_STRENGTH Prev_Strength = STRENGTH_WEAK;
|
|
|
|
int Mode_Confirmation_Count = 0;
|
|
int Reversal_Confirm_Counter = 0;
|
|
|
|
bool MA7_Cross_14_Warning = false;
|
|
bool MA7_Cross_21_Warning = false;
|
|
bool MA50_Break_Warning = false;
|
|
|
|
bool Fib_Reject_Warning = false;
|
|
bool MFIB_Reject_Warning = false;
|
|
|
|
bool Fib_Reclaim_Warning = false; // NEW: Fib reclaim signal
|
|
bool MFIB_Reclaim_Warning = false; // NEW: MFIB reclaim signal
|
|
bool Fib_Break_Warning = false; // NEW: Fib break signal
|
|
bool MFIB_Break_Warning = false; // NEW: MFIB break signal
|
|
|
|
bool MA_Reject_Warning = false;
|
|
bool MA_Reclaim_Warning = false; // NEW: MA reclaim signal
|
|
bool MA_Break_Warning = false; // NEW: MA break signal
|
|
|
|
bool Stoch_Extreme_Warning = false;
|
|
bool Stoch_Reject_Warning = false;
|
|
bool Stoch_Level_Cross = false; // NEW: K x D at key level
|
|
|
|
// Strong MA warnings (140, 230, 500, 50)
|
|
bool MA50_Warning = false;
|
|
bool MA140_Warning = false;
|
|
bool MA230_Warning = false;
|
|
bool MA500_Warning = false;
|
|
|
|
bool Pullback_Warning = false;
|
|
bool Retracement_Warning = false;
|
|
bool Band_Snap_Warning = false;
|
|
|
|
bool Is_Pullback_State = false;
|
|
bool Is_Retracement_State = false;
|
|
|
|
// NEW: Re-entry combo flags
|
|
bool MA14_Magnet_Active = false; // Price hugging MA14
|
|
bool Fib_Break_Confirmed = false; // Clean fib break
|
|
bool MFIB_Break_Confirmed = false; // Clean MFIB break
|
|
bool Strong_MA_Bounce = false; // Bounce off 140/230/500
|
|
bool Trend_Resumption = false; // Post-pullback trend resume
|
|
|
|
int Warning_Confluence_Count = 0;
|
|
bool Warning_Confluence_3Plus = false;
|
|
|
|
struct PositionRec
|
|
{
|
|
ulong ticket;
|
|
double entry;
|
|
double original_lot;
|
|
bool is_buy;
|
|
bool partial_tp_hit;
|
|
bool be_set;
|
|
bool trailing_active;
|
|
bool is_runner;
|
|
SETUP_TYPE setup_type;
|
|
TRADE_CATEGORY category;
|
|
string setup_name;
|
|
MODE_FAMILY entry_family;
|
|
TREND_BIAS entry_bias;
|
|
TREND_STRENGTH entry_strength;
|
|
double distance_from_current;
|
|
datetime last_close_time;
|
|
bool closed_at_sl; // NEW: Track if closed at SL
|
|
bool closed_at_be; // NEW: Track if closed at BE
|
|
double close_price; // NEW: Track close price for re-entry reference
|
|
|
|
// WAR SURVIVOR: MFIB partial tracking
|
|
int mfib_partials_taken; // Count of MFIB partials taken (0-4 possible)
|
|
double last_mfib_partial_price; // Last price where MFIB partial was taken
|
|
};
|
|
PositionRec OpenPositions[];
|
|
enum TRADE_POSTURE
|
|
{
|
|
POSTURE_DEFENSIVE = 0,
|
|
POSTURE_COUNTER = 1,
|
|
POSTURE_NEUTRAL = 2,
|
|
POSTURE_STRONG = 3,
|
|
POSTURE_SUPREME = 4
|
|
};
|
|
|
|
int PraiseScore = 0;
|
|
int WarnScore = 0;
|
|
TRADE_POSTURE Current_Posture = POSTURE_NEUTRAL;
|
|
|
|
// praise flags (optional for debugging/labeling)
|
|
bool P_TripleMagnetHold = false;
|
|
bool P_PowerCouple1421 = false;
|
|
bool P_MFIB_Staircase = false;
|
|
bool P_MFIB_Express = false;
|
|
bool P_MFIB_BreakHold = false;
|
|
bool P_MAStackPerfect = false;
|
|
bool P_CleanReclaimSeq = false;
|
|
bool P_MultiLevelBO = false;
|
|
|
|
// NEW: Track recently closed positions for re-entry opportunities
|
|
struct ClosedPositionRec
|
|
{
|
|
SETUP_TYPE setup_type;
|
|
TRADE_CATEGORY category;
|
|
bool was_buy;
|
|
double close_price;
|
|
datetime close_time;
|
|
bool closed_at_sl;
|
|
bool closed_at_be;
|
|
};
|
|
ClosedPositionRec RecentClosures[10]; // Track last 10 closures
|
|
int ClosureIndex = 0;
|
|
|
|
int TodayTrades = 0;
|
|
int BuyTrades = 0;
|
|
int SellTrades = 0;
|
|
int ClosedByReversal = 0;
|
|
|
|
int SetupCount[19];
|
|
datetime LastEntryTime[19];
|
|
|
|
//================ HELPERS ==================//
|
|
double MidPrice()
|
|
{
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
return (bid + ask) / 2.0;
|
|
}
|
|
|
|
bool NearLevel(const double price, const double level, const double tolPoints)
|
|
{
|
|
return (MathAbs(price - level) <= tolPoints * _Point);
|
|
}
|
|
|
|
bool StochCrossUp()
|
|
{
|
|
return (Stoch_K_Previous < Stoch_D_Current && Stoch_K_Current >= Stoch_D_Current);
|
|
}
|
|
|
|
bool StochCrossDown()
|
|
{
|
|
return (Stoch_K_Previous > Stoch_D_Current && Stoch_K_Current <= Stoch_D_Current);
|
|
}
|
|
|
|
bool IsBullBias() { return (Current_Bias == BIAS_BULL); }
|
|
bool IsBearBias() { return (Current_Bias == BIAS_BEAR); }
|
|
|
|
bool Bull_MA50_Reclaimed()
|
|
{
|
|
bool reclaimed = (MA_Previous[0] <= MA_Previous[3]) && (MA_Current[0] > MA_Current[3]);
|
|
double low0 = iLow(_Symbol, PERIOD_CURRENT, 0);
|
|
double close0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
bool rejected = (low0 <= MA_Current[3] && close0 > MA_Current[3] && (StochCrossUp() || Stoch_K_Current > 50));
|
|
return (reclaimed || rejected);
|
|
}
|
|
|
|
bool Bear_MA50_Reclaimed()
|
|
{
|
|
bool reclaimed = (MA_Previous[0] >= MA_Previous[3]) && (MA_Current[0] < MA_Current[3]);
|
|
double high0 = iHigh(_Symbol, PERIOD_CURRENT, 0);
|
|
double close0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
bool rejected = (high0 >= MA_Current[3] && close0 < MA_Current[3] && (StochCrossDown() || Stoch_K_Current < 50));
|
|
return (reclaimed || rejected);
|
|
}
|
|
TRADE_CATEGORY SetupCategoryFromType(SETUP_TYPE s)
|
|
{
|
|
switch(s)
|
|
{
|
|
case SETUP_RANGE_ENGINE:
|
|
case SETUP_MEAN_REV:
|
|
case SETUP_PULLBACK_COUNTER:
|
|
case SETUP_RETRACEMENT_COUNTER:
|
|
case SETUP_FIB_REJECT:
|
|
return CATEGORY_COUNTER_TREND;
|
|
default:
|
|
return CATEGORY_CONTINUATION;
|
|
}
|
|
}
|
|
|
|
string PostureToText(TRADE_POSTURE p)
|
|
{
|
|
switch(p)
|
|
{
|
|
case POSTURE_SUPREME: return "SUPREME TREND";
|
|
case POSTURE_STRONG: return "STRONG but AWARE";
|
|
case POSTURE_NEUTRAL: return "NEUTRAL";
|
|
case POSTURE_COUNTER: return "COUNTER MODE";
|
|
case POSTURE_DEFENSIVE: return "DEFENSIVE";
|
|
}
|
|
return "NEUTRAL";
|
|
}
|
|
|
|
// Track position closure for re-entry opportunities
|
|
void RecordClosure(SETUP_TYPE setup, TRADE_CATEGORY cat, bool was_buy, double close_price, bool at_sl, bool at_be)
|
|
{
|
|
RecentClosures[ClosureIndex].setup_type = setup;
|
|
RecentClosures[ClosureIndex].category = cat;
|
|
RecentClosures[ClosureIndex].was_buy = was_buy;
|
|
RecentClosures[ClosureIndex].close_price = close_price;
|
|
RecentClosures[ClosureIndex].close_time = TimeCurrent();
|
|
RecentClosures[ClosureIndex].closed_at_sl = at_sl;
|
|
RecentClosures[ClosureIndex].closed_at_be = at_be;
|
|
|
|
ClosureIndex = (ClosureIndex + 1) % 10; // Circular buffer
|
|
}
|
|
|
|
// Check if recently closed at SL or BE (within last 10 bars)
|
|
bool RecentlyStopped(SETUP_TYPE setup)
|
|
{
|
|
datetime now = TimeCurrent();
|
|
datetime cutoff = now - 10 * PeriodSeconds(PERIOD_CURRENT);
|
|
|
|
for(int i=0; i<10; i++)
|
|
{
|
|
if(RecentClosures[i].setup_type == setup &&
|
|
RecentClosures[i].close_time > cutoff &&
|
|
(RecentClosures[i].closed_at_sl || RecentClosures[i].closed_at_be))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
// COMPREHENSIVE RE-ENTRY SYSTEM
|
|
//+------------------------------------------------------------------+
|
|
bool CanReEnter(SETUP_TYPE setup)
|
|
{
|
|
if(!Allow_Re_Entry) return true;
|
|
|
|
datetime now = TimeCurrent();
|
|
datetime cooldown_end = LastEntryTime[setup] + Re_Entry_Cooldown_Bars * PeriodSeconds(PERIOD_CURRENT);
|
|
bool cooldown_passed = (now >= cooldown_end);
|
|
|
|
// Check if recently stopped out
|
|
bool recently_stopped = RecentlyStopped(setup);
|
|
|
|
//================================================================
|
|
// RE-ENTRY COMBO TRIGGERS (Override cooldown)
|
|
//================================================================
|
|
|
|
// COMBO 1: 3+ Rejection/Reclaim at Strong MAs (140, 230, 500+)
|
|
int reject_reclaim_count = 0;
|
|
if(Fib_Reject_Warning) reject_reclaim_count++;
|
|
if(MFIB_Reject_Warning) reject_reclaim_count++;
|
|
if(MA_Reject_Warning) reject_reclaim_count++;
|
|
if(Fib_Reclaim_Warning) reject_reclaim_count++;
|
|
if(MFIB_Reclaim_Warning) reject_reclaim_count++;
|
|
if(MA_Reclaim_Warning) reject_reclaim_count++;
|
|
|
|
bool at_strong_ma = (MA140_Warning || MA230_Warning || MA500_Warning);
|
|
bool combo1_strong_ma_confluence = (reject_reclaim_count >= 3 && at_strong_ma);
|
|
|
|
// COMBO 2: MA14 Magnet + Fib/MFIB Break (Trending)
|
|
bool combo2_ma14_magnet_break = (MA14_Magnet_Active && (Fib_Break_Confirmed || MFIB_Break_Confirmed));
|
|
|
|
// COMBO 3: Strong MA Bounce + Stoch Confirmation (Post-SL/BE)
|
|
bool combo3_strong_bounce = (Strong_MA_Bounce && recently_stopped &&
|
|
(Stoch_Level_Cross || StochCrossUp() || StochCrossDown()));
|
|
|
|
// COMBO 4: Trend Resumption after Pullback (MA50 reclaim + 2+ signals)
|
|
bool combo4_trend_resume = (Trend_Resumption && Warning_Confluence_Count >= 2);
|
|
|
|
// COMBO 5: Fib/MFIB Reclaim + MA Alignment (Post-BE)
|
|
bool mas_aligned_bull = (MA_Current[0] > MA_Current[1]) && (MA_Current[1] > MA_Current[2]);
|
|
bool mas_aligned_bear = (MA_Current[0] < MA_Current[1]) && (MA_Current[1] < MA_Current[2]);
|
|
bool combo5_level_reclaim = ((Fib_Reclaim_Warning || MFIB_Reclaim_Warning) &&
|
|
recently_stopped && (mas_aligned_bull || mas_aligned_bear));
|
|
|
|
// COMBO 6: Band Snap Recovery + Strong MA (Overextension correction)
|
|
bool combo6_snap_recovery = (Band_Snap_Warning && at_strong_ma && recently_stopped);
|
|
|
|
// COMBO 7: Multiple Level Confluence (Fib + MFIB + MA all align)
|
|
bool fib_and_mfib = (Fib_Reject_Warning || Fib_Reclaim_Warning) &&
|
|
(MFIB_Reject_Warning || MFIB_Reclaim_Warning);
|
|
bool combo7_triple_level = (fib_and_mfib && (MA_Reject_Warning || MA_Reclaim_Warning));
|
|
|
|
// COMBO 8: Stoch Extreme + Fib/MFIB Level + Post-SL
|
|
bool combo8_extreme_level = (Stoch_Extreme_Warning && recently_stopped &&
|
|
(Fib_Reject_Warning || MFIB_Reject_Warning));
|
|
|
|
// COMBO 9: MA Cross + Level Break + Continuation State
|
|
bool combo9_cross_break = (MA7_Cross_14_Warning && (Fib_Break_Confirmed || MFIB_Break_Confirmed) &&
|
|
Current_State == STATE_CONTINUATION);
|
|
|
|
// COMBO 10: 4+ Warning Confluence (Extreme conviction)
|
|
bool combo10_mega_confluence = (Warning_Confluence_Count >= 4);
|
|
|
|
//================================================================
|
|
// DECISION LOGIC
|
|
//================================================================
|
|
void UpdatePosture()
|
|
{
|
|
// WarnScore uses your confluence count (already comprehensive)
|
|
WarnScore = Warning_Confluence_Count;
|
|
|
|
if(!Use_PraiseWarn_Engine)
|
|
{
|
|
Current_Posture = POSTURE_NEUTRAL;
|
|
return;
|
|
}
|
|
|
|
// Matrix:
|
|
// P>=3,W<=1 => SUPREME
|
|
// P=3,W=2 => STRONG
|
|
// P=1-2,W=1-2 => NEUTRAL
|
|
// P<=1,W>=3 => COUNTER
|
|
// P=0,W>=4 => DEFENSIVE
|
|
if(PraiseScore >= 3 && WarnScore <= 1) Current_Posture = POSTURE_SUPREME;
|
|
else if(PraiseScore == 3 && WarnScore == 2) Current_Posture = POSTURE_STRONG;
|
|
else if(PraiseScore <= 1 && WarnScore >= 4) Current_Posture = POSTURE_DEFENSIVE;
|
|
else if(PraiseScore <= 1 && WarnScore >= 3) Current_Posture = POSTURE_COUNTER;
|
|
else Current_Posture = POSTURE_NEUTRAL;
|
|
}
|
|
|
|
// If ANY combo triggers, allow immediate re-entry
|
|
bool combo_triggered =
|
|
combo1_strong_ma_confluence ||
|
|
combo2_ma14_magnet_break ||
|
|
combo3_strong_bounce ||
|
|
combo4_trend_resume ||
|
|
combo5_level_reclaim ||
|
|
combo6_snap_recovery ||
|
|
combo7_triple_level ||
|
|
combo8_extreme_level ||
|
|
combo9_cross_break ||
|
|
combo10_mega_confluence;
|
|
|
|
// Log re-entry combo if triggered
|
|
if(combo_triggered && !cooldown_passed)
|
|
{
|
|
string combo_name = "";
|
|
if(combo1_strong_ma_confluence) combo_name = "3+Reject/Reclaim@StrongMA";
|
|
else if(combo2_ma14_magnet_break) combo_name = "MA14Magnet+FibBreak";
|
|
else if(combo3_strong_bounce) combo_name = "StrongMA_Bounce+Stoch";
|
|
else if(combo4_trend_resume) combo_name = "TrendResumption";
|
|
else if(combo5_level_reclaim) combo_name = "Level_Reclaim+MA_Align";
|
|
else if(combo6_snap_recovery) combo_name = "BandSnap_Recovery";
|
|
else if(combo7_triple_level) combo_name = "Triple_Level_Confluence";
|
|
else if(combo8_extreme_level) combo_name = "Stoch_Extreme+Level";
|
|
else if(combo9_cross_break) combo_name = "MA_Cross+Level_Break";
|
|
else if(combo10_mega_confluence) combo_name = "4+_Confluence";
|
|
|
|
Print("🔁 RE-ENTRY COMBO TRIGGERED: ", combo_name);
|
|
}
|
|
|
|
return (cooldown_passed || combo_triggered);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
Print("========================================");
|
|
Print("QuarterTheory_VIZION_FINAL v5.7");
|
|
Print("⚔️ WAR SURVIVOR SYSTEM:");
|
|
Print(" - Aggressive MFIB Partials: 25% at each reject");
|
|
Print(" - Larger Initial Size: ", DoubleToString(War_Survivor_Lot_Multiplier, 1), "x multiplier");
|
|
Print(" - Max 4 MFIB partials per trade");
|
|
Print(" - Survive frequent trailing stops");
|
|
Print("SMART RE-ENTRY:");
|
|
Print(" - 10 combo triggers for post-SL/BE re-entry");
|
|
Print(" - 3+ Reject/Reclaim at MA140/230/500");
|
|
Print("ALL 18 SETUPS ACTIVE:");
|
|
Print(" - 14 Continuation (150 SL, 4000 TP)");
|
|
Print(" - 4 Counter-Trend (50 SL, 3000 TP)");
|
|
Print("TRAILING SL:");
|
|
Print(" - Counter: 150pts behind price");
|
|
Print(" - Continuation: 300pts behind price");
|
|
Print("========================================");
|
|
|
|
Trade.SetExpertMagicNumber(MagicNumber);
|
|
Trade.SetDeviationInPoints(50);
|
|
Trade.SetTypeFilling(ORDER_FILLING_FOK);
|
|
|
|
Stoch_Handle = iStochastic(_Symbol, PERIOD_CURRENT, Stoch_K_Period, Stoch_D_Period,
|
|
Stoch_Slowing, MODE_SMA, STO_LOWHIGH);
|
|
ATR_Handle = iATR(_Symbol, PERIOD_CURRENT, 14);
|
|
ADX_Handle = iADX(_Symbol, PERIOD_CURRENT, 14);
|
|
|
|
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);
|
|
|
|
ArrayInitialize(SetupCount, 0);
|
|
ArrayInitialize(LastEntryTime, 0);
|
|
|
|
CalculateLevels();
|
|
if(Show_Levels) DrawLevels();
|
|
|
|
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);
|
|
if(ATR_Handle != INVALID_HANDLE) IndicatorRelease(ATR_Handle);
|
|
if(ADX_Handle != INVALID_HANDLE) IndicatorRelease(ADX_Handle);
|
|
|
|
ObjectsDeleteAll(0, "Level_");
|
|
ObjectsDeleteAll(0, "MFIB_");
|
|
ObjectsDeleteAll(0, "ModeLabel");
|
|
ObjectsDeleteAll(0, "StateLabel");
|
|
ObjectsDeleteAll(0, "PraiseLabel");
|
|
ObjectsDeleteAll(0, "WarningLabel");
|
|
ObjectsDeleteAll(0, "MFIBLabel");
|
|
|
|
Print("Final: B:", BuyTrades, " | S:", SellTrades, " | Reversed:", ClosedByReversal);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CalculateLevels()
|
|
{
|
|
// Static Fibonacci levels for reference
|
|
double high = iHigh(_Symbol, PERIOD_CURRENT, 0);
|
|
double low = iLow(_Symbol, PERIOD_CURRENT, 0);
|
|
|
|
for(int i=1; i<=Lookback_Bars; i++)
|
|
{
|
|
double h = iHigh(_Symbol, PERIOD_CURRENT, i);
|
|
double l = iLow(_Symbol, PERIOD_CURRENT, i);
|
|
if(h > high) high = h;
|
|
if(l < low) low = l;
|
|
}
|
|
|
|
double range = high - low;
|
|
PriceLevels[0] = low;
|
|
PriceLevels[1] = low + range * 0.236;
|
|
PriceLevels[2] = low + range * 0.382;
|
|
PriceLevels[3] = low + range * 0.5;
|
|
PriceLevels[4] = low + range * 0.618;
|
|
PriceLevels[5] = low + range * 0.786;
|
|
PriceLevels[6] = high;
|
|
|
|
// MOVING FIBONACCI - From ATH to ATL (stacked from top)
|
|
double ath = iHigh(_Symbol, PERIOD_CURRENT, 0);
|
|
double 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 > ath) ath = h;
|
|
if(l < atl) atl = l;
|
|
}
|
|
|
|
MFIB_High = ath;
|
|
MFIB_Low = atl;
|
|
double mfib_range = ath - atl;
|
|
|
|
// Levels stacked from ATH down to ATL
|
|
MFIB_Level_236 = ath - (mfib_range * 0.236); // 23.6% down from ATH
|
|
MFIB_Level_382 = ath - (mfib_range * 0.382); // 38.2% down from ATH *** KEY BIAS LEVEL ***
|
|
MFIB_Level_050 = ath - (mfib_range * 0.500); // 50% down from ATH
|
|
MFIB_Level_618 = ath - (mfib_range * 0.618); // 61.8% down from ATH *** KEY LEVEL ***
|
|
MFIB_Level_786 = ath - (mfib_range * 0.786); // 78.6% down from ATH
|
|
|
|
// MFIB .382 Bias Logic
|
|
if(Use_MFIB_382_Bias)
|
|
{
|
|
double current = MidPrice();
|
|
|
|
if(current > MFIB_Level_382)
|
|
MFIB_Bias = BIAS_BULL; // Above .382 = bullish bias
|
|
else if(current < MFIB_Level_382)
|
|
MFIB_Bias = BIAS_BEAR; // Below .382 = bearish bias
|
|
else
|
|
MFIB_Bias = BIAS_NEUTRAL;
|
|
}
|
|
else
|
|
{
|
|
MFIB_Bias = BIAS_NEUTRAL;
|
|
}
|
|
}
|
|
|
|
void DrawLevels()
|
|
{
|
|
ObjectsDeleteAll(0, "Level_");
|
|
ObjectsDeleteAll(0, "MFIB_");
|
|
|
|
color level_colors[7] = {clrRed, clrOrange, clrYellow, clrLime, clrCyan, clrBlue, clrMagenta};
|
|
|
|
// Draw static fib levels
|
|
for(int i=0; i<7; i++)
|
|
{
|
|
string name = "Level_" + IntegerToString(i);
|
|
ObjectCreate(0, name, OBJ_HLINE, 0, 0, PriceLevels[i]);
|
|
ObjectSetInteger(0, name, OBJPROP_COLOR, level_colors[i]);
|
|
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
|
|
ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
|
|
}
|
|
|
|
// Draw MFIB levels (more prominent)
|
|
string mfib_name = "MFIB_382";
|
|
ObjectCreate(0, mfib_name, OBJ_HLINE, 0, 0, MFIB_Level_382);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_COLOR, clrYellow);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_STYLE, STYLE_SOLID);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_WIDTH, 2);
|
|
|
|
mfib_name = "MFIB_618";
|
|
ObjectCreate(0, mfib_name, OBJ_HLINE, 0, 0, MFIB_Level_618);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_COLOR, clrCyan);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_STYLE, STYLE_SOLID);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_WIDTH, 2);
|
|
|
|
mfib_name = "MFIB_050";
|
|
ObjectCreate(0, mfib_name, OBJ_HLINE, 0, 0, MFIB_Level_050);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_COLOR, clrWhite);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_STYLE, STYLE_SOLID);
|
|
ObjectSetInteger(0, mfib_name, OBJPROP_WIDTH, 1);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void UpdateIndicators()
|
|
{
|
|
for(int i=0; i<10; i++)
|
|
{
|
|
double curr[1], prev[1], prev2[1];
|
|
if(CopyBuffer(MA_Handles[i], 0, 0, 1, curr) > 0) MA_Current[i] = curr[0];
|
|
if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) MA_Previous[i] = prev[0];
|
|
if(CopyBuffer(MA_Handles[i], 0, 2, 1, prev2) > 0) MA_Prev2[i] = prev2[0];
|
|
}
|
|
|
|
double k_curr[1], k_prev[1], k_prev2[1], d_curr[1];
|
|
if(CopyBuffer(Stoch_Handle, MAIN_LINE, 0, 1, k_curr) > 0) Stoch_K_Current = k_curr[0];
|
|
if(CopyBuffer(Stoch_Handle, MAIN_LINE, 1, 1, k_prev) > 0) Stoch_K_Previous = k_prev[0];
|
|
if(CopyBuffer(Stoch_Handle, MAIN_LINE, 2, 1, k_prev2) > 0) Stoch_K_Prev2 = k_prev2[0];
|
|
if(CopyBuffer(Stoch_Handle, SIGNAL_LINE, 0, 1, d_curr) > 0) Stoch_D_Current = d_curr[0];
|
|
|
|
double atr[1], adx[1];
|
|
if(CopyBuffer(ATR_Handle, 0, 0, 1, atr) > 0) Current_ATR = atr[0];
|
|
if(CopyBuffer(ADX_Handle, 0, 0, 1, adx) > 0) Current_ADX = adx[0];
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void DetectWarnings()
|
|
{
|
|
double current = MidPrice();
|
|
double bufferPts = (double)MA_Touch_Buffer;
|
|
double prev = iClose(_Symbol, PERIOD_CURRENT, 1);
|
|
|
|
// MFIB levels array for use throughout function
|
|
double mfib_levels[5] = {MFIB_Level_236, MFIB_Level_382, MFIB_Level_050, MFIB_Level_618, MFIB_Level_786};
|
|
|
|
// Reset all warnings
|
|
MA7_Cross_14_Warning = false;
|
|
MA7_Cross_21_Warning = false;
|
|
MA50_Break_Warning = false;
|
|
|
|
Fib_Reject_Warning = false;
|
|
MFIB_Reject_Warning = false;
|
|
Fib_Reclaim_Warning = false;
|
|
MFIB_Reclaim_Warning = false;
|
|
Fib_Break_Warning = false;
|
|
MFIB_Break_Warning = false;
|
|
|
|
MA_Reject_Warning = false;
|
|
MA_Reclaim_Warning = false;
|
|
MA_Break_Warning = false;
|
|
|
|
Stoch_Extreme_Warning = false;
|
|
Stoch_Reject_Warning = false;
|
|
Stoch_Level_Cross = false;
|
|
|
|
MA50_Warning = false;
|
|
MA140_Warning = false;
|
|
MA230_Warning = false;
|
|
MA500_Warning = false;
|
|
|
|
Pullback_Warning = false;
|
|
Retracement_Warning = false;
|
|
Band_Snap_Warning = false;
|
|
void DetectPraiseSignals()
|
|
{
|
|
// reset
|
|
PraiseScore = 0;
|
|
P_TripleMagnetHold = false;
|
|
P_PowerCouple1421 = false;
|
|
P_MFIB_Staircase = false;
|
|
P_MFIB_Express = false;
|
|
P_MFIB_BreakHold = false;
|
|
P_MAStackPerfect = false;
|
|
P_CleanReclaimSeq = false;
|
|
P_MultiLevelBO = false;
|
|
|
|
if(Current_ATR <= 0.0) return;
|
|
|
|
double current = MidPrice();
|
|
double prevClose = iClose(_Symbol, PERIOD_CURRENT, 1);
|
|
double close0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
|
|
// MFIB array
|
|
double mf[5] = {MFIB_Level_236, MFIB_Level_382, MFIB_Level_050, MFIB_Level_618, MFIB_Level_786};
|
|
double buf = (double)Praise_Break_BufferPts * _Point;
|
|
|
|
//==========================
|
|
// P1: 7x14x21 Triple Magnet Hold
|
|
//==========================
|
|
double spread721 = MathAbs(MA_Current[0] - MA_Current[2]);
|
|
bool magnet721 = (spread721 / Current_ATR) <= Magnet_Triple_MaxATR;
|
|
|
|
bool side_bull = (current > MA_Current[0] && current > MA_Current[1] && current > MA_Current[2]);
|
|
bool side_bear = (current < MA_Current[0] && current < MA_Current[1] && current < MA_Current[2]);
|
|
|
|
if(magnet721 && (side_bull || side_bear))
|
|
{
|
|
P_TripleMagnetHold = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// P2: 14x21 Power Couple
|
|
//==========================
|
|
double spread1421 = MathAbs(MA_Current[1] - MA_Current[2]);
|
|
bool magnet1421 = (spread1421 / Current_ATR) <= Magnet_14_21_MaxATR;
|
|
|
|
bool slope_up = (MA_Current[1] > MA_Previous[1]) && (MA_Current[2] > MA_Previous[2]);
|
|
bool slope_dn = (MA_Current[1] < MA_Previous[1]) && (MA_Current[2] < MA_Previous[2]);
|
|
|
|
if(magnet1421 && (slope_up || slope_dn))
|
|
{
|
|
P_PowerCouple1421 = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// P6: MA Stack Perfection (7>14>21>50>230) or reverse
|
|
//==========================
|
|
bool stack_bull = (MA_Current[0] > MA_Current[1] && MA_Current[1] > MA_Current[2] &&
|
|
MA_Current[2] > MA_Current[3] && MA_Current[3] > MA_Current[5]);
|
|
bool stack_bear = (MA_Current[0] < MA_Current[1] && MA_Current[1] < MA_Current[2] &&
|
|
MA_Current[2] < MA_Current[3] && MA_Current[3] < MA_Current[5]);
|
|
|
|
if(stack_bull || stack_bear)
|
|
{
|
|
P_MAStackPerfect = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// MFIB crossings count (for Express/Staircase)
|
|
//==========================
|
|
int crossed = 0;
|
|
for(int i=0;i<5;i++)
|
|
{
|
|
bool crossedUp = (prevClose < mf[i] && close0 > mf[i]);
|
|
bool crossedDn = (prevClose > mf[i] && close0 < mf[i]);
|
|
if(crossedUp || crossedDn) crossed++;
|
|
}
|
|
|
|
//==========================
|
|
// P4: MFIB Express (skips levels) = 2+ MFIB levels crossed in 1 bar + displacement
|
|
//==========================
|
|
double disp = MathAbs(close0 - prevClose);
|
|
if(crossed >= 2 && disp >= (Current_ATR * Express_ATR_Mult))
|
|
{
|
|
P_MFIB_Express = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// P5: MFIB Breakout Hold (cross + holds beyond buffer)
|
|
//==========================
|
|
bool mfib_hold = false;
|
|
for(int i=0;i<5;i++)
|
|
{
|
|
bool brokeUp = (prevClose < mf[i] && close0 > mf[i] + buf);
|
|
bool brokeDn = (prevClose > mf[i] && close0 < mf[i] - buf);
|
|
if(brokeUp || brokeDn) { mfib_hold = true; break; }
|
|
}
|
|
if(mfib_hold)
|
|
{
|
|
P_MFIB_BreakHold = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// P3: MFIB Staircase Advance (no stoch) = clean break confirmed + ADX ok + no band snap
|
|
// (you already compute MFIB_Break_Confirmed without stoch)
|
|
//==========================
|
|
if(MFIB_Break_Confirmed && Current_ADX >= 18 && !Band_Snap_Warning)
|
|
{
|
|
P_MFIB_Staircase = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// P7: Clean Reclaim Sequence (reclaims without rejects)
|
|
// Uses your reclaim flags (they do NOT require stoch)
|
|
//==========================
|
|
int reclaim_ct = 0;
|
|
if(Fib_Reclaim_Warning) reclaim_ct++;
|
|
if(MFIB_Reclaim_Warning) reclaim_ct++;
|
|
if(MA_Reclaim_Warning) reclaim_ct++;
|
|
|
|
bool no_reject = (!Fib_Reject_Warning && !MFIB_Reject_Warning && !MA_Reject_Warning);
|
|
if(reclaim_ct >= 2 && no_reject)
|
|
{
|
|
P_CleanReclaimSeq = true;
|
|
PraiseScore++;
|
|
}
|
|
|
|
//==========================
|
|
// P8: Multi-Level Breakout (Fib + MFIB + MA break alignment)
|
|
//==========================
|
|
bool multi = (Fib_Break_Confirmed || Fib_Break_Warning) &&
|
|
(MFIB_Break_Confirmed || MFIB_Break_Warning) &&
|
|
(MA_Break_Warning || MA50_Break_Warning);
|
|
|
|
if(multi)
|
|
{
|
|
P_MultiLevelBO = true;
|
|
PraiseScore++;
|
|
}
|
|
}
|
|
|
|
//================================================================
|
|
// 1) STOCHASTIC ANALYSIS
|
|
//================================================================
|
|
|
|
// A) Extreme levels
|
|
if(Stoch_K_Current <= Stoch_Extreme_Low || Stoch_K_Current >= Stoch_Extreme_High)
|
|
Stoch_Extreme_Warning = true;
|
|
|
|
// B) Cross at key levels (20, 35, 50, 65, 80)
|
|
bool k_crossed_d = false;
|
|
bool near_key_level = false;
|
|
|
|
// Check if K crossed D (either direction)
|
|
if((Stoch_K_Previous < Stoch_D_Current && Stoch_K_Current >= Stoch_D_Current) ||
|
|
(Stoch_K_Previous > Stoch_D_Current && Stoch_K_Current <= Stoch_D_Current))
|
|
{
|
|
k_crossed_d = true;
|
|
}
|
|
|
|
// Check if current stoch is near any key level
|
|
for(int i=0; i<5; i++)
|
|
{
|
|
if(MathAbs(Stoch_K_Current - Stoch_Levels[i]) <= 5.0)
|
|
{
|
|
near_key_level = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(k_crossed_d && near_key_level)
|
|
Stoch_Level_Cross = true;
|
|
|
|
// C) Reject patterns (cross at meaningful bands)
|
|
bool stoch_reject_down = (StochCrossDown() && Stoch_K_Current > 50);
|
|
bool stoch_reject_up = (StochCrossUp() && Stoch_K_Current < 50);
|
|
if(stoch_reject_down || stoch_reject_up || Stoch_Level_Cross)
|
|
Stoch_Reject_Warning = true;
|
|
|
|
//================================================================
|
|
// 2) MA CROSS ANALYSIS
|
|
//================================================================
|
|
|
|
// MA7 x MA14 cross (pullback signal)
|
|
bool ma7_crossed_14_down = (MA_Previous[0] > MA_Previous[1]) && (MA_Current[0] <= MA_Current[1]);
|
|
bool ma7_crossed_14_up = (MA_Previous[0] < MA_Previous[1]) && (MA_Current[0] >= MA_Current[1]);
|
|
if(ma7_crossed_14_down || ma7_crossed_14_up)
|
|
{
|
|
MA7_Cross_14_Warning = true;
|
|
Pullback_Warning = true;
|
|
}
|
|
|
|
// MA7 x MA21 cross (retracement signal)
|
|
bool ma7_crossed_21_down = (MA_Previous[0] > MA_Previous[2]) && (MA_Current[0] <= MA_Current[2]);
|
|
bool ma7_crossed_21_up = (MA_Previous[0] < MA_Previous[2]) && (MA_Current[0] >= MA_Current[2]);
|
|
if(ma7_crossed_21_down || ma7_crossed_21_up)
|
|
{
|
|
MA7_Cross_21_Warning = true;
|
|
Retracement_Warning = true;
|
|
}
|
|
|
|
// MA50 break (reversal warning)
|
|
bool ma7_broke_50_down = (MA_Previous[0] > MA_Previous[3]) && (MA_Current[0] <= MA_Current[3]);
|
|
bool ma7_broke_50_up = (MA_Previous[0] < MA_Previous[3]) && (MA_Current[0] >= MA_Current[3]);
|
|
if(ma7_broke_50_down || ma7_broke_50_up)
|
|
MA50_Break_Warning = true;
|
|
|
|
//================================================================
|
|
// 3) BAND SNAP
|
|
//================================================================
|
|
if(Current_ATR > 0.0)
|
|
{
|
|
double distance = MathAbs(current - MA_Current[0]);
|
|
double band_threshold = Current_ATR * Band_Snap_ATR_Multiplier;
|
|
if(distance >= band_threshold)
|
|
Band_Snap_Warning = true;
|
|
}
|
|
|
|
//================================================================
|
|
// 5) FIBONACCI LEVEL ANALYSIS (Reject, Reclaim, Break)
|
|
//================================================================
|
|
|
|
bool at_fib = false;
|
|
int fib_level_idx = -1;
|
|
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(NearLevel(current, PriceLevels[i], bufferPts))
|
|
{
|
|
at_fib = true;
|
|
fib_level_idx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(at_fib)
|
|
{
|
|
double fib_level = PriceLevels[fib_level_idx];
|
|
|
|
// REJECT: Price hits level + stoch reject/extreme
|
|
if(Stoch_Extreme_Warning || Stoch_Reject_Warning || Stoch_Level_Cross)
|
|
Fib_Reject_Warning = true;
|
|
|
|
// RECLAIM: Price crosses back above/below level
|
|
if((prev < fib_level && current > fib_level) || (prev > fib_level && current < fib_level))
|
|
Fib_Reclaim_Warning = true;
|
|
|
|
// BREAK: Price decisively breaks through
|
|
if(MathAbs(current - fib_level) > bufferPts * 1.5)
|
|
Fib_Break_Warning = true;
|
|
}
|
|
|
|
//================================================================
|
|
// 6) MFIB LEVEL ANALYSIS (Reject, Reclaim, Break)
|
|
//================================================================
|
|
|
|
bool at_mfib = false;
|
|
double mfib_level = 0;
|
|
|
|
for(int i=0; i<5; i++)
|
|
{
|
|
if(NearLevel(current, mfib_levels[i], bufferPts))
|
|
{
|
|
at_mfib = true;
|
|
mfib_level = mfib_levels[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(at_mfib)
|
|
{
|
|
// REJECT: Price hits MFIB + stoch signal
|
|
if(Stoch_Extreme_Warning || Stoch_Reject_Warning || Stoch_Level_Cross)
|
|
MFIB_Reject_Warning = true;
|
|
|
|
// RECLAIM: Price crosses MFIB level
|
|
if((prev < mfib_level && current > mfib_level) || (prev > mfib_level && current < mfib_level))
|
|
MFIB_Reclaim_Warning = true;
|
|
|
|
// BREAK: Price breaks through MFIB decisively
|
|
if(MathAbs(current - mfib_level) > bufferPts * 1.5)
|
|
MFIB_Break_Warning = true;
|
|
}
|
|
|
|
//================================================================
|
|
// 7) STRONG MA ANALYSIS (50, 140, 230, 500)
|
|
//================================================================
|
|
|
|
// Check proximity to each strong MA
|
|
bool at_ma50 = NearLevel(current, MA_Current[3], bufferPts);
|
|
bool at_ma140 = NearLevel(current, MA_Current[4], bufferPts);
|
|
bool at_ma230 = NearLevel(current, MA_Current[5], bufferPts);
|
|
bool at_ma500 = NearLevel(current, MA_Current[6], bufferPts);
|
|
|
|
if(at_ma50) MA50_Warning = true;
|
|
if(at_ma140) MA140_Warning = true;
|
|
if(at_ma230) MA230_Warning = true;
|
|
if(at_ma500) MA500_Warning = true;
|
|
|
|
// MA REJECT: At strong MA + stoch signal
|
|
if((at_ma50 || at_ma140 || at_ma230 || at_ma500) &&
|
|
(Stoch_Extreme_Warning || Stoch_Reject_Warning || Stoch_Level_Cross))
|
|
{
|
|
MA_Reject_Warning = true;
|
|
}
|
|
|
|
// MA RECLAIM: Price reclaims strong MA
|
|
|
|
if(at_ma50 && ((prev < MA_Current[3] && current > MA_Current[3]) ||
|
|
(prev > MA_Current[3] && current < MA_Current[3])))
|
|
MA_Reclaim_Warning = true;
|
|
|
|
if(at_ma140 && ((prev < MA_Current[4] && current > MA_Current[4]) ||
|
|
(prev > MA_Current[4] && current < MA_Current[4])))
|
|
MA_Reclaim_Warning = true;
|
|
|
|
// MA BREAK: Price breaks away from MA
|
|
if((at_ma50 || at_ma140 || at_ma230) && MathAbs(current - MA_Current[3]) > bufferPts * 2)
|
|
MA_Break_Warning = true;
|
|
|
|
//================================================================
|
|
// 8) PULLBACK CONFLUENCE
|
|
// Mix and match: (MA, Fib, MFIB, Stoch) x (Reject, Reclaim, Break)
|
|
//================================================================
|
|
|
|
// Any 2+ of these combinations = pullback signal
|
|
int pullback_signals = 0;
|
|
|
|
if(MA7_Cross_14_Warning) pullback_signals++;
|
|
if(Fib_Reject_Warning) pullback_signals++;
|
|
if(MFIB_Reject_Warning) pullback_signals++;
|
|
if(MA_Reject_Warning) pullback_signals++;
|
|
if(Stoch_Level_Cross) pullback_signals++;
|
|
if(Band_Snap_Warning) pullback_signals++;
|
|
if(Fib_Reclaim_Warning) pullback_signals++;
|
|
if(MFIB_Reclaim_Warning) pullback_signals++;
|
|
if(MA_Reclaim_Warning) pullback_signals++;
|
|
|
|
if(pullback_signals >= 2)
|
|
Pullback_Warning = true;
|
|
|
|
//================================================================
|
|
// 9) WARNING CONFLUENCE COUNT
|
|
//================================================================
|
|
Warning_Confluence_Count = 0;
|
|
|
|
if(Stoch_Extreme_Warning) Warning_Confluence_Count++;
|
|
if(Stoch_Reject_Warning) Warning_Confluence_Count++;
|
|
if(Stoch_Level_Cross) Warning_Confluence_Count++;
|
|
|
|
if(MA7_Cross_14_Warning) Warning_Confluence_Count++;
|
|
if(MA7_Cross_21_Warning) Warning_Confluence_Count++;
|
|
if(MA50_Break_Warning) Warning_Confluence_Count++;
|
|
|
|
if(Fib_Reject_Warning) Warning_Confluence_Count++;
|
|
if(MFIB_Reject_Warning) Warning_Confluence_Count++;
|
|
if(MA_Reject_Warning) Warning_Confluence_Count++;
|
|
|
|
if(Fib_Reclaim_Warning) Warning_Confluence_Count++;
|
|
if(MFIB_Reclaim_Warning) Warning_Confluence_Count++;
|
|
if(MA_Reclaim_Warning) Warning_Confluence_Count++;
|
|
|
|
if(Band_Snap_Warning) Warning_Confluence_Count++;
|
|
|
|
if(MA50_Warning) Warning_Confluence_Count++;
|
|
if(MA140_Warning) Warning_Confluence_Count++;
|
|
if(MA230_Warning) Warning_Confluence_Count++;
|
|
if(MA500_Warning) Warning_Confluence_Count++;
|
|
|
|
Warning_Confluence_3Plus = (Warning_Confluence_Count >= 3);
|
|
|
|
//================================================================
|
|
// 10) RE-ENTRY COMBO FLAGS
|
|
//================================================================
|
|
|
|
// Strong MA flag for use in re-entry detection
|
|
bool at_strong_ma = (MA140_Warning || MA230_Warning || MA500_Warning);
|
|
|
|
// MA14 Magnet: Price hugging MA14 (within 0.7 ATR)
|
|
MA14_Magnet_Active = false;
|
|
if(Current_ATR > 0.0)
|
|
{
|
|
double distance_to_ma14 = MathAbs(current - MA_Current[1]);
|
|
if((distance_to_ma14 / Current_ATR) < 0.7)
|
|
MA14_Magnet_Active = true;
|
|
}
|
|
|
|
// Fib Break Confirmed: Price cleanly broke through fib level
|
|
Fib_Break_Confirmed = false;
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(MathAbs(prev - PriceLevels[i]) < bufferPts * 0.5 && // Was near level
|
|
MathAbs(current - PriceLevels[i]) > bufferPts * 2.0) // Now far from level
|
|
{
|
|
Fib_Break_Confirmed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// MFIB Break Confirmed: Price cleanly broke through MFIB level
|
|
MFIB_Break_Confirmed = false;
|
|
for(int i=0; i<5; i++)
|
|
{
|
|
if(MathAbs(prev - mfib_levels[i]) < bufferPts * 0.5 &&
|
|
MathAbs(current - mfib_levels[i]) > bufferPts * 2.0)
|
|
{
|
|
MFIB_Break_Confirmed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Strong MA Bounce: Price touched strong MA and bounced with stoch confirmation
|
|
Strong_MA_Bounce = false;
|
|
if(at_strong_ma)
|
|
{
|
|
// Check if price was on opposite side of MA and now back
|
|
bool ma140_bounce = false, ma230_bounce = false, ma500_bounce = false;
|
|
|
|
if(MA140_Warning)
|
|
{
|
|
if((prev < MA_Current[4] && current > MA_Current[4]) ||
|
|
(prev > MA_Current[4] && current < MA_Current[4]))
|
|
ma140_bounce = true;
|
|
}
|
|
|
|
if(MA230_Warning)
|
|
{
|
|
if((prev < MA_Current[5] && current > MA_Current[5]) ||
|
|
(prev > MA_Current[5] && current < MA_Current[5]))
|
|
ma230_bounce = true;
|
|
}
|
|
|
|
if(MA500_Warning)
|
|
{
|
|
if((prev < MA_Current[6] && current > MA_Current[6]) ||
|
|
(prev > MA_Current[6] && current < MA_Current[6]))
|
|
ma500_bounce = true;
|
|
}
|
|
|
|
if((ma140_bounce || ma230_bounce || ma500_bounce) &&
|
|
(Stoch_Level_Cross || Stoch_Reject_Warning))
|
|
Strong_MA_Bounce = true;
|
|
}
|
|
|
|
// Trend Resumption: MA50 reclaimed after pullback
|
|
Trend_Resumption = false;
|
|
if(IsBullBias() && Bull_MA50_Reclaimed()) Trend_Resumption = true;
|
|
if(IsBearBias() && Bear_MA50_Reclaimed()) Trend_Resumption = true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void DetectFamilyBiasStrength(MODE_FAMILY &family, TREND_BIAS &bias, TREND_STRENGTH &strength)
|
|
{
|
|
double current = MidPrice();
|
|
|
|
bool mas_aligned_bull = (MA_Current[0] > MA_Current[1]) && (MA_Current[1] > MA_Current[2]) && (MA_Current[2] > MA_Current[3]);
|
|
bool mas_aligned_bear = (MA_Current[0] < MA_Current[1]) && (MA_Current[1] < MA_Current[2]) && (MA_Current[2] < MA_Current[3]);
|
|
|
|
double recent_high = iHigh(_Symbol, PERIOD_CURRENT, 0);
|
|
double recent_low = iLow(_Symbol, PERIOD_CURRENT, 0);
|
|
for(int i=1; i<20; i++)
|
|
{
|
|
recent_high = MathMax(recent_high, iHigh(_Symbol, PERIOD_CURRENT, i));
|
|
recent_low = MathMin(recent_low, iLow(_Symbol, PERIOD_CURRENT, i));
|
|
}
|
|
double range_size = (recent_high - recent_low) / current;
|
|
bool is_ranging = (range_size < Range_Price_Threshold);
|
|
|
|
bool ma_clustered = false;
|
|
if(Current_ATR > 0.0)
|
|
ma_clustered = ((MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR) < Chop_ATR_Threshold);
|
|
bool is_choppy = (ma_clustered || Current_ADX < 15);
|
|
|
|
// Bias detection WITH MFIB .382 confirmation
|
|
if(mas_aligned_bull && (MFIB_Bias == BIAS_BULL || !Use_MFIB_382_Bias))
|
|
bias = BIAS_BULL;
|
|
else if(mas_aligned_bear && (MFIB_Bias == BIAS_BEAR || !Use_MFIB_382_Bias))
|
|
bias = BIAS_BEAR;
|
|
else
|
|
{
|
|
// Use MFIB bias as tiebreaker when MAs not fully aligned
|
|
if(MFIB_Bias == BIAS_BULL && MA_Current[0] > MA_Current[3])
|
|
bias = BIAS_BULL;
|
|
else if(MFIB_Bias == BIAS_BEAR && MA_Current[0] < MA_Current[3])
|
|
bias = BIAS_BEAR;
|
|
else if(MA_Current[0] > MA_Current[3])
|
|
bias = BIAS_BULL;
|
|
else if(MA_Current[0] < MA_Current[3])
|
|
bias = BIAS_BEAR;
|
|
else
|
|
bias = BIAS_NEUTRAL;
|
|
}
|
|
|
|
if(is_choppy && !(mas_aligned_bull || mas_aligned_bear))
|
|
family = FAMILY_CHOP;
|
|
else if(is_ranging && !(mas_aligned_bull || mas_aligned_bear))
|
|
family = FAMILY_RANGING;
|
|
else if(bias != BIAS_NEUTRAL)
|
|
family = FAMILY_TRENDING;
|
|
else
|
|
family = FAMILY_TRANSITIONAL;
|
|
|
|
if(Current_ADX > 25 && (mas_aligned_bull || mas_aligned_bear))
|
|
strength = STRENGTH_STRONG;
|
|
else if(Current_ADX > 18 && (mas_aligned_bull || mas_aligned_bear))
|
|
strength = STRENGTH_CONFIRMED;
|
|
else
|
|
strength = STRENGTH_WEAK;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
PRICE_STATE DetermineStateFromContext()
|
|
{
|
|
if(Current_Family == FAMILY_RANGING)
|
|
{
|
|
double current = MidPrice();
|
|
double bufferPts = (double)MA_Touch_Buffer;
|
|
|
|
bool near_low = NearLevel(current, PriceLevels[1], bufferPts) || NearLevel(current, PriceLevels[0], bufferPts);
|
|
bool near_high = NearLevel(current, PriceLevels[5], bufferPts) || NearLevel(current, PriceLevels[6], bufferPts);
|
|
|
|
if(near_low || near_high) return STATE_RANGE_EDGE_TEST;
|
|
if(Stoch_Reject_Warning || Stoch_Extreme_Warning || Fib_Reject_Warning || MFIB_Reject_Warning) return STATE_RANGE_REJECTION;
|
|
|
|
double close0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
if(close0 > PriceLevels[6] || close0 < PriceLevels[0]) return STATE_RANGE_BREAK_CONFIRMED;
|
|
if(NearLevel(current, PriceLevels[6], bufferPts) || NearLevel(current, PriceLevels[0], bufferPts)) return STATE_RANGE_BREAK_ATTEMPT;
|
|
|
|
return STATE_RANGE_MID_DRIFT;
|
|
}
|
|
|
|
if(Current_Family == FAMILY_CHOP)
|
|
{
|
|
if(Current_ADX < 12 && !Stoch_Reject_Warning) return STATE_CHOP_NOISE;
|
|
|
|
if(Current_ATR > 0)
|
|
{
|
|
double body = MathAbs(iClose(_Symbol, PERIOD_CURRENT, 0) - iOpen(_Symbol, PERIOD_CURRENT, 0));
|
|
if((body / Current_ATR) > 1.2) return STATE_CHOP_VOL_SPIKE;
|
|
|
|
double cluster = MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR;
|
|
if(Current_ADX < 15 && cluster < 0.25) return STATE_CHOP_SQUEEZE;
|
|
}
|
|
|
|
if(Stoch_Reject_Warning) return STATE_CHOP_FAKEOUT_LOOP;
|
|
return STATE_CHOP_NOISE;
|
|
}
|
|
|
|
bool ma7_above_14 = (MA_Current[0] > MA_Current[1]);
|
|
bool ma7_above_21 = (MA_Current[0] > MA_Current[2]);
|
|
bool ma7_above_50 = (MA_Current[0] > MA_Current[3]);
|
|
bool ma14_above_50 = (MA_Current[1] > MA_Current[3]);
|
|
bool ma21_above_50 = (MA_Current[2] > MA_Current[3]);
|
|
|
|
bool ma7_below_14 = (MA_Current[0] < MA_Current[1]);
|
|
bool ma7_below_21 = (MA_Current[0] < MA_Current[2]);
|
|
bool ma7_below_50 = (MA_Current[0] < MA_Current[3]);
|
|
bool ma14_below_50 = (MA_Current[1] < MA_Current[3]);
|
|
bool ma21_below_50 = (MA_Current[2] < MA_Current[3]);
|
|
|
|
bool structure_intact_bull = (ma14_above_50 && ma21_above_50);
|
|
bool structure_intact_bear = (ma14_below_50 && ma21_below_50);
|
|
|
|
bool pullbackSignal =
|
|
(Pullback_Warning || MFIB_Reject_Warning || Fib_Reject_Warning ||
|
|
Stoch_Reject_Warning || Band_Snap_Warning || Stoch_Level_Cross ||
|
|
MFIB_Reclaim_Warning || Fib_Reclaim_Warning || MA_Reclaim_Warning);
|
|
|
|
bool retraceSignal = (MA7_Cross_21_Warning || Retracement_Warning ||
|
|
MA140_Warning || MA230_Warning || MA500_Warning);
|
|
|
|
// Strong MA warnings indicate deeper pullback (potential retracement/reversal)
|
|
bool strongMA_pressure = (MA140_Warning || MA230_Warning || MA500_Warning || MA50_Warning);
|
|
|
|
bool confluenceAligned = false;
|
|
if(IsBullBias() && structure_intact_bull) confluenceAligned = Warning_Confluence_3Plus;
|
|
if(IsBearBias() && structure_intact_bear) confluenceAligned = Warning_Confluence_3Plus;
|
|
|
|
if(IsBullBias())
|
|
{
|
|
if(ma7_below_50 && !ma14_above_50 && !ma21_above_50) return STATE_REVERSAL_CONFIRMED;
|
|
|
|
if(MA50_Break_Warning && (retraceSignal || strongMA_pressure || Stoch_Extreme_Warning || Stoch_Reject_Warning || Warning_Confluence_3Plus))
|
|
return STATE_REVERSAL_ATTEMPT;
|
|
|
|
// DEEP RETRACEMENT: MA7x21 cross OR testing strong MAs (140/230/500)
|
|
if(MA7_Cross_21_Warning || strongMA_pressure || (!ma7_above_21 && (pullbackSignal || retraceSignal || confluenceAligned)))
|
|
return STATE_DEEP_RETRACEMENT;
|
|
|
|
// PULLBACK: MA7x14 cross OR 2+ pullback signals with structure intact
|
|
if(MA7_Cross_14_Warning || (structure_intact_bull && (pullbackSignal || confluenceAligned)))
|
|
return STATE_PULLBACK;
|
|
|
|
return STATE_CONTINUATION;
|
|
}
|
|
|
|
if(IsBearBias())
|
|
{
|
|
if(ma7_above_50 && !ma14_below_50 && !ma21_below_50) return STATE_REVERSAL_CONFIRMED;
|
|
|
|
if(MA50_Break_Warning && (retraceSignal || strongMA_pressure || Stoch_Extreme_Warning || Stoch_Reject_Warning || Warning_Confluence_3Plus))
|
|
return STATE_REVERSAL_ATTEMPT;
|
|
|
|
// DEEP RETRACEMENT: MA7x21 cross OR testing strong MAs (140/230/500)
|
|
if(MA7_Cross_21_Warning || strongMA_pressure || (!ma7_below_21 && (pullbackSignal || retraceSignal || confluenceAligned)))
|
|
return STATE_DEEP_RETRACEMENT;
|
|
|
|
// PULLBACK: MA7x14 cross OR 2+ pullback signals with structure intact
|
|
if(MA7_Cross_14_Warning || (structure_intact_bear && (pullbackSignal || confluenceAligned)))
|
|
return STATE_PULLBACK;
|
|
|
|
return STATE_CONTINUATION;
|
|
}
|
|
|
|
return STATE_UNKNOWN;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
string FamilyToText(MODE_FAMILY f)
|
|
{
|
|
switch(f)
|
|
{
|
|
case FAMILY_TRENDING: return "Trending";
|
|
case FAMILY_RANGING: return "Ranging";
|
|
case FAMILY_CHOP: return "Chop";
|
|
case FAMILY_TRANSITIONAL: return "Transitional";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
string BiasToText(TREND_BIAS b)
|
|
{
|
|
if(b == BIAS_BULL) return "Bull";
|
|
if(b == BIAS_BEAR) return "Bear";
|
|
return "Neutral";
|
|
}
|
|
|
|
string StrengthToText(TREND_STRENGTH s)
|
|
{
|
|
switch(s)
|
|
{
|
|
case STRENGTH_WEAK: return "Weak";
|
|
case STRENGTH_CONFIRMED: return "Confirmed";
|
|
case STRENGTH_STRONG: return "Strong";
|
|
}
|
|
return "Weak";
|
|
}
|
|
|
|
string StateToText(PRICE_STATE s)
|
|
{
|
|
switch(s)
|
|
{
|
|
case STATE_CONTINUATION: return "Continuation";
|
|
case STATE_PULLBACK: return "Pullback";
|
|
case STATE_DEEP_RETRACEMENT: return "Deep Retracement";
|
|
case STATE_REVERSAL_ATTEMPT: return "Reversal Attempt";
|
|
case STATE_REVERSAL_CONFIRMED: return "Reversal Confirmed";
|
|
|
|
case STATE_RANGE_MID_DRIFT: return "Range: Mid Drift";
|
|
case STATE_RANGE_EDGE_TEST: return "Range: Edge Test";
|
|
case STATE_RANGE_REJECTION: return "Range: Rejection";
|
|
case STATE_RANGE_BREAK_ATTEMPT: return "Range: Break Attempt";
|
|
case STATE_RANGE_BREAK_CONFIRMED: return "Range: Break Confirmed";
|
|
|
|
case STATE_CHOP_NOISE: return "Chop: Noise";
|
|
case STATE_CHOP_VOL_SPIKE: return "Chop: Vol Spike";
|
|
case STATE_CHOP_SQUEEZE: return "Chop: Squeeze";
|
|
case STATE_CHOP_FAKEOUT_LOOP: return "Chop: Fakeout Loop";
|
|
|
|
default: return "Unknown";
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void UpdateLabels()
|
|
{
|
|
ObjectDelete(0, "ModeLabel");
|
|
ObjectCreate(0, "ModeLabel", OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_YDISTANCE, 20);
|
|
|
|
string mode_text = "MODE: " + FamilyToText(Current_Family);
|
|
if(Current_Family == FAMILY_TRENDING)
|
|
mode_text += " | " + StrengthToText(Current_Strength) + " " + BiasToText(Current_Bias);
|
|
|
|
color mode_color = clrYellow;
|
|
if(Current_Family == FAMILY_TRENDING)
|
|
{
|
|
if(Current_Bias == BIAS_BULL) mode_color = (Current_Strength == STRENGTH_STRONG ? clrLime : (Current_Strength == STRENGTH_CONFIRMED ? clrGreenYellow : clrGreen));
|
|
if(Current_Bias == BIAS_BEAR) mode_color = (Current_Strength == STRENGTH_STRONG ? clrRed : (Current_Strength == STRENGTH_CONFIRMED ? clrOrangeRed : clrOrange));
|
|
}
|
|
else if(Current_Family == FAMILY_RANGING) mode_color = clrAqua;
|
|
else if(Current_Family == FAMILY_CHOP) mode_color = clrViolet;
|
|
|
|
ObjectSetString(0, "ModeLabel", OBJPROP_TEXT, mode_text);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_COLOR, mode_color);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_FONTSIZE, 12);
|
|
|
|
// MFIB BIAS LABEL
|
|
ObjectDelete(0, "MFIBLabel");
|
|
if(Use_MFIB_382_Bias)
|
|
{
|
|
ObjectCreate(0, "MFIBLabel", OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, "MFIBLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, "MFIBLabel", OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, "MFIBLabel", OBJPROP_YDISTANCE, 40);
|
|
|
|
string mfib_text = "MFIB .382 BIAS: " + BiasToText(MFIB_Bias);
|
|
color mfib_color = (MFIB_Bias == BIAS_BULL ? clrLime : (MFIB_Bias == BIAS_BEAR ? clrRed : clrGray));
|
|
|
|
ObjectSetString(0, "MFIBLabel", OBJPROP_TEXT, mfib_text);
|
|
ObjectSetInteger(0, "MFIBLabel", OBJPROP_COLOR, mfib_color);
|
|
ObjectSetInteger(0, "MFIBLabel", OBJPROP_FONTSIZE, 11);
|
|
}
|
|
|
|
ObjectDelete(0, "StateLabel");
|
|
ObjectCreate(0, "StateLabel", OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_YDISTANCE, Use_MFIB_382_Bias ? 60 : 40);
|
|
|
|
string state_text = "STATE: " + StateToText(Current_State);
|
|
|
|
if(Current_Family == FAMILY_TRENDING && (Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT))
|
|
{
|
|
if(IsBullBias() && !Bull_MA50_Reclaimed())
|
|
state_text += " | ACTION: COUNTER-SELLS (50 SL)";
|
|
else if(IsBearBias() && !Bear_MA50_Reclaimed())
|
|
state_text += " | ACTION: COUNTER-BUYS (50 SL)";
|
|
else
|
|
state_text += " | ACTION: TREND-OK (150 SL)";
|
|
}
|
|
|
|
color state_color = clrWhite;
|
|
if(Current_State == STATE_CONTINUATION) state_color = clrLime;
|
|
else if(Current_State == STATE_PULLBACK) state_color = clrYellow;
|
|
else if(Current_State == STATE_DEEP_RETRACEMENT) state_color = clrOrange;
|
|
else if(Current_State == STATE_REVERSAL_ATTEMPT) state_color = clrOrangeRed;
|
|
else if(Current_State == STATE_REVERSAL_CONFIRMED) state_color = clrRed;
|
|
else if(Current_Family == FAMILY_RANGING) state_color = clrAqua;
|
|
else if(Current_Family == FAMILY_CHOP) state_color = clrViolet;
|
|
|
|
ObjectSetString(0, "StateLabel", OBJPROP_TEXT, state_text);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_COLOR, state_color);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_FONTSIZE, 11);
|
|
|
|
bool anyWarn =
|
|
(Stoch_Extreme_Warning || Stoch_Reject_Warning || Stoch_Level_Cross ||
|
|
MA7_Cross_14_Warning || MA7_Cross_21_Warning ||
|
|
MA50_Break_Warning || MA50_Warning || MA140_Warning || MA230_Warning || MA500_Warning ||
|
|
Fib_Reject_Warning || MFIB_Reject_Warning ||
|
|
Fib_Reclaim_Warning || MFIB_Reclaim_Warning || MA_Reclaim_Warning ||
|
|
MA_Reject_Warning || Band_Snap_Warning || Warning_Confluence_3Plus);
|
|
|
|
//====================
|
|
// PRAISE/WARN LABEL (TOP RIGHT)
|
|
//====================
|
|
if(anyPraise)
|
|
ObjectDelete(0, "PraiseLabel");
|
|
ObjectCreate(0, "PraiseLabel", OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, "PraiseLabel", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
|
|
ObjectSetInteger(0, "PraiseLabel", OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, "PraiseLabel", OBJPROP_YDISTANCE, 20);
|
|
|
|
string pw = PostureToText(Current_Posture) + " | P=" + IntegerToString(PraiseScore) + " W=" + IntegerToString(WarnScore);
|
|
color pwc = clrWhite;
|
|
if(Current_Posture == POSTURE_STRONG) pwc = clrGreenYellow;
|
|
if(Current_Posture == POSTURE_COUNTER) pwc = clrOrange;
|
|
if(Current_Posture == POSTURE_DEFENSIVE) pwc = clrRed;
|
|
|
|
ObjectSetString(0, "PraiseLabel", OBJPROP_TEXT, pw);
|
|
ObjectSetInteger(0, "PraiseLabel", OBJPROP_COLOR, pwc);
|
|
ObjectSetInteger(0, "PraiseLabel", OBJPROP_FONTSIZE, 11);
|
|
|
|
if(anyWarn)
|
|
{
|
|
ObjectDelete(0, "WarningLabel");
|
|
ObjectCreate(0, "WarningLabel", OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_YDISTANCE, Use_MFIB_382_Bias ? 80 : 60);
|
|
|
|
string warn_text = "WARN: ";
|
|
if(Stoch_Extreme_Warning) warn_text += "STOCH-EXT | ";
|
|
if(Stoch_Reject_Warning) warn_text += "STOCH-REJ | ";
|
|
if(Stoch_Level_Cross) warn_text += "STOCH-LVL | ";
|
|
if(MA7_Cross_14_Warning) warn_text += "MA7x14-PB | ";
|
|
if(MA7_Cross_21_Warning) warn_text += "MA7x21-RET | ";
|
|
if(MA50_Break_Warning) warn_text += "MA50-BRK | ";
|
|
if(MA50_Warning) warn_text += "MA50 | ";
|
|
if(MA140_Warning) warn_text += "MA140 | ";
|
|
if(MA230_Warning) warn_text += "MA230 | ";
|
|
if(MA500_Warning) warn_text += "MA500 | ";
|
|
if(Fib_Reject_Warning) warn_text += "FIB-REJ | ";
|
|
if(MFIB_Reject_Warning) warn_text += "MFIB-REJ | ";
|
|
if(Fib_Reclaim_Warning) warn_text += "FIB-RCL | ";
|
|
if(MFIB_Reclaim_Warning) warn_text += "MFIB-RCL | ";
|
|
if(MA_Reclaim_Warning) warn_text += "MA-RCL | ";
|
|
if(MA_Reject_Warning) warn_text += "MA-REJ | ";
|
|
if(Band_Snap_Warning) warn_text += "BAND-SNAP | ";
|
|
if(Warning_Confluence_3Plus) warn_text += "3+CONF | ";
|
|
|
|
warn_text += "W=" + IntegerToString(Warning_Confluence_Count);
|
|
|
|
ObjectSetString(0, "WarningLabel", OBJPROP_TEXT, warn_text);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_FONTSIZE, 10);
|
|
}
|
|
else
|
|
{
|
|
ObjectDelete(0, "WarningLabel");
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void UpdateModeAndState()
|
|
{
|
|
MODE_FAMILY detected_family;
|
|
TREND_BIAS detected_bias;
|
|
TREND_STRENGTH detected_strength;
|
|
|
|
DetectFamilyBiasStrength(detected_family, detected_bias, detected_strength);
|
|
|
|
Current_Family = detected_family;
|
|
Current_Bias = detected_bias;
|
|
Current_Strength = detected_strength;
|
|
|
|
PRICE_STATE detected_state = DetermineStateFromContext();
|
|
|
|
bool changed =
|
|
(detected_family != Prev_Family) ||
|
|
(detected_bias != Prev_Bias) ||
|
|
(detected_strength != Prev_Strength);
|
|
|
|
if(changed)
|
|
{
|
|
int required = Mode_Confirmation_Bars;
|
|
if(detected_state == STATE_REVERSAL_CONFIRMED) required = 1;
|
|
|
|
if(detected_family == Prev_Family && detected_bias == Prev_Bias && detected_strength == Prev_Strength)
|
|
{
|
|
Mode_Confirmation_Count++;
|
|
if(Mode_Confirmation_Count >= required)
|
|
{
|
|
Prev_Family = detected_family;
|
|
Prev_Bias = detected_bias;
|
|
Prev_Strength = detected_strength;
|
|
|
|
Current_Family = detected_family;
|
|
Current_Bias = detected_bias;
|
|
Current_Strength = detected_strength;
|
|
Current_State = detected_state;
|
|
|
|
Mode_Confirmation_Count = 0;
|
|
Reversal_Confirm_Counter = 0;
|
|
|
|
if(Current_State == STATE_REVERSAL_CONFIRMED)
|
|
CloseOnFullReversal();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Prev_Family = detected_family;
|
|
Prev_Bias = detected_bias;
|
|
Prev_Strength = detected_strength;
|
|
Mode_Confirmation_Count = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Mode_Confirmation_Count = 0;
|
|
Current_State = detected_state;
|
|
}
|
|
|
|
Is_Pullback_State = (Current_State == STATE_PULLBACK);
|
|
Is_Retracement_State = (Current_State == STATE_DEEP_RETRACEMENT);
|
|
|
|
UpdateLabels();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void MarkRunners()
|
|
{
|
|
double current = MidPrice();
|
|
|
|
for(int i=0; i<ArraySize(OpenPositions); i++)
|
|
{
|
|
if(PositionSelectByTicket(OpenPositions[i].ticket))
|
|
{
|
|
double entry = OpenPositions[i].entry;
|
|
OpenPositions[i].distance_from_current = MathAbs(current - entry) / _Point;
|
|
}
|
|
}
|
|
|
|
for(int i=0; i<ArraySize(OpenPositions)-1; i++)
|
|
{
|
|
for(int j=i+1; j<ArraySize(OpenPositions); j++)
|
|
{
|
|
if(OpenPositions[j].distance_from_current > OpenPositions[i].distance_from_current)
|
|
{
|
|
PositionRec tmp = OpenPositions[i];
|
|
OpenPositions[i] = OpenPositions[j];
|
|
OpenPositions[j] = tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i=0; i<ArraySize(OpenPositions); i++)
|
|
OpenPositions[i].is_runner = (i < Min_Runners_To_Keep);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CloseOnFullReversal()
|
|
{
|
|
if(!Only_Close_On_Full_Reversal) return;
|
|
|
|
MarkRunners();
|
|
Print("🔄 REVERSAL CONFIRMED - Closing opposing positions (protecting runners)");
|
|
|
|
for(int i=PositionsTotal()-1; i>=0; i--)
|
|
{
|
|
if(PositionGetTicket(i) == 0) continue;
|
|
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
|
|
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
|
|
|
|
ulong ticket = PositionGetTicket(i);
|
|
bool is_buy = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY);
|
|
|
|
int idx = -1;
|
|
for(int j=0; j<ArraySize(OpenPositions); j++)
|
|
{
|
|
if(OpenPositions[j].ticket == ticket) { idx = j; break; }
|
|
}
|
|
|
|
if(idx >= 0 && OpenPositions[idx].is_runner)
|
|
continue;
|
|
|
|
bool should_close = false;
|
|
if(is_buy && IsBearBias()) should_close = true;
|
|
if(!is_buy && IsBullBias()) should_close = true;
|
|
|
|
if(should_close)
|
|
{
|
|
if(Trade.PositionClose(ticket))
|
|
ClosedByReversal++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool IsDirectionAllowed(bool is_buy)
|
|
{
|
|
if(!Use_Market_Mode_Filter) return true;
|
|
// Praise/Warn posture gating (does NOT decide direction, only allows categories)
|
|
if(Use_PraiseWarn_Engine)
|
|
{
|
|
// In DEFENSIVE: continuation paused (counter only)
|
|
if(Current_Posture == POSTURE_DEFENSIVE)
|
|
{
|
|
// continuation setups call OpenTrade with CATEGORY_CONTINUATION
|
|
// we can't see category here; direction filter stays neutral.
|
|
// So we enforce in OpenTrade/CanReEnter via category check.
|
|
}
|
|
}
|
|
|
|
|
|
if(Current_Family == FAMILY_TRENDING)
|
|
{
|
|
if(Current_State == STATE_REVERSAL_CONFIRMED)
|
|
{
|
|
if(IsBullBias() && !is_buy) return false;
|
|
if(IsBearBias() && is_buy) return false;
|
|
return true;
|
|
}
|
|
|
|
if(Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT)
|
|
{
|
|
if(IsBullBias())
|
|
{
|
|
if(!Bull_MA50_Reclaimed())
|
|
return (!is_buy); // SELLS ONLY
|
|
return is_buy;
|
|
}
|
|
|
|
if(IsBearBias())
|
|
{
|
|
if(!Bear_MA50_Reclaimed())
|
|
return (is_buy); // BUYS ONLY
|
|
return (!is_buy);
|
|
}
|
|
}
|
|
|
|
if(Current_State == STATE_CONTINUATION)
|
|
{
|
|
if(IsBullBias() && !is_buy) return false;
|
|
if(IsBearBias() && is_buy) return false;
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
int CountSetupTrades(SETUP_TYPE setup)
|
|
{
|
|
int count = 0;
|
|
for(int i=0; i<PositionsTotal(); i++)
|
|
{
|
|
if(PositionGetTicket(i) == 0) continue;
|
|
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
|
|
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
|
|
|
|
ulong t = PositionGetTicket(i);
|
|
|
|
for(int j=0; j<ArraySize(OpenPositions); j++)
|
|
{
|
|
if(OpenPositions[j].ticket == t)
|
|
{
|
|
if(OpenPositions[j].setup_type == setup)
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
double GetLotSize(TRADE_CATEGORY category)
|
|
{
|
|
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 sl_points = (category == CATEGORY_COUNTER_TREND) ? Counter_SL_Points : Continuation_SL_Points;
|
|
|
|
double lot = risk / ((sl_points * _Point / tickSize) * tickValue);
|
|
|
|
// WAR SURVIVOR: Apply multiplier for larger initial positions
|
|
// This allows us to survive more stops while taking aggressive partials
|
|
if(Use_MFIB_Partials)
|
|
lot = lot * War_Survivor_Lot_Multiplier;
|
|
|
|
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;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void OpenTrade(bool buy, double price, string setup_name, SETUP_TYPE setup_type, TRADE_CATEGORY category)
|
|
{
|
|
if(!IsDirectionAllowed(buy)) return;
|
|
if(!CanReEnter(setup_type)) return;
|
|
|
|
if(CountSetupTrades(setup_type) >= Max_Trades_Per_Setup) return;
|
|
if(PositionsTotal() >= Max_Total_Trades) return;
|
|
|
|
datetime now = TimeCurrent();
|
|
if(now - LastEntryTime[setup_type] < 1) return;
|
|
|
|
double lot = GetLotSize(category);
|
|
if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return;
|
|
|
|
double sl, tp;
|
|
|
|
if(category == CATEGORY_COUNTER_TREND)
|
|
{
|
|
sl = buy ? price - Counter_SL_Points * _Point : price + Counter_SL_Points * _Point;
|
|
tp = buy ? price + Counter_TP_Points * _Point : price - Counter_TP_Points * _Point;
|
|
}
|
|
else
|
|
{
|
|
sl = buy ? price - Continuation_SL_Points * _Point : price + Continuation_SL_Points * _Point;
|
|
tp = buy ? price + Continuation_TP_Points * _Point : price - Continuation_TP_Points * _Point;
|
|
}
|
|
|
|
string cat_text = (category == CATEGORY_COUNTER_TREND) ? "CTR" : "CONT";
|
|
string bias_text = BiasToText(MFIB_Bias);
|
|
string comment = setup_name + "|" + cat_text + "|" + FamilyToText(Current_Family) + "|" + bias_text;
|
|
|
|
bool result = false;
|
|
if(buy) result = Trade.Buy(lot, _Symbol, 0, sl, tp, comment);
|
|
else result = Trade.Sell(lot, _Symbol, 0, sl, tp, comment);
|
|
|
|
if(result)
|
|
{
|
|
LastEntryTime[setup_type] = now;
|
|
TodayTrades++;
|
|
if(buy) BuyTrades++; else SellTrades++;
|
|
SetupCount[setup_type]++;
|
|
|
|
ulong ticket = Trade.ResultOrder();
|
|
|
|
int size = ArraySize(OpenPositions);
|
|
ArrayResize(OpenPositions, size+1);
|
|
|
|
OpenPositions[size].ticket = ticket;
|
|
OpenPositions[size].entry = price;
|
|
OpenPositions[size].original_lot = lot;
|
|
OpenPositions[size].is_buy = buy;
|
|
OpenPositions[size].partial_tp_hit = false;
|
|
OpenPositions[size].be_set = false;
|
|
OpenPositions[size].trailing_active = false;
|
|
OpenPositions[size].is_runner = false;
|
|
OpenPositions[size].setup_type = setup_type;
|
|
OpenPositions[size].category = category;
|
|
OpenPositions[size].setup_name = setup_name;
|
|
OpenPositions[size].entry_family = Current_Family;
|
|
OpenPositions[size].entry_bias = Current_Bias;
|
|
OpenPositions[size].entry_strength = Current_Strength;
|
|
OpenPositions[size].distance_from_current = 0;
|
|
OpenPositions[size].last_close_time = 0;
|
|
OpenPositions[size].closed_at_sl = false; // NEW
|
|
OpenPositions[size].closed_at_be = false; // NEW
|
|
OpenPositions[size].close_price = 0; // NEW
|
|
OpenPositions[size].mfib_partials_taken = 0; // WAR SURVIVOR
|
|
OpenPositions[size].last_mfib_partial_price = 0; // WAR SURVIVOR
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void ManagePositions()
|
|
{
|
|
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 = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
double current_sl = PositionGetDouble(POSITION_SL);
|
|
double current_tp = PositionGetDouble(POSITION_TP);
|
|
bool is_buy = OpenPositions[idx].is_buy;
|
|
TRADE_CATEGORY cat = OpenPositions[idx].category;
|
|
|
|
double current = is_buy ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double profit_points = is_buy ? (current - entry) / _Point : (entry - current) / _Point;
|
|
|
|
int partial_tp_pts = (cat == CATEGORY_COUNTER_TREND) ? Counter_Partial_TP : Continuation_Partial_TP;
|
|
double partial_pct = (cat == CATEGORY_COUNTER_TREND) ? Counter_Partial_Percent : Continuation_Partial_Percent;
|
|
int be_pts = (cat == CATEGORY_COUNTER_TREND) ? Counter_BreakEven_Points : Continuation_BreakEven_Points;
|
|
int trail_pts = (cat == CATEGORY_COUNTER_TREND) ? Counter_Trail_Points : Continuation_Trail_Points;
|
|
|
|
if(!OpenPositions[idx].partial_tp_hit && profit_points >= partial_tp_pts)
|
|
{
|
|
double current_lot = PositionGetDouble(POSITION_VOLUME);
|
|
double close_size = NormalizeDouble(OpenPositions[idx].original_lot * partial_pct / 100.0, 2);
|
|
|
|
if(close_size > 0 && close_size <= current_lot)
|
|
{
|
|
if(Trade.PositionClosePartial(ticket, close_size))
|
|
OpenPositions[idx].partial_tp_hit = true;
|
|
}
|
|
}
|
|
|
|
//===================================================================
|
|
// WAR SURVIVOR: AGGRESSIVE MFIB PARTIAL SYSTEM
|
|
// Take 25% at each MFIB rejection to lock in gains frequently
|
|
//===================================================================
|
|
if(Use_MFIB_Partials && profit_points >= MFIB_Partial_Min_Profit && OpenPositions[idx].mfib_partials_taken < 4)
|
|
{
|
|
bool mfib_reject_happened = false;
|
|
double mfib_reject_price = 0;
|
|
|
|
// Check if we're at a MFIB level with rejection
|
|
double mfib_levels[5] = {MFIB_Level_236, MFIB_Level_382, MFIB_Level_050, MFIB_Level_618, MFIB_Level_786};
|
|
|
|
for(int m=0; m<5; m++)
|
|
{
|
|
double dist_to_level = MathAbs(current - mfib_levels[m]) / _Point;
|
|
|
|
// At MFIB level (within 50 points)
|
|
if(dist_to_level <= 50)
|
|
{
|
|
// Check for rejection signs
|
|
bool has_reject_signal = (MFIB_Reject_Warning || Stoch_Reject_Warning ||
|
|
Stoch_Extreme_Warning || Warning_Confluence_3Plus);
|
|
|
|
// Check if different from last partial
|
|
bool new_level = (OpenPositions[idx].last_mfib_partial_price == 0) ||
|
|
(MathAbs(current - OpenPositions[idx].last_mfib_partial_price) / _Point > 100);
|
|
|
|
if(has_reject_signal && new_level)
|
|
{
|
|
mfib_reject_happened = true;
|
|
mfib_reject_price = mfib_levels[m];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Execute MFIB partial
|
|
if(mfib_reject_happened)
|
|
{
|
|
double current_lot = PositionGetDouble(POSITION_VOLUME);
|
|
double close_size = NormalizeDouble(OpenPositions[idx].original_lot * MFIB_Partial_Percent / 100.0, 2);
|
|
|
|
// Ensure we don't close more than available
|
|
if(close_size > current_lot)
|
|
close_size = current_lot * 0.25; // Take 25% of what's left
|
|
|
|
if(close_size > 0 && close_size >= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
|
|
{
|
|
if(Trade.PositionClosePartial(ticket, close_size))
|
|
{
|
|
OpenPositions[idx].mfib_partials_taken++;
|
|
OpenPositions[idx].last_mfib_partial_price = mfib_reject_price;
|
|
|
|
Print("💰 WAR SURVIVOR MFIB PARTIAL #", OpenPositions[idx].mfib_partials_taken,
|
|
" | Closed ", close_size, " lots at MFIB ", DoubleToString(mfib_reject_price, 2),
|
|
" | +", DoubleToString(profit_points, 1), " pts");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!OpenPositions[idx].be_set && profit_points >= be_pts)
|
|
{
|
|
if((is_buy && current_sl < entry) || (!is_buy && current_sl > entry))
|
|
{
|
|
if(Trade.PositionModify(ticket, entry, current_tp))
|
|
OpenPositions[idx].be_set = true;
|
|
}
|
|
}
|
|
|
|
if(profit_points >= be_pts + 50)
|
|
{
|
|
OpenPositions[idx].trailing_active = true;
|
|
|
|
double newSL = 0;
|
|
bool should_modify = false;
|
|
|
|
if(is_buy)
|
|
{
|
|
newSL = current - trail_pts * _Point;
|
|
if(newSL > current_sl + 30 * _Point) should_modify = true;
|
|
}
|
|
else
|
|
{
|
|
newSL = current + trail_pts * _Point;
|
|
if(newSL < current_sl - 30 * _Point) should_modify = true;
|
|
}
|
|
|
|
if(should_modify) Trade.PositionModify(ticket, newSL, current_tp);
|
|
}
|
|
|
|
// Update close price for tracking
|
|
OpenPositions[idx].close_price = current;
|
|
}
|
|
|
|
// Check for recently closed positions (for re-entry tracking)
|
|
for(int i=ArraySize(OpenPositions)-1; i>=0; i--)
|
|
{
|
|
ulong ticket = OpenPositions[i].ticket;
|
|
|
|
// Check if position still exists
|
|
if(!PositionSelectByTicket(ticket))
|
|
{
|
|
// Position was closed - determine if at SL or BE
|
|
double entry = OpenPositions[i].entry;
|
|
double close_price = OpenPositions[i].close_price;
|
|
bool is_buy = OpenPositions[i].is_buy;
|
|
|
|
// Check if closed at BE (close price near entry)
|
|
bool at_be = (MathAbs(close_price - entry) / _Point < 10);
|
|
|
|
// Check if closed at SL (assuming loss)
|
|
bool at_sl = false;
|
|
if(is_buy && close_price < entry) at_sl = true;
|
|
if(!is_buy && close_price > entry) at_sl = true;
|
|
|
|
if(at_be) at_sl = false; // BE takes precedence
|
|
|
|
// Record closure for re-entry system
|
|
RecordClosure(OpenPositions[i].setup_type, OpenPositions[i].category,
|
|
OpenPositions[i].is_buy, close_price, at_sl, at_be);
|
|
|
|
// Remove from array
|
|
for(int j=i; j<ArraySize(OpenPositions)-1; j++)
|
|
OpenPositions[j] = OpenPositions[j+1];
|
|
ArrayResize(OpenPositions, ArraySize(OpenPositions)-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
UpdateIndicators();
|
|
DetectWarnings();
|
|
|
|
static int tick_count = 0;
|
|
tick_count++;
|
|
if(tick_count >= 100)
|
|
{
|
|
CalculateLevels();
|
|
if(Show_Levels) DrawLevels();
|
|
tick_count = 0;
|
|
}
|
|
|
|
UpdateModeAndState();
|
|
ManagePositions();
|
|
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double current = (bid + ask) / 2.0;
|
|
double previous = iClose(_Symbol, PERIOD_CURRENT, 1);
|
|
double buffer = MA_Touch_Buffer * _Point;
|
|
|
|
//=================================================================
|
|
// PULLBACK COUNTER-TREND SETUPS (50 SL)
|
|
//=================================================================
|
|
if(Current_Family == FAMILY_TRENDING && Is_Pullback_State)
|
|
{
|
|
bool bull = IsBullBias();
|
|
bool bear = IsBearBias();
|
|
bool ma50_not_reclaimed = (bull && !Bull_MA50_Reclaimed()) || (bear && !Bear_MA50_Reclaimed());
|
|
|
|
if(ma50_not_reclaimed)
|
|
{
|
|
int pb_signals = 0;
|
|
if(MA7_Cross_14_Warning) pb_signals++;
|
|
if(MFIB_Reject_Warning) pb_signals++;
|
|
if(Band_Snap_Warning) pb_signals++;
|
|
if(Stoch_Reject_Warning || Stoch_Extreme_Warning) pb_signals++;
|
|
|
|
if(pb_signals >= 2)
|
|
{
|
|
if(bull) OpenTrade(false, bid, "PB-COUNTER-SELL", SETUP_PULLBACK_COUNTER, CATEGORY_COUNTER_TREND);
|
|
if(bear) OpenTrade(true, ask, "PB-COUNTER-BUY", SETUP_PULLBACK_COUNTER, CATEGORY_COUNTER_TREND);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=================================================================
|
|
// RETRACEMENT COUNTER-TREND SETUPS (50 SL)
|
|
//=================================================================
|
|
if(Current_Family == FAMILY_TRENDING && Is_Retracement_State)
|
|
{
|
|
bool bull = IsBullBias();
|
|
bool bear = IsBearBias();
|
|
bool ma50_not_reclaimed = (bull && !Bull_MA50_Reclaimed()) || (bear && !Bear_MA50_Reclaimed());
|
|
|
|
if(ma50_not_reclaimed)
|
|
{
|
|
int ret_signals = 0;
|
|
if(MA7_Cross_21_Warning) ret_signals++;
|
|
if(MFIB_Reject_Warning) ret_signals++;
|
|
if(Band_Snap_Warning) ret_signals++;
|
|
if(Stoch_Reject_Warning || Stoch_Extreme_Warning) ret_signals++;
|
|
|
|
if(ret_signals >= 2)
|
|
{
|
|
if(bull) OpenTrade(false, bid, "RET-COUNTER-SELL", SETUP_RETRACEMENT_COUNTER, CATEGORY_COUNTER_TREND);
|
|
if(bear) OpenTrade(true, ask, "RET-COUNTER-BUY", SETUP_RETRACEMENT_COUNTER, CATEGORY_COUNTER_TREND);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=================================================================
|
|
// CONTINUATION SETUPS (150 SL) - ALL 16 ORIGINAL SETUPS
|
|
//=================================================================
|
|
if(Current_Family == FAMILY_TRENDING && Current_State == STATE_CONTINUATION)
|
|
{
|
|
// 1. MA14 CROSS
|
|
int ma14_crosses = 0;
|
|
for(int i=0; i<10; i++) if(i != 1 && MA_Current[1] > MA_Current[i]) ma14_crosses++;
|
|
if(ma14_crosses >= 2) OpenTrade(true, ask, "MA14-CROSS↑", SETUP_MA14_CROSS, CATEGORY_CONTINUATION);
|
|
|
|
ma14_crosses = 0;
|
|
for(int i=0; i<10; i++) if(i != 1 && MA_Current[1] < MA_Current[i]) ma14_crosses++;
|
|
if(ma14_crosses >= 2) OpenTrade(false, bid, "MA14-CROSS↓", SETUP_MA14_CROSS, CATEGORY_CONTINUATION);
|
|
|
|
// 2. MA50 BOUNCE
|
|
if(MathAbs(current - MA_Current[3]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE, CATEGORY_CONTINUATION);
|
|
OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE, CATEGORY_CONTINUATION);
|
|
}
|
|
|
|
// 3. MA140 BOUNCE
|
|
if(MathAbs(current - MA_Current[4]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA140-BOUNCE↑", SETUP_MA140_BOUNCE, CATEGORY_CONTINUATION);
|
|
OpenTrade(false, bid, "MA140-BOUNCE↓", SETUP_MA140_BOUNCE, CATEGORY_CONTINUATION);
|
|
}
|
|
|
|
// 4. MA230 BOUNCE
|
|
if(MathAbs(current - MA_Current[5]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA230-BOUNCE↑", SETUP_MA230_BOUNCE, CATEGORY_CONTINUATION);
|
|
OpenTrade(false, bid, "MA230-BOUNCE↓", SETUP_MA230_BOUNCE, CATEGORY_CONTINUATION);
|
|
}
|
|
|
|
// 5. MA500 TOUCH
|
|
if(MathAbs(current - MA_Current[6]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA500-TOUCH↑", SETUP_MA500_TOUCH, CATEGORY_CONTINUATION);
|
|
OpenTrade(false, bid, "MA500-TOUCH↓", SETUP_MA500_TOUCH, CATEGORY_CONTINUATION);
|
|
}
|
|
|
|
// 6. FIB BREAKS
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(MathAbs(current - PriceLevels[i]) <= buffer)
|
|
{
|
|
if(previous < PriceLevels[i])
|
|
OpenTrade(true, ask, "FIB-BREAK↑", SETUP_FIB_BREAK, CATEGORY_CONTINUATION);
|
|
if(previous > PriceLevels[i])
|
|
OpenTrade(false, bid, "FIB-BREAK↓", SETUP_FIB_BREAK, CATEGORY_CONTINUATION);
|
|
}
|
|
}
|
|
|
|
// 7. FIB RECLAIM
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(NearLevel(current, PriceLevels[i], buffer))
|
|
{
|
|
if(MA_Previous[0] < PriceLevels[i] && MA_Current[0] > PriceLevels[i])
|
|
OpenTrade(true, ask, "FIB-RECLAIM↑", SETUP_FIB_RECLAIM, CATEGORY_CONTINUATION);
|
|
if(MA_Previous[0] > PriceLevels[i] && MA_Current[0] < PriceLevels[i])
|
|
OpenTrade(false, bid, "FIB-RECLAIM↓", SETUP_FIB_RECLAIM, CATEGORY_CONTINUATION);
|
|
}
|
|
}
|
|
|
|
// 8. MAGNET WALK
|
|
bool hugging = (Current_ATR > 0.0) ? (MathAbs(current - MA_Current[2]) / Current_ATR < 0.7) : false;
|
|
if(hugging && MA_Current[0] > MA_Current[3])
|
|
OpenTrade(true, ask, "MAGNET-WALK↑", SETUP_MAGNET_WALK, CATEGORY_CONTINUATION);
|
|
if(hugging && MA_Current[0] < MA_Current[3])
|
|
OpenTrade(false, bid, "MAGNET-WALK↓", SETUP_MAGNET_WALK, CATEGORY_CONTINUATION);
|
|
|
|
// 9. MFIB LADDER (near MFIB levels)
|
|
if(NearLevel(current, MFIB_Level_618, buffer) || NearLevel(current, MFIB_Level_382, buffer))
|
|
{
|
|
if(IsBullBias()) OpenTrade(true, ask, "MFIB-LADDER↑", SETUP_MFIB_LADDER, CATEGORY_CONTINUATION);
|
|
if(IsBearBias()) OpenTrade(false, bid, "MFIB-LADDER↓", SETUP_MFIB_LADDER, CATEGORY_CONTINUATION);
|
|
}
|
|
|
|
// 10. STAIRCASE ADVANCE - MA stack with momentum
|
|
bool mas_stacked_bull = (MA_Current[0] > MA_Current[1]) && (MA_Current[1] > MA_Current[2]) &&
|
|
(MA_Current[2] > MA_Current[3]) && (MA_Current[3] > MA_Current[4]);
|
|
bool mas_stacked_bear = (MA_Current[0] < MA_Current[1]) && (MA_Current[1] < MA_Current[2]) &&
|
|
(MA_Current[2] < MA_Current[3]) && (MA_Current[3] < MA_Current[4]);
|
|
|
|
if(mas_stacked_bull && Current_ADX > 25 && !Band_Snap_Warning)
|
|
OpenTrade(true, ask, "STAIRCASE↑", SETUP_STAIRCASE_ADV, CATEGORY_CONTINUATION);
|
|
if(mas_stacked_bear && Current_ADX > 25 && !Band_Snap_Warning)
|
|
OpenTrade(false, bid, "STAIRCASE↓", SETUP_STAIRCASE_ADV, CATEGORY_CONTINUATION);
|
|
|
|
// 11. CONTROLLED PULLBACK - Minor pullback in strong trend
|
|
bool minor_pb_bull = (MA_Current[0] < MA_Current[1]) && (MA_Current[0] > MA_Current[3]) &&
|
|
(Stoch_K_Current < 50) && (Stoch_K_Current > Stoch_Low);
|
|
bool minor_pb_bear = (MA_Current[0] > MA_Current[1]) && (MA_Current[0] < MA_Current[3]) &&
|
|
(Stoch_K_Current > 50) && (Stoch_K_Current < Stoch_High);
|
|
|
|
if(minor_pb_bull && IsBullBias())
|
|
OpenTrade(true, ask, "CTRL-PB↑", SETUP_CTRL_PULLBACK, CATEGORY_CONTINUATION);
|
|
if(minor_pb_bear && IsBearBias())
|
|
OpenTrade(false, bid, "CTRL-PB↓", SETUP_CTRL_PULLBACK, CATEGORY_CONTINUATION);
|
|
|
|
// 12. TIMEFRAME RESET - Price resets to key level then resumes
|
|
bool tf_reset_bull = (MA_Previous[0] < MA_Current[3]) && (MA_Current[0] >= MA_Current[3]) &&
|
|
(Stoch_K_Current > Stoch_K_Previous);
|
|
bool tf_reset_bear = (MA_Previous[0] > MA_Current[3]) && (MA_Current[0] <= MA_Current[3]) &&
|
|
(Stoch_K_Current < Stoch_K_Previous);
|
|
|
|
if(tf_reset_bull && IsBullBias())
|
|
OpenTrade(true, ask, "TF-RESET↑", SETUP_TF_RESET, CATEGORY_CONTINUATION);
|
|
if(tf_reset_bear && IsBearBias())
|
|
OpenTrade(false, bid, "TF-RESET↓", SETUP_TF_RESET, CATEGORY_CONTINUATION);
|
|
|
|
// 14. MFIB PRESS - Sustained pressure at MFIB levels
|
|
bool mfib_press_bull = (NearLevel(current, MFIB_Level_618, buffer) || NearLevel(current, MFIB_Level_786, buffer)) &&
|
|
(MA_Current[0] > MA_Current[1]) && (Stoch_K_Current > 50);
|
|
bool mfib_press_bear = (NearLevel(current, MFIB_Level_236, buffer) || NearLevel(current, MFIB_Level_382, buffer)) &&
|
|
(MA_Current[0] < MA_Current[1]) && (Stoch_K_Current < 50);
|
|
|
|
if(mfib_press_bull && IsBullBias())
|
|
OpenTrade(true, ask, "MFIB-PRESS↑", SETUP_MFIB_PRESS, CATEGORY_CONTINUATION);
|
|
if(mfib_press_bear && IsBearBias())
|
|
OpenTrade(false, bid, "MFIB-PRESS↓", SETUP_MFIB_PRESS, CATEGORY_CONTINUATION);
|
|
}
|
|
|
|
//=================================================================
|
|
// RANGE SETUPS (50 SL) - Counter-trend parameters
|
|
//=================================================================
|
|
if(Current_Family == FAMILY_RANGING)
|
|
{
|
|
// Range edge entries
|
|
if(MathAbs(current - PriceLevels[1]) < buffer && Stoch_K_Current < 35)
|
|
OpenTrade(true, ask, "RANGE-BUY", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND);
|
|
if(MathAbs(current - PriceLevels[5]) < buffer && Stoch_K_Current > 65)
|
|
OpenTrade(false, bid, "RANGE-SELL", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND);
|
|
|
|
// MFIB reject in range
|
|
if(MFIB_Reject_Warning && (Stoch_Reject_Warning || Stoch_Extreme_Warning || Warning_Confluence_3Plus))
|
|
{
|
|
if(current <= MFIB_Level_050) OpenTrade(true, ask, "RANGE-MFIB-BUY", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND);
|
|
if(current >= MFIB_Level_050) OpenTrade(false, bid, "RANGE-MFIB-SELL", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND);
|
|
}
|
|
|
|
// 8. FIB REJECT in range (using SETUP_FIB_REJECT)
|
|
if(Fib_Reject_Warning)
|
|
{
|
|
if(current <= PriceLevels[3]) OpenTrade(true, ask, "RANGE-FIB-BUY", SETUP_FIB_REJECT, CATEGORY_COUNTER_TREND);
|
|
if(current >= PriceLevels[3]) OpenTrade(false, bid, "RANGE-FIB-SELL", SETUP_FIB_REJECT, CATEGORY_COUNTER_TREND);
|
|
}
|
|
}
|
|
|
|
//=================================================================
|
|
// CHOP SETUPS (50 SL) - Counter-trend parameters
|
|
//=================================================================
|
|
if(Current_Family == FAMILY_CHOP)
|
|
{
|
|
if(Stoch_Extreme_Warning || Stoch_Reject_Warning || Fib_Reject_Warning || MFIB_Reject_Warning || Warning_Confluence_3Plus)
|
|
{
|
|
if(Stoch_K_Current <= Stoch_Low) OpenTrade(true, ask, "CHOP-REV-BUY", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND);
|
|
if(Stoch_K_Current >= Stoch_High) OpenTrade(false, bid, "CHOP-REV-SELL", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND);
|
|
}
|
|
|
|
// Band snap in chop
|
|
if(Band_Snap_Warning)
|
|
{
|
|
if(current < MA_Current[0]) OpenTrade(true, ask, "CHOP-SNAP-BUY", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND);
|
|
if(current > MA_Current[0]) OpenTrade(false, bid, "CHOP-SNAP-SELL", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+ |