Files
mql-trading-bots/MultiSignal_Confluence.mq5
Garfield 74308b38e7 Initial commit: MQL Trading Bots
- MultiSignal Confluence EA v1.11 (stop loss bug fixed)
- Harmonic Pattern Finder v2 (optimized)
- Candlestick Pattern EA (fixed)
- Pivot Fade EA v4 (fixed)
- Bot series (10001, 10002, EnhancedEA)

Performance: ~19% return in 2 months on 00k account
2026-03-21 18:39:48 -04:00

481 lines
16 KiB
Plaintext

//+------------------------------------------------------------------+
//| MultiSignal_Confluence.mq5 |
//| Combined Pivot + Harmonic + Candlestick |
//| High Probability Trader |
//| FIXED VERSION - Actually generates signals |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Abbey Road Tech"
#property link "https://www.abbeyroadtech.com"
#property version "1.10"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 6
//--- Plot settings
#property indicator_label1 "Pivot_Signal"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_label2 "Harmonic_Signal"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
#property indicator_label3 "Candlestick_Signal"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrOrange
#property indicator_style3 STYLE_SOLID
#property indicator_width3 2
#property indicator_label4 "Confluence_Buy"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrLime
#property indicator_style4 STYLE_SOLID
#property indicator_width4 3
#property indicator_label5 "Confluence_Sell"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrRed
#property indicator_style5 STYLE_SOLID
#property indicator_width5 3
#property indicator_label6 "Confluence_Strength"
#property indicator_type6 DRAW_NONE
//--- Input Parameters
input group "=== Confluence Settings ==="
input int InpMinConfluence = 2; // Min signals for alert (1-3)
input bool InpRequireTrendAlignment = true; // All signals must agree
input int InpMaxSignalAge = 3; // Max bars for signal validity
input bool InpDebugMode = false; // Show debug prints
input group "=== Pivot Settings ==="
input bool InpUsePivots = true; // Enable pivot signals
input double InpPivotThreshold = 0.0010; // Min distance from pivot
input group "=== Harmonic Settings ==="
input bool InpUseHarmonics = true; // Enable harmonic signals
input double InpHarmonicSlack = 0.02; // Pattern tolerance
input group "=== Candlestick Settings ==="
input bool InpUseCandlesticks = true; // Enable candlestick signals
input double InpMinBodyRatio = 0.3; // Min body/wick ratio
//--- Buffers for display
double PivotSignalBuffer[];
double HarmonicSignalBuffer[];
double CandleSignalBuffer[];
double ConfluenceBuyBuffer[];
double ConfluenceSellBuffer[];
double ConfluenceStrengthBuffer[];
//--- Pivot levels
double pivotP, pivotR1, pivotR2, pivotS1, pivotS2;
datetime lastPivotCalc = 0;
//--- Global signal flags for current bar
int currentBuySignals = 0;
int currentSellSignals = 0;
string signalSources = "";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Set indicator buffers
SetIndexBuffer(0, PivotSignalBuffer, INDICATOR_DATA);
SetIndexBuffer(1, HarmonicSignalBuffer, INDICATOR_DATA);
SetIndexBuffer(2, CandleSignalBuffer, INDICATOR_DATA);
SetIndexBuffer(3, ConfluenceBuyBuffer, INDICATOR_DATA);
SetIndexBuffer(4, ConfluenceSellBuffer, INDICATOR_DATA);
SetIndexBuffer(5, ConfluenceStrengthBuffer, INDICATOR_DATA);
//--- Set arrow codes
PlotIndexSetInteger(0, PLOT_ARROW, 159);
PlotIndexSetInteger(1, PLOT_ARROW, 233);
PlotIndexSetInteger(2, PLOT_ARROW, 234);
PlotIndexSetInteger(3, PLOT_ARROW, 233);
PlotIndexSetInteger(4, PLOT_ARROW, 234);
//--- Initialize buffers
ArrayInitialize(PivotSignalBuffer, EMPTY_VALUE);
ArrayInitialize(HarmonicSignalBuffer, EMPTY_VALUE);
ArrayInitialize(CandleSignalBuffer, EMPTY_VALUE);
ArrayInitialize(ConfluenceBuyBuffer, EMPTY_VALUE);
ArrayInitialize(ConfluenceSellBuffer, EMPTY_VALUE);
ArrayInitialize(ConfluenceStrengthBuffer, 0);
Print("MultiSignal Confluence v1.10 Initialized");
Print("Settings: MinConfluence=", InpMinConfluence,
", Pivots=", InpUsePivots,
", Harmonics=", InpUseHarmonics,
", Candlesticks=", InpUseCandlesticks);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "Confluence_");
Print("MultiSignal Confluence Indicator Deinitialized");
}
//+------------------------------------------------------------------+
//| Calculate Pivot Levels |
//+------------------------------------------------------------------+
void CalculatePivots()
{
double prevHigh = iHigh(_Symbol, PERIOD_D1, 1);
double prevLow = iLow(_Symbol, PERIOD_D1, 1);
double prevClose = iClose(_Symbol, PERIOD_D1, 1);
pivotP = (prevHigh + prevLow + prevClose) / 3.0;
pivotR1 = (pivotP * 2) - prevLow;
pivotR2 = pivotP + (prevHigh - prevLow);
pivotS1 = (pivotP * 2) - prevHigh;
pivotS2 = pivotP - (prevHigh - prevLow);
lastPivotCalc = iTime(_Symbol, PERIOD_D1, 0);
}
//+------------------------------------------------------------------+
//| Check for Pivot Signals |
//+------------------------------------------------------------------+
void CheckPivotSignals(int bar)
{
if(!InpUsePivots) return;
// Recalculate pivots daily
datetime currentDay = iTime(_Symbol, PERIOD_D1, 0);
if(currentDay != lastPivotCalc)
CalculatePivots();
double close = iClose(_Symbol, _Period, bar);
double low = iLow(_Symbol, _Period, bar);
double high = iHigh(_Symbol, _Period, bar);
double threshold = InpPivotThreshold;
bool isBuy = false;
bool isSell = false;
// Buy at support
if((MathAbs(close - pivotS1) < threshold) ||
(MathAbs(close - pivotS2) < threshold) ||
(low <= pivotS1 && close > pivotS1) ||
(low <= pivotS2 && close > pivotS2))
{
isBuy = true;
PivotSignalBuffer[bar] = low - 10 * _Point;
currentBuySignals++;
signalSources += "P ";
if(InpDebugMode) Print("Pivot BUY signal at bar ", bar, " price ", close);
}
// Sell at resistance
else if((MathAbs(close - pivotR1) < threshold) ||
(MathAbs(close - pivotR2) < threshold) ||
(high >= pivotR1 && close < pivotR1) ||
(high >= pivotR2 && close < pivotR2))
{
isSell = true;
PivotSignalBuffer[bar] = high + 10 * _Point;
currentSellSignals++;
signalSources += "P ";
if(InpDebugMode) Print("Pivot SELL signal at bar ", bar, " price ", close);
}
else
{
PivotSignalBuffer[bar] = EMPTY_VALUE;
}
}
//+------------------------------------------------------------------+
//| Check for Candlestick Patterns |
//+------------------------------------------------------------------+
void CheckCandlestickSignals(int bar)
{
if(!InpUseCandlesticks) return;
double open = iOpen(_Symbol, _Period, bar);
double high = iHigh(_Symbol, _Period, bar);
double low = iLow(_Symbol, _Period, bar);
double close = iClose(_Symbol, _Period, bar);
double body = MathAbs(close - open);
double range = high - low;
double upperWick = high - MathMax(open, close);
double lowerWick = MathMin(open, close) - low;
if(range == 0) return;
bool isBuy = false;
bool isSell = false;
// Bullish Hammer
if(close > open && lowerWick > body * 2 && upperWick < body * 0.5)
{
if(lowerWick / range > InpMinBodyRatio)
{
isBuy = true;
CandleSignalBuffer[bar] = low - 15 * _Point;
currentBuySignals++;
signalSources += "C ";
if(InpDebugMode) Print("Hammer BUY at bar ", bar);
}
}
// Bearish Shooting Star
else if(close < open && upperWick > body * 2 && lowerWick < body * 0.5)
{
if(upperWick / range > InpMinBodyRatio)
{
isSell = true;
CandleSignalBuffer[bar] = high + 15 * _Point;
currentSellSignals++;
signalSources += "C ";
if(InpDebugMode) Print("Shooting Star SELL at bar ", bar);
}
}
// Bullish Engulfing
else if(bar + 1 < iBars(_Symbol, _Period))
{
double prevOpen = iOpen(_Symbol, _Period, bar + 1);
double prevClose = iClose(_Symbol, _Period, bar + 1);
if(prevClose < prevOpen && close > open &&
open <= prevClose && close >= prevOpen)
{
isBuy = true;
CandleSignalBuffer[bar] = low - 15 * _Point;
currentBuySignals++;
signalSources += "C ";
if(InpDebugMode) Print("Engulfing BUY at bar ", bar);
}
// Bearish Engulfing
else if(prevClose > prevOpen && close < open &&
open >= prevClose && close <= prevOpen)
{
isSell = true;
CandleSignalBuffer[bar] = high + 15 * _Point;
currentSellSignals++;
signalSources += "C ";
if(InpDebugMode) Print("Engulfing SELL at bar ", bar);
}
}
if(!isBuy && !isSell)
CandleSignalBuffer[bar] = EMPTY_VALUE;
}
//+------------------------------------------------------------------+
//| Check for Harmonic Patterns |
//+------------------------------------------------------------------+
void CheckHarmonicSignals(int bar, int rates_total)
{
if(!InpUseHarmonics) return;
if(bar + 4 >= rates_total) return;
// Get swing points
double X = iHigh(_Symbol, _Period, bar + 4);
double A = iLow(_Symbol, _Period, bar + 3);
double B = iHigh(_Symbol, _Period, bar + 2);
double C = iLow(_Symbol, _Period, bar + 1);
double D = iClose(_Symbol, _Period, bar);
double XA = MathAbs(A - X);
double AB = MathAbs(B - A);
double BC = MathAbs(C - B);
double CD = MathAbs(D - C);
if(XA == 0 || AB == 0 || BC == 0) return;
double ab_xa = AB / XA;
double bc_ab = BC / AB;
double cd_bc = CD / BC;
bool isBuy = false;
bool isSell = false;
// Bullish AB=CD (simplified)
if(X > A && A < B && B > C && C < D)
{
if(ab_xa >= 0.5 && ab_xa <= 0.8 &&
bc_ab >= 0.5 && bc_ab <= 0.8 &&
cd_bc >= 0.9 && cd_bc <= 1.1)
{
isBuy = true;
HarmonicSignalBuffer[bar] = D - 20 * _Point;
currentBuySignals++;
signalSources += "H ";
if(InpDebugMode) Print("Harmonic BUY at bar ", bar);
}
}
// Bearish AB=CD (simplified)
else if(X < A && A > B && B < C && C > D)
{
if(ab_xa >= 0.5 && ab_xa <= 0.8 &&
bc_ab >= 0.5 && bc_ab <= 0.8 &&
cd_bc >= 0.9 && cd_bc <= 1.1)
{
isSell = true;
HarmonicSignalBuffer[bar] = D + 20 * _Point;
currentSellSignals++;
signalSources += "H ";
if(InpDebugMode) Print("Harmonic SELL at bar ", bar);
}
}
if(!isBuy && !isSell)
HarmonicSignalBuffer[bar] = EMPTY_VALUE;
}
//+------------------------------------------------------------------+
//| Calculate Confluence |
//+------------------------------------------------------------------+
void CalculateConfluence(int bar)
{
// Reset counters
currentBuySignals = 0;
currentSellSignals = 0;
signalSources = "";
// Check all signal types
CheckPivotSignals(bar);
CheckHarmonicSignals(bar, iBars(_Symbol, _Period));
CheckCandlestickSignals(bar);
double confluenceStrength = 0;
// Strong Buy Confluence
if(currentBuySignals >= InpMinConfluence &&
(!InpRequireTrendAlignment || currentSellSignals == 0))
{
confluenceStrength = 0.7 + (currentBuySignals * 0.1);
if(confluenceStrength > 1.0) confluenceStrength = 1.0;
ConfluenceBuyBuffer[bar] = iLow(_Symbol, _Period, bar) - 30 * _Point;
ConfluenceSellBuffer[bar] = EMPTY_VALUE;
ConfluenceStrengthBuffer[bar] = confluenceStrength;
// Create visual label
string objName = "Confluence_Buy_" + IntegerToString(bar);
if(ObjectFind(0, objName) < 0)
{
datetime time = iTime(_Symbol, _Period, bar);
double price = iLow(_Symbol, _Period, bar);
ObjectCreate(0, objName, OBJ_TEXT, 0, time, price - 50 * _Point);
ObjectSetString(0, objName, OBJPROP_TEXT,
"BUY: " + signalSources + "(" + IntegerToString(currentBuySignals) + ")");
ObjectSetInteger(0, objName, OBJPROP_COLOR, clrLime);
ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, 8);
}
if(InpDebugMode || bar == 0)
Print("CONFLUENCE BUY at bar ", bar, " Strength=", confluenceStrength,
" Signals=", currentBuySignals, " Sources=", signalSources);
}
// Strong Sell Confluence
else if(currentSellSignals >= InpMinConfluence &&
(!InpRequireTrendAlignment || currentBuySignals == 0))
{
confluenceStrength = -(0.7 + (currentSellSignals * 0.1));
if(confluenceStrength < -1.0) confluenceStrength = -1.0;
ConfluenceSellBuffer[bar] = iHigh(_Symbol, _Period, bar) + 30 * _Point;
ConfluenceBuyBuffer[bar] = EMPTY_VALUE;
ConfluenceStrengthBuffer[bar] = confluenceStrength;
// Create visual label
string objName = "Confluence_Sell_" + IntegerToString(bar);
if(ObjectFind(0, objName) < 0)
{
datetime time = iTime(_Symbol, _Period, bar);
double price = iHigh(_Symbol, _Period, bar);
ObjectCreate(0, objName, OBJ_TEXT, 0, time, price + 50 * _Point);
ObjectSetString(0, objName, OBJPROP_TEXT,
"SELL: " + signalSources + "(" + IntegerToString(currentSellSignals) + ")");
ObjectSetInteger(0, objName, OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, 8);
}
if(InpDebugMode || bar == 0)
Print("CONFLUENCE SELL at bar ", bar, " Strength=", confluenceStrength,
" Signals=", currentSellSignals, " Sources=", signalSources);
}
else
{
ConfluenceBuyBuffer[bar] = EMPTY_VALUE;
ConfluenceSellBuffer[bar] = EMPTY_VALUE;
ConfluenceStrengthBuffer[bar] = 0;
}
// Update info panel on most recent bar
if(bar == 0)
UpdateInfoPanel();
}
//+------------------------------------------------------------------+
//| Update Info Panel |
//+------------------------------------------------------------------+
void UpdateInfoPanel()
{
string objName = "Confluence_InfoPanel";
if(ObjectFind(0, objName) < 0)
{
ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, 30);
}
string text = "=== CONFLUENCE v1.10 ===\n";
text += "Buy: " + IntegerToString(currentBuySignals) + " " + signalSources + "\n";
text += "Sell: " + IntegerToString(currentSellSignals) + "\n";
if(currentBuySignals >= InpMinConfluence)
text += "STATUS: STRONG BUY\n";
else if(currentSellSignals >= InpMinConfluence)
text += "STATUS: STRONG SELL\n";
else
text += "STATUS: SCANNING...\n";
text += "Min: " + IntegerToString(InpMinConfluence) + "/3";
ObjectSetString(0, objName, OBJPROP_TEXT, text);
ObjectSetInteger(0, objName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, 10);
}
//+------------------------------------------------------------------+
//| 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[])
{
int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;
for(int i = start; i < rates_total && !IsStopped(); i++)
{
CalculateConfluence(i);
}
return(rates_total);
}
//+------------------------------------------------------------------+