mql5/Indicators/QQE_TV_main.mq5

746 lines
29 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_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
//+------------------------------------------------------------------+