mql5/Experts/Archive/PME_Diagnostic_Script.mq5

301 行
13 KiB
MQL5
Raw パーマリンク 通常表示 履歴

2025-10-03 10:03:10 +01:00
//+------------------------------------------------------------------+
//| PME_Diagnostic_Script.mq5 |
//| Diagnose Why Positions Are Closing Early |
//+------------------------------------------------------------------+
#property script_show_inputs
#include "Modules_PME/DataTypes_PME.mqh"
#include "Modules_PME/Utilities_PME.mqh"
#include "Modules_PME/RiskManager_PME.mqh"
#include "Modules_PME/TechnicalAnalysis_PME.mqh"
#include "Modules_PME/PositionManager_PME.mqh"
//+------------------------------------------------------------------+
//| Input Parameters |
//+------------------------------------------------------------------+
input bool InpCheckCurrentPositions = true; // Check Current Positions
input bool InpCheckExitConditions = true; // Check Exit Conditions
input bool InpCheckRiskLimits = true; // Check Risk Limits
input bool InpCheckTechnicalSignals = true; // Check Technical Signals
input bool InpShowDetailedReport = true; // Show Detailed Report
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
Print("========================================");
Print(" PME DIAGNOSTIC ANALYSIS");
Print("========================================");
Print("Analyzing why positions might be closing early...\n");
// Initialize components
CUtilities* utils = new CUtilities();
CRiskManager* risk = new CRiskManager();
CTechnicalAnalysis* tech = new CTechnicalAnalysis();
CPositionManager* manager = new CPositionManager();
// Initialize
utils.Initialize(LOG_DEBUG, false);
risk.Initialize(utils, 2.0, 6.0, 20.0);
tech.Initialize(utils);
manager.Initialize(utils, risk, tech, 0);
// 1. CHECK CURRENT POSITIONS
if(InpCheckCurrentPositions)
{
Print("\n--- CURRENT POSITIONS ---");
int total = PositionsTotal();
Print("Total positions: ", total);
for(int i = 0; i < total; i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
{
string symbol = PositionGetString(POSITION_SYMBOL);
ENUM_ORDER_TYPE type = (ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double profit = PositionGetDouble(POSITION_PROFIT);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
// Calculate bars in trade
int bars = Bars(symbol, PERIOD_CURRENT, open_time, TimeCurrent());
Print("\nPosition #", ticket, ":");
Print(" Symbol: ", symbol, " | Type: ", EnumToString(type));
Print(" Volume: ", volume, " | Profit: ", DoubleToString(profit, 2));
Print(" SL: ", sl > 0 ? DoubleToString(sl, 5) : "NONE");
Print(" TP: ", tp > 0 ? DoubleToString(tp, 5) : "NONE");
Print(" Bars in trade: ", bars);
// Check for issues
if(sl == 0) Print(" ⚠️ WARNING: No stop loss!");
if(tp == 0) Print(" ⚠️ WARNING: No take profit!");
if(bars < 5) Print(" ⚠️ WARNING: Very new position (< 5 bars)");
}
}
}
// 2. CHECK EXIT CONDITIONS
if(InpCheckExitConditions)
{
Print("\n--- EXIT CONDITIONS ANALYSIS ---");
for(int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
{
string symbol = PositionGetString(POSITION_SYMBOL);
ENUM_ORDER_TYPE type = (ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);
double entry = PositionGetDouble(POSITION_PRICE_OPEN);
double current = PositionGetDouble(POSITION_PRICE_CURRENT);
double profit = PositionGetDouble(POSITION_PROFIT);
Print("\nPosition #", ticket, " Exit Analysis:");
// Calculate profit in points
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
double profit_points = 0;
if(type == ORDER_TYPE_BUY)
profit_points = (current - entry) / point;
else
profit_points = (entry - current) / point;
Print(" Profit: ", DoubleToString(profit, 2), " | Points: ", DoubleToString(profit_points, 1));
// Check various exit conditions
// Breakeven check (default 20 points)
if(profit_points >= 20 && profit_points < 30)
Print(" 📊 Near breakeven trigger (20 pts)");
// Trail start check (default 30 points)
if(profit_points >= 30 && profit_points < 50)
Print(" 📊 Near trail start trigger (30 pts)");
// Partial close check (default 30 points)
if(profit_points >= 30 && profit_points < 60)
Print(" 📊 In partial close zone (30-60 pts)");
// Check if losing position
if(profit < 0)
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double loss_percent = MathAbs(profit / balance * 100);
Print(" 📉 Losing position: -", DoubleToString(loss_percent, 2), "%");
if(loss_percent > 1.5)
Print(" ⚠️ WARNING: Approaching max loss per trade limit!");
}
}
}
}
// 3. CHECK RISK LIMITS
if(InpCheckRiskLimits)
{
Print("\n--- RISK LIMITS ANALYSIS ---");
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double margin = AccountInfoDouble(ACCOUNT_MARGIN);
double free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
Print("Balance: ", DoubleToString(balance, 2));
Print("Equity: ", DoubleToString(equity, 2));
Print("Margin: ", DoubleToString(margin, 2));
Print("Free Margin: ", DoubleToString(free_margin, 2));
// Check daily loss
double daily_loss = risk.GetDailyLoss();
Print("\nDaily Loss: ", DoubleToString(daily_loss, 2), "%");
if(daily_loss > 4)
Print(" ⚠️ WARNING: High daily loss (>4%)");
if(daily_loss > 6)
Print(" 🚨 CRITICAL: Approaching daily loss limit (6%)!");
// Check drawdown
double drawdown = risk.GetDrawdown();
Print("Drawdown: ", DoubleToString(drawdown, 2), "%");
if(drawdown > 10)
Print(" ⚠️ WARNING: Significant drawdown (>10%)");
if(drawdown > 20)
Print(" 🚨 CRITICAL: Approaching max drawdown limit (20%)!");
// Check total exposure
double total_lots = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByTicket(PositionGetTicket(i)))
total_lots += PositionGetDouble(POSITION_VOLUME);
}
Print("\nTotal Exposure: ", DoubleToString(total_lots, 2), " lots");
// Margin level
if(margin > 0)
{
double margin_level = (equity / margin) * 100;
Print("Margin Level: ", DoubleToString(margin_level, 2), "%");
if(margin_level < 200)
Print(" ⚠️ WARNING: Low margin level!");
}
}
// 4. CHECK TECHNICAL SIGNALS
if(InpCheckTechnicalSignals)
{
Print("\n--- TECHNICAL SIGNALS ANALYSIS ---");
for(int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
{
string symbol = PositionGetString(POSITION_SYMBOL);
ENUM_ORDER_TYPE type = (ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);
double entry = PositionGetDouble(POSITION_PRICE_OPEN);
double current = PositionGetDouble(POSITION_PRICE_CURRENT);
Print("\nPosition #", ticket, " (", symbol, "):");
// Get indicators
double rsi = tech.GetRSI(symbol);
double ma20 = tech.GetMA(symbol);
double atr = tech.GetATR(symbol);
ENUM_MARKET_CONDITION market = tech.GetMarketCondition(symbol);
Print(" RSI: ", DoubleToString(rsi, 1));
Print(" MA20: ", DoubleToString(ma20, 5));
Print(" ATR: ", DoubleToString(atr, 5));
Print(" Market: ", MarketConditionToString(market));
// Check exit conditions
if(type == ORDER_TYPE_BUY)
{
if(rsi > 70)
Print(" 📊 RSI Overbought (>70) - Potential exit signal");
if(rsi > 80)
Print(" 🚨 RSI Extreme Overbought (>80) - Strong exit signal");
if(current < ma20)
Print(" 📊 Price below MA20 - Weakness signal");
// Check if would exit
ENUM_EXIT_REASON exit = tech.CheckExitSignal(symbol, type, entry, current);
if(exit != EXIT_NONE)
Print(" 🚨 TECHNICAL EXIT TRIGGERED: ", ExitReasonToString(exit));
}
else // SELL
{
if(rsi < 30)
Print(" 📊 RSI Oversold (<30) - Potential exit signal");
if(rsi < 20)
Print(" 🚨 RSI Extreme Oversold (<20) - Strong exit signal");
if(current > ma20)
Print(" 📊 Price above MA20 - Weakness signal");
// Check if would exit
ENUM_EXIT_REASON exit = tech.CheckExitSignal(symbol, type, entry, current);
if(exit != EXIT_NONE)
Print(" 🚨 TECHNICAL EXIT TRIGGERED: ", ExitReasonToString(exit));
}
}
}
}
// 5. DETAILED REPORT
if(InpShowDetailedReport)
{
Print("\n========================================");
Print(" DIAGNOSTIC SUMMARY");
Print("========================================");
Print("\n🔍 COMMON CAUSES OF PREMATURE CLOSING:");
Print("\n1. TECHNICAL EXITS:");
Print(" - RSI > 70 (longs) or < 30 (shorts)");
Print(" - Price crosses MA");
Print(" Solution: Disable InpUseTechnicalExits");
Print("\n2. TIME-BASED EXITS:");
Print(" - Max bars in trade (default 100)");
Print(" - Friday close");
Print(" Solution: Disable InpTimeBasedExits");
Print("\n3. RISK LIMITS:");
Print(" - Max loss per trade (2%)");
Print(" - Daily loss limit (6%)");
Print(" - Max drawdown (20%)");
Print(" Solution: Increase risk limits");
Print("\n4. PROFIT PROTECTION:");
Print(" - 50% retracement from peak");
Print(" Solution: Increase protection threshold");
Print("\n📋 RECOMMENDED ACTIONS:");
Print("1. Set InpUseTechnicalExits = false");
Print("2. Set InpTimeBasedExits = false");
Print("3. Set InpFridayClose = false");
Print("4. Increase breakeven trigger to 30+ points");
Print("5. Increase trail start to 50+ points");
Print("6. Review the optimized modules provided");
Print("\n✅ Use the optimized settings in:");
Print(" ERMT_PME_Optimized_Settings.mqh");
}
// Cleanup
delete manager;
delete tech;
delete risk;
delete utils;
Print("\n========================================");
Print(" DIAGNOSTIC COMPLETE");
Print("========================================");
}
//+------------------------------------------------------------------+