mql5/Indicators/QQE_TV_subwindow.mq5

329 lines
12 KiB
MQL5
Raw Permalink Normal View History

Module Integration Summary for External Trade Management Overview To fully integrate the enhanced external trade management system, updates are required to 5 out of 7 existing modules. The updates maintain backward compatibility while adding new functionality for external trade handling. Module Update Requirements 🟢 No Updates Required (2 modules) TechnicalAnalysis.mqh - Already provides necessary calculations EntrySystem.mqh - Only handles EA's own entry signals 🟡 Minor Updates (2 modules) DataTypes.mqh - Add external trade structures and fields Utilities.mqh - Enhanced logging for external trades 🟠 Moderate Updates (3 modules) RiskManager.mqh - Enhanced risk enforcement methods TradeManager.mqh - Improved stop management for externals Dashboard.mqh - Display external trade information Integration Steps Phase 1: Data Structures (DataTypes.mqh) Add ENUM_EXTERNAL_STATUS enumeration Extend ManagedTrade structure with external-specific fields Add ExternalTradeStats structure for metrics Update DashboardConfig with show_external flag Key additions: external_status - Track state of external trade source_name - Identify where trade came from stops_modified - Track if we modified the trade original_sl/tp - Store original values for comparison Phase 2: Risk Management (RiskManager.mqh) Add EnforceRiskRulesEnhanced() method Implement GetExternalExposure() for risk aggregation Add UpdateExternalStats() for tracking Enhance ValidateAndAdjustRiskExternal() method Key features: Separate risk calculation for external trades Cache mechanism for performance Statistical tracking of external positions Smart risk adjustment without closing trades Phase 3: Trade Management (TradeManager.mqh) Add ApplyDefaultStopsEnhanced() with better logic Implement OverrideExternalStops() with smart override Create ManageExternalTrade() with different rules Add ApplyBreakevenExternal() with wider triggers Key features: Smart stop override (only improve, never worsen) Different management rules for external trades Respect minimum broker distances Track modification success/failure rates Phase 4: User Interface (Dashboard.mqh) Add CreateExternalSection() for display area Implement UpdateExternalSection() for real-time updates Add SetCustomText() for flexible display Create ShowExternalTrades() toggle method Key features: Real-time external trade count and risk Color-coded risk warnings List of active external positions Modification statistics display Phase 5: Logging (Utilities.mqh) Add LogExternalTrade() for detailed event logging Create separate CSV log for external trades Enhance GenerateReportEnhanced() with external section Add IdentifyTradeSource() for magic number interpretation Key features: Separate CSV log for external trade events Detailed tracking of all modifications Source identification from magic numbers Enhanced reporting with external statistics
2025-08-27 14:21:02 +01:00
//+------------------------------------------------------------------+
//| QQE_Cross_v6.0_SubWindow.mq5 |
//| QQE Visualization SubWindow |
//| by JustUncleL |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Based on JustUncleL's work"
#property link "https://www.mql5.com"
#property version "6.00"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 5
#property indicator_plots 3
#property indicator_level1 40
#property indicator_level2 50
#property indicator_level3 60
#property indicator_levelcolor clrDarkSlateGray
#property indicator_levelstyle STYLE_DOT
#property indicator_height 150
// Input parameters
input int RSILen = 14; // RSI Length
input int SF = 8; // RSI Smoothing Factor
input double QQEfactor = 5.0; // Fast QQE Factor
input int threshhold = 10; // RSI Threshold
input bool showHistogram = true; // Show QQE Histogram
input color colorBullish = clrLime; // Bullish Color
input color colorNeutral = clrGray; // Neutral Color
input color colorBearish = clrRed; // Bearish Color
// Indicator buffers
double RSIndexBuffer[];
double FastAtrRsiTLBuffer[];
double HistogramBuffer[];
double HistogramColors[];
double RSIBuffer[];
// Internal arrays
double AtrRsi[];
double MaAtrRsi[];
double DeltaFastAtrRsi[];
double longband[];
double shortband[];
int trend[];
// Global variables
int rsi_handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set indicator name
IndicatorSetString(INDICATOR_SHORTNAME, "QQE(" + IntegerToString(RSILen) + "," + IntegerToString(SF) + ")");
// Set buffers
SetIndexBuffer(0, RSIndexBuffer, INDICATOR_DATA);
SetIndexBuffer(1, FastAtrRsiTLBuffer, INDICATOR_DATA);
SetIndexBuffer(2, HistogramBuffer, INDICATOR_DATA);
SetIndexBuffer(3, HistogramColors, INDICATOR_COLOR_INDEX);
SetIndexBuffer(4, RSIBuffer, INDICATOR_CALCULATIONS);
// Configure RSI Line
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrYellow);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 2);
PlotIndexSetString(0, PLOT_LABEL, "QQE RSI");
// Configure Fast ATR Line
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrAqua);
PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE_DASH);
PlotIndexSetString(1, PLOT_LABEL, "QQE Line");
// Configure Histogram
PlotIndexSetInteger(2, PLOT_DRAW_TYPE, showHistogram ? DRAW_COLOR_HISTOGRAM : DRAW_NONE);
PlotIndexSetInteger(2, PLOT_LINE_WIDTH, 2);
PlotIndexSetString(2, PLOT_LABEL, "QQE Histogram");
PlotIndexSetInteger(2, PLOT_COLOR_INDEXES, 3);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, colorBullish);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, 1, colorNeutral);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, 2, colorBearish);
// Set arrays as series
ArraySetAsSeries(RSIndexBuffer, true);
ArraySetAsSeries(FastAtrRsiTLBuffer, true);
ArraySetAsSeries(HistogramBuffer, true);
ArraySetAsSeries(HistogramColors, true);
ArraySetAsSeries(RSIBuffer, true);
// Create RSI handle
rsi_handle = iRSI(NULL, 0, RSILen, PRICE_CLOSE);
if(rsi_handle == INVALID_HANDLE)
{
Print("Failed to create RSI handle");
return(INIT_FAILED);
}
// Resize arrays
int bars = Bars(_Symbol, _Period);
ArrayResize(AtrRsi, bars);
ArrayResize(MaAtrRsi, bars);
ArrayResize(DeltaFastAtrRsi, bars);
ArrayResize(longband, bars);
ArrayResize(shortband, bars);
ArrayResize(trend, bars);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(rsi_handle);
}
//+------------------------------------------------------------------+
//| Calculate EMA |
//+------------------------------------------------------------------+
double CalculateEMA(const double &price[], int period, int shift, double prev_ema)
{
if(shift >= ArraySize(price) - 1) return price[shift];
double alpha = 2.0 / (period + 1);
if(prev_ema == 0)
{
// Calculate SMA for first value
double sum = 0;
for(int i = 0; i < period && shift + i < ArraySize(price); i++)
sum += price[shift + i];
return sum / period;
}
return alpha * price[shift] + (1 - alpha) * prev_ema;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total < RSILen + SF + 10) return(0);
// Copy RSI data
if(CopyBuffer(rsi_handle, 0, 0, rates_total, RSIBuffer) <= 0) return(0);
int limit = rates_total - prev_calculated;
if(prev_calculated > 0) limit++;
// Calculate QQE
int Wilders_Period = RSILen * 2 - 1;
// First pass: Calculate RSIndex
for(int i = rates_total - 1; i >= 0; i--)
{
if(i == rates_total - 1)
RSIndexBuffer[i] = RSIBuffer[i];
else
RSIndexBuffer[i] = CalculateEMA(RSIBuffer, SF, i, RSIndexBuffer[i+1]);
// Calculate AtrRsi
if(i < rates_total - 1)
AtrRsi[i] = MathAbs(RSIndexBuffer[i+1] - RSIndexBuffer[i]);
else
AtrRsi[i] = 0;
}
// Second pass: Calculate MaAtrRsi and DeltaFastAtrRsi
for(int i = rates_total - 1; i >= 0; i--)
{
if(i == rates_total - 1)
{
MaAtrRsi[i] = AtrRsi[i];
DeltaFastAtrRsi[i] = AtrRsi[i] * QQEfactor;
}
else
{
MaAtrRsi[i] = CalculateEMA(AtrRsi, Wilders_Period, i, MaAtrRsi[i+1]);
double temp = CalculateEMA(MaAtrRsi, Wilders_Period, i,
(i < rates_total - 2 ? DeltaFastAtrRsi[i+1] / QQEfactor : MaAtrRsi[i]));
DeltaFastAtrRsi[i] = temp * QQEfactor;
}
}
// Third pass: Calculate bands and trend
for(int i = rates_total - 1; i >= 0; i--)
{
double newshortband = RSIndexBuffer[i] + DeltaFastAtrRsi[i];
double newlongband = RSIndexBuffer[i] - DeltaFastAtrRsi[i];
if(i == rates_total - 1)
{
longband[i] = newlongband;
shortband[i] = newshortband;
trend[i] = 1;
}
else
{
// Longband calculation
if(RSIndexBuffer[i+1] > longband[i+1] && RSIndexBuffer[i] > longband[i+1])
longband[i] = MathMax(longband[i+1], newlongband);
else
longband[i] = newlongband;
// Shortband calculation
if(RSIndexBuffer[i+1] < shortband[i+1] && RSIndexBuffer[i] < shortband[i+1])
shortband[i] = MathMin(shortband[i+1], newshortband);
else
shortband[i] = newshortband;
// Trend calculation
if(RSIndexBuffer[i] > shortband[i+1])
trend[i] = 1;
else if(RSIndexBuffer[i] < longband[i+1])
trend[i] = -1;
else
trend[i] = trend[i+1];
}
// Set Fast ATR line
FastAtrRsiTLBuffer[i] = (trend[i] == 1) ? longband[i] : shortband[i];
// Set Histogram
HistogramBuffer[i] = RSIndexBuffer[i];
// Color the histogram based on threshold levels
if(RSIndexBuffer[i] > 50 + threshhold)
HistogramColors[i] = 0; // Bullish
else if(RSIndexBuffer[i] < 50 - threshhold)
HistogramColors[i] = 2; // Bearish
else
HistogramColors[i] = 1; // Neutral
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Get QQE values for external use |
//+------------------------------------------------------------------+
bool GetQQEValues(int shift, double &rsi_value, double &qqe_line, int &qqe_trend)
{
if(shift < 0 || shift >= ArraySize(RSIndexBuffer))
return false;
rsi_value = RSIndexBuffer[shift];
qqe_line = FastAtrRsiTLBuffer[shift];
qqe_trend = trend[shift];
return true;
}
//+------------------------------------------------------------------+
//| Check for QQE cross signals |
//+------------------------------------------------------------------+
int CheckQQESignal(int shift)
{
if(shift < 1 || shift >= ArraySize(RSIndexBuffer))
return 0;
// Check for bullish cross
if(RSIndexBuffer[shift] > FastAtrRsiTLBuffer[shift] &&
RSIndexBuffer[shift+1] <= FastAtrRsiTLBuffer[shift+1])
return 1;
// Check for bearish cross
if(RSIndexBuffer[shift] < FastAtrRsiTLBuffer[shift] &&
RSIndexBuffer[shift+1] >= FastAtrRsiTLBuffer[shift+1])
return -1;
return 0;
}
//+------------------------------------------------------------------+
//| Check for threshold crosses |
//+------------------------------------------------------------------+
int CheckThresholdCross(int shift)
{
if(shift < 1 || shift >= ArraySize(RSIndexBuffer))
return 0;
double upper_threshold = 50 + threshhold;
double lower_threshold = 50 - threshhold;
// Check for exit above upper threshold
if(RSIndexBuffer[shift] > upper_threshold &&
RSIndexBuffer[shift+1] <= upper_threshold)
return 1;
// Check for exit below lower threshold
if(RSIndexBuffer[shift] < lower_threshold &&
RSIndexBuffer[shift+1] >= lower_threshold)
return -1;
return 0;
}
//+------------------------------------------------------------------+
//| Check for zero line crosses |
//+------------------------------------------------------------------+
int CheckZeroCross(int shift)
{
if(shift < 1 || shift >= ArraySize(RSIndexBuffer))
return 0;
// Check for bullish zero cross
if(RSIndexBuffer[shift] > 50 && RSIndexBuffer[shift+1] <= 50)
return 1;
// Check for bearish zero cross
if(RSIndexBuffer[shift] < 50 && RSIndexBuffer[shift+1] >= 50)
return -1;
return 0;
}
//+------------------------------------------------------------------+