mql5/Indicators/QQE_TV_subwindow.mq5
darashikoh 0fb1bd1b0a 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

329 lines
No EOL
12 KiB
MQL5

//+------------------------------------------------------------------+
//| 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;
}
//+------------------------------------------------------------------+