1254 lines
No EOL
109 KiB
MQL5
1254 lines
No EOL
109 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| QuarterTheory_VIZION_v7_PATTERNS.mq5 |
|
|
//| + CANDLESTICK PATTERNS: Confirmation for Structure Signals |
|
|
//| PRAISE SYSTEM: 8 Trend Signals | WAR SURVIVOR: MFIB Partials |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "QuarterTheory x VIZION"
|
|
#property version "7.00"
|
|
#property strict
|
|
|
|
#include <Trade/Trade.mqh>
|
|
CTrade Trade;
|
|
|
|
//================ CORE STRUCTURES ==================//
|
|
struct SignalParams {
|
|
int sl_points, be_points, trail_points, tp_points;
|
|
int partial_tp;
|
|
double partial_pct;
|
|
};
|
|
|
|
struct IndicatorData {
|
|
double ma[10], ma_prev[10], ma_prev2[10];
|
|
double stoch_k, stoch_k_prev, stoch_k_prev2;
|
|
double stoch_d;
|
|
double atr, adx;
|
|
};
|
|
|
|
struct MFIBLevels {
|
|
double high, low;
|
|
double level_236, level_382, level_050, level_618, level_786;
|
|
};
|
|
|
|
struct PositionRecord {
|
|
ulong ticket;
|
|
double entry, original_lot, close_price, last_mfib_partial_price;
|
|
bool is_buy, partial_tp_hit, be_set, trailing_active, is_runner;
|
|
bool closed_at_sl, closed_at_be;
|
|
int setup_type, category, entry_family, entry_bias, entry_strength;
|
|
int mfib_partials_taken;
|
|
double distance_from_current;
|
|
string setup_name;
|
|
};
|
|
|
|
struct ClosureRecord {
|
|
int setup_type, category;
|
|
bool was_buy, closed_at_sl, closed_at_be;
|
|
double close_price;
|
|
datetime close_time;
|
|
};
|
|
|
|
struct CandlePatterns {
|
|
// Bullish Patterns
|
|
bool bull_engulfing, bull_hammer, bull_morning_star;
|
|
bool bull_piercing, bull_three_white;
|
|
|
|
// Bearish Patterns
|
|
bool bear_engulfing, bear_shooting_star, bear_evening_star;
|
|
bool bear_dark_cloud, bear_three_black;
|
|
|
|
// Reversal Indicators
|
|
bool doji, spinning_top, harami;
|
|
|
|
// Counts
|
|
int bullish_count, bearish_count, reversal_count;
|
|
|
|
// Pattern Strength
|
|
bool strong_bullish_pattern, strong_bearish_pattern;
|
|
bool reversal_warning;
|
|
};
|
|
|
|
struct Warnings {
|
|
bool stoch_extreme, stoch_reject, stoch_level_cross;
|
|
bool ma7_cross_14, ma7_cross_21, ma50_break;
|
|
bool fib_reject, fib_reclaim, fib_break;
|
|
bool mfib_reject, mfib_reclaim, mfib_break;
|
|
bool ma_reject, ma_reclaim, ma_break;
|
|
bool band_snap, ma50, ma140, ma230, ma500;
|
|
bool pullback, retracement;
|
|
bool ma14_magnet, fib_break_confirmed, mfib_break_confirmed;
|
|
bool strong_ma_bounce, trend_resumption;
|
|
|
|
// Pattern-enhanced warnings
|
|
bool pattern_reversal_warn;
|
|
bool pattern_rejection_confirm;
|
|
|
|
int confluence_count;
|
|
bool confluence_3plus;
|
|
};
|
|
|
|
struct Praise {
|
|
bool triple_magnet, power_couple;
|
|
bool mfib_staircase, mfib_express, mfib_breakout;
|
|
bool ma_stack, clean_reclaim, multi_breakout;
|
|
|
|
// Pattern-enhanced praise
|
|
bool pattern_confirmation;
|
|
bool pattern_momentum_align;
|
|
|
|
int count;
|
|
};
|
|
|
|
//================ 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 };
|
|
|
|
//================ 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 "=== CANDLESTICK PATTERNS ==="
|
|
input bool Use_Pattern_Detection = true;
|
|
input bool Pattern_Boost_Praise = true;
|
|
input bool Pattern_Enhance_Warnings = true;
|
|
input double Pattern_Praise_Multiplier = 1.3;
|
|
input double Pattern_Size_Threshold = 0.3; // Min body size vs ATR for pattern validity
|
|
|
|
input group "=== REVERSAL CONFIRMATION ==="
|
|
input bool Only_Close_On_Full_Reversal = true;
|
|
|
|
input group "=== MA SYSTEM ==="
|
|
input int MA_1 = 7, MA_2 = 14, MA_3 = 21, MA_4 = 50, MA_5 = 140;
|
|
input int MA_6 = 230, MA_7 = 500, MA_8 = 1000, MA_9 = 1100, 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;
|
|
input double Stoch_Extreme_Low = 15.0;
|
|
input double Stoch_High = 70.0;
|
|
input double Stoch_Low = 30.0;
|
|
|
|
input group "=== MOVING FIBONACCI ==="
|
|
input int MFIB_Lookback = 500;
|
|
input bool Use_MFIB_382_Bias = true;
|
|
|
|
input group "=== FIBONACCI ==="
|
|
input int Lookback_Bars = 200;
|
|
input bool Show_Levels = true;
|
|
|
|
input group "=== SIGNAL PARAMETERS ==="
|
|
input int Continuation_SL_Points = 150;
|
|
input int Continuation_BreakEven = 300;
|
|
input int Continuation_Trail = 300;
|
|
input int Continuation_TP = 4000;
|
|
input int Continuation_Partial_TP = 900;
|
|
input double Continuation_Partial_Pct = 33.0;
|
|
|
|
input int Counter_SL_Points = 50;
|
|
input int Counter_BreakEven = 25;
|
|
input int Counter_Trail = 150;
|
|
input int Counter_TP = 3000;
|
|
input int Counter_Partial_TP = 100;
|
|
input double Counter_Partial_Pct = 50.0;
|
|
|
|
input group "=== WAR SURVIVOR & PRAISE ==="
|
|
input bool Use_MFIB_Partials = true;
|
|
input double MFIB_Partial_Percent = 25.0;
|
|
input int MFIB_Partial_Min_Profit = 30;
|
|
input double War_Survivor_Multiplier = 2.5;
|
|
|
|
input bool Use_Praise_System = true;
|
|
input double Praise_Multiplier_Strong = 1.5;
|
|
input double Praise_Multiplier_Supreme = 2.0;
|
|
input int Praise_Tight_Trail = 100;
|
|
input bool Pause_Counter_On_Praise = true;
|
|
input bool Reduce_Continuation_Warn = true;
|
|
input bool Max_Aggression_Mode = true;
|
|
|
|
input group "=== OTHER SETTINGS ==="
|
|
input double Band_Snap_ATR_Multiplier = 2.0;
|
|
input bool Allow_Re_Entry = true;
|
|
input int Re_Entry_Cooldown_Bars = 5;
|
|
|
|
//================ GLOBALS ==================//
|
|
int Stoch_Handle, ATR_Handle, ADX_Handle;
|
|
int MA_Handles[10];
|
|
double PriceLevels[7];
|
|
|
|
IndicatorData Indicators;
|
|
MFIBLevels MFIB;
|
|
PositionRecord OpenPositions[];
|
|
ClosureRecord RecentClosures[10];
|
|
int ClosureIndex = 0;
|
|
|
|
Warnings Warn;
|
|
Praise PraiseSignals;
|
|
CandlePatterns Patterns;
|
|
|
|
MODE_FAMILY Current_Family, Prev_Family;
|
|
TREND_BIAS Current_Bias, Prev_Bias, MFIB_Bias;
|
|
TREND_STRENGTH Current_Strength, Prev_Strength;
|
|
PRICE_STATE Current_State;
|
|
int Mode_Confirmation_Count, Reversal_Confirm_Counter;
|
|
|
|
int TodayTrades = 0, BuyTrades = 0, SellTrades = 0, ClosedByReversal = 0;
|
|
int SetupCount[19];
|
|
datetime LastEntryTime[19];
|
|
|
|
double Stoch_Levels[5] = {20.0, 35.0, 50.0, 65.0, 80.0};
|
|
int MA_Periods[10] = {7, 14, 21, 50, 140, 230, 500, 1000, 1100, 1300};
|
|
|
|
//================ HELPERS ==================//
|
|
double Mid() { return (SymbolInfoDouble(_Symbol, SYMBOL_BID) + SymbolInfoDouble(_Symbol, SYMBOL_ASK)) / 2.0; }
|
|
bool Near(double price, double level, double tolPts) { return MathAbs(price - level) <= tolPts * _Point; }
|
|
bool StochUp() { return (Indicators.stoch_k_prev < Indicators.stoch_d && Indicators.stoch_k >= Indicators.stoch_d); }
|
|
bool StochDn() { return (Indicators.stoch_k_prev > Indicators.stoch_d && Indicators.stoch_k <= Indicators.stoch_d); }
|
|
bool IsBull() { return (Current_Bias == BIAS_BULL); }
|
|
bool IsBear() { return (Current_Bias == BIAS_BEAR); }
|
|
|
|
bool BullMA50Reclaim() {
|
|
bool rec = (Indicators.ma_prev[0] <= Indicators.ma_prev[3]) && (Indicators.ma[0] > Indicators.ma[3]);
|
|
double low0 = iLow(_Symbol, PERIOD_CURRENT, 0), close0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
bool rej = (low0 <= Indicators.ma[3] && close0 > Indicators.ma[3] && (StochUp() || Indicators.stoch_k > 50));
|
|
return (rec || rej);
|
|
}
|
|
|
|
bool BearMA50Reclaim() {
|
|
bool rec = (Indicators.ma_prev[0] >= Indicators.ma_prev[3]) && (Indicators.ma[0] < Indicators.ma[3]);
|
|
double high0 = iHigh(_Symbol, PERIOD_CURRENT, 0), close0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
bool rej = (high0 >= Indicators.ma[3] && close0 < Indicators.ma[3] && (StochDn() || Indicators.stoch_k < 50));
|
|
return (rec || rej);
|
|
}
|
|
|
|
void RecordClosure(int setup, int 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;
|
|
}
|
|
|
|
bool RecentlyStopped(int setup) {
|
|
datetime cutoff = TimeCurrent() - 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;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| CANDLESTICK PATTERN DETECTION
|
|
//+------------------------------------------------------------------+
|
|
double CandleBody(int shift) {
|
|
double open = iOpen(_Symbol, PERIOD_CURRENT, shift);
|
|
double close = iClose(_Symbol, PERIOD_CURRENT, shift);
|
|
return MathAbs(close - open);
|
|
}
|
|
|
|
double CandleRange(int shift) {
|
|
return iHigh(_Symbol, PERIOD_CURRENT, shift) - iLow(_Symbol, PERIOD_CURRENT, shift);
|
|
}
|
|
|
|
bool IsBullishCandle(int shift) {
|
|
return iClose(_Symbol, PERIOD_CURRENT, shift) > iOpen(_Symbol, PERIOD_CURRENT, shift);
|
|
}
|
|
|
|
bool IsBearishCandle(int shift) {
|
|
return iClose(_Symbol, PERIOD_CURRENT, shift) < iOpen(_Symbol, PERIOD_CURRENT, shift);
|
|
}
|
|
|
|
double UpperWick(int shift) {
|
|
double high = iHigh(_Symbol, PERIOD_CURRENT, shift);
|
|
double close = iClose(_Symbol, PERIOD_CURRENT, shift);
|
|
double open = iOpen(_Symbol, PERIOD_CURRENT, shift);
|
|
return high - MathMax(close, open);
|
|
}
|
|
|
|
double LowerWick(int shift) {
|
|
double low = iLow(_Symbol, PERIOD_CURRENT, shift);
|
|
double close = iClose(_Symbol, PERIOD_CURRENT, shift);
|
|
double open = iOpen(_Symbol, PERIOD_CURRENT, shift);
|
|
return MathMin(close, open) - low;
|
|
}
|
|
|
|
void DetectCandlePatterns() {
|
|
if(!Use_Pattern_Detection) {
|
|
ZeroMemory(Patterns);
|
|
return;
|
|
}
|
|
|
|
ZeroMemory(Patterns);
|
|
|
|
double atr = Indicators.atr;
|
|
if(atr <= 0) return;
|
|
|
|
// Get candle data
|
|
double o0 = iOpen(_Symbol, PERIOD_CURRENT, 0);
|
|
double h0 = iHigh(_Symbol, PERIOD_CURRENT, 0);
|
|
double l0 = iLow(_Symbol, PERIOD_CURRENT, 0);
|
|
double c0 = iClose(_Symbol, PERIOD_CURRENT, 0);
|
|
|
|
double o1 = iOpen(_Symbol, PERIOD_CURRENT, 1);
|
|
double h1 = iHigh(_Symbol, PERIOD_CURRENT, 1);
|
|
double l1 = iLow(_Symbol, PERIOD_CURRENT, 1);
|
|
double c1 = iClose(_Symbol, PERIOD_CURRENT, 1);
|
|
|
|
double o2 = iOpen(_Symbol, PERIOD_CURRENT, 2);
|
|
double h2 = iHigh(_Symbol, PERIOD_CURRENT, 2);
|
|
double l2 = iLow(_Symbol, PERIOD_CURRENT, 2);
|
|
double c2 = iClose(_Symbol, PERIOD_CURRENT, 2);
|
|
|
|
double body0 = CandleBody(0);
|
|
double body1 = CandleBody(1);
|
|
double body2 = CandleBody(2);
|
|
double range1 = CandleRange(1);
|
|
|
|
// Minimum body size requirement
|
|
double min_body = atr * Pattern_Size_Threshold;
|
|
|
|
//=== BULLISH ENGULFING ===
|
|
if(IsBearishCandle(1) && IsBullishCandle(0)) {
|
|
if(c0 > o1 && o0 < c1 && body0 > body1 * 1.2 && body0 > min_body) {
|
|
Patterns.bull_engulfing = true;
|
|
Patterns.bullish_count++;
|
|
}
|
|
}
|
|
|
|
//=== BEARISH ENGULFING ===
|
|
if(IsBullishCandle(1) && IsBearishCandle(0)) {
|
|
if(c0 < o1 && o0 > c1 && body0 > body1 * 1.2 && body0 > min_body) {
|
|
Patterns.bear_engulfing = true;
|
|
Patterns.bearish_count++;
|
|
}
|
|
}
|
|
|
|
//=== HAMMER (Bullish) ===
|
|
if(IsBullishCandle(1)) {
|
|
double lower_wick = LowerWick(1);
|
|
double upper_wick = UpperWick(1);
|
|
if(lower_wick > body1 * 2.0 && upper_wick < body1 * 0.5 && body1 > min_body) {
|
|
Patterns.bull_hammer = true;
|
|
Patterns.bullish_count++;
|
|
}
|
|
}
|
|
|
|
//=== SHOOTING STAR (Bearish) ===
|
|
if(IsBearishCandle(1)) {
|
|
double upper_wick = UpperWick(1);
|
|
double lower_wick = LowerWick(1);
|
|
if(upper_wick > body1 * 2.0 && lower_wick < body1 * 0.5 && body1 > min_body) {
|
|
Patterns.bear_shooting_star = true;
|
|
Patterns.bearish_count++;
|
|
}
|
|
}
|
|
|
|
//=== MORNING STAR (Bullish) ===
|
|
if(IsBearishCandle(2) && IsBullishCandle(0)) {
|
|
if(body1 < body2 * 0.3 && body1 < body0 * 0.3 && c0 > (o2 + c2) / 2 && body0 > min_body) {
|
|
Patterns.bull_morning_star = true;
|
|
Patterns.bullish_count += 2; // Strong pattern
|
|
}
|
|
}
|
|
|
|
//=== EVENING STAR (Bearish) ===
|
|
if(IsBullishCandle(2) && IsBearishCandle(0)) {
|
|
if(body1 < body2 * 0.3 && body1 < body0 * 0.3 && c0 < (o2 + c2) / 2 && body0 > min_body) {
|
|
Patterns.bear_evening_star = true;
|
|
Patterns.bearish_count += 2; // Strong pattern
|
|
}
|
|
}
|
|
|
|
//=== PIERCING PATTERN (Bullish) ===
|
|
if(IsBearishCandle(1) && IsBullishCandle(0)) {
|
|
double midpoint = c1 + (o1 - c1) * 0.5;
|
|
if(c0 > midpoint && c0 < o1 && o0 < c1 && body0 > min_body) {
|
|
Patterns.bull_piercing = true;
|
|
Patterns.bullish_count++;
|
|
}
|
|
}
|
|
|
|
//=== DARK CLOUD COVER (Bearish) ===
|
|
if(IsBullishCandle(1) && IsBearishCandle(0)) {
|
|
double midpoint = o1 + (c1 - o1) * 0.5;
|
|
if(c0 < midpoint && c0 > o1 && o0 > c1 && body0 > min_body) {
|
|
Patterns.bear_dark_cloud = true;
|
|
Patterns.bearish_count++;
|
|
}
|
|
}
|
|
|
|
//=== THREE WHITE SOLDIERS (Bullish) ===
|
|
if(IsBullishCandle(2) && IsBullishCandle(1) && IsBullishCandle(0)) {
|
|
if(c1 > c2 && c0 > c1 && o1 > o2 && o1 < c2 && o0 > o1 && o0 < c1) {
|
|
if(body0 > min_body && body1 > min_body && body2 > min_body) {
|
|
Patterns.bull_three_white = true;
|
|
Patterns.bullish_count += 2; // Very strong
|
|
}
|
|
}
|
|
}
|
|
|
|
//=== THREE BLACK CROWS (Bearish) ===
|
|
if(IsBearishCandle(2) && IsBearishCandle(1) && IsBearishCandle(0)) {
|
|
if(c1 < c2 && c0 < c1 && o1 < o2 && o1 > c2 && o0 < o1 && o0 > c1) {
|
|
if(body0 > min_body && body1 > min_body && body2 > min_body) {
|
|
Patterns.bear_three_black = true;
|
|
Patterns.bearish_count += 2; // Very strong
|
|
}
|
|
}
|
|
}
|
|
|
|
//=== DOJI (Reversal Warning) ===
|
|
if(body1 < range1 * 0.1 && range1 > min_body) {
|
|
Patterns.doji = true;
|
|
Patterns.reversal_count++;
|
|
}
|
|
|
|
//=== SPINNING TOP (Indecision) ===
|
|
if(body1 < range1 * 0.3 && body1 > range1 * 0.1) {
|
|
double upper_wick = UpperWick(1);
|
|
double lower_wick = LowerWick(1);
|
|
if(upper_wick > body1 && lower_wick > body1) {
|
|
Patterns.spinning_top = true;
|
|
Patterns.reversal_count++;
|
|
}
|
|
}
|
|
|
|
//=== HARAMI (Reversal) ===
|
|
if(body0 < body1 * 0.5) {
|
|
if(IsBearishCandle(1) && IsBullishCandle(0) && o0 > c1 && c0 < o1) {
|
|
Patterns.harami = true;
|
|
Patterns.reversal_count++;
|
|
}
|
|
if(IsBullishCandle(1) && IsBearishCandle(0) && o0 < c1 && c0 > o1) {
|
|
Patterns.harami = true;
|
|
Patterns.reversal_count++;
|
|
}
|
|
}
|
|
|
|
// Pattern Strength Assessment
|
|
Patterns.strong_bullish_pattern = (Patterns.bullish_count >= 2) ||
|
|
Patterns.bull_morning_star ||
|
|
Patterns.bull_three_white;
|
|
|
|
Patterns.strong_bearish_pattern = (Patterns.bearish_count >= 2) ||
|
|
Patterns.bear_evening_star ||
|
|
Patterns.bear_three_black;
|
|
|
|
Patterns.reversal_warning = (Patterns.reversal_count >= 1) ||
|
|
Patterns.doji ||
|
|
Patterns.harami;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
int OnInit() {
|
|
Print("========== QuarterTheory VIZION v7 (PATTERNS) ==========");
|
|
Print("CANDLESTICK PATTERNS: Structure + Pattern Confirmation");
|
|
Print("WAR SURVIVOR: 2.5x size + 25% MFIB partials");
|
|
Print("PRAISE SYSTEM: 8 Trend Signals + Pattern Boost");
|
|
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);
|
|
|
|
for(int i=0; i<10; i++) MA_Handles[i] = iMA(_Symbol, PERIOD_CURRENT, MA_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_");
|
|
Print("Final: B:", BuyTrades, " | S:", SellTrades, " | Reversed:", ClosedByReversal);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CalculateLevels() {
|
|
double high = iHigh(_Symbol, PERIOD_CURRENT, 0), low = iLow(_Symbol, PERIOD_CURRENT, 0);
|
|
for(int i=1; i<=Lookback_Bars; i++) {
|
|
double h = iHigh(_Symbol, PERIOD_CURRENT, i), l = iLow(_Symbol, PERIOD_CURRENT, i);
|
|
if(h > high) high = h;
|
|
if(l < low) low = l;
|
|
}
|
|
double range = high - low;
|
|
PriceLevels[0] = low;
|
|
for(int i=1; i<6; i++) PriceLevels[i] = low + range * (i==1 ? 0.236 : i==2 ? 0.382 : i==3 ? 0.5 : i==4 ? 0.618 : 0.786);
|
|
PriceLevels[6] = high;
|
|
|
|
double ath = iHigh(_Symbol, PERIOD_CURRENT, 0), atl = iLow(_Symbol, PERIOD_CURRENT, 0);
|
|
for(int i=1; i<=MFIB_Lookback; i++) {
|
|
double h = iHigh(_Symbol, PERIOD_CURRENT, i), 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;
|
|
MFIB.level_236 = ath - (mfib_range * 0.236);
|
|
MFIB.level_382 = ath - (mfib_range * 0.382);
|
|
MFIB.level_050 = ath - (mfib_range * 0.500);
|
|
MFIB.level_618 = ath - (mfib_range * 0.618);
|
|
MFIB.level_786 = ath - (mfib_range * 0.786);
|
|
|
|
if(Use_MFIB_382_Bias) {
|
|
double current = Mid();
|
|
if(current > MFIB.level_382) MFIB_Bias = BIAS_BULL;
|
|
else if(current < MFIB.level_382) MFIB_Bias = BIAS_BEAR;
|
|
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};
|
|
for(int i=0; i<7; i++) {
|
|
ObjectCreate(0, "Level_" + IntegerToString(i), OBJ_HLINE, 0, 0, PriceLevels[i]);
|
|
ObjectSetInteger(0, "Level_" + IntegerToString(i), OBJPROP_COLOR, level_colors[i]);
|
|
ObjectSetInteger(0, "Level_" + IntegerToString(i), OBJPROP_STYLE, STYLE_DOT);
|
|
}
|
|
ObjectCreate(0, "MFIB_382", OBJ_HLINE, 0, 0, MFIB.level_382);
|
|
ObjectSetInteger(0, "MFIB_382", OBJPROP_COLOR, clrYellow);
|
|
ObjectSetInteger(0, "MFIB_382", OBJPROP_WIDTH, 2);
|
|
ObjectCreate(0, "MFIB_618", OBJ_HLINE, 0, 0, MFIB.level_618);
|
|
ObjectSetInteger(0, "MFIB_618", OBJPROP_COLOR, clrCyan);
|
|
ObjectSetInteger(0, "MFIB_618", OBJPROP_WIDTH, 2);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
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) Indicators.ma[i] = curr[0];
|
|
if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) Indicators.ma_prev[i] = prev[0];
|
|
if(CopyBuffer(MA_Handles[i], 0, 2, 1, prev2) > 0) Indicators.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) Indicators.stoch_k = k_curr[0];
|
|
if(CopyBuffer(Stoch_Handle, MAIN_LINE, 1, 1, k_prev) > 0) Indicators.stoch_k_prev = k_prev[0];
|
|
if(CopyBuffer(Stoch_Handle, MAIN_LINE, 2, 1, k_prev2) > 0) Indicators.stoch_k_prev2 = k_prev2[0];
|
|
if(CopyBuffer(Stoch_Handle, SIGNAL_LINE, 0, 1, d_curr) > 0) Indicators.stoch_d = d_curr[0];
|
|
double atr[1], adx[1];
|
|
if(CopyBuffer(ATR_Handle, 0, 0, 1, atr) > 0) Indicators.atr = atr[0];
|
|
if(CopyBuffer(ADX_Handle, 0, 0, 1, adx) > 0) Indicators.adx = adx[0];
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void DetectWarnings() {
|
|
double current = Mid(), prev = iClose(_Symbol, PERIOD_CURRENT, 1), bufPts = (double)MA_Touch_Buffer;
|
|
double mfib_levels[5] = {MFIB.level_236, MFIB.level_382, MFIB.level_050, MFIB.level_618, MFIB.level_786};
|
|
|
|
ZeroMemory(Warn);
|
|
|
|
if(Indicators.stoch_k <= Stoch_Extreme_Low || Indicators.stoch_k >= Stoch_Extreme_High) Warn.stoch_extreme = true;
|
|
|
|
bool k_crossed_d = (Indicators.stoch_k_prev < Indicators.stoch_d && Indicators.stoch_k >= Indicators.stoch_d) ||
|
|
(Indicators.stoch_k_prev > Indicators.stoch_d && Indicators.stoch_k <= Indicators.stoch_d);
|
|
bool near_key = false;
|
|
for(int i=0; i<5; i++) if(MathAbs(Indicators.stoch_k - Stoch_Levels[i]) <= 5.0) { near_key = true; break; }
|
|
if(k_crossed_d && near_key) Warn.stoch_level_cross = true;
|
|
|
|
bool stoch_reject_dn = (StochDn() && Indicators.stoch_k > 50);
|
|
bool stoch_reject_up = (StochUp() && Indicators.stoch_k < 50);
|
|
if(stoch_reject_dn || stoch_reject_up || Warn.stoch_level_cross) Warn.stoch_reject = true;
|
|
|
|
bool ma7_crossed_14_dn = (Indicators.ma_prev[0] > Indicators.ma_prev[1]) && (Indicators.ma[0] <= Indicators.ma[1]);
|
|
bool ma7_crossed_14_up = (Indicators.ma_prev[0] < Indicators.ma_prev[1]) && (Indicators.ma[0] >= Indicators.ma[1]);
|
|
if(ma7_crossed_14_dn || ma7_crossed_14_up) { Warn.ma7_cross_14 = true; Warn.pullback = true; }
|
|
|
|
bool ma7_crossed_21_dn = (Indicators.ma_prev[0] > Indicators.ma_prev[2]) && (Indicators.ma[0] <= Indicators.ma[2]);
|
|
bool ma7_crossed_21_up = (Indicators.ma_prev[0] < Indicators.ma_prev[2]) && (Indicators.ma[0] >= Indicators.ma[2]);
|
|
if(ma7_crossed_21_dn || ma7_crossed_21_up) { Warn.ma7_cross_21 = true; Warn.retracement = true; }
|
|
|
|
bool ma7_broke_50_dn = (Indicators.ma_prev[0] > Indicators.ma_prev[3]) && (Indicators.ma[0] <= Indicators.ma[3]);
|
|
bool ma7_broke_50_up = (Indicators.ma_prev[0] < Indicators.ma_prev[3]) && (Indicators.ma[0] >= Indicators.ma[3]);
|
|
if(ma7_broke_50_dn || ma7_broke_50_up) Warn.ma50_break = true;
|
|
|
|
if(Indicators.atr > 0.0) {
|
|
double distance = MathAbs(current - Indicators.ma[0]);
|
|
if(distance >= Indicators.atr * Band_Snap_ATR_Multiplier) Warn.band_snap = true;
|
|
}
|
|
|
|
bool at_fib = false;
|
|
int fib_idx = -1;
|
|
for(int i=1; i<6; i++) if(Near(current, PriceLevels[i], bufPts)) { at_fib = true; fib_idx = i; break; }
|
|
|
|
if(at_fib) {
|
|
if(Warn.stoch_extreme || Warn.stoch_reject || Warn.stoch_level_cross) Warn.fib_reject = true;
|
|
if((prev < PriceLevels[fib_idx] && current > PriceLevels[fib_idx]) ||
|
|
(prev > PriceLevels[fib_idx] && current < PriceLevels[fib_idx])) Warn.fib_reclaim = true;
|
|
if(MathAbs(current - PriceLevels[fib_idx]) > bufPts * 1.5) Warn.fib_break = true;
|
|
}
|
|
|
|
bool at_mfib = false;
|
|
double mfib_level = 0;
|
|
for(int i=0; i<5; i++) if(Near(current, mfib_levels[i], bufPts)) { at_mfib = true; mfib_level = mfib_levels[i]; break; }
|
|
|
|
if(at_mfib) {
|
|
if(Warn.stoch_extreme || Warn.stoch_reject || Warn.stoch_level_cross) Warn.mfib_reject = true;
|
|
if((prev < mfib_level && current > mfib_level) || (prev > mfib_level && current < mfib_level)) Warn.mfib_reclaim = true;
|
|
if(MathAbs(current - mfib_level) > bufPts * 1.5) Warn.mfib_break = true;
|
|
}
|
|
|
|
if(Near(current, Indicators.ma[3], bufPts)) Warn.ma50 = true;
|
|
if(Near(current, Indicators.ma[4], bufPts)) Warn.ma140 = true;
|
|
if(Near(current, Indicators.ma[5], bufPts)) Warn.ma230 = true;
|
|
if(Near(current, Indicators.ma[6], bufPts)) Warn.ma500 = true;
|
|
|
|
if((Warn.ma50 || Warn.ma140 || Warn.ma230 || Warn.ma500) &&
|
|
(Warn.stoch_extreme || Warn.stoch_reject || Warn.stoch_level_cross)) Warn.ma_reject = true;
|
|
|
|
if(Warn.ma50 && ((prev < Indicators.ma[3] && current > Indicators.ma[3]) || (prev > Indicators.ma[3] && current < Indicators.ma[3]))) Warn.ma_reclaim = true;
|
|
if(Warn.ma140 && ((prev < Indicators.ma[4] && current > Indicators.ma[4]) || (prev > Indicators.ma[4] && current < Indicators.ma[4]))) Warn.ma_reclaim = true;
|
|
if((Warn.ma50 || Warn.ma140 || Warn.ma230) && MathAbs(current - Indicators.ma[3]) > bufPts * 2) Warn.ma_break = true;
|
|
|
|
// PATTERN-ENHANCED WARNINGS
|
|
if(Pattern_Enhance_Warnings && Use_Pattern_Detection) {
|
|
// Reversal patterns confirm warning signals
|
|
if(Patterns.reversal_warning && (Warn.stoch_extreme || Warn.ma_reject || Warn.fib_reject)) {
|
|
Warn.pattern_reversal_warn = true;
|
|
}
|
|
|
|
// Bearish patterns confirm bullish rejections
|
|
if(IsBull() && Patterns.strong_bearish_pattern && (Warn.ma_reject || Warn.fib_reject || Warn.mfib_reject)) {
|
|
Warn.pattern_rejection_confirm = true;
|
|
}
|
|
|
|
// Bullish patterns confirm bearish rejections
|
|
if(IsBear() && Patterns.strong_bullish_pattern && (Warn.ma_reject || Warn.fib_reject || Warn.mfib_reject)) {
|
|
Warn.pattern_rejection_confirm = true;
|
|
}
|
|
}
|
|
|
|
Warn.confluence_count = 0;
|
|
if(Warn.stoch_extreme) Warn.confluence_count++;
|
|
if(Warn.stoch_reject) Warn.confluence_count++;
|
|
if(Warn.stoch_level_cross) Warn.confluence_count++;
|
|
if(Warn.ma7_cross_14) Warn.confluence_count++;
|
|
if(Warn.ma7_cross_21) Warn.confluence_count++;
|
|
if(Warn.ma50_break) Warn.confluence_count++;
|
|
if(Warn.fib_reject) Warn.confluence_count++;
|
|
if(Warn.mfib_reject) Warn.confluence_count++;
|
|
if(Warn.ma_reject) Warn.confluence_count++;
|
|
if(Warn.fib_reclaim) Warn.confluence_count++;
|
|
if(Warn.mfib_reclaim) Warn.confluence_count++;
|
|
if(Warn.ma_reclaim) Warn.confluence_count++;
|
|
if(Warn.band_snap) Warn.confluence_count++;
|
|
if(Warn.ma50) Warn.confluence_count++;
|
|
if(Warn.ma140) Warn.confluence_count++;
|
|
if(Warn.ma230) Warn.confluence_count++;
|
|
if(Warn.ma500) Warn.confluence_count++;
|
|
if(Warn.pattern_reversal_warn) Warn.confluence_count++;
|
|
if(Warn.pattern_rejection_confirm) Warn.confluence_count++;
|
|
Warn.confluence_3plus = (Warn.confluence_count >= 3);
|
|
|
|
if(Indicators.atr > 0.0) {
|
|
double dist_ma14 = MathAbs(current - Indicators.ma[1]) / Indicators.atr;
|
|
Warn.ma14_magnet = (dist_ma14 < 0.7);
|
|
}
|
|
|
|
for(int i=1; i<6; i++) {
|
|
if(MathAbs(prev - PriceLevels[i]) < bufPts * 0.5 && MathAbs(current - PriceLevels[i]) > bufPts * 2.0) {
|
|
Warn.fib_break_confirmed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for(int i=0; i<5; i++) {
|
|
if(MathAbs(prev - mfib_levels[i]) < bufPts * 0.5 && MathAbs(current - mfib_levels[i]) > bufPts * 2.0) {
|
|
Warn.mfib_break_confirmed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool at_strong_ma = (Warn.ma140 || Warn.ma230 || Warn.ma500);
|
|
if(at_strong_ma) {
|
|
bool ma140_bounce = Warn.ma140 && ((prev < Indicators.ma[4] && current > Indicators.ma[4]) || (prev > Indicators.ma[4] && current < Indicators.ma[4]));
|
|
bool ma230_bounce = Warn.ma230 && ((prev < Indicators.ma[5] && current > Indicators.ma[5]) || (prev > Indicators.ma[5] && current < Indicators.ma[5]));
|
|
bool ma500_bounce = Warn.ma500 && ((prev < Indicators.ma[6] && current > Indicators.ma[6]) || (prev > Indicators.ma[6] && current < Indicators.ma[6]));
|
|
if((ma140_bounce || ma230_bounce || ma500_bounce) &&
|
|
(Warn.stoch_level_cross || Warn.stoch_reject)) Warn.strong_ma_bounce = true;
|
|
}
|
|
|
|
Warn.trend_resumption = (IsBull() && BullMA50Reclaim()) || (IsBear() && BearMA50Reclaim());
|
|
}
|
|
|
|
void DetectPraiseSignals() {
|
|
if(!Use_Praise_System) { PraiseSignals.count = 0; return; }
|
|
|
|
double current = Mid(), bufPts = (double)MA_Touch_Buffer;
|
|
ZeroMemory(PraiseSignals);
|
|
|
|
if(Indicators.atr > 0.0) {
|
|
double d7 = MathAbs(current - Indicators.ma[0]) / Indicators.atr;
|
|
double d14 = MathAbs(current - Indicators.ma[1]) / Indicators.atr;
|
|
double d21 = MathAbs(current - Indicators.ma[2]) / Indicators.atr;
|
|
bool all_close = (d7 < 0.5) && (d14 < 0.7) && (d21 < 0.9);
|
|
bool trending = (Indicators.ma[0] > Indicators.ma_prev[0] && Indicators.ma[1] > Indicators.ma_prev[1] && Indicators.ma[2] > Indicators.ma_prev[2]) ||
|
|
(Indicators.ma[0] < Indicators.ma_prev[0] && Indicators.ma[1] < Indicators.ma_prev[1] && Indicators.ma[2] < Indicators.ma_prev[2]);
|
|
if(all_close && trending && !Warn.band_snap) PraiseSignals.triple_magnet = true;
|
|
}
|
|
|
|
if(Indicators.atr > 0.0) {
|
|
double dist = MathAbs(Indicators.ma[1] - Indicators.ma[2]) / Indicators.atr;
|
|
bool close = (dist < 0.3);
|
|
bool same_dir = (Indicators.ma[1] > Indicators.ma_prev[1] && Indicators.ma[2] > Indicators.ma_prev[2]) ||
|
|
(Indicators.ma[1] < Indicators.ma_prev[1] && Indicators.ma[2] < Indicators.ma_prev[2]);
|
|
bool side = (IsBull() && Indicators.ma[0] > Indicators.ma[1]) || (IsBear() && Indicators.ma[0] < Indicators.ma[1]);
|
|
bool hugging = MathAbs(current - Indicators.ma[1]) / Indicators.atr < 0.8 || MathAbs(current - Indicators.ma[2]) / Indicators.atr < 0.8;
|
|
if(close && same_dir && side && hugging) PraiseSignals.power_couple = true;
|
|
}
|
|
|
|
bool stack_bull = (Indicators.ma[0] > Indicators.ma[1]) && (Indicators.ma[1] > Indicators.ma[2]) && (Indicators.ma[2] > Indicators.ma[3]) && (Indicators.ma[3] > Indicators.ma[4]);
|
|
bool stack_bear = (Indicators.ma[0] < Indicators.ma[1]) && (Indicators.ma[1] < Indicators.ma[2]) && (Indicators.ma[2] < Indicators.ma[3]) && (Indicators.ma[3] < Indicators.ma[4]);
|
|
|
|
bool properly_spaced = true;
|
|
if(Indicators.atr > 0.0) {
|
|
for(int i=0; i<4; i++) {
|
|
double spacing = MathAbs(Indicators.ma[i] - Indicators.ma[i+1]) / Indicators.atr;
|
|
if(spacing < 0.1) { properly_spaced = false; break; }
|
|
}
|
|
}
|
|
|
|
bool all_trending = true;
|
|
for(int i=0; i<5; i++) if(MathAbs(Indicators.ma[i] - Indicators.ma_prev[i]) / _Point < 5) { all_trending = false; break; }
|
|
|
|
if((stack_bull || stack_bear) && properly_spaced && all_trending) PraiseSignals.ma_stack = true;
|
|
|
|
if(Warn.mfib_break_confirmed && Indicators.adx > 25) PraiseSignals.mfib_breakout = true;
|
|
if(Warn.fib_break_confirmed && Indicators.adx > 25) PraiseSignals.multi_breakout = true;
|
|
|
|
// PATTERN-ENHANCED PRAISE
|
|
if(Pattern_Boost_Praise && Use_Pattern_Detection) {
|
|
// Bullish patterns align with bullish structure
|
|
if(IsBull() && Patterns.strong_bullish_pattern &&
|
|
(PraiseSignals.ma_stack || PraiseSignals.triple_magnet || PraiseSignals.power_couple)) {
|
|
PraiseSignals.pattern_confirmation = true;
|
|
}
|
|
|
|
// Bearish patterns align with bearish structure
|
|
if(IsBear() && Patterns.strong_bearish_pattern &&
|
|
(PraiseSignals.ma_stack || PraiseSignals.triple_magnet || PraiseSignals.power_couple)) {
|
|
PraiseSignals.pattern_confirmation = true;
|
|
}
|
|
|
|
// Multiple bullish patterns with trend momentum
|
|
if(IsBull() && Patterns.bullish_count >= 2 && Indicators.adx > 25 && !Warn.band_snap) {
|
|
PraiseSignals.pattern_momentum_align = true;
|
|
}
|
|
|
|
// Multiple bearish patterns with trend momentum
|
|
if(IsBear() && Patterns.bearish_count >= 2 && Indicators.adx > 25 && !Warn.band_snap) {
|
|
PraiseSignals.pattern_momentum_align = true;
|
|
}
|
|
}
|
|
|
|
PraiseSignals.count = 0;
|
|
if(PraiseSignals.triple_magnet) PraiseSignals.count++;
|
|
if(PraiseSignals.power_couple) PraiseSignals.count++;
|
|
if(PraiseSignals.mfib_staircase) PraiseSignals.count++;
|
|
if(PraiseSignals.mfib_express) PraiseSignals.count++;
|
|
if(PraiseSignals.mfib_breakout) PraiseSignals.count++;
|
|
if(PraiseSignals.ma_stack) PraiseSignals.count++;
|
|
if(PraiseSignals.clean_reclaim) PraiseSignals.count++;
|
|
if(PraiseSignals.multi_breakout) PraiseSignals.count++;
|
|
if(PraiseSignals.pattern_confirmation) PraiseSignals.count++;
|
|
if(PraiseSignals.pattern_momentum_align) PraiseSignals.count++;
|
|
}
|
|
|
|
void DetectFamilyBiasStrength(MODE_FAMILY &family, TREND_BIAS &bias, TREND_STRENGTH &strength) {
|
|
double current = Mid();
|
|
|
|
bool mas_bull = (Indicators.ma[0] > Indicators.ma[1]) && (Indicators.ma[1] > Indicators.ma[2]) && (Indicators.ma[2] > Indicators.ma[3]);
|
|
bool mas_bear = (Indicators.ma[0] < Indicators.ma[1]) && (Indicators.ma[1] < Indicators.ma[2]) && (Indicators.ma[2] < Indicators.ma[3]);
|
|
|
|
double recent_high = iHigh(_Symbol, PERIOD_CURRENT, 0), 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(Indicators.atr > 0.0) ma_clustered = ((MathAbs(Indicators.ma[0] - Indicators.ma[3]) / Indicators.atr) < Chop_ATR_Threshold);
|
|
bool is_choppy = (ma_clustered || Indicators.adx < 15);
|
|
|
|
if(mas_bull && (MFIB_Bias == BIAS_BULL || !Use_MFIB_382_Bias)) bias = BIAS_BULL;
|
|
else if(mas_bear && (MFIB_Bias == BIAS_BEAR || !Use_MFIB_382_Bias)) bias = BIAS_BEAR;
|
|
else if(MFIB_Bias == BIAS_BULL && Indicators.ma[0] > Indicators.ma[3]) bias = BIAS_BULL;
|
|
else if(MFIB_Bias == BIAS_BEAR && Indicators.ma[0] < Indicators.ma[3]) bias = BIAS_BEAR;
|
|
else if(Indicators.ma[0] > Indicators.ma[3]) bias = BIAS_BULL;
|
|
else if(Indicators.ma[0] < Indicators.ma[3]) bias = BIAS_BEAR;
|
|
else bias = BIAS_NEUTRAL;
|
|
|
|
if(is_choppy && !(mas_bull || mas_bear)) family = FAMILY_CHOP;
|
|
else if(is_ranging && !(mas_bull || mas_bear)) family = FAMILY_RANGING;
|
|
else if(bias != BIAS_NEUTRAL) family = FAMILY_TRENDING;
|
|
else family = FAMILY_TRANSITIONAL;
|
|
|
|
if(Indicators.adx > 25 && (mas_bull || mas_bear)) strength = STRENGTH_STRONG;
|
|
else if(Indicators.adx > 18 && (mas_bull || mas_bear)) strength = STRENGTH_CONFIRMED;
|
|
else strength = STRENGTH_WEAK;
|
|
}
|
|
|
|
PRICE_STATE DetermineState() {
|
|
if(Current_Family == FAMILY_RANGING) {
|
|
double current = Mid(), bufPts = (double)MA_Touch_Buffer;
|
|
bool near_low = Near(current, PriceLevels[1], bufPts) || Near(current, PriceLevels[0], bufPts);
|
|
bool near_high = Near(current, PriceLevels[5], bufPts) || Near(current, PriceLevels[6], bufPts);
|
|
if(near_low || near_high) return STATE_RANGE_EDGE_TEST;
|
|
if(Warn.stoch_reject || Warn.stoch_extreme || Warn.fib_reject || Warn.mfib_reject) return STATE_RANGE_REJECTION;
|
|
return STATE_RANGE_MID_DRIFT;
|
|
}
|
|
|
|
if(Current_Family == FAMILY_CHOP) {
|
|
if(Indicators.adx < 12 && !Warn.stoch_reject) return STATE_CHOP_NOISE;
|
|
if(Warn.stoch_reject) return STATE_CHOP_FAKEOUT_LOOP;
|
|
return STATE_CHOP_NOISE;
|
|
}
|
|
|
|
bool ma7_above_50 = (Indicators.ma[0] > Indicators.ma[3]);
|
|
bool ma7_below_50 = (Indicators.ma[0] < Indicators.ma[3]);
|
|
bool ma14_above_50 = (Indicators.ma[1] > Indicators.ma[3]);
|
|
bool ma14_below_50 = (Indicators.ma[1] < Indicators.ma[3]);
|
|
|
|
bool pullback_sig = (Warn.pullback || Warn.mfib_reject || Warn.fib_reject || Warn.stoch_reject || Warn.band_snap || Warn.stoch_level_cross);
|
|
bool retrace_sig = (Warn.ma7_cross_21 || Warn.retracement || Warn.ma140 || Warn.ma230 || Warn.ma500);
|
|
bool strong_ma_pressure = (Warn.ma140 || Warn.ma230 || Warn.ma500 || Warn.ma50);
|
|
|
|
if(IsBull()) {
|
|
if(ma7_below_50 && !ma14_above_50) return STATE_REVERSAL_CONFIRMED;
|
|
if(Warn.ma50_break && (retrace_sig || strong_ma_pressure || Warn.stoch_extreme || Warn.confluence_3plus)) return STATE_REVERSAL_ATTEMPT;
|
|
if(Warn.ma7_cross_21 || strong_ma_pressure || (!Indicators.ma[0] > Indicators.ma[2] && (pullback_sig || retrace_sig))) return STATE_DEEP_RETRACEMENT;
|
|
if(Warn.ma7_cross_14 || (ma14_above_50 && pullback_sig)) return STATE_PULLBACK;
|
|
return STATE_CONTINUATION;
|
|
}
|
|
|
|
if(IsBear()) {
|
|
if(ma7_above_50 && !ma14_below_50) return STATE_REVERSAL_CONFIRMED;
|
|
if(Warn.ma50_break && (retrace_sig || strong_ma_pressure || Warn.stoch_extreme || Warn.confluence_3plus)) return STATE_REVERSAL_ATTEMPT;
|
|
if(Warn.ma7_cross_21 || strong_ma_pressure || (!Indicators.ma[0] < Indicators.ma[2] && (pullback_sig || retrace_sig))) return STATE_DEEP_RETRACEMENT;
|
|
if(Warn.ma7_cross_14 || (ma14_below_50 && pullback_sig)) return STATE_PULLBACK;
|
|
return STATE_CONTINUATION;
|
|
}
|
|
|
|
return STATE_UNKNOWN;
|
|
}
|
|
|
|
string StateStr(PRICE_STATE s) {
|
|
if(s == STATE_CONTINUATION) return "CONT";
|
|
if(s == STATE_PULLBACK) return "PULLBACK";
|
|
if(s == STATE_DEEP_RETRACEMENT) return "RETRACE";
|
|
if(s == STATE_REVERSAL_CONFIRMED) return "REV-CONF";
|
|
if(s == STATE_RANGE_EDGE_TEST) return "RANGE-EDGE";
|
|
if(s == STATE_CHOP_NOISE) return "CHOP";
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
string BiasStr(TREND_BIAS b) { return (b == BIAS_BULL ? "BULL" : (b == BIAS_BEAR ? "BEAR" : "NEUTRAL")); }
|
|
string FamilyStr(MODE_FAMILY f) { return (f == FAMILY_TRENDING ? "TREND" : (f == FAMILY_RANGING ? "RANGE" : (f == FAMILY_CHOP ? "CHOP" : "TRANS"))); }
|
|
|
|
void UpdateLabels() {
|
|
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, 20);
|
|
|
|
string mode_text = FamilyStr(Current_Family) + " | " + BiasStr(Current_Bias) + " | " + StateStr(Current_State);
|
|
mode_text += " | P:" + IntegerToString(PraiseSignals.count) + " W:" + IntegerToString(Warn.confluence_count);
|
|
|
|
// Add pattern info
|
|
if(Use_Pattern_Detection) {
|
|
mode_text += " | Bull:" + IntegerToString(Patterns.bullish_count) + " Bear:" + IntegerToString(Patterns.bearish_count);
|
|
}
|
|
|
|
color txt_color = clrWhite;
|
|
if(Current_Family == FAMILY_TRENDING && IsBull()) txt_color = clrLime;
|
|
else if(Current_Family == FAMILY_TRENDING && IsBear()) txt_color = clrRed;
|
|
else if(Current_Family == FAMILY_RANGING) txt_color = clrCyan;
|
|
else if(Current_Family == FAMILY_CHOP) txt_color = clrViolet;
|
|
|
|
ObjectSetString(0, "StateLabel", OBJPROP_TEXT, mode_text);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_COLOR, txt_color);
|
|
ObjectSetInteger(0, "StateLabel", OBJPROP_FONTSIZE, 11);
|
|
}
|
|
|
|
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;
|
|
Current_State = DetermineState();
|
|
|
|
UpdateLabels();
|
|
}
|
|
|
|
void MarkRunners() {
|
|
double current = Mid();
|
|
for(int i=0; i<ArraySize(OpenPositions); i++) {
|
|
if(PositionSelectByTicket(OpenPositions[i].ticket)) {
|
|
OpenPositions[i].distance_from_current = MathAbs(current - OpenPositions[i].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) {
|
|
PositionRecord 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 - Closing opposing positions");
|
|
|
|
for(int i=PositionsTotal()-1; i>=0; i--) {
|
|
if(!PositionGetTicket(i)) 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 = (is_buy && IsBear()) || (!is_buy && IsBull());
|
|
if(should_close) { if(Trade.PositionClose(ticket)) ClosedByReversal++; }
|
|
}
|
|
}
|
|
|
|
bool IsDirectionAllowed(bool is_buy) {
|
|
if(!Use_Market_Mode_Filter) return true;
|
|
|
|
if(Current_Family == FAMILY_TRENDING) {
|
|
if(Current_State == STATE_REVERSAL_CONFIRMED) {
|
|
if(IsBull() && !is_buy) return false;
|
|
if(IsBear() && is_buy) return false;
|
|
return true;
|
|
}
|
|
|
|
if(Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT) {
|
|
if(IsBull()) return (!is_buy && !BullMA50Reclaim()) || (is_buy && BullMA50Reclaim());
|
|
if(IsBear()) return (is_buy && !BearMA50Reclaim()) || (!is_buy && BearMA50Reclaim());
|
|
}
|
|
|
|
if(Current_State == STATE_CONTINUATION) {
|
|
if(IsBull() && !is_buy) return false;
|
|
if(IsBear() && is_buy) return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int CountSetupTrades(int setup) {
|
|
int count = 0;
|
|
for(int i=0; i<PositionsTotal(); i++) {
|
|
if(!PositionGetTicket(i)) 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 && OpenPositions[j].setup_type == setup) count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
SignalParams GetSignalParams(int category) {
|
|
SignalParams p;
|
|
if(category == CATEGORY_COUNTER_TREND) {
|
|
p.sl_points = Counter_SL_Points;
|
|
p.be_points = Counter_BreakEven;
|
|
p.trail_points = Counter_Trail;
|
|
p.tp_points = Counter_TP;
|
|
p.partial_tp = Counter_Partial_TP;
|
|
p.partial_pct = Counter_Partial_Pct;
|
|
} else {
|
|
p.sl_points = Continuation_SL_Points;
|
|
p.be_points = Continuation_BreakEven;
|
|
p.trail_points = Continuation_Trail;
|
|
p.tp_points = Continuation_TP;
|
|
p.partial_tp = Continuation_Partial_TP;
|
|
p.partial_pct = Continuation_Partial_Pct;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
double GetLotSize(int 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);
|
|
SignalParams p = GetSignalParams(category);
|
|
double lot = risk / ((p.sl_points * _Point / tickSize) * tickValue);
|
|
|
|
if(Use_MFIB_Partials) lot = lot * War_Survivor_Multiplier;
|
|
|
|
if(Use_Praise_System) {
|
|
if(category == CATEGORY_CONTINUATION) {
|
|
// Pattern boost for continuation trades
|
|
if(Pattern_Boost_Praise && (PraiseSignals.pattern_confirmation || PraiseSignals.pattern_momentum_align)) {
|
|
lot = lot * Pattern_Praise_Multiplier;
|
|
}
|
|
|
|
if(PraiseSignals.count >= 4) lot = lot * Praise_Multiplier_Supreme;
|
|
else if(PraiseSignals.count == 3) lot = lot * Praise_Multiplier_Strong;
|
|
if(Reduce_Continuation_Warn && Warn.confluence_count >= 3) lot = lot * 0.5;
|
|
} else if(category == CATEGORY_COUNTER_TREND) {
|
|
if(Pause_Counter_On_Praise && PraiseSignals.count >= 3) lot = lot * 0.25;
|
|
}
|
|
}
|
|
|
|
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, int setup_type, int category) {
|
|
if(!IsDirectionAllowed(buy)) return;
|
|
if(!Allow_Re_Entry || (TimeCurrent() - LastEntryTime[setup_type] >= 1)) {
|
|
if(CountSetupTrades(setup_type) >= Max_Trades_Per_Setup) return;
|
|
if(PositionsTotal() >= Max_Total_Trades) return;
|
|
|
|
double lot = GetLotSize(category);
|
|
if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return;
|
|
|
|
SignalParams p = GetSignalParams(category);
|
|
double sl = buy ? price - p.sl_points * _Point : price + p.sl_points * _Point;
|
|
double tp = buy ? price + p.tp_points * _Point : price - p.tp_points * _Point;
|
|
|
|
string comment = setup_name + "|" + (category == CATEGORY_COUNTER_TREND ? "CTR" : "CONT");
|
|
|
|
bool result = buy ? Trade.Buy(lot, _Symbol, 0, sl, tp, comment) : Trade.Sell(lot, _Symbol, 0, sl, tp, comment);
|
|
|
|
if(result) {
|
|
LastEntryTime[setup_type] = TimeCurrent();
|
|
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].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;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ManagePositions() {
|
|
for(int i=PositionsTotal()-1; i>=0; i--) {
|
|
ulong ticket = PositionGetTicket(i);
|
|
if(!ticket) 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;
|
|
int 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;
|
|
|
|
SignalParams p = GetSignalParams(cat);
|
|
int trail = p.trail_points;
|
|
if(Use_Praise_System && cat == CATEGORY_CONTINUATION && PraiseSignals.count >= 4) trail = Praise_Tight_Trail;
|
|
|
|
if(!OpenPositions[idx].partial_tp_hit && profit_points >= p.partial_tp) {
|
|
double current_lot = PositionGetDouble(POSITION_VOLUME);
|
|
double close_size = NormalizeDouble(OpenPositions[idx].original_lot * p.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;
|
|
}
|
|
}
|
|
|
|
if(Use_MFIB_Partials && profit_points >= MFIB_Partial_Min_Profit && OpenPositions[idx].mfib_partials_taken < 4) {
|
|
double mfib_levels[5] = {MFIB.level_236, MFIB.level_382, MFIB.level_050, MFIB.level_618, MFIB.level_786};
|
|
bool at_mfib = false;
|
|
double mfib_price = 0;
|
|
|
|
for(int m=0; m<5; m++) {
|
|
if(MathAbs(current - mfib_levels[m]) / _Point <= 50) {
|
|
if((Warn.mfib_reject || Warn.stoch_reject || Warn.stoch_extreme || Warn.confluence_3plus) &&
|
|
(OpenPositions[idx].last_mfib_partial_price == 0 || MathAbs(current - OpenPositions[idx].last_mfib_partial_price) / _Point > 100)) {
|
|
at_mfib = true;
|
|
mfib_price = mfib_levels[m];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(at_mfib) {
|
|
double current_lot = PositionGetDouble(POSITION_VOLUME);
|
|
double close_size = NormalizeDouble(OpenPositions[idx].original_lot * MFIB_Partial_Percent / 100.0, 2);
|
|
if(close_size > current_lot) close_size = current_lot * 0.25;
|
|
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_price;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!OpenPositions[idx].be_set && profit_points >= p.be_points) {
|
|
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 >= p.be_points + 50) {
|
|
OpenPositions[idx].trailing_active = true;
|
|
double newSL = is_buy ? current - trail * _Point : current + trail * _Point;
|
|
bool should_modify = is_buy ? (newSL > current_sl + 30 * _Point) : (newSL < current_sl - 30 * _Point);
|
|
if(should_modify) Trade.PositionModify(ticket, newSL, current_tp);
|
|
}
|
|
|
|
OpenPositions[idx].close_price = current;
|
|
}
|
|
|
|
for(int i=ArraySize(OpenPositions)-1; i>=0; i--) {
|
|
if(!PositionSelectByTicket(OpenPositions[i].ticket)) {
|
|
double entry = OpenPositions[i].entry;
|
|
double close_price = OpenPositions[i].close_price;
|
|
bool is_buy = OpenPositions[i].is_buy;
|
|
bool at_be = (MathAbs(close_price - entry) / _Point < 10);
|
|
bool at_sl = !at_be && ((is_buy && close_price < entry) || (!is_buy && close_price > entry));
|
|
|
|
RecordClosure(OpenPositions[i].setup_type, OpenPositions[i].category, OpenPositions[i].is_buy, close_price, at_sl, at_be);
|
|
|
|
for(int j=i; j<ArraySize(OpenPositions)-1; j++) OpenPositions[j] = OpenPositions[j+1];
|
|
ArrayResize(OpenPositions, ArraySize(OpenPositions)-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnTick() {
|
|
UpdateIndicators();
|
|
DetectCandlePatterns(); // NEW: Pattern detection
|
|
DetectWarnings();
|
|
DetectPraiseSignals();
|
|
|
|
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 buffer = MA_Touch_Buffer * _Point;
|
|
|
|
if(Current_Family == FAMILY_TRENDING && Current_State == STATE_CONTINUATION) {
|
|
if(IsBull()) {
|
|
if(Indicators.ma[0] > Indicators.ma[1]) OpenTrade(true, ask, "MA-CROSS↑", SETUP_MA14_CROSS, CATEGORY_CONTINUATION);
|
|
if(Near(current, Indicators.ma[3], buffer)) OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE, CATEGORY_CONTINUATION);
|
|
if(Near(current, Indicators.ma[4], buffer)) OpenTrade(true, ask, "MA140-BOUNCE↑", SETUP_MA140_BOUNCE, CATEGORY_CONTINUATION);
|
|
if(Near(current, Indicators.ma[5], buffer)) OpenTrade(true, ask, "MA230-BOUNCE↑", SETUP_MA230_BOUNCE, CATEGORY_CONTINUATION);
|
|
|
|
bool stack = (Indicators.ma[0] > Indicators.ma[1]) && (Indicators.ma[1] > Indicators.ma[2]) && (Indicators.ma[2] > Indicators.ma[3]) && (Indicators.ma[3] > Indicators.ma[4]);
|
|
if(stack && Indicators.adx > 25 && !Warn.band_snap) OpenTrade(true, ask, "STAIRCASE↑", SETUP_STAIRCASE_ADV, CATEGORY_CONTINUATION);
|
|
} else if(IsBear()) {
|
|
if(Indicators.ma[0] < Indicators.ma[1]) OpenTrade(false, bid, "MA-CROSS↓", SETUP_MA14_CROSS, CATEGORY_CONTINUATION);
|
|
if(Near(current, Indicators.ma[3], buffer)) OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE, CATEGORY_CONTINUATION);
|
|
if(Near(current, Indicators.ma[4], buffer)) OpenTrade(false, bid, "MA140-BOUNCE↓", SETUP_MA140_BOUNCE, CATEGORY_CONTINUATION);
|
|
|
|
bool stack = (Indicators.ma[0] < Indicators.ma[1]) && (Indicators.ma[1] < Indicators.ma[2]) && (Indicators.ma[2] < Indicators.ma[3]) && (Indicators.ma[3] < Indicators.ma[4]);
|
|
if(stack && Indicators.adx > 25 && !Warn.band_snap) OpenTrade(false, bid, "STAIRCASE↓", SETUP_STAIRCASE_ADV, CATEGORY_CONTINUATION);
|
|
}
|
|
}
|
|
|
|
if(Current_Family == FAMILY_RANGING) {
|
|
if(Near(current, PriceLevels[1], buffer) && Indicators.stoch_k < 35) OpenTrade(true, ask, "RANGE-BUY", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND);
|
|
if(Near(current, PriceLevels[5], buffer) && Indicators.stoch_k > 65) OpenTrade(false, bid, "RANGE-SELL", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND);
|
|
}
|
|
|
|
if(Current_Family == FAMILY_CHOP) {
|
|
if(Warn.stoch_extreme || Warn.stoch_reject || Warn.confluence_3plus) {
|
|
if(Indicators.stoch_k <= Stoch_Low) OpenTrade(true, ask, "CHOP-REV-BUY", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND);
|
|
if(Indicators.stoch_k >= Stoch_High) OpenTrade(false, bid, "CHOP-REV-SELL", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+ |