1122 líneas
Sin EOL
78 KiB
MQL5
1122 líneas
Sin EOL
78 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| QuarterTheory_VIZION_REFINED_v4.5.mq5 |
|
|
//| EARLY DETECTION | PULLBACK vs REVERSAL | RUNNERS |
|
|
//| 7x14 Cross Warnings | Structure Failure | Band Snap |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "QuarterTheory x VIZION - Refined v4.5"
|
|
#property version "4.50"
|
|
#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; // Always keep this many far entries
|
|
|
|
input group "=== MARKET MODE SYSTEM ==="
|
|
input bool Use_Market_Mode_Filter = true;
|
|
input int Mode_Confirmation_Bars = 2; // Reduced for faster detection
|
|
input double Chop_ATR_Threshold = 0.5;
|
|
input double Range_Price_Threshold = 0.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 group "=== MFIB SYSTEM ==="
|
|
input int MFIB_Lookback = 500;
|
|
|
|
input group "=== FIBONACCI ==="
|
|
input int Lookback_Bars = 200;
|
|
input bool Show_Levels = true;
|
|
|
|
input group "=== 300 RULE EXIT SYSTEM ==="
|
|
input int Initial_SL_Points = 300;
|
|
input int BreakEven_Points = 300;
|
|
input int Trailing_Distance_Points = 300;
|
|
input int TP_Points = 1500;
|
|
input int Partial_TP_Points = 900;
|
|
input double Partial_TP_Percent = 33.0;
|
|
|
|
//================ ENUMS ==================//
|
|
enum MARKET_MODE {
|
|
MODE_STRONG_BULL_TREND,
|
|
MODE_BULL_TREND,
|
|
MODE_BEAR_TREND,
|
|
MODE_STRONG_BEAR_TREND,
|
|
MODE_CHOPPY,
|
|
MODE_RANGING,
|
|
MODE_TRANSITIONAL
|
|
};
|
|
|
|
enum MARKET_CONDITION {
|
|
COND_CONTROLLED_PULLBACK, // Healthy breathing
|
|
COND_STRUCTURE_FAILURE, // Pullback → reversal
|
|
COND_BAND_SNAP, // Overextension snap
|
|
COND_CLEAN_TREND, // Strong trending
|
|
COND_REVERSAL_WARNING, // Early reversal signs
|
|
COND_CONSOLIDATION, // Sideways chop
|
|
COND_NONE
|
|
};
|
|
|
|
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
|
|
};
|
|
|
|
//================ 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, Stoch_D_Previous = 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];
|
|
|
|
double MFIB_High, MFIB_Low;
|
|
double MFIB_Level_236, MFIB_Level_382, MFIB_Level_050;
|
|
double MFIB_Level_618, MFIB_Level_786;
|
|
|
|
MARKET_MODE Current_Mode = MODE_TRANSITIONAL;
|
|
MARKET_MODE Previous_Mode = MODE_TRANSITIONAL;
|
|
int Mode_Confirmation_Count = 0;
|
|
|
|
MARKET_CONDITION Current_Condition = COND_NONE;
|
|
|
|
// Warning flags
|
|
bool MA7_Cross_14_Warning = false;
|
|
bool Fib_Reject_Warning = false;
|
|
bool MA_Reject_Warning = false;
|
|
bool Stoch_Extreme_Warning = false;
|
|
bool Structure_Failure_Warning = false;
|
|
|
|
struct Position {
|
|
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;
|
|
string setup_name;
|
|
MARKET_MODE entry_mode;
|
|
double distance_from_current;
|
|
};
|
|
Position OpenPositions[];
|
|
|
|
int TodayTrades = 0;
|
|
int BuyTrades = 0;
|
|
int SellTrades = 0;
|
|
int ClosedByMode = 0;
|
|
|
|
int SetupCount[17];
|
|
datetime LastEntryTime[17];
|
|
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
Print("========================================");
|
|
Print("REFINED SYSTEM v4.5");
|
|
Print("EARLY DETECTION | PULLBACK vs REVERSAL");
|
|
Print("7x14 CROSS WARNINGS | RUNNER MANAGEMENT");
|
|
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();
|
|
|
|
Print("Mode Filter: ON | Min Runners:", Min_Runners_To_Keep);
|
|
Print("Early Detection: ACTIVE");
|
|
|
|
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, "ModeLabel");
|
|
ObjectsDeleteAll(0, "ConditionLabel");
|
|
ObjectsDeleteAll(0, "WarningLabel");
|
|
|
|
Print("Final: Buys:", BuyTrades, " | Sells:", SellTrades);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CalculateLevels()
|
|
{
|
|
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;
|
|
|
|
MFIB_High = high;
|
|
MFIB_Low = low;
|
|
MFIB_Level_236 = low + range * 0.236;
|
|
MFIB_Level_382 = low + range * 0.382;
|
|
MFIB_Level_050 = low + range * 0.5;
|
|
MFIB_Level_618 = low + range * 0.618;
|
|
MFIB_Level_786 = low + range * 0.786;
|
|
}
|
|
|
|
void DrawLevels()
|
|
{
|
|
ObjectsDeleteAll(0, "Level_");
|
|
color level_colors[7] = {clrRed, clrOrange, clrYellow, clrLime, clrCyan, clrBlue, clrMagenta};
|
|
|
|
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_SOLID);
|
|
ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void DetectWarnings()
|
|
{
|
|
double current = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double buffer = MA_Touch_Buffer * _Point;
|
|
|
|
// Reset warnings
|
|
MA7_Cross_14_Warning = false;
|
|
Fib_Reject_Warning = false;
|
|
MA_Reject_Warning = false;
|
|
Stoch_Extreme_Warning = false;
|
|
Structure_Failure_Warning = false;
|
|
|
|
// 1. MA7 x MA14 CROSS WARNING (Critical for trend change)
|
|
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;
|
|
|
|
// Check if at fib level for extra confirmation
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(MathAbs(current - PriceLevels[i]) <= buffer * 2)
|
|
{
|
|
Fib_Reject_Warning = true;
|
|
Print("⚠️ REVERSAL WARNING: MA7x14 at FIB ", i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. FIB REJECT with OB/OS
|
|
bool at_fib = false;
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(MathAbs(current - PriceLevels[i]) <= buffer)
|
|
{
|
|
at_fib = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(at_fib && (Stoch_K_Current > 70 || Stoch_K_Current < 30))
|
|
{
|
|
Fib_Reject_Warning = true;
|
|
Stoch_Extreme_Warning = true;
|
|
}
|
|
|
|
// 3. MA REJECT at 50/140/230
|
|
bool at_ma50 = MathAbs(current - MA_Current[3]) <= buffer;
|
|
bool at_ma140 = MathAbs(current - MA_Current[4]) <= buffer;
|
|
bool at_ma230 = MathAbs(current - MA_Current[5]) <= buffer;
|
|
|
|
if((at_ma50 || at_ma140 || at_ma230) && (Stoch_K_Current > 70 || Stoch_K_Current < 30))
|
|
{
|
|
MA_Reject_Warning = true;
|
|
Stoch_Extreme_Warning = true;
|
|
}
|
|
|
|
// 4. STRUCTURE FAILURE
|
|
// 7 rejected at 50+, 21 broken, price beyond 50, stoch failed
|
|
bool ma7_below_50 = MA_Current[0] < MA_Current[3];
|
|
bool ma7_above_50 = MA_Current[0] > MA_Current[3];
|
|
bool ma21_broken_down = (MA_Previous[2] > MA_Current[3]) && (MA_Current[2] < MA_Current[3]);
|
|
bool ma21_broken_up = (MA_Previous[2] < MA_Current[3]) && (MA_Current[2] > MA_Current[3]);
|
|
bool price_beyond_50 = MathAbs(current - MA_Current[3]) / Current_ATR > 1.0;
|
|
|
|
if((ma7_below_50 && ma21_broken_down && price_beyond_50) ||
|
|
(ma7_above_50 && ma21_broken_up && price_beyond_50))
|
|
{
|
|
Structure_Failure_Warning = true;
|
|
Print("🚨 STRUCTURE FAILURE: Pullback → Reversal");
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
MARKET_CONDITION DetectCondition()
|
|
{
|
|
double current = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
|
|
// 1. CONTROLLED PULLBACK
|
|
// 7 rejected, 14/21 hold, stoch resets
|
|
bool ma7_rejected = (MA_Current[0] < MA_Previous[0]) || (MA_Current[0] > MA_Previous[0]);
|
|
bool ma14_holds = MathAbs(MA_Current[1] - MA_Previous[1]) / Current_ATR < 0.3;
|
|
bool ma21_holds = MathAbs(MA_Current[2] - MA_Previous[2]) / Current_ATR < 0.3;
|
|
bool stoch_reset_from_top = (Stoch_K_Prev2 > 70) && (Stoch_K_Previous > 60) && (Stoch_K_Current < 50);
|
|
bool stoch_reset_from_bottom = (Stoch_K_Prev2 < 30) && (Stoch_K_Previous < 40) && (Stoch_K_Current > 50);
|
|
|
|
if(ma7_rejected && ma14_holds && ma21_holds && (stoch_reset_from_top || stoch_reset_from_bottom))
|
|
{
|
|
return COND_CONTROLLED_PULLBACK;
|
|
}
|
|
|
|
// 2. STRUCTURE FAILURE
|
|
if(Structure_Failure_Warning)
|
|
{
|
|
return COND_STRUCTURE_FAILURE;
|
|
}
|
|
|
|
// 3. BAND SNAP
|
|
// Far from 21 & 50, stoch OB/OS, MFIB extension
|
|
double dist_from_21 = MathAbs(current - MA_Current[2]) / Current_ATR;
|
|
double dist_from_50 = MathAbs(current - MA_Current[3]) / Current_ATR;
|
|
bool far_from_mas = (dist_from_21 > 2.0) && (dist_from_50 > 2.5);
|
|
bool at_mfib_extension = (current > MFIB_Level_786) || (current < MFIB_Level_236);
|
|
bool stoch_extreme = (Stoch_K_Current > 80) || (Stoch_K_Current < 20);
|
|
|
|
if(far_from_mas && at_mfib_extension && stoch_extreme)
|
|
{
|
|
return COND_BAND_SNAP;
|
|
}
|
|
|
|
// 4. REVERSAL WARNING
|
|
if(MA7_Cross_14_Warning && (Fib_Reject_Warning || MA_Reject_Warning))
|
|
{
|
|
return COND_REVERSAL_WARNING;
|
|
}
|
|
|
|
// 5. CLEAN TREND
|
|
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]);
|
|
|
|
if((mas_aligned_bull || mas_aligned_bear) && Current_ADX > 25)
|
|
{
|
|
return COND_CLEAN_TREND;
|
|
}
|
|
|
|
// 6. CONSOLIDATION
|
|
double recent_range = 0;
|
|
for(int i=0; i<10; i++)
|
|
{
|
|
recent_range += MathAbs(iHigh(_Symbol, PERIOD_CURRENT, i) - iLow(_Symbol, PERIOD_CURRENT, i));
|
|
}
|
|
recent_range /= 10;
|
|
|
|
if(recent_range / Current_ATR < 1.0)
|
|
{
|
|
return COND_CONSOLIDATION;
|
|
}
|
|
|
|
return COND_NONE;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
MARKET_MODE DetermineMarketMode()
|
|
{
|
|
double current = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
|
|
// EARLY DETECTION LOGIC
|
|
// If we see MA7x14 cross + rejection, flip immediately
|
|
if(MA7_Cross_14_Warning && (Fib_Reject_Warning || MA_Reject_Warning || Structure_Failure_Warning))
|
|
{
|
|
// Determine new direction
|
|
bool ma7_below_14 = MA_Current[0] < MA_Current[1];
|
|
bool ma7_above_14 = MA_Current[0] > MA_Current[1];
|
|
|
|
if(ma7_below_14 && Stoch_K_Current < 50)
|
|
{
|
|
Print("🔴 EARLY BEAR DETECTION: MA7x14 cross + rejection");
|
|
return MODE_BEAR_TREND;
|
|
}
|
|
|
|
if(ma7_above_14 && Stoch_K_Current > 50)
|
|
{
|
|
Print("🟢 EARLY BULL DETECTION: MA7x14 cross + rejection");
|
|
return MODE_BULL_TREND;
|
|
}
|
|
}
|
|
|
|
// Standard trend detection
|
|
bool ma7_above_50 = MA_Current[0] > MA_Current[3];
|
|
bool ma7_above_140 = MA_Current[0] > MA_Current[4];
|
|
bool ma7_above_230 = MA_Current[0] > MA_Current[5];
|
|
bool ma7_below_50 = MA_Current[0] < MA_Current[3];
|
|
bool ma7_below_140 = MA_Current[0] < MA_Current[4];
|
|
bool ma7_below_230 = MA_Current[0] < MA_Current[5];
|
|
|
|
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]);
|
|
|
|
bool above_mfib_618 = current > MFIB_Level_618;
|
|
bool below_mfib_382 = current < MFIB_Level_382;
|
|
|
|
bool stoch_trending_up = (Stoch_K_Current > Stoch_D_Current) && (Stoch_K_Current > 50);
|
|
bool stoch_trending_down = (Stoch_K_Current < Stoch_D_Current) && (Stoch_K_Current < 50);
|
|
|
|
// Chop/range detection
|
|
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 = (MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR < Chop_ATR_Threshold);
|
|
bool is_choppy = (ma_clustered || Current_ADX < 20);
|
|
|
|
// Priority: Early signals > Strong trends > Chop/Range
|
|
if(is_choppy && !MA7_Cross_14_Warning)
|
|
return MODE_CHOPPY;
|
|
|
|
if(is_ranging && !mas_aligned_bull && !mas_aligned_bear && !MA7_Cross_14_Warning)
|
|
return MODE_RANGING;
|
|
|
|
// Strong trends
|
|
if(mas_aligned_bull && ma7_above_230 && above_mfib_618 && stoch_trending_up && Current_ADX > 25)
|
|
return MODE_STRONG_BULL_TREND;
|
|
|
|
if(mas_aligned_bear && ma7_below_230 && below_mfib_382 && stoch_trending_down && Current_ADX > 25)
|
|
return MODE_STRONG_BEAR_TREND;
|
|
|
|
// Regular trends (relaxed requirements for early detection)
|
|
if(mas_aligned_bull && ma7_above_50 && Current_ADX > 18)
|
|
return MODE_BULL_TREND;
|
|
|
|
if(mas_aligned_bear && ma7_below_50 && Current_ADX > 18)
|
|
return MODE_BEAR_TREND;
|
|
|
|
return MODE_TRANSITIONAL;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void UpdateMarketMode()
|
|
{
|
|
MARKET_MODE detected_mode = DetermineMarketMode();
|
|
|
|
// Faster confirmation for warning signals
|
|
int required_confirms = Mode_Confirmation_Bars;
|
|
if(MA7_Cross_14_Warning && (Fib_Reject_Warning || MA_Reject_Warning))
|
|
{
|
|
required_confirms = 1; // Immediate flip on strong signals
|
|
}
|
|
|
|
if(detected_mode != Current_Mode)
|
|
{
|
|
if(detected_mode == Previous_Mode)
|
|
{
|
|
Mode_Confirmation_Count++;
|
|
if(Mode_Confirmation_Count >= required_confirms)
|
|
{
|
|
MARKET_MODE old_mode = Current_Mode;
|
|
Current_Mode = detected_mode;
|
|
Mode_Confirmation_Count = 0;
|
|
|
|
Print(">>> MODE FLIP: ", EnumToString(old_mode), " → ", EnumToString(Current_Mode));
|
|
|
|
if(Use_Market_Mode_Filter)
|
|
CloseInvalidPositions();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Previous_Mode = detected_mode;
|
|
Mode_Confirmation_Count = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Mode_Confirmation_Count = 0;
|
|
}
|
|
|
|
UpdateLabels();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void UpdateLabels()
|
|
{
|
|
// Mode Label
|
|
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, 30);
|
|
|
|
string mode_text = "";
|
|
color mode_color = clrYellow;
|
|
|
|
switch(Current_Mode)
|
|
{
|
|
case MODE_STRONG_BULL_TREND: mode_text = "MODE: STRONG BULL ↑↑"; mode_color = clrLime; break;
|
|
case MODE_BULL_TREND: mode_text = "MODE: BULL TREND ↑"; mode_color = clrGreenYellow; break;
|
|
case MODE_BEAR_TREND: mode_text = "MODE: BEAR TREND ↓"; mode_color = clrOrange; break;
|
|
case MODE_STRONG_BEAR_TREND: mode_text = "MODE: STRONG BEAR ↓↓"; mode_color = clrRed; break;
|
|
case MODE_CHOPPY: mode_text = "MODE: CHOPPY ⚡"; mode_color = clrViolet; break;
|
|
case MODE_RANGING: mode_text = "MODE: RANGING ↔"; mode_color = clrAqua; break;
|
|
case MODE_TRANSITIONAL: mode_text = "MODE: TRANSITIONAL ~"; mode_color = clrYellow; break;
|
|
}
|
|
|
|
ObjectSetString(0, "ModeLabel", OBJPROP_TEXT, mode_text);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_COLOR, mode_color);
|
|
ObjectSetInteger(0, "ModeLabel", OBJPROP_FONTSIZE, 12);
|
|
|
|
// Condition Label
|
|
ObjectDelete(0, "ConditionLabel");
|
|
ObjectCreate(0, "ConditionLabel", OBJ_LABEL, 0, 0, 0);
|
|
ObjectSetInteger(0, "ConditionLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
|
ObjectSetInteger(0, "ConditionLabel", OBJPROP_XDISTANCE, 10);
|
|
ObjectSetInteger(0, "ConditionLabel", OBJPROP_YDISTANCE, 50);
|
|
|
|
string cond_text = "CONDITION: ";
|
|
color cond_color = clrWhite;
|
|
|
|
switch(Current_Condition)
|
|
{
|
|
case COND_CONTROLLED_PULLBACK: cond_text += "PULLBACK ↩"; cond_color = clrYellow; break;
|
|
case COND_STRUCTURE_FAILURE: cond_text += "STRUCTURE FAIL ⚠"; cond_color = clrRed; break;
|
|
case COND_BAND_SNAP: cond_text += "BAND SNAP 📐"; cond_color = clrOrange; break;
|
|
case COND_CLEAN_TREND: cond_text += "CLEAN TREND ✓"; cond_color = clrLime; break;
|
|
case COND_REVERSAL_WARNING: cond_text += "REVERSAL WARNING 🔄"; cond_color = clrRed; break;
|
|
case COND_CONSOLIDATION: cond_text += "CONSOLIDATION 📊"; cond_color = clrAqua; break;
|
|
case COND_NONE: cond_text += "NORMAL"; break;
|
|
}
|
|
|
|
ObjectSetString(0, "ConditionLabel", OBJPROP_TEXT, cond_text);
|
|
ObjectSetInteger(0, "ConditionLabel", OBJPROP_COLOR, cond_color);
|
|
ObjectSetInteger(0, "ConditionLabel", OBJPROP_FONTSIZE, 10);
|
|
|
|
// Warning Label
|
|
if(MA7_Cross_14_Warning || Fib_Reject_Warning || MA_Reject_Warning || Structure_Failure_Warning)
|
|
{
|
|
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, 70);
|
|
|
|
string warn_text = "⚠️ ";
|
|
if(MA7_Cross_14_Warning) warn_text += "MA7x14 | ";
|
|
if(Fib_Reject_Warning) warn_text += "FIB REJECT | ";
|
|
if(MA_Reject_Warning) warn_text += "MA REJECT | ";
|
|
if(Structure_Failure_Warning) warn_text += "STRUCTURE FAIL";
|
|
|
|
ObjectSetString(0, "WarningLabel", OBJPROP_TEXT, warn_text);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, "WarningLabel", OBJPROP_FONTSIZE, 10);
|
|
}
|
|
else
|
|
{
|
|
ObjectDelete(0, "WarningLabel");
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void MarkRunners()
|
|
{
|
|
double current = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
|
|
// Update distances
|
|
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;
|
|
}
|
|
}
|
|
|
|
// Sort by distance (far entries first)
|
|
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)
|
|
{
|
|
Position temp = OpenPositions[i];
|
|
OpenPositions[i] = OpenPositions[j];
|
|
OpenPositions[j] = temp;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Mark top N as runners
|
|
for(int i=0; i<ArraySize(OpenPositions); i++)
|
|
{
|
|
OpenPositions[i].is_runner = (i < Min_Runners_To_Keep);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CloseInvalidPositions()
|
|
{
|
|
MarkRunners();
|
|
|
|
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;
|
|
|
|
// Find in our array
|
|
int idx = -1;
|
|
for(int j=0; j<ArraySize(OpenPositions); j++)
|
|
{
|
|
if(OpenPositions[j].ticket == ticket) { idx = j; break; }
|
|
}
|
|
|
|
// Protect runners
|
|
if(idx >= 0 && OpenPositions[idx].is_runner)
|
|
{
|
|
Print("🏃 RUNNER PROTECTED: ", OpenPositions[idx].setup_name);
|
|
continue;
|
|
}
|
|
|
|
bool should_close = false;
|
|
|
|
// Close opposing trades
|
|
if(is_buy && (Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND))
|
|
should_close = true;
|
|
|
|
if(!is_buy && (Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND))
|
|
should_close = true;
|
|
|
|
// Close trend trades in chop/range (but not runners)
|
|
if((Current_Mode == MODE_CHOPPY || Current_Mode == MODE_RANGING) && idx >= 0)
|
|
{
|
|
SETUP_TYPE setup = OpenPositions[idx].setup_type;
|
|
if(setup != SETUP_MEAN_REV && setup != SETUP_RANGE_ENGINE &&
|
|
setup != SETUP_FIB_REJECT && setup != SETUP_CTRL_PULLBACK)
|
|
should_close = true;
|
|
}
|
|
|
|
if(should_close)
|
|
{
|
|
if(Trade.PositionClose(ticket))
|
|
{
|
|
ClosedByMode++;
|
|
Print("✂ CLOSED: ", is_buy ? "BUY" : "SELL", " (not runner)");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
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], d_prev[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];
|
|
if(CopyBuffer(Stoch_Handle, SIGNAL_LINE, 1, 1, d_prev) > 0) Stoch_D_Previous = d_prev[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];
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool IsSetupValidForMode(SETUP_TYPE setup, bool is_buy)
|
|
{
|
|
if(!Use_Market_Mode_Filter) return true;
|
|
|
|
// CONDITION-BASED FILTERING
|
|
|
|
// During CONTROLLED PULLBACK - wait for reclaim
|
|
if(Current_Condition == COND_CONTROLLED_PULLBACK)
|
|
{
|
|
// Only enter when 7 reclaims 21
|
|
bool ma7_reclaimed_21 = (MA_Previous[0] < MA_Current[2]) && (MA_Current[0] > MA_Current[2]);
|
|
if(!ma7_reclaimed_21) return false;
|
|
}
|
|
|
|
// During STRUCTURE FAILURE - enter on 7 cross 21
|
|
if(Current_Condition == COND_STRUCTURE_FAILURE)
|
|
{
|
|
bool ma7_crossed_21 = (MA_Previous[0] > MA_Current[2] && MA_Current[0] < MA_Current[2]) ||
|
|
(MA_Previous[0] < MA_Current[2] && MA_Current[0] > MA_Current[2]);
|
|
if(!ma7_crossed_21) return false;
|
|
}
|
|
|
|
// During BAND SNAP - only counter-trend
|
|
if(Current_Condition == COND_BAND_SNAP)
|
|
{
|
|
if(setup != SETUP_MEAN_REV && setup != SETUP_FIB_REJECT)
|
|
return false;
|
|
}
|
|
|
|
// MODE-BASED FILTERING
|
|
switch(Current_Mode)
|
|
{
|
|
case MODE_STRONG_BULL_TREND:
|
|
if(!is_buy) return false;
|
|
break;
|
|
|
|
case MODE_STRONG_BEAR_TREND:
|
|
if(is_buy) return false;
|
|
break;
|
|
|
|
case MODE_CHOPPY:
|
|
if(setup != SETUP_MEAN_REV && setup != SETUP_CTRL_PULLBACK && setup != SETUP_FIB_REJECT)
|
|
return false;
|
|
break;
|
|
|
|
case MODE_RANGING:
|
|
if(setup != SETUP_RANGE_ENGINE && setup != SETUP_MEAN_REV &&
|
|
setup != SETUP_FIB_REJECT && setup != SETUP_MA50_BOUNCE)
|
|
return false;
|
|
break;
|
|
}
|
|
|
|
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;
|
|
|
|
for(int j=0; j<ArraySize(OpenPositions); j++)
|
|
{
|
|
if(OpenPositions[j].ticket == PositionGetTicket(i))
|
|
{
|
|
if(OpenPositions[j].setup_type == setup)
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
double GetLotSize()
|
|
{
|
|
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 / ((Initial_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;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void OpenTrade(bool buy, double price, string setup_name, SETUP_TYPE setup_type)
|
|
{
|
|
if(!IsSetupValidForMode(setup_type, buy)) 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;
|
|
LastEntryTime[setup_type] = now;
|
|
|
|
double lot = GetLotSize();
|
|
if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return;
|
|
|
|
double sl = buy ? price - Initial_SL_Points * _Point : price + Initial_SL_Points * _Point;
|
|
double tp = buy ? price + TP_Points * _Point : price - TP_Points * _Point;
|
|
|
|
string comment = setup_name + "|" + EnumToString(Current_Mode);
|
|
|
|
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)
|
|
{
|
|
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].setup_name = setup_name;
|
|
OpenPositions[size].entry_mode = Current_Mode;
|
|
OpenPositions[size].distance_from_current = 0;
|
|
|
|
Print("✓ ", setup_name, " ", buy ? "BUY" : "SELL");
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
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;
|
|
|
|
double current = is_buy ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double profit_points = is_buy ? (current - entry) / _Point : (entry - current) / _Point;
|
|
|
|
// Partial TP
|
|
if(!OpenPositions[idx].partial_tp_hit && profit_points >= Partial_TP_Points)
|
|
{
|
|
double current_lot = PositionGetDouble(POSITION_VOLUME);
|
|
double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Partial_TP_Percent / 100.0, 2);
|
|
|
|
if(close_size > 0 && close_size <= current_lot)
|
|
{
|
|
if(Trade.PositionClosePartial(ticket, close_size))
|
|
{
|
|
OpenPositions[idx].partial_tp_hit = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Break Even
|
|
if(!OpenPositions[idx].be_set && profit_points >= BreakEven_Points)
|
|
{
|
|
if((is_buy && current_sl < entry) || (!is_buy && current_sl > entry))
|
|
{
|
|
if(Trade.PositionModify(ticket, entry, current_tp))
|
|
{
|
|
OpenPositions[idx].be_set = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Trailing
|
|
if(profit_points >= BreakEven_Points + 100)
|
|
{
|
|
OpenPositions[idx].trailing_active = true;
|
|
|
|
double newSL = 0;
|
|
bool should_modify = false;
|
|
|
|
if(is_buy)
|
|
{
|
|
newSL = current - Trailing_Distance_Points * _Point;
|
|
if(newSL > current_sl + 30 * _Point) should_modify = true;
|
|
}
|
|
else
|
|
{
|
|
newSL = current + Trailing_Distance_Points * _Point;
|
|
if(newSL < current_sl - 30 * _Point) should_modify = true;
|
|
}
|
|
|
|
if(should_modify) Trade.PositionModify(ticket, newSL, current_tp);
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
UpdateIndicators();
|
|
DetectWarnings();
|
|
Current_Condition = DetectCondition();
|
|
UpdateMarketMode();
|
|
ManagePositions();
|
|
|
|
static int tick_count = 0;
|
|
tick_count++;
|
|
if(tick_count >= 100)
|
|
{
|
|
CalculateLevels();
|
|
tick_count = 0;
|
|
}
|
|
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double current = (bid + ask) / 2;
|
|
double previous = iClose(_Symbol, PERIOD_CURRENT, 1);
|
|
double buffer = MA_Touch_Buffer * _Point;
|
|
|
|
//=================================================================
|
|
// SETUPS WITH CONDITION & MODE FILTERING
|
|
//=================================================================
|
|
|
|
// SETUP 1: MA14 CROSS
|
|
if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING)
|
|
{
|
|
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);
|
|
|
|
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);
|
|
}
|
|
|
|
// SETUP 2-5: MA BOUNCES
|
|
if(Current_Mode != MODE_CHOPPY)
|
|
{
|
|
if(MathAbs(current - MA_Current[3]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE);
|
|
OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE);
|
|
}
|
|
|
|
if(MathAbs(current - MA_Current[4]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA140-BOUNCE↑", SETUP_MA140_BOUNCE);
|
|
OpenTrade(false, bid, "MA140-BOUNCE↓", SETUP_MA140_BOUNCE);
|
|
}
|
|
|
|
if(MathAbs(current - MA_Current[5]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA230-BOUNCE↑", SETUP_MA230_BOUNCE);
|
|
OpenTrade(false, bid, "MA230-BOUNCE↓", SETUP_MA230_BOUNCE);
|
|
}
|
|
|
|
if(MathAbs(current - MA_Current[6]) <= buffer)
|
|
{
|
|
OpenTrade(true, ask, "MA500-TOUCH↑", SETUP_MA500_TOUCH);
|
|
OpenTrade(false, bid, "MA500-TOUCH↓", SETUP_MA500_TOUCH);
|
|
}
|
|
}
|
|
|
|
// SETUP 6-8: FIB TRADING
|
|
for(int i=1; i<6; i++)
|
|
{
|
|
if(MathAbs(current - PriceLevels[i]) <= buffer)
|
|
{
|
|
if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND ||
|
|
Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND)
|
|
{
|
|
if(previous < PriceLevels[i])
|
|
OpenTrade(true, ask, "FIB-BREAK↑", SETUP_FIB_BREAK);
|
|
if(previous > PriceLevels[i])
|
|
OpenTrade(false, bid, "FIB-BREAK↓", SETUP_FIB_BREAK);
|
|
}
|
|
|
|
if(Current_Mode == MODE_RANGING || Current_Mode == MODE_CHOPPY)
|
|
{
|
|
if(Stoch_K_Current > 65)
|
|
OpenTrade(false, bid, "FIB-REJECT↓", SETUP_FIB_REJECT);
|
|
if(Stoch_K_Current < 35)
|
|
OpenTrade(true, ask, "FIB-REJECT↑", SETUP_FIB_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
// SETUP 9: MAGNET WALK
|
|
if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND ||
|
|
Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND)
|
|
{
|
|
bool hugging = (MathAbs(current - MA_Current[2]) / Current_ATR < 0.7);
|
|
if(hugging && MA_Current[0] > MA_Current[3])
|
|
OpenTrade(true, ask, "MAGNET-WALK↑", SETUP_MAGNET_WALK);
|
|
if(hugging && MA_Current[0] < MA_Current[3])
|
|
OpenTrade(false, bid, "MAGNET-WALK↓", SETUP_MAGNET_WALK);
|
|
}
|
|
|
|
// SETUP 10: STAIRCASE
|
|
if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING)
|
|
{
|
|
if(MA_Current[1] > MA_Previous[1] && MA_Current[1] > MA_Current[3])
|
|
OpenTrade(true, ask, "STAIRCASE↑", SETUP_STAIRCASE_ADV);
|
|
if(MA_Current[1] < MA_Previous[1] && MA_Current[1] < MA_Current[3])
|
|
OpenTrade(false, bid, "STAIRCASE↓", SETUP_STAIRCASE_ADV);
|
|
}
|
|
|
|
// SETUP 11: CONTROLLED PULLBACK
|
|
bool near_ma = MathAbs(current - MA_Current[3]) / Current_ATR < 1.5;
|
|
if(near_ma)
|
|
{
|
|
bool stoch_reset_bull = Stoch_K_Previous > 55 && Stoch_K_Current < 50;
|
|
bool stoch_reset_bear = Stoch_K_Previous < 45 && Stoch_K_Current > 50;
|
|
|
|
if(stoch_reset_bull)
|
|
OpenTrade(true, ask, "CTRL-PULLBACK↑", SETUP_CTRL_PULLBACK);
|
|
if(stoch_reset_bear)
|
|
OpenTrade(false, bid, "CTRL-PULLBACK↓", SETUP_CTRL_PULLBACK);
|
|
}
|
|
|
|
// SETUP 12: TIMEFRAME RESET
|
|
if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING)
|
|
{
|
|
if(Stoch_K_Current < 35 && MA_Current[0] > MA_Current[6])
|
|
OpenTrade(true, ask, "TF-RESET↑", SETUP_TF_RESET);
|
|
if(Stoch_K_Current > 65 && MA_Current[0] < MA_Current[6])
|
|
OpenTrade(false, bid, "TF-RESET↓", SETUP_TF_RESET);
|
|
}
|
|
|
|
// SETUP 13: MFIB LADDER
|
|
if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND ||
|
|
Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND)
|
|
{
|
|
if(MathAbs(current - MFIB_Level_618) <= buffer)
|
|
{
|
|
if(previous <= MFIB_Level_618)
|
|
OpenTrade(true, ask, "MFIB-LADDER618↑", SETUP_MFIB_LADDER);
|
|
if(previous >= MFIB_Level_618)
|
|
OpenTrade(false, bid, "MFIB-LADDER618↓", SETUP_MFIB_LADDER);
|
|
}
|
|
}
|
|
|
|
// SETUP 14: MFIB PRESS
|
|
if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING)
|
|
{
|
|
bool near_mfib = MathAbs(current - MFIB_Level_050) / Current_ATR < 1.2;
|
|
if(near_mfib)
|
|
{
|
|
if(MA_Current[1] > MA_Current[3])
|
|
OpenTrade(true, ask, "MFIB-PRESS↑", SETUP_MFIB_PRESS);
|
|
if(MA_Current[1] < MA_Current[3])
|
|
OpenTrade(false, bid, "MFIB-PRESS↓", SETUP_MFIB_PRESS);
|
|
}
|
|
}
|
|
|
|
// SETUP 15: MEAN REVERSION
|
|
bool near_230 = MathAbs(current - MA_Current[5]) / Current_ATR < 1.0;
|
|
if(near_230)
|
|
{
|
|
if(Stoch_K_Current < 30)
|
|
OpenTrade(true, ask, "MEAN-REV-BUY", SETUP_MEAN_REV);
|
|
if(Stoch_K_Current > 70)
|
|
OpenTrade(false, bid, "MEAN-REV-SELL", SETUP_MEAN_REV);
|
|
}
|
|
|
|
// SETUP 16: RANGE ENGINE
|
|
if(Current_Mode == MODE_RANGING)
|
|
{
|
|
if(MathAbs(current - PriceLevels[1]) < buffer && Stoch_K_Current < 35)
|
|
OpenTrade(true, ask, "RANGE-BUY", SETUP_RANGE_ENGINE);
|
|
if(MathAbs(current - PriceLevels[5]) < buffer && Stoch_K_Current > 65)
|
|
OpenTrade(false, bid, "RANGE-SELL", SETUP_RANGE_ENGINE);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+ |