2
1
Çatalla 0
şundan çatallanmış SahrJohn/RSI-Stoch-MA-EA
RSI-Stoch-MA-EA/Tradeexecution.mqh
SahrJohn 26ea936918
2026-01-22 04:48:51 -06:00

451 satır
No EOL
17 KiB
MQL5

//+------------------------------------------------------------------+
//| TradeExecution_ENHANCED.mqh |
//| ENHANCED Trade Logic with Smart Filtering |
//| RANGING: Only trade MFIB bias direction |
//| CHOP: W≥2 → Counters only, P>W → Continuations only |
//| TRENDING: All setups allowed (existing logic) |
//| Cooldown: 5 minutes between trades |
//+------------------------------------------------------------------+
#property copyright "QuarterTheory x VIZION"
#property strict
#include "GlobalVariables.mqh"
#include "InputParams.mqh"
#include "Utilities.mqh"
#include "ReEntry.mqh"
#include "Openai.mqh"
#include <Trade/Trade.mqh>
extern CTrade Trade;
//================ COOLDOWN MANAGEMENT ==================//
const int TRADE_COOLDOWN_SECONDS = 300; // 5 minutes between trades
datetime Last_Trade_Time = 0;
//+------------------------------------------------------------------+
//| Check if AI is enabled and initialized |
//+------------------------------------------------------------------+
//================ FORWARD DECLARATIONS ==================//
//bool IsAIEnabled();
//+------------------------------------------------------------------+
//| Check if we're in cooldown period |
//+------------------------------------------------------------------+
bool IsInCooldown()
{
datetime now = TimeCurrent();
if(now - Last_Trade_Time < TRADE_COOLDOWN_SECONDS)
{
int remaining = TRADE_COOLDOWN_SECONDS - (int)(now - Last_Trade_Time);
Print("⏳ Trade cooldown: ", remaining, "s remaining");
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Enhanced setup filtering based on market conditions |
//+------------------------------------------------------------------+
bool IsSetupAllowed(SETUP_TYPE setup, bool is_buy, TRADE_CATEGORY category)
{
string setup_name = SetupTypeToString(setup);
//================================================================
// TRENDING MARKET: Allow all setups (existing behavior)
//================================================================
if(Current_Family == FAMILY_TRENDING)
{
Print("📈 TRENDING: All setups allowed | Setup: ", setup_name);
return true;
}
//================================================================
// RANGING MARKET: Only trade MFIB bias direction
//================================================================
if(Current_Family == FAMILY_RANGING)
{
bool mfib_bullish = (Current_Bias == BIAS_BULL);
bool mfib_bearish = (Current_Bias == BIAS_BEAR);
// MFIB BULLISH: Only allow BUY setups
if(mfib_bullish && !is_buy)
{
Print("⛔ RANGING: MFIB=BULL, blocking SELL setup | ", setup_name);
return false;
}
// MFIB BEARISH: Only allow SELL setups
if(mfib_bearish && is_buy)
{
Print("⛔ RANGING: MFIB=BEAR, blocking BUY setup | ", setup_name);
return false;
}
Print("✅ RANGING: MFIB=", (mfib_bullish ? "BULL" : "BEAR"),
" | Allowing ", (is_buy ? "BUY" : "SELL"), " | ", setup_name);
return true;
}
//================================================================
// CHOP MARKET: W vs P logic + pullback priority
//================================================================
if(Current_Family == FAMILY_CHOP)
{
int warns = Warning_Confluence_Count;
int praise = Praise_Count;
// RULE 1: W ≥ 2 → Trade COUNTERS only (pullbacks may reverse)
if(warns >= 2)
{
if(category == CATEGORY_COUNTER_TREND)
{
Print("✅ CHOP: W=", warns, " ≥2 → COUNTER allowed | ", setup_name);
return true;
}
else
{
Print("⛔ CHOP: W=", warns, " ≥2 → CONTINUATION blocked | ", setup_name);
return false;
}
}
// RULE 2: P > W → Trade CONTINUATIONS only
if(praise > warns)
{
if(category == CATEGORY_CONTINUATION)
{
Print("✅ CHOP: P=", praise, " > W=", warns, " → CONTINUATION allowed | ", setup_name);
return true;
}
else
{
Print("⛔ CHOP: P=", praise, " > W=", warns, " → COUNTER blocked | ", setup_name);
return false;
}
}
// RULE 3: W < 2 and W ≥ P → No clear signal, skip
Print("⛔ CHOP: W=", warns, " P=", praise, " → No clear bias, skipping | ", setup_name);
return false;
}
// Default: allow
return true;
}
//+------------------------------------------------------------------+
//| Check if trade direction is allowed by market mode |
//+------------------------------------------------------------------+
bool IsDirectionAllowed(bool is_buy)
{
if(!Use_Market_Mode_Filter) return true;
if(Current_Family == FAMILY_TRENDING)
{
// Reversal confirmed - only allow trades in new direction
if(Current_State == STATE_REVERSAL_CONFIRMED)
{
if(IsBullBias() && !is_buy) return false;
if(IsBearBias() && is_buy) return false;
return true;
}
// Pullback/Retracement - check MA50 reclaim status
if(Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT)
{
if(IsBullBias())
{
if(!Bull_MA50_Reclaimed())
return (!is_buy); // SELLS ONLY - counter-trend
return is_buy; // BUYS ONLY - trend following
}
if(IsBearBias())
{
if(!Bear_MA50_Reclaimed())
return (is_buy); // BUYS ONLY - counter-trend
return (!is_buy); // SELLS ONLY - trend following
}
}
// Continuation - only allow trades with the trend
if(Current_State == STATE_CONTINUATION)
{
if(IsBullBias() && !is_buy) return false;
if(IsBearBias() && is_buy) return false;
return true;
}
return true;
}
return true;
}
//+------------------------------------------------------------------+
//| Count existing trades for a setup |
//+------------------------------------------------------------------+
int CountSetupTrades(SETUP_TYPE setup)
{
int count = 0;
for(int i=0; i<PositionsTotal(); i++)
{
if(PositionGetTicket(i) == 0) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
ulong t = PositionGetTicket(i);
for(int j=0; j<ArraySize(OpenPositions); j++)
{
if(OpenPositions[j].ticket == t)
{
if(OpenPositions[j].setup_type == setup)
count++;
break;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| Calculate lot size with War Survivor and Praise multipliers |
//+------------------------------------------------------------------+
double GetLotSize(TRADE_CATEGORY category)
{
double risk = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Per_Trade / 100.0;
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double sl_points = (category == CATEGORY_COUNTER_TREND) ? Counter_SL_Points : Continuation_SL_Points;
double lot = risk / ((sl_points * _Point / tickSize) * tickValue);
// WAR SURVIVOR: Apply multiplier for larger initial positions
if(Use_MFIB_Partials)
lot = lot * War_Survivor_Lot_Multiplier;
// PRAISE SYSTEM: Dynamic sizing based on PRAISE vs WARN
if(Use_Praise_System)
{
if(category == CATEGORY_CONTINUATION)
{
// CONTINUATION TRADES: Boost on PRAISE, reduce on WARN
if(Praise_Count >= 4)
lot = lot * Praise_Size_Multiplier_Supreme; // Supreme praise = 2x
else if(Praise_Count == 3)
lot = lot * Praise_Size_Multiplier_Strong; // Strong praise = 1.5x
// Reduce size if high warnings
if(Reduce_Continuation_On_Warn && Warning_Confluence_Count >= 3)
lot = lot * 0.5; // Cut continuation size in half when warned
}
else if(category == CATEGORY_COUNTER_TREND)
{
// COUNTER-TREND TRADES: Boost on WARN, reduce on PRAISE
if(Warning_Confluence_Count >= 3)
lot = lot * 1.0; // Full size counter when warned
// Reduce counter size if high praise (strong trend)
if(Pause_Counter_On_Praise && Praise_Count >= 3)
lot = lot * 0.25; // Minimal counter when praised (trend strong)
}
}
// Normalize to broker requirements
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;
}
//+------------------------------------------------------------------+
//| Open a trade with full setup tracking |
//+------------------------------------------------------------------+
void OpenTrade(bool buy, double price, string setup_name, SETUP_TYPE setup_type, TRADE_CATEGORY category)
{
//================================================================
// PHASE 1: COOLDOWN CHECK
//================================================================
if(IsInCooldown())
{
return;
}
//================================================================
// PHASE 2: ENHANCED SETUP FILTERING
//================================================================
if(!IsSetupAllowed(setup_type, buy, category))
{
Print("⛔ Setup filtered out by market conditions");
return;
}
//================================================================
// PHASE 3: STANDARD PRE-FLIGHT CHECKS
//================================================================
if(!IsDirectionAllowed(buy)) return;
if(!CanReEnter(setup_type)) return;
if(CountSetupTrades(setup_type) >= Max_Trades_Per_Setup) return;
if(PositionsTotal() >= Max_Total_Trades) return;
datetime now = TimeCurrent();
if(now - LastEntryTime[setup_type] < 1) return;
// Calculate lot size
double lot = GetLotSize(category);
if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return;
//================================================================
// PHASE 4: AI TRADE VALIDATION (Optional)
//================================================================
if(Use_OpenAI && AI_Validate_Trades && IsAIEnabled())
{
Print("🤖 Requesting AI validation for ", setup_name);
string ai_response = ValidateTradeWithAI(setup_name, buy, category);
// Parse AI response for YES/NO
bool ai_approved = false;
if(StringFind(ai_response, "YES") >= 0)
{
ai_approved = true;
AI_Validation_Accepts++;
Print("✅ AI APPROVED: ", ai_response);
}
else if(StringFind(ai_response, "NO") >= 0)
{
AI_Validation_Rejects++;
Print("❌ AI REJECTED: ", ai_response);
return; // Don't take the trade
}
else if(StringFind(ai_response, "MAYBE") >= 0)
{
// Reduce position size on MAYBE
lot = lot * 0.5;
Print("⚠️ AI CAUTIOUS (50% size): ", ai_response);
}
}
//================================================================
// PHASE 5: CALCULATE SL AND TP
//================================================================
double sl, tp;
if(category == CATEGORY_COUNTER_TREND)
{
sl = buy ? price - Counter_SL_Points * _Point : price + Counter_SL_Points * _Point;
tp = buy ? price + Counter_TP_Points * _Point : price - Counter_TP_Points * _Point;
}
else
{
sl = buy ? price - Continuation_SL_Points * _Point : price + Continuation_SL_Points * _Point;
tp = buy ? price + Continuation_TP_Points * _Point : price - Continuation_TP_Points * _Point;
}
//================================================================
// PHASE 6: BUILD COMMENT WITH FULL CONTEXT
//================================================================
string cat_text = (category == CATEGORY_COUNTER_TREND) ? "CTR" : "CONT";
string bias_text = BiasToText(MFIB_Bias);
string family_text = FamilyToText(Current_Family);
string wp_text = "W" + IntegerToString(Warning_Confluence_Count) +
"P" + IntegerToString(Praise_Count);
string comment = setup_name + "|" + cat_text + "|" + family_text + "|" +
bias_text + "|" + wp_text;
//================================================================
// PHASE 7: EXECUTE TRADE
//================================================================
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)
{
//================================================================
// PHASE 8: UPDATE TRACKING AND COOLDOWN
//================================================================
Last_Trade_Time = now; // START COOLDOWN
LastEntryTime[setup_type] = now;
TodayTrades++;
if(buy) BuyTrades++;
else SellTrades++;
SetupCount[setup_type]++;
ulong ticket = Trade.ResultOrder();
// Add to position tracking array
int size = ArraySize(OpenPositions);
ArrayResize(OpenPositions, size+1);
OpenPositions[size].ticket = ticket;
OpenPositions[size].entry = price;
OpenPositions[size].original_lot = lot;
OpenPositions[size].is_buy = buy;
OpenPositions[size].partial_tp_hit = false;
OpenPositions[size].be_set = false;
OpenPositions[size].trailing_active = false;
OpenPositions[size].is_runner = false;
OpenPositions[size].setup_type = setup_type;
OpenPositions[size].category = category;
OpenPositions[size].setup_name = setup_name;
OpenPositions[size].entry_family = Current_Family;
OpenPositions[size].entry_bias = Current_Bias;
OpenPositions[size].entry_strength = Current_Strength;
OpenPositions[size].distance_from_current = 0;
OpenPositions[size].last_close_time = 0;
OpenPositions[size].closed_at_sl = false;
OpenPositions[size].closed_at_be = false;
OpenPositions[size].close_price = 0;
OpenPositions[size].mfib_partials_taken = 0;
OpenPositions[size].last_mfib_partial_price = 0;
// Enhanced logging
Print("╔════════════════════════════════════════╗");
Print("║ ✅ TRADE EXECUTED ║");
Print("╠════════════════════════════════════════╣");
Print("║ Direction: ", (buy ? "BUY " : "SELL"), "");
Print("║ Setup: ", setup_name);
Print("║ Category: ", cat_text, "");
Print("║ Market: ", family_text, "");
Print("║ Bias: ", bias_text, "");
Print("║ W=", Warning_Confluence_Count, " P=", Praise_Count, "");
Print("║ Lot Size: ", DoubleToString(lot, 2), "");
Print("║ Cooldown: 5 minutes ║");
Print("╚════════════════════════════════════════╝");
}
}
//+------------------------------------------------------------------+
//| Helper: Convert setup type to string |
//+------------------------------------------------------------------+
string SetupTypeToString(SETUP_TYPE setup)
{
// Match your actual SETUP_TYPE enum values
if(setup == SETUP_MA14_CROSS) return "MA14_CROSS";
if(setup == SETUP_MA50_BOUNCE) return "MA50_BOUNCE";
if(setup == SETUP_MA140_BOUNCE) return "MA140_BOUNCE";
if(setup == SETUP_MA230_BOUNCE) return "MA230_BOUNCE";
if(setup == SETUP_MA500_TOUCH) return "MA500_TOUCH";
if(setup == SETUP_FIB_BREAK) return "FIB_BREAK";
if(setup == SETUP_FIB_RECLAIM) return "FIB_RECLAIM";
if(setup == SETUP_MAGNET_WALK) return "MAGNET_WALK";
if(setup == SETUP_MFIB_LADDER) return "MFIB_LADDER";
if(setup == SETUP_STAIRCASE_ADV) return "STAIRCASE";
if(setup == SETUP_CTRL_PULLBACK) return "CTRL_PB";
if(setup == SETUP_TF_RESET) return "TF_RESET";
if(setup == SETUP_MFIB_PRESS) return "MFIB_PRESS";
if(setup == SETUP_RANGE_ENGINE) return "RANGE_ENGINE";
if(setup == SETUP_FIB_REJECT) return "FIB_REJECT";
if(setup == SETUP_MEAN_REV) return "MEAN_REV";
return "UNKNOWN";
}