mql5/Indicators/QQE_TV_main.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

746 lines
No EOL
29 KiB
MQL5

//+------------------------------------------------------------------+
//| QQE_Cross_v6.0_Main.mq5 |
//| Converted from Pine Script v3 |
//| by JustUncleL |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Based on JustUncleL's work"
#property link "https://www.mql5.com"
#property version "6.00"
#property indicator_chart_window
#property indicator_buffers 22
#property indicator_plots 12
// 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 int anchor = 4; // Relative TimeFrame Multiplier for Second MA Ribbon
// MA parameters
input ENUM_MA_METHOD type1 = MODE_EMA; // Fast MA Type
input int len1 = 16; // Fast MA Length
input ENUM_MA_METHOD type2 = MODE_EMA; // Medium MA Type
input int len2 = 21; // Medium MA Length
input ENUM_MA_METHOD type3 = MODE_EMA; // Slow MA Type
input int len3 = 26; // Slow MA Length
// Display options
input bool showAvgs = true; // Show Moving Average Lines
input bool dynamicMAColors = true; // Use Dynamic MA Colors (Bullish/Bearish)
input bool colorBars = true; // Color Price Bars by Trend
input bool sQQEx = true; // Show QQE Signal crosses
input bool sQQEz = false; // Show QQE Zero crosses
input bool sQQEc = true; // Show QQE Threshold Channel Exits
// Color inputs for MAs (when not using dynamic colors)
input color colorMAFast = clrLime; // Fast MA Color
input color colorMAMedium = clrYellow; // Medium MA Color
input color colorMASlow = clrRed; // Slow MA Color
input color colorMAFastAlt = clrLightGreen; // Fast MA Alt Color
input color colorMAMediumAlt = clrGold; // Medium MA Alt Color
input color colorMASlowAlt = clrCrimson; // Slow MA Alt Color
// Dynamic color inputs (when dynamicMAColors = true)
input color colorMABullish = clrLime; // MA Bullish Color
input color colorMABearish = clrRed; // MA Bearish Color
input color colorMANeutral = clrGray; // MA Neutral Color
// Color inputs for signals
input color colorBuySignal = clrLime; // Buy Signal Color
input color colorSellSignal = clrRed; // Sell Signal Color
input color colorMAGreen = clrAqua; // MA Turned Green Color
input color colorMABlue = clrBlue; // MA Turned Red Color
input color colorTPSignal = clrViolet; // Take Profit Color
// Signal options
input string tradeSignal = "XC"; // Select which QQE signal to Buy/Sell (XC/XQ/XZ)
input string closeSignal = "XQ"; // Select which QQE signal to Close Order (XC/XQ/XZ)
input bool xfilter = true; // Filter XQ Buy/Sell Orders by Threshold
input bool filter = false; // Use Moving Average Filter
input bool dfilter = true; // Use Trend Directional Filter
input bool ufirst = false; // Only Alert First Buy/Sell in a new Trend
// Indicator buffers
double ma_fastBuffer[];
double ma_mediumBuffer[];
double ma_slowBuffer[];
double ma_fast_altBuffer[];
double ma_medium_altBuffer[];
double ma_slow_altBuffer[];
double BuySignalBuffer[];
double SellSignalBuffer[];
double TurnedAquaBuffer[];
double TurnedBlueBuffer[];
double TPLongBuffer[];
double TPShortBuffer[];
// Color index buffers for dynamic MA colors
double ma_mediumColorBuffer[];
double ma_medium_altColorBuffer[];
// Calculation buffers
double RSIBuffer[];
double RSIndexBuffer[];
double FastAtrRsiTLBuffer[];
double longbandBuffer[];
double shortbandBuffer[];
double CloseLongBuffer[];
double CloseShortBuffer[];
double ColorBuffer[];
// Global variables
int rsi_handle;
int trend[];
int direction[];
int altDirection[];
double AtrRsi[];
double MaAtrRsi[];
double DeltaFastAtrRsi[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set indicator name
IndicatorSetString(INDICATOR_SHORTNAME, "QQE Cross v6.0");
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
// Set buffer mapping
int idx = 0;
// Data buffers
SetIndexBuffer(idx++, ma_fastBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, ma_mediumBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, ma_slowBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, ma_fast_altBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, ma_medium_altBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, ma_slow_altBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, BuySignalBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, SellSignalBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, TurnedAquaBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, TurnedBlueBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, TPLongBuffer, INDICATOR_DATA);
SetIndexBuffer(idx++, TPShortBuffer, INDICATOR_DATA);
// Color buffers for dynamic MA colors
SetIndexBuffer(idx++, ma_mediumColorBuffer, INDICATOR_COLOR_INDEX);
SetIndexBuffer(idx++, ma_medium_altColorBuffer, INDICATOR_COLOR_INDEX);
// Calculation buffers
SetIndexBuffer(idx++, RSIBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, RSIndexBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, FastAtrRsiTLBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, longbandBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, shortbandBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, CloseLongBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, CloseShortBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(idx++, ColorBuffer, INDICATOR_CALCULATIONS);
// Configure MA plots
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, showAvgs ? DRAW_LINE : DRAW_NONE);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, colorMAFast);
PlotIndexSetString(0, PLOT_LABEL, "MA Fast");
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, showAvgs ? (dynamicMAColors ? DRAW_COLOR_LINE : DRAW_LINE) : DRAW_NONE);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, colorMAMedium);
PlotIndexSetInteger(1, PLOT_LINE_WIDTH, 2);
PlotIndexSetString(1, PLOT_LABEL, "MA Medium");
if(dynamicMAColors)
{
PlotIndexSetInteger(1, PLOT_COLOR_INDEXES, 3);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 0, colorMABullish);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 1, colorMANeutral);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 2, colorMABearish);
}
PlotIndexSetInteger(2, PLOT_DRAW_TYPE, showAvgs ? DRAW_LINE : DRAW_NONE);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, colorMASlow);
PlotIndexSetString(2, PLOT_LABEL, "MA Slow");
PlotIndexSetInteger(3, PLOT_DRAW_TYPE, showAvgs && anchor > 1 ? DRAW_LINE : DRAW_NONE);
PlotIndexSetInteger(3, PLOT_LINE_COLOR, colorMAFastAlt);
PlotIndexSetInteger(3, PLOT_LINE_STYLE, STYLE_DASH);
PlotIndexSetString(3, PLOT_LABEL, "MA Fast Alt");
PlotIndexSetInteger(4, PLOT_DRAW_TYPE, showAvgs && anchor > 1 ? (dynamicMAColors ? DRAW_COLOR_LINE : DRAW_LINE) : DRAW_NONE);
PlotIndexSetInteger(4, PLOT_LINE_COLOR, colorMAMediumAlt);
PlotIndexSetInteger(4, PLOT_LINE_WIDTH, 2);
PlotIndexSetInteger(4, PLOT_LINE_STYLE, STYLE_DASH);
PlotIndexSetString(4, PLOT_LABEL, "MA Medium Alt");
if(dynamicMAColors)
{
PlotIndexSetInteger(4, PLOT_COLOR_INDEXES, 3);
PlotIndexSetInteger(4, PLOT_LINE_COLOR, 0, colorMABullish);
PlotIndexSetInteger(4, PLOT_LINE_COLOR, 1, colorMANeutral);
PlotIndexSetInteger(4, PLOT_LINE_COLOR, 2, colorMABearish);
}
PlotIndexSetInteger(5, PLOT_DRAW_TYPE, showAvgs && anchor > 1 ? DRAW_LINE : DRAW_NONE);
PlotIndexSetInteger(5, PLOT_LINE_COLOR, colorMASlowAlt);
PlotIndexSetInteger(5, PLOT_LINE_STYLE, STYLE_DASH);
PlotIndexSetString(5, PLOT_LABEL, "MA Slow Alt");
// Signal arrows
PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(6, PLOT_ARROW, 233);
PlotIndexSetInteger(6, PLOT_LINE_COLOR, colorBuySignal);
PlotIndexSetInteger(6, PLOT_LINE_WIDTH, 2);
PlotIndexSetString(6, PLOT_LABEL, "Buy Signal");
PlotIndexSetInteger(7, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(7, PLOT_ARROW, 234);
PlotIndexSetInteger(7, PLOT_LINE_COLOR, colorSellSignal);
PlotIndexSetInteger(7, PLOT_LINE_WIDTH, 2);
PlotIndexSetString(7, PLOT_LABEL, "Sell Signal");
PlotIndexSetInteger(8, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(8, PLOT_ARROW, 233);
PlotIndexSetInteger(8, PLOT_LINE_COLOR, colorMAGreen);
PlotIndexSetString(8, PLOT_LABEL, "MA Turned Green");
PlotIndexSetInteger(9, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(9, PLOT_ARROW, 234);
PlotIndexSetInteger(9, PLOT_LINE_COLOR, colorMABlue);
PlotIndexSetString(9, PLOT_LABEL, "MA Turned Red");
PlotIndexSetInteger(10, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(10, PLOT_ARROW, 116);
PlotIndexSetInteger(10, PLOT_LINE_COLOR, colorTPSignal);
PlotIndexSetString(10, PLOT_LABEL, "Take Profit Long");
PlotIndexSetInteger(11, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(11, PLOT_ARROW, 116);
PlotIndexSetInteger(11, PLOT_LINE_COLOR, colorTPSignal);
PlotIndexSetString(11, PLOT_LABEL, "Take Profit Short");
// Initialize arrays
ArraySetAsSeries(ma_fastBuffer, true);
ArraySetAsSeries(ma_mediumBuffer, true);
ArraySetAsSeries(ma_slowBuffer, true);
ArraySetAsSeries(ma_fast_altBuffer, true);
ArraySetAsSeries(ma_medium_altBuffer, true);
ArraySetAsSeries(ma_slow_altBuffer, true);
ArraySetAsSeries(BuySignalBuffer, true);
ArraySetAsSeries(SellSignalBuffer, true);
ArraySetAsSeries(TurnedAquaBuffer, true);
ArraySetAsSeries(TurnedBlueBuffer, true);
ArraySetAsSeries(TPLongBuffer, true);
ArraySetAsSeries(TPShortBuffer, true);
ArraySetAsSeries(ma_mediumColorBuffer, true);
ArraySetAsSeries(ma_medium_altColorBuffer, true);
ArraySetAsSeries(RSIBuffer, true);
ArraySetAsSeries(RSIndexBuffer, true);
ArraySetAsSeries(FastAtrRsiTLBuffer, true);
ArraySetAsSeries(longbandBuffer, true);
ArraySetAsSeries(shortbandBuffer, true);
ArraySetAsSeries(CloseLongBuffer, true);
ArraySetAsSeries(CloseShortBuffer, true);
ArraySetAsSeries(ColorBuffer, true);
// Create RSI handle
rsi_handle = iRSI(NULL, 0, RSILen, PRICE_CLOSE);
if(rsi_handle == INVALID_HANDLE)
{
Print("Error creating RSI handle");
return(INIT_FAILED);
}
// Resize arrays
int bars = Bars(_Symbol, _Period);
ArrayResize(trend, bars);
ArrayResize(direction, bars);
ArrayResize(altDirection, bars);
ArrayResize(AtrRsi, bars);
ArrayResize(MaAtrRsi, bars);
ArrayResize(DeltaFastAtrRsi, 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;
}
//+------------------------------------------------------------------+
//| Calculate Moving Average |
//+------------------------------------------------------------------+
double CalculateMA(const double &price[], ENUM_MA_METHOD method, int period, int shift)
{
double ma_values[];
ArraySetAsSeries(ma_values, true);
int copied = 0;
switch(method)
{
case MODE_SMA:
copied = iMA(_Symbol, _Period, period, 0, MODE_SMA, PRICE_CLOSE);
break;
case MODE_EMA:
copied = iMA(_Symbol, _Period, period, 0, MODE_EMA, PRICE_CLOSE);
break;
case MODE_SMMA:
copied = iMA(_Symbol, _Period, period, 0, MODE_SMMA, PRICE_CLOSE);
break;
case MODE_LWMA:
copied = iMA(_Symbol, _Period, period, 0, MODE_LWMA, PRICE_CLOSE);
break;
}
if(copied > 0 && shift < ArraySize(price))
{
if(CopyBuffer(copied, 0, shift, 1, ma_values) > 0)
return ma_values[0];
}
// Fallback to manual calculation
if(method == MODE_SMA)
{
double sum = 0;
for(int i = 0; i < period && shift + i < ArraySize(price); i++)
sum += price[shift + i];
return sum / period;
}
else if(method == MODE_EMA)
{
static double prev_ema = 0;
if(shift == ArraySize(price) - 1) prev_ema = 0;
prev_ema = CalculateEMA(price, period, shift, prev_ema);
return prev_ema;
}
return price[shift];
}
//+------------------------------------------------------------------+
//| Check if value is rising |
//+------------------------------------------------------------------+
bool IsRising(const double &buffer[], int shift, int period)
{
if(shift + period >= ArraySize(buffer)) return false;
return buffer[shift] > buffer[shift + period];
}
//+------------------------------------------------------------------+
//| Check if value is falling |
//+------------------------------------------------------------------+
bool IsFalling(const double &buffer[], int shift, int period)
{
if(shift + period >= ArraySize(buffer)) return false;
return buffer[shift] < buffer[shift + period];
}
//+------------------------------------------------------------------+
//| 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);
ArraySetAsSeries(close, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
int limit = rates_total - prev_calculated;
if(prev_calculated > 0) limit++;
// Calculate QQE
int Wilders_Period = RSILen * 2 - 1;
for(int i = rates_total - 1; i >= 0; i--)
{
// Calculate RSIndex (EMA of RSI)
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;
}
// 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;
}
}
// 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)
{
longbandBuffer[i] = newlongband;
shortbandBuffer[i] = newshortband;
trend[i] = 1;
}
else
{
// Longband calculation
if(RSIndexBuffer[i+1] > longbandBuffer[i+1] && RSIndexBuffer[i] > longbandBuffer[i+1])
longbandBuffer[i] = MathMax(longbandBuffer[i+1], newlongband);
else
longbandBuffer[i] = newlongband;
// Shortband calculation
if(RSIndexBuffer[i+1] < shortbandBuffer[i+1] && RSIndexBuffer[i] < shortbandBuffer[i+1])
shortbandBuffer[i] = MathMin(shortbandBuffer[i+1], newshortband);
else
shortbandBuffer[i] = newshortband;
// Trend calculation
if(RSIndexBuffer[i] > shortbandBuffer[i+1])
trend[i] = 1;
else if(RSIndexBuffer[i] < longbandBuffer[i+1])
trend[i] = -1;
else
trend[i] = trend[i+1];
}
FastAtrRsiTLBuffer[i] = (trend[i] == 1) ? longbandBuffer[i] : shortbandBuffer[i];
}
// Calculate Moving Averages
for(int i = rates_total - 1; i >= 0; i--)
{
ma_fastBuffer[i] = CalculateMA(close, type1, len1, i);
ma_mediumBuffer[i] = CalculateMA(close, type2, len2, i);
ma_slowBuffer[i] = CalculateMA(close, type3, len3, i);
if(anchor > 1)
{
ma_fast_altBuffer[i] = CalculateMA(close, type1, len1 * anchor, i);
ma_medium_altBuffer[i] = CalculateMA(close, type2, len2 * anchor, i);
ma_slow_altBuffer[i] = CalculateMA(close, type3, len3 * anchor, i);
}
// Direction
direction[i] = IsRising(ma_mediumBuffer, i, 3) ? 1 : (IsFalling(ma_mediumBuffer, i, 3) ? -1 : 0);
if(anchor > 1)
altDirection[i] = IsRising(ma_medium_altBuffer, i, 3) ? 1 : (IsFalling(ma_medium_altBuffer, i, 3) ? -1 : 0);
}
// Calculate signals
static int QQExlong = 0, QQExshort = 0;
static int QQEzlong = 0, QQEzshort = 0;
static int QQEclong = 0, QQEcshort = 0;
static int buy_ = 0, sell_ = 0;
static int Buy = 0, Sell = 0;
static int tradestate = 0;
for(int i = limit - 1; i >= 0; i--)
{
// Initialize buffers
BuySignalBuffer[i] = EMPTY_VALUE;
SellSignalBuffer[i] = EMPTY_VALUE;
TurnedAquaBuffer[i] = EMPTY_VALUE;
TurnedBlueBuffer[i] = EMPTY_VALUE;
TPLongBuffer[i] = EMPTY_VALUE;
TPShortBuffer[i] = EMPTY_VALUE;
if(i >= rates_total - 2) continue;
// QQE Crosses
QQExlong = (FastAtrRsiTLBuffer[i] < RSIndexBuffer[i]) ? QQExlong + 1 : 0;
QQExshort = (FastAtrRsiTLBuffer[i] > RSIndexBuffer[i]) ? QQExshort + 1 : 0;
// Zero crosses
QQEzlong = (RSIndexBuffer[i] >= 50) ? QQEzlong + 1 : 0;
QQEzshort = (RSIndexBuffer[i] < 50) ? QQEzshort + 1 : 0;
// Threshold channel crosses
QQEclong = (RSIndexBuffer[i] > (50 + threshhold)) ? QQEclong + 1 : 0;
QQEcshort = (RSIndexBuffer[i] < (50 - threshhold)) ? QQEcshort + 1 : 0;
// Filter conditions
bool QQEflong = true;
bool QQEfshort = true;
if(filter)
{
if(anchor == 1)
{
QQEflong = (close[i] > ma_mediumBuffer[i] && ma_mediumBuffer[i] > ma_slowBuffer[i] && ma_fastBuffer[i] > ma_mediumBuffer[i]);
QQEfshort = (close[i] < ma_mediumBuffer[i] && ma_mediumBuffer[i] < ma_slowBuffer[i] && ma_fastBuffer[i] < ma_mediumBuffer[i]);
}
else
{
QQEflong = (ma_mediumBuffer[i] > ma_medium_altBuffer[i] && close[i] > ma_fastBuffer[i] && ma_fastBuffer[i] > ma_mediumBuffer[i]);
QQEfshort = (ma_mediumBuffer[i] < ma_medium_altBuffer[i] && close[i] < ma_fastBuffer[i] && ma_fastBuffer[i] < ma_mediumBuffer[i]);
}
}
if(dfilter)
{
if(anchor == 1)
{
QQEflong = QQEflong && (direction[i] > 0);
QQEfshort = QQEfshort && (direction[i] < 0);
}
else
{
QQEflong = QQEflong && (direction[i] > 0 && altDirection[i] > 0 && close[i] > ma_mediumBuffer[i]);
QQEfshort = QQEfshort && (direction[i] < 0 && altDirection[i] < 0 && close[i] < ma_mediumBuffer[i]);
}
}
bool QQExfilter = (!xfilter || RSIndexBuffer[i] > (50 + threshhold) || RSIndexBuffer[i] < (50 - threshhold));
// Buy/Sell signals
if(tradeSignal == "XC")
{
buy_ = (QQEclong == 1 && QQEflong) ? buy_ + 1 : 0;
sell_ = (QQEcshort == 1 && QQEfshort) ? sell_ + 1 : 0;
}
else if(tradeSignal == "XQ")
{
buy_ = (QQExlong == 1 && QQEflong && QQExfilter) ? buy_ + 1 : 0;
sell_ = (QQExshort == 1 && QQEfshort && QQExfilter) ? sell_ + 1 : 0;
}
else if(tradeSignal == "XZ")
{
buy_ = (QQEzlong == 1 && QQEflong) ? buy_ + 1 : 0;
sell_ = (QQEzshort == 1 && QQEfshort) ? sell_ + 1 : 0;
}
// First buy/sell in trend
Buy = (sell_ > 0) ? 0 : ((buy_ == 1 || Buy > 0) ? Buy + 1 : Buy);
Sell = (buy_ > 0) ? 0 : ((sell_ == 1 || Sell > 0) ? Sell + 1 : Sell);
int buy = ufirst ? Buy : buy_;
int sell = ufirst ? Sell : sell_;
// Trade state management
bool isLong = false;
bool isShort = false;
if(tradestate == 0)
{
if(buy == 1)
{
tradestate = 1;
isLong = true;
}
else if(sell == 1)
{
tradestate = 2;
isShort = true;
}
}
else if(tradestate == 1)
{
// Check for close long conditions
if(closeSignal == "XQ" && QQExshort == 1)
tradestate = 0;
else if(closeSignal == "XC" && QQEcshort == 1)
tradestate = 0;
else if(closeSignal == "XZ" && QQEzshort == 1)
tradestate = 0;
}
else if(tradestate == 2)
{
// Check for close short conditions
if(closeSignal == "XQ" && QQExlong == 1)
tradestate = 0;
else if(closeSignal == "XC" && QQEclong == 1)
tradestate = 0;
else if(closeSignal == "XZ" && QQEzlong == 1)
tradestate = 0;
}
// Set signals
if(isLong && i > 0)
BuySignalBuffer[i-1] = low[i-1] - 10 * _Point;
if(isShort && i > 0)
SellSignalBuffer[i-1] = high[i-1] + 10 * _Point;
// MA color changes
if(i < rates_total - 2 && anchor > 1)
{
bool turned_aqua = (altDirection[i+1] < 0 && altDirection[i] > 0);
bool turned_blue = (altDirection[i+1] > 0 && altDirection[i] < 0);
if(turned_aqua)
TurnedAquaBuffer[i] = low[i] - 20 * _Point;
if(turned_blue)
TurnedBlueBuffer[i] = high[i] + 20 * _Point;
// Take profit signals
bool take_profit_long = ma_slowBuffer[i] > ma_fast_altBuffer[i] &&
ma_slowBuffer[i] > ma_slow_altBuffer[i] &&
direction[i+1] > 0 && direction[i] < 0;
bool take_profit_short = ma_slowBuffer[i] < ma_fast_altBuffer[i] &&
ma_slowBuffer[i] < ma_slow_altBuffer[i] &&
direction[i+1] < 0 && direction[i] > 0;
if(take_profit_long)
TPLongBuffer[i] = high[i] + 30 * _Point;
if(take_profit_short)
TPShortBuffer[i] = low[i] - 30 * _Point;
}
// Update color buffer for bar coloring
if(anchor > 1)
ColorBuffer[i] = altDirection[i] < 0 ? 0 : 1; // 0 for red, 1 for green
// Set dynamic MA colors based on direction
if(dynamicMAColors)
{
// Medium MA color
if(direction[i] > 0)
ma_mediumColorBuffer[i] = 0; // Bullish
else if(direction[i] < 0)
ma_mediumColorBuffer[i] = 2; // Bearish
else
ma_mediumColorBuffer[i] = 1; // Neutral
// Medium Alt MA color
if(anchor > 1)
{
if(altDirection[i] > 0)
ma_medium_altColorBuffer[i] = 0; // Bullish
else if(altDirection[i] < 0)
ma_medium_altColorBuffer[i] = 2; // Bearish
else
ma_medium_altColorBuffer[i] = 1; // Neutral
}
}
// Color price bars if enabled
if(colorBars && anchor > 1 && i == 0)
{
if(altDirection[i] > 0)
ChartSetInteger(ChartID(), CHART_COLOR_CANDLE_BULL, colorMABullish);
else if(altDirection[i] < 0)
ChartSetInteger(ChartID(), CHART_COLOR_CANDLE_BEAR, colorMABearish);
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Get QQE signals for Expert Advisors |
//+------------------------------------------------------------------+
double GetQQEValue(int shift, int buffer_num)
{
// buffer_num: 0=RSIndex, 1=FastAtrRsiTL, 2=Signal State
switch(buffer_num)
{
case 0: return RSIndexBuffer[shift];
case 1: return FastAtrRsiTLBuffer[shift];
case 2: return trend[shift];
default: return 0;
}
}
//New Features Added:
//1. Dynamic MA Colors Option
//
//New input: dynamicMAColors (default: true)
//When enabled, the Medium MA lines change color based on their direction
//When disabled, MAs use the fixed colors you set
//
//2. Color Bar Option
//
//New input: colorBars (default: true)
//Colors the price bars based on the alternative MA ribbon direction
//Matches the original Pine Script's barcolor() function
//
//3. Dynamic Color Scheme
//
//colorMABullish - Color when MA is rising (default: Lime)
//colorMABearish - Color when MA is falling (default: Red)
//colorMANeutral - Color when MA is flat (default: Gray)
//
//How It Works:
//MA Ribbon Colors:
//
//Medium MA (21 EMA):
//
//Green/Lime: When rising (bullish)
//Red: When falling (bearish)
//Gray: When flat (neutral)
//
//
//Medium Alternative MA (84 EMA) (when anchor > 1):
//
//Same color logic as above
//Helps identify longer-term trend
//
//
//
//Visual Signals:
//
//Colored MA lines show immediate trend direction
//Price bars change color based on the longer-term trend
//Arrow signals still appear for MA direction changes
//Take profit signals when trends diverge
//
//Benefits:
//
//Quick trend identification: Instantly see if MAs are bullish or bearish
//Multi-timeframe confirmation: Both regular and alternative MAs show their own trends
//Clean visual hierarchy: Important MAs change color while others stay fixed
//Matches original Pine Script: Now includes the bar coloring feature
//
//This makes it much easier to:
//
//Identify trend changes quickly
//Confirm trade direction with MA alignment
//Spot divergences between timeframes
//Trade with the overall trend
//+------------------------------------------------------------------+