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