New EA and Indi
This commit is contained in:
753
EMA Indi/Base_EMA_Reversal.mq5
Normal file
753
EMA Indi/Base_EMA_Reversal.mq5
Normal file
@@ -0,0 +1,753 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Base_EMA_Reversal.mq5 |
|
||||
//| Multi-Stage EMA Reversal Signal Indicator |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
|
||||
// Properties
|
||||
#property indicator_buffers 15
|
||||
#property indicator_plots 6
|
||||
|
||||
// Plot configurations - Signal plots (6)
|
||||
#property indicator_label1 "BUY_SIGNAL"
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrLime
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
#property indicator_label2 "SELL_SIGNAL"
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 2
|
||||
#property indicator_label3 "BUY_SL"
|
||||
#property indicator_type3 DRAW_ARROW
|
||||
#property indicator_color3 clrGray
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 1
|
||||
#property indicator_label4 "SELL_SL"
|
||||
#property indicator_type4 DRAW_ARROW
|
||||
#property indicator_color4 clrGray
|
||||
#property indicator_style4 STYLE_SOLID
|
||||
#property indicator_width4 1
|
||||
#property indicator_label5 "BUY_TP"
|
||||
#property indicator_type5 DRAW_ARROW
|
||||
#property indicator_color5 clrBlue
|
||||
#property indicator_style5 STYLE_SOLID
|
||||
#property indicator_width5 1
|
||||
#property indicator_label6 "SELL_TP"
|
||||
#property indicator_type6 DRAW_ARROW
|
||||
#property indicator_color6 clrBlue
|
||||
#property indicator_style6 STYLE_SOLID
|
||||
#property indicator_width6 1
|
||||
|
||||
// EMA Line plots (7)
|
||||
#property indicator_label7 "EMA_50"
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrRed
|
||||
#property indicator_style7 STYLE_SOLID
|
||||
#property indicator_width7 1
|
||||
#property indicator_label8 "EMA_100"
|
||||
#property indicator_type8 DRAW_LINE
|
||||
#property indicator_color8 clrOrange
|
||||
#property indicator_style8 STYLE_SOLID
|
||||
#property indicator_width8 1
|
||||
#property indicator_label9 "EMA_200"
|
||||
#property indicator_type9 DRAW_LINE
|
||||
#property indicator_color9 clrYellow
|
||||
#property indicator_style9 STYLE_SOLID
|
||||
#property indicator_width9 1
|
||||
#property indicator_label10 "EMA_300"
|
||||
#property indicator_type10 DRAW_LINE
|
||||
#property indicator_color10 clrGreen
|
||||
#property indicator_style10 STYLE_SOLID
|
||||
#property indicator_width10 1
|
||||
#property indicator_label11 "EMA_400"
|
||||
#property indicator_type11 DRAW_LINE
|
||||
#property indicator_color11 clrBlue
|
||||
#property indicator_style11 STYLE_SOLID
|
||||
#property indicator_width11 1
|
||||
#property indicator_label12 "EMA_500"
|
||||
#property indicator_type12 DRAW_LINE
|
||||
#property indicator_color12 clrPurple
|
||||
#property indicator_style12 STYLE_SOLID
|
||||
#property indicator_width12 1
|
||||
#property indicator_label13 "EMA_600"
|
||||
#property indicator_type13 DRAW_LINE
|
||||
#property indicator_color13 clrMagenta
|
||||
#property indicator_style13 STYLE_SOLID
|
||||
#property indicator_width13 1
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Input Parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
input group "=== EMA Settings ==="
|
||||
input int InpEMA50_Period = 50;
|
||||
input int InpEMA100_Period = 100;
|
||||
input int InpEMA200_Period = 200;
|
||||
input int InpEMA300_Period = 300;
|
||||
input int InpEMA400_Period = 400;
|
||||
input int InpEMA500_Period = 500;
|
||||
input int InpEMA600_Period = 600;
|
||||
|
||||
input group "=== Setup Settings ==="
|
||||
input int InpLookbackPeriod = 100; // Lookback bars for base detection
|
||||
input double InpBaseThreshold = 50; // Pullback threshold (points)
|
||||
input int InpPullbackBars = 2; // Max bars to wait for pullback
|
||||
input int InpSkipBars = 50; // Bars to skip at startup
|
||||
|
||||
input group "=== ATR Settings ==="
|
||||
input int InpATRPeriod = 14; // ATR period for TP fallback
|
||||
|
||||
input group "=== Display Settings ==="
|
||||
input bool InpShowStageLabels = true; // Show stage labels on chart
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Indicator Buffers |
|
||||
//+------------------------------------------------------------------+
|
||||
double BuySignalBuffer[];
|
||||
double SellSignalBuffer[];
|
||||
double BuySLBuffer[];
|
||||
double SellSLBuffer[];
|
||||
double BuyTPBuffer[];
|
||||
double SellTPBuffer[];
|
||||
double BuyStateBuffer[];
|
||||
double SellStateBuffer[];
|
||||
|
||||
// EMA Line buffers for display
|
||||
double EMA50_Buffer[];
|
||||
double EMA100_Buffer[];
|
||||
double EMA200_Buffer[];
|
||||
double EMA300_Buffer[];
|
||||
double EMA400_Buffer[];
|
||||
double EMA500_Buffer[];
|
||||
double EMA600_Buffer[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| EMA Handles |
|
||||
//+------------------------------------------------------------------+
|
||||
int h_ema50, h_ema100, h_ema200;
|
||||
int h_ema300, h_ema400, h_ema500, h_ema600;
|
||||
int h_atr;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| State Tracking Variables |
|
||||
//+------------------------------------------------------------------+
|
||||
int buy_state = 0;
|
||||
int sell_state = 0;
|
||||
double BaseLow = 0;
|
||||
double BaseHigh = 0;
|
||||
datetime last_signal_time = 0;
|
||||
|
||||
// EMA touch tracking
|
||||
bool buy_ema_touched = false;
|
||||
bool sell_ema_touched = false;
|
||||
int ema_touch_bar = -1;
|
||||
int buy_touch_ema_count = 0;
|
||||
int sell_touch_ema_count = 0;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnInit |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
// Create EMA handles
|
||||
h_ema50 = iMA(_Symbol, _Period, InpEMA50_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_ema100 = iMA(_Symbol, _Period, InpEMA100_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_ema200 = iMA(_Symbol, _Period, InpEMA200_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_ema300 = iMA(_Symbol, _Period, InpEMA300_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_ema400 = iMA(_Symbol, _Period, InpEMA400_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_ema500 = iMA(_Symbol, _Period, InpEMA500_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_ema600 = iMA(_Symbol, _Period, InpEMA600_Period, 0, MODE_EMA, PRICE_CLOSE);
|
||||
h_atr = iATR(_Symbol, _Period, InpATRPeriod);
|
||||
|
||||
// Validate handles
|
||||
if(h_ema50 == INVALID_HANDLE || h_ema100 == INVALID_HANDLE || h_ema200 == INVALID_HANDLE ||
|
||||
h_ema300 == INVALID_HANDLE || h_ema400 == INVALID_HANDLE || h_ema500 == INVALID_HANDLE ||
|
||||
h_ema600 == INVALID_HANDLE || h_atr == INVALID_HANDLE)
|
||||
{
|
||||
Print("Error creating indicator handles");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
// Set buffers
|
||||
SetIndexBuffer(0, BuySignalBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, SellSignalBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BuySLBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(3, SellSLBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(4, BuyTPBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(5, SellTPBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(6, BuyStateBuffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(7, SellStateBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
// EMA Line buffers
|
||||
SetIndexBuffer(8, EMA50_Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(9, EMA100_Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(10, EMA200_Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(11, EMA300_Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(12, EMA400_Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(13, EMA500_Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(14, EMA600_Buffer, INDICATOR_DATA);
|
||||
|
||||
// Configure plots
|
||||
PlotIndexSetInteger(0, PLOT_ARROW, 233); // Up arrow for buy
|
||||
PlotIndexSetInteger(1, PLOT_ARROW, 234); // Down arrow for sell
|
||||
PlotIndexSetInteger(2, PLOT_ARROW, 159); // Dot for SL
|
||||
PlotIndexSetInteger(3, PLOT_ARROW, 159); // Dot for SL
|
||||
PlotIndexSetInteger(4, PLOT_ARROW, 160); // Plus for TP
|
||||
PlotIndexSetInteger(5, PLOT_ARROW, 160); // Plus for TP
|
||||
|
||||
// Set empty values for all plots
|
||||
for(int i = 0; i < 14; i++)
|
||||
{
|
||||
PlotIndexSetDouble(i, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
}
|
||||
|
||||
Print("Base_EMA_Reversal initialized successfully");
|
||||
Print("EMA Periods: ", InpEMA50_Period, ", ", InpEMA100_Period, ", ", InpEMA200_Period, ", ",
|
||||
InpEMA300_Period, ", ", InpEMA400_Period, ", ", InpEMA500_Period, ", ", InpEMA600_Period);
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnDeinit |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
// Release handles
|
||||
if(h_ema50 != INVALID_HANDLE) IndicatorRelease(h_ema50);
|
||||
if(h_ema100 != INVALID_HANDLE) IndicatorRelease(h_ema100);
|
||||
if(h_ema200 != INVALID_HANDLE) IndicatorRelease(h_ema200);
|
||||
if(h_ema300 != INVALID_HANDLE) IndicatorRelease(h_ema300);
|
||||
if(h_ema400 != INVALID_HANDLE) IndicatorRelease(h_ema400);
|
||||
if(h_ema500 != INVALID_HANDLE) IndicatorRelease(h_ema500);
|
||||
if(h_ema600 != INVALID_HANDLE) IndicatorRelease(h_ema600);
|
||||
if(h_atr != INVALID_HANDLE) IndicatorRelease(h_atr);
|
||||
|
||||
// Delete all stage label objects
|
||||
ObjectsDeleteAll(0, "EMA_Stage_");
|
||||
|
||||
Print("Base_EMA_Reversal deinitialized");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnCalculate |
|
||||
//+------------------------------------------------------------------+
|
||||
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[])
|
||||
{
|
||||
// Set arrays as series (index 0 = current bar)
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(BuySignalBuffer, true);
|
||||
ArraySetAsSeries(SellSignalBuffer, true);
|
||||
ArraySetAsSeries(BuySLBuffer, true);
|
||||
ArraySetAsSeries(SellSLBuffer, true);
|
||||
ArraySetAsSeries(BuyTPBuffer, true);
|
||||
ArraySetAsSeries(SellTPBuffer, true);
|
||||
ArraySetAsSeries(BuyStateBuffer, true);
|
||||
ArraySetAsSeries(SellStateBuffer, true);
|
||||
|
||||
// Check minimum data requirement
|
||||
if(rates_total < InpSkipBars + InpLookbackPeriod + InpEMA600_Period)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
// Copy EMA data
|
||||
double ema50[], ema100[], ema200[];
|
||||
double ema300[], ema400[], ema500[], ema600[];
|
||||
double atr[];
|
||||
|
||||
ArraySetAsSeries(ema50, true);
|
||||
ArraySetAsSeries(ema100, true);
|
||||
ArraySetAsSeries(ema200, true);
|
||||
ArraySetAsSeries(ema300, true);
|
||||
ArraySetAsSeries(ema400, true);
|
||||
ArraySetAsSeries(ema500, true);
|
||||
ArraySetAsSeries(ema600, true);
|
||||
ArraySetAsSeries(atr, true);
|
||||
|
||||
ArraySetAsSeries(EMA50_Buffer, true);
|
||||
ArraySetAsSeries(EMA100_Buffer, true);
|
||||
ArraySetAsSeries(EMA200_Buffer, true);
|
||||
ArraySetAsSeries(EMA300_Buffer, true);
|
||||
ArraySetAsSeries(EMA400_Buffer, true);
|
||||
ArraySetAsSeries(EMA500_Buffer, true);
|
||||
ArraySetAsSeries(EMA600_Buffer, true);
|
||||
|
||||
if(CopyBuffer(h_ema50, 0, 0, rates_total, ema50) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema100, 0, 0, rates_total, ema100) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema200, 0, 0, rates_total, ema200) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema300, 0, 0, rates_total, ema300) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema400, 0, 0, rates_total, ema400) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema500, 0, 0, rates_total, ema500) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema600, 0, 0, rates_total, ema600) <= 0) return(0);
|
||||
if(CopyBuffer(h_atr, 0, 0, rates_total, atr) <= 0) return(0);
|
||||
|
||||
// Copy EMA values to display buffers
|
||||
if(CopyBuffer(h_ema50, 0, 0, rates_total, EMA50_Buffer) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema100, 0, 0, rates_total, EMA100_Buffer) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema200, 0, 0, rates_total, EMA200_Buffer) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema300, 0, 0, rates_total, EMA300_Buffer) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema400, 0, 0, rates_total, EMA400_Buffer) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema500, 0, 0, rates_total, EMA500_Buffer) <= 0) return(0);
|
||||
if(CopyBuffer(h_ema600, 0, 0, rates_total, EMA600_Buffer) <= 0) return(0);
|
||||
|
||||
// Calculate start position
|
||||
int bars_to_process;
|
||||
int start_bar;
|
||||
|
||||
if(prev_calculated == 0)
|
||||
{
|
||||
// First calculation - initialize base levels
|
||||
bars_to_process = rates_total - InpSkipBars - 1;
|
||||
start_bar = InpSkipBars;
|
||||
|
||||
// Initialize BaseLow/BaseHigh from lookback period
|
||||
int lookback_start = InpSkipBars + InpLookbackPeriod;
|
||||
int lookback_end = InpSkipBars + 1;
|
||||
|
||||
BaseLow = low[lookback_start];
|
||||
BaseHigh = high[lookback_start];
|
||||
|
||||
for(int i = lookback_start; i >= lookback_end; i--)
|
||||
{
|
||||
if(low[i] < BaseLow) BaseLow = low[i];
|
||||
if(high[i] > BaseHigh) BaseHigh = high[i];
|
||||
}
|
||||
|
||||
// Initialize states
|
||||
buy_state = 1;
|
||||
sell_state = 1;
|
||||
buy_ema_touched = false;
|
||||
sell_ema_touched = false;
|
||||
ema_touch_bar = -1;
|
||||
|
||||
Print("Initialization: BaseLow = ", BaseLow, ", BaseHigh = ", BaseHigh);
|
||||
|
||||
// Clear buffers
|
||||
ArrayInitialize(BuySignalBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(SellSignalBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(BuySLBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(SellSLBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(BuyTPBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(SellTPBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(BuyStateBuffer, 0);
|
||||
ArrayInitialize(SellStateBuffer, 0);
|
||||
ArrayInitialize(EMA50_Buffer, EMPTY_VALUE);
|
||||
ArrayInitialize(EMA100_Buffer, EMPTY_VALUE);
|
||||
ArrayInitialize(EMA200_Buffer, EMPTY_VALUE);
|
||||
ArrayInitialize(EMA300_Buffer, EMPTY_VALUE);
|
||||
ArrayInitialize(EMA400_Buffer, EMPTY_VALUE);
|
||||
ArrayInitialize(EMA500_Buffer, EMPTY_VALUE);
|
||||
ArrayInitialize(EMA600_Buffer, EMPTY_VALUE);
|
||||
}
|
||||
else if(rates_total > prev_calculated)
|
||||
{
|
||||
// New bars added - process only new bars
|
||||
bars_to_process = rates_total - prev_calculated;
|
||||
start_bar = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recalculate last bar only
|
||||
bars_to_process = 1;
|
||||
start_bar = 0;
|
||||
}
|
||||
|
||||
// Process bars
|
||||
for(int i = start_bar; i < start_bar + bars_to_process && i < rates_total - InpSkipBars; i++)
|
||||
{
|
||||
// Skip initialization area
|
||||
if(i >= rates_total - InpSkipBars) continue;
|
||||
|
||||
// Default buffer values (EMPTY_VALUE for all signal/SL/TP buffers)
|
||||
BuySignalBuffer[i] = EMPTY_VALUE;
|
||||
SellSignalBuffer[i] = EMPTY_VALUE;
|
||||
BuySLBuffer[i] = EMPTY_VALUE;
|
||||
SellSLBuffer[i] = EMPTY_VALUE;
|
||||
BuyTPBuffer[i] = EMPTY_VALUE;
|
||||
SellTPBuffer[i] = EMPTY_VALUE;
|
||||
|
||||
// Copy EMA values to display buffers
|
||||
EMA50_Buffer[i] = ema50[i];
|
||||
EMA100_Buffer[i] = ema100[i];
|
||||
EMA200_Buffer[i] = ema200[i];
|
||||
EMA300_Buffer[i] = ema300[i];
|
||||
EMA400_Buffer[i] = ema400[i];
|
||||
EMA500_Buffer[i] = ema500[i];
|
||||
EMA600_Buffer[i] = ema600[i];
|
||||
|
||||
// Update state buffers
|
||||
BuyStateBuffer[i] = buy_state;
|
||||
SellStateBuffer[i] = sell_state;
|
||||
|
||||
// State 1: Finding Base (continuous tracking)
|
||||
if(buy_state == 1 || buy_state == 0)
|
||||
{
|
||||
if(low[i] < BaseLow)
|
||||
{
|
||||
BaseLow = low[i];
|
||||
}
|
||||
buy_state = 1;
|
||||
}
|
||||
|
||||
if(sell_state == 1 || sell_state == 0)
|
||||
{
|
||||
if(high[i] > BaseHigh)
|
||||
{
|
||||
BaseHigh = high[i];
|
||||
}
|
||||
sell_state = 1;
|
||||
}
|
||||
|
||||
// Check for EMA touch (State 1 -> State 2)
|
||||
// BUY SIDE: Price touches EMA from below (close below -> close above)
|
||||
if(buy_state == 1 && !buy_ema_touched)
|
||||
{
|
||||
// Find lowest EMA (most resistance from below)
|
||||
double lowest_ema = ema50[i];
|
||||
if(ema100[i] < lowest_ema) lowest_ema = ema100[i];
|
||||
if(ema200[i] < lowest_ema) lowest_ema = ema200[i];
|
||||
|
||||
// Previous bar close
|
||||
double prev_close = (i < rates_total - 1) ? close[i + 1] : close[i];
|
||||
|
||||
// EMA touch from below (previous close at/below, current close above)
|
||||
if(prev_close <= lowest_ema && close[i] > lowest_ema)
|
||||
{
|
||||
buy_ema_touched = true;
|
||||
ema_touch_bar = i;
|
||||
|
||||
// Count EMAs crossed
|
||||
buy_touch_ema_count = 0;
|
||||
if(close[i] > ema50[i]) buy_touch_ema_count++;
|
||||
if(close[i] > ema100[i]) buy_touch_ema_count++;
|
||||
if(close[i] > ema200[i]) buy_touch_ema_count++;
|
||||
|
||||
buy_state = 2;
|
||||
BuyStateBuffer[i] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// SELL SIDE: Price touches EMA from above (close above -> close below)
|
||||
if(sell_state == 1 && !sell_ema_touched)
|
||||
{
|
||||
// Find highest EMA (most support from above)
|
||||
double highest_ema = ema50[i];
|
||||
if(ema100[i] > highest_ema) highest_ema = ema100[i];
|
||||
if(ema200[i] > highest_ema) highest_ema = ema200[i];
|
||||
|
||||
// Previous bar close
|
||||
double prev_close = (i < rates_total - 1) ? close[i + 1] : close[i];
|
||||
|
||||
// EMA touch from above (previous close at/above, current close below)
|
||||
if(prev_close >= highest_ema && close[i] < highest_ema)
|
||||
{
|
||||
sell_ema_touched = true;
|
||||
ema_touch_bar = i;
|
||||
|
||||
// Count EMAs crossed
|
||||
sell_touch_ema_count = 0;
|
||||
if(close[i] < ema50[i]) sell_touch_ema_count++;
|
||||
if(close[i] < ema100[i]) sell_touch_ema_count++;
|
||||
if(close[i] < ema200[i]) sell_touch_ema_count++;
|
||||
|
||||
sell_state = 2;
|
||||
SellStateBuffer[i] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// State 3: Decision (within pullback window)
|
||||
// BUY SIDE DECISION
|
||||
if(buy_ema_touched)
|
||||
{
|
||||
int bars_since_touch = ema_touch_bar - i;
|
||||
|
||||
// Timeout check - if more than pullback bars passed, cancel
|
||||
if(bars_since_touch > InpPullbackBars)
|
||||
{
|
||||
buy_ema_touched = false;
|
||||
buy_state = 1;
|
||||
BuyStateBuffer[i] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cancel condition: crossed EMA below again
|
||||
double lowest_ema_current = ema50[i];
|
||||
if(ema100[i] < lowest_ema_current) lowest_ema_current = ema100[i];
|
||||
if(ema200[i] < lowest_ema_current) lowest_ema_current = ema200[i];
|
||||
|
||||
if(close[i] < lowest_ema_current)
|
||||
{
|
||||
buy_ema_touched = false;
|
||||
buy_state = 1;
|
||||
BuyStateBuffer[i] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pullback check
|
||||
double pullback_distance = MathAbs(low[i] - BaseLow) / _Point;
|
||||
|
||||
if(pullback_distance <= InpBaseThreshold)
|
||||
{
|
||||
// GENERATE BUY SIGNAL
|
||||
BuySignalBuffer[i] = close[i];
|
||||
BuySLBuffer[i] = BaseLow;
|
||||
BuyTPBuffer[i] = CalculateBuyTP(close[i], ema300[i], ema400[i], ema500[i], ema600[i], atr[i]);
|
||||
BuyStateBuffer[i] = 3;
|
||||
|
||||
// Create signal label
|
||||
if(InpShowStageLabels)
|
||||
{
|
||||
UpdateStageLabels(time[i], 3, sell_state, low[i] - 50 * _Point, i);
|
||||
}
|
||||
|
||||
// Reset
|
||||
buy_ema_touched = false;
|
||||
buy_state = 1;
|
||||
last_signal_time = time[i];
|
||||
|
||||
// Recalculate BaseLow from bar before signal
|
||||
RecalculateBaseBuy(i, rates_total, low);
|
||||
|
||||
Print("BUY SIGNAL at ", TimeToString(time[i]), " Price: ", close[i], " SL: ", BaseLow,
|
||||
" TP: ", BuyTPBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// SELL SIDE DECISION
|
||||
if(sell_ema_touched)
|
||||
{
|
||||
int bars_since_touch = ema_touch_bar - i;
|
||||
|
||||
// Timeout check - if more than pullback bars passed, cancel
|
||||
if(bars_since_touch > InpPullbackBars)
|
||||
{
|
||||
sell_ema_touched = false;
|
||||
sell_state = 1;
|
||||
SellStateBuffer[i] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cancel condition: crossed EMA above again
|
||||
double highest_ema_current = ema50[i];
|
||||
if(ema100[i] > highest_ema_current) highest_ema_current = ema100[i];
|
||||
if(ema200[i] > highest_ema_current) highest_ema_current = ema200[i];
|
||||
|
||||
if(close[i] > highest_ema_current)
|
||||
{
|
||||
sell_ema_touched = false;
|
||||
sell_state = 1;
|
||||
SellStateBuffer[i] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pullback check
|
||||
double pullback_distance = MathAbs(high[i] - BaseHigh) / _Point;
|
||||
|
||||
if(pullback_distance <= InpBaseThreshold)
|
||||
{
|
||||
// GENERATE SELL SIGNAL
|
||||
SellSignalBuffer[i] = close[i];
|
||||
SellSLBuffer[i] = BaseHigh;
|
||||
SellTPBuffer[i] = CalculateSellTP(close[i], ema300[i], ema400[i], ema500[i], ema600[i], atr[i]);
|
||||
SellStateBuffer[i] = 3;
|
||||
|
||||
// Create signal label
|
||||
if(InpShowStageLabels)
|
||||
{
|
||||
UpdateStageLabels(time[i], 3, sell_state, high[i] + 50 * _Point, i);
|
||||
}
|
||||
|
||||
// Reset
|
||||
sell_ema_touched = false;
|
||||
sell_state = 1;
|
||||
last_signal_time = time[i];
|
||||
|
||||
// Recalculate BaseHigh from bar before signal
|
||||
RecalculateBaseSell(i, rates_total, high);
|
||||
|
||||
Print("SELL SIGNAL at ", TimeToString(time[i]), " Price: ", close[i], " SL: ", BaseHigh,
|
||||
" TP: ", SellTPBuffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate Buy Take Profit |
|
||||
//+------------------------------------------------------------------+
|
||||
double CalculateBuyTP(double entry_price, double ema300, double ema400,
|
||||
double ema500, double ema600, double atr)
|
||||
{
|
||||
double tp = 0;
|
||||
|
||||
// Find lowest valid EMA ABOVE price (closest = best risk/reward)
|
||||
if(ema300 > entry_price)
|
||||
{
|
||||
if(tp == 0 || ema300 < tp) tp = ema300;
|
||||
}
|
||||
if(ema400 > entry_price)
|
||||
{
|
||||
if(tp == 0 || ema400 < tp) tp = ema400;
|
||||
}
|
||||
if(ema500 > entry_price)
|
||||
{
|
||||
if(tp == 0 || ema500 < tp) tp = ema500;
|
||||
}
|
||||
if(ema600 > entry_price)
|
||||
{
|
||||
if(tp == 0 || ema600 < tp) tp = ema600;
|
||||
}
|
||||
|
||||
// ATR fallback: if no valid EMA above price
|
||||
if(tp == 0 && atr > 0)
|
||||
{
|
||||
tp = entry_price + atr * 2;
|
||||
}
|
||||
|
||||
return NormalizeDouble(tp, _Digits);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate Sell Take Profit |
|
||||
//+------------------------------------------------------------------+
|
||||
double CalculateSellTP(double entry_price, double ema300, double ema400,
|
||||
double ema500, double ema600, double atr)
|
||||
{
|
||||
double tp = 0;
|
||||
|
||||
// Find highest valid EMA BELOW price (closest = best risk/reward)
|
||||
if(ema300 < entry_price)
|
||||
{
|
||||
if(tp == 0 || ema300 > tp) tp = ema300;
|
||||
}
|
||||
if(ema400 < entry_price)
|
||||
{
|
||||
if(tp == 0 || ema400 > tp) tp = ema400;
|
||||
}
|
||||
if(ema500 < entry_price)
|
||||
{
|
||||
if(tp == 0 || ema500 > tp) tp = ema500;
|
||||
}
|
||||
if(ema600 < entry_price)
|
||||
{
|
||||
if(tp == 0 || ema600 > tp) tp = ema600;
|
||||
}
|
||||
|
||||
// ATR fallback: if no valid EMA below price
|
||||
if(tp == 0 && atr > 0)
|
||||
{
|
||||
tp = entry_price - atr * 2;
|
||||
}
|
||||
|
||||
return NormalizeDouble(tp, _Digits);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recalculate Buy Base Level After Signal |
|
||||
//+------------------------------------------------------------------+
|
||||
void RecalculateBaseBuy(int signal_bar, int total_bars, const double &low_arr[])
|
||||
{
|
||||
// Start from bar before signal
|
||||
BaseLow = low_arr[signal_bar + 1];
|
||||
|
||||
// Find new base from that point forward
|
||||
for(int j = signal_bar + 1; j < total_bars - InpSkipBars; j++)
|
||||
{
|
||||
if(low_arr[j] < BaseLow)
|
||||
{
|
||||
BaseLow = low_arr[j];
|
||||
}
|
||||
}
|
||||
|
||||
// Print("BaseLow recalculated: ", BaseLow, " after buy signal");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recalculate Sell Base Level After Signal |
|
||||
//+------------------------------------------------------------------+
|
||||
void RecalculateBaseSell(int signal_bar, int total_bars, const double &high_arr[])
|
||||
{
|
||||
// Start from bar before signal
|
||||
BaseHigh = high_arr[signal_bar + 1];
|
||||
|
||||
// Find new base from that point forward
|
||||
for(int j = signal_bar + 1; j < total_bars - InpSkipBars; j++)
|
||||
{
|
||||
if(high_arr[j] > BaseHigh)
|
||||
{
|
||||
BaseHigh = high_arr[j];
|
||||
}
|
||||
}
|
||||
|
||||
// Print("BaseHigh recalculated: ", BaseHigh, " after sell signal");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Update Stage Labels |
|
||||
//+------------------------------------------------------------------+
|
||||
void UpdateStageLabels(datetime label_time, int buy_st, int sell_st, double price, int bar_index)
|
||||
{
|
||||
string label_name = "EMA_Stage_" + IntegerToString(bar_index);
|
||||
|
||||
string text = "";
|
||||
color label_color;
|
||||
|
||||
// Format: "BUY/SELL" for signal bars
|
||||
if(buy_st == 3)
|
||||
{
|
||||
text = "BUY SIGNAL";
|
||||
label_color = clrLime;
|
||||
}
|
||||
else if(sell_st == 3)
|
||||
{
|
||||
text = "SELL SIGNAL";
|
||||
label_color = clrRed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show state only when not in signal
|
||||
text = StringFormat("B:%d S:%d", buy_st, sell_st);
|
||||
label_color = clrGray;
|
||||
switch(buy_st)
|
||||
{
|
||||
case 0: label_color = clrGray; break;
|
||||
case 1: label_color = clrBlue; break;
|
||||
case 2: label_color = clrOrange; break;
|
||||
case 3: label_color = clrGreen; break;
|
||||
default: label_color = clrGray;
|
||||
}
|
||||
}
|
||||
|
||||
// Create or update label
|
||||
if(ObjectFind(0, label_name) < 0)
|
||||
{
|
||||
ObjectCreate(0, label_name, OBJ_TEXT, 0, label_time, price);
|
||||
}
|
||||
|
||||
ObjectSetString(0, label_name, OBJPROP_TEXT, text);
|
||||
ObjectSetInteger(0, label_name, OBJPROP_COLOR, label_color);
|
||||
ObjectSetInteger(0, label_name, OBJPROP_FONTSIZE, 14);
|
||||
ObjectSetInteger(0, label_name, OBJPROP_ANCHOR, ANCHOR_UPPER);
|
||||
ObjectSetInteger(0, label_name, OBJPROP_SELECTABLE, false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
148
EMA Indi/README.md
Normal file
148
EMA Indi/README.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# Base-EMA Multi-Stage Reversal Signal Indicator
|
||||
|
||||
## Overview
|
||||
|
||||
The Base-EMA Reversal Indicator is a sophisticated trading tool that identifies potential reversal opportunities using a multi-stage state machine approach with EMA confluence. The indicator tracks both buy and sell opportunities through a systematic process of base formation, EMA confirmation, and pullback detection.
|
||||
|
||||
## Features
|
||||
|
||||
### 8 Indicator Buffers
|
||||
1. **BUY_SIGNAL** (Buffer 0): Price level for buy entry (up arrow)
|
||||
2. **SELL_SIGNAL** (Buffer 1): Price level for sell entry (down arrow)
|
||||
3. **BUY_SL** (Buffer 2): Stop Loss level for buy positions (from base low)
|
||||
4. **SELL_SL** (Buffer 3): Stop Loss level for sell positions (from base high)
|
||||
5. **BUY_TP** (Buffer 4): Take Profit level for buy positions (EMA 600)
|
||||
6. **SELL_TP** (Buffer 5): Take Profit level for sell positions (EMA 600)
|
||||
7. **BUY_STATE** (Buffer 6): Current buy state (0-3) for EA consumption
|
||||
8. **SELL_STATE** (Buffer 7): Current sell state (0-3) for EA consumption
|
||||
|
||||
### Input Parameters
|
||||
|
||||
#### EMA Settings
|
||||
- **EMA 50 Period**: Fast EMA period (default: 50)
|
||||
- **EMA 100 Period**: Medium-fast EMA period (default: 100)
|
||||
- **EMA 200 Period**: Medium EMA period (default: 200)
|
||||
- **EMA 300 Period**: Medium-slow EMA period (default: 300)
|
||||
- **EMA 400 Period**: Slow EMA period (default: 400)
|
||||
- **EMA 500 Period**: Very slow EMA period (default: 500)
|
||||
- **EMA 600 Period**: Target EMA for TP (default: 600)
|
||||
|
||||
#### Setup Settings
|
||||
- **Lookback Period**: Bars to look back for base detection (default: 20)
|
||||
- **Base Threshold**: Points tolerance for pullback to base (default: 50)
|
||||
- **State Reset Period**: Bars before resetting state if no signal (default: 50)
|
||||
|
||||
#### Display Settings
|
||||
- **Show Dashboard**: Toggle dashboard display (default: true)
|
||||
- **Show Stage Labels**: Toggle stage label display (default: true)
|
||||
- **Show EMA Lines**: Toggle EMA lines display (default: true)
|
||||
|
||||
## Logic Workflow
|
||||
|
||||
### Buy Side State Machine (Looking for reversal up to EMA 600)
|
||||
|
||||
#### State 0: Idle/Reset
|
||||
- Waiting for new low formation
|
||||
|
||||
#### State 1: Find Base
|
||||
- Price makes new low in `InpLookback` bars (at frist install then use last signal as a start of lookback)
|
||||
- Store `BaseLow = Low[i]`
|
||||
- Transition to State 2
|
||||
|
||||
#### State 2: Confirm Test
|
||||
- Price touches or crosses EMA 50, 100, or 200 from below
|
||||
- Wait for pullback opportunity
|
||||
- Transition to State 3
|
||||
|
||||
#### State 3: Wait Pullback
|
||||
- Price pulls back to `BaseLow` within `InpBaseThreshold` points
|
||||
- Generate buy signal at current close
|
||||
- Set SL at `BaseLow`
|
||||
- Set TP at EMA 600
|
||||
- Reset to State 0
|
||||
|
||||
### Sell Side State Machine (Looking for reversal down to EMA 600)
|
||||
|
||||
#### State 0: Idle/Reset
|
||||
- Waiting for new high formation
|
||||
|
||||
#### State 1: Find Base
|
||||
- Price makes new high in `InpLookback` bars (at frist install then use last signal as a start of lookback)
|
||||
- Store `BaseHigh = High[i]`
|
||||
- Transition to State 2
|
||||
|
||||
#### State 2: Confirm Test
|
||||
- Price touches or crosses EMA 50, 100, or 200 from above
|
||||
- Wait for bounce back opportunity
|
||||
- Transition to State 3
|
||||
|
||||
#### State 3: Wait Pullback
|
||||
- Price bounces back to `BaseHigh` within `InpBaseThreshold` points
|
||||
- Generate sell signal at current close
|
||||
- Set SL at `BaseHigh`
|
||||
- Set TP at EMA 600
|
||||
- Reset to State 0
|
||||
|
||||
## Visual Elements
|
||||
|
||||
### Color Scheme
|
||||
- **EMA 50**: Red
|
||||
- **EMA 100**: Orange
|
||||
- **EMA 200**: Yellow
|
||||
- **EMA 300**: Green
|
||||
- **EMA 400**: Blue
|
||||
- **EMA 500**: Purple
|
||||
- **EMA 600**: Magenta
|
||||
- **Buy Signals**: Lime green arrows (↑)
|
||||
- **Sell Signals**: Red arrows (↓)
|
||||
- **SL Lines**: Gray dashed lines
|
||||
- **TP Lines**: Blue dotted lines
|
||||
- **Stage Labels**: Color-coded by state
|
||||
|
||||
### Stage Labels
|
||||
Located in top-right corner, shows:
|
||||
- Current buy stage with colored background
|
||||
- Current sell stage with colored background
|
||||
- State descriptions for active states
|
||||
|
||||
## State Descriptions
|
||||
|
||||
| State | Value | Description | Color |
|
||||
|-------|-------|-------------|-------|
|
||||
| Idle/Reset | 0 | Waiting for setup | Gray |
|
||||
| Finding Base | 1 | Looking for new high/low | Blue |
|
||||
| Confirm Test | 2 | EMA touch/cross detected | Orange |
|
||||
| Wait Pullback | 3 | Waiting for pullback to base | Green |
|
||||
|
||||
|
||||
### For EA Developers
|
||||
The indicator provides two key buffers for automated trading systems:
|
||||
- `BUY_STATE_BUFFER` (6): Current buy state (0-3)
|
||||
- `SELL_STATE_BUFFER` (7): Current sell state (0-3)
|
||||
|
||||
These buffers can be accessed programmatically to:
|
||||
- Monitor setup progression
|
||||
- Trigger automated entries at State 3
|
||||
- Implement custom risk management
|
||||
- Build multi-timeframe strategies
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Buffer Configuration
|
||||
```mql5
|
||||
#property indicator_buffers 8
|
||||
#property indicator_plots 6
|
||||
```
|
||||
|
||||
### Performance Considerations
|
||||
- Uses iMA() handles for efficient EMA calculation
|
||||
- Implements series arrays for optimal memory usage
|
||||
- Minimal repainting - signals generated on bar close
|
||||
- Efficient object management for dashboard and labels
|
||||
|
||||
### Error Handling
|
||||
- Validates EMA handle creation
|
||||
- Checks array bounds before access
|
||||
- Graceful cleanup on deinitialization
|
||||
- Proper series array management
|
||||
|
||||
372
EMA Indi/USER_GUIDE.md
Normal file
372
EMA Indi/USER_GUIDE.md
Normal file
@@ -0,0 +1,372 @@
|
||||
# Base EMA Reversal Indicator - User Guide
|
||||
|
||||
**Version**: 1.0
|
||||
**Date**: 2025-01-22
|
||||
**File**: Base_EMA_Reversal.mq5
|
||||
|
||||
---
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
The Base EMA Reversal Indicator identifies potential reversal opportunities using a multi-stage state machine approach with EMA confluence. The indicator tracks both buy and sell opportunities through base formation, EMA confirmation, and pullback detection.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Strategy Logic
|
||||
|
||||
### Core Concept
|
||||
When price touches EMA (50/100/200), TWO possible outcomes:
|
||||
1. **Pullback**: Price revisits previous high/low → SIGNAL
|
||||
2. **Breakthrough**: Price makes new high/low → Continue watching
|
||||
|
||||
### State Machine (States 0-3)
|
||||
|
||||
#### Buy Side
|
||||
- **State 0**: Startup/Reset (only at initialization)
|
||||
- **State 1**: Finding Base - Track lowest price continuously
|
||||
- **State 2**: EMA Touched - Price closed ABOVE EMA 50/100/200
|
||||
- **State 3**: Decision/Signal - Within 2 bars of EMA touch
|
||||
- Pullback to BaseLow (within 50 points) → **BUY SIGNAL**
|
||||
- Cross EMA below again → Cancel, back to State 1
|
||||
|
||||
#### Sell Side (Mirror of Buy Side)
|
||||
- **State 0**: Startup/Reset (only at initialization)
|
||||
- **State 1**: Finding Base - Track highest price continuously
|
||||
- **State 2**: EMA Touched - Price closed BELOW EMA 50/100/200
|
||||
- **State 3**: Decision/Signal - Within 2 bars of EMA touch
|
||||
- Pullback to BaseHigh (within 50 points) → **SELL SIGNAL**
|
||||
- Cross EMA above again → Cancel, back to State 1
|
||||
|
||||
### TP Selection Logic
|
||||
- **Buy Signals**: Find LOWEST valid EMA ABOVE price from [300, 400, 500, 600]
|
||||
- **Sell Signals**: Find HIGHEST valid EMA BELOW price from [300, 400, 500, 600]
|
||||
- **ATR Fallback**: If no valid EMA position, use ATR × 2
|
||||
|
||||
---
|
||||
|
||||
## 📊 Buffer Structure (8 Buffers)
|
||||
|
||||
| Index | Buffer Name | Purpose | Value Type | When Populated |
|
||||
|-------|-------------|---------|------------|----------------|
|
||||
| 0 | BUY_SIGNAL | Buy entry price | Price | Signal bars only |
|
||||
| 1 | SELL_SIGNAL | Sell entry price | Price | Signal bars only |
|
||||
| 2 | BUY_SL | Buy stop loss | Price (BaseLow) | Signal bars only |
|
||||
| 3 | SELL_SL | Sell stop loss | Price (BaseHigh) | Signal bars only |
|
||||
| 4 | BUY_TP | Buy take profit | Price (EMA or ATR) | Signal bars only |
|
||||
| 5 | SELL_TP | Sell take profit | Price (EMA or ATR) | Signal bars only |
|
||||
| 6 | BUY_STATE | Buy state tracker | 0-3 | Every bar |
|
||||
| 7 | SELL_STATE | Sell state tracker | 0-3 | Every bar |
|
||||
|
||||
**Important**: Signal buffers (0-5) = EMPTY_VALUE when not applicable. EA will check for non-EMPTY_VALUE to detect signals.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Input Parameters
|
||||
|
||||
### EMA Settings
|
||||
| Parameter | Default | Description |
|
||||
|-----------|----------|-------------|
|
||||
| EMA 50 Period | 50 | Fast EMA (confirmation) |
|
||||
| EMA 100 Period | 100 | Medium-fast EMA (confirmation) |
|
||||
| EMA 200 Period | 200 | Medium EMA (confirmation) |
|
||||
| EMA 300 Period | 300 | TP1 target |
|
||||
| EMA 400 Period | 400 | TP2 target |
|
||||
| EMA 500 Period | 500 | TP3 target |
|
||||
| EMA 600 Period | 600 | TP4 target |
|
||||
|
||||
### Setup Settings
|
||||
| Parameter | Default | Description |
|
||||
|-----------|----------|-------------|
|
||||
| Lookback Period | 100 | Bars for initial base detection |
|
||||
| Base Threshold | 50 | Pullback tolerance (points) |
|
||||
| Pullback Bars | 2 | Max bars to wait for pullback |
|
||||
| Skip Bars | 50 | Bars skipped at startup |
|
||||
|
||||
### ATR Settings
|
||||
| Parameter | Default | Description |
|
||||
|-----------|----------|-------------|
|
||||
| ATR Period | 14 | ATR period for TP fallback |
|
||||
|
||||
### Display Settings
|
||||
| Parameter | Default | Description |
|
||||
|-----------|----------|-------------|
|
||||
| Show Stage Labels | true | Display state labels on chart |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Installation
|
||||
|
||||
### Step 1: Copy Files to MetaTrader 5
|
||||
|
||||
1. Navigate to your MetaTrader 5 data folder:
|
||||
- **Windows**: `C:\Users\{Username}\AppData\Roaming\MetaQuotes\Terminal\{TerminalID}\MQL5\`
|
||||
- **Mac**: Open MetaTrader 5 → File → Open Data Folder
|
||||
|
||||
2. Copy `Base_EMA_Reversal.mq5` to: `MQL5/Indicators/`
|
||||
|
||||
### Step 2: Compile the Indicator
|
||||
|
||||
1. Open MetaEditor 5 (press F4 in MetaTrader 5)
|
||||
2. File → Open → Select `Base_EMA_Reversal.mq5`
|
||||
3. Press F7 or click "Compile"
|
||||
4. Verify **0 errors** in "Errors" tab (warnings are OK)
|
||||
5. Close MetaEditor 5
|
||||
|
||||
### Step 3: Install Indicator on Chart
|
||||
|
||||
1. In MetaTrader 5, right-click on "Navigator" → "Refresh"
|
||||
2. Drag `Base EMA Reversal` from Navigator → Indicators to EURUSD H1 chart
|
||||
3. Configure parameters if needed
|
||||
4. Click OK
|
||||
|
||||
### Step 4: Enable Visual Elements
|
||||
|
||||
Ensure you can see:
|
||||
- ✅ **7 EMA lines** (Red, Orange, Yellow, Green, Blue, Purple, Magenta)
|
||||
- ✅ **Stage labels** "B:X S:Y" on each bar (color-coded)
|
||||
- ✅ **Buy signals** (Lime ↑ arrows)
|
||||
- ✅ **Sell signals** (Red ↓ arrows)
|
||||
- ✅ **SL markers** (Gray dots)
|
||||
- ✅ **TP markers** (Blue +)
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Visual Elements
|
||||
|
||||
### EMA Lines (7 EMAs) - NOW VISIBLE!
|
||||
- **EMA 50**: Red (Plot 7)
|
||||
- **EMA 100**: Orange (Plot 8)
|
||||
- **EMA 200**: Yellow (Plot 9)
|
||||
- **EMA 300**: Green (Plot 10)
|
||||
- **EMA 400**: Blue (Plot 11)
|
||||
- **EMA 500**: Purple (Plot 12)
|
||||
- **EMA 600**: Magenta (Plot 13)
|
||||
|
||||
### Signal Arrows
|
||||
- **Buy Signal**: Arrow code 233 (↑), Lime color
|
||||
- **Sell Signal**: Arrow code 234 (↓), Red color
|
||||
|
||||
### Signal Labels (Only on Signal Bars - Large Font)
|
||||
- **Buy Signal Labels**: "BUY SIGNAL" - Lime color, Font Size 14
|
||||
- **Sell Signal Labels**: "SELL SIGNAL" - Red color, Font Size 14
|
||||
- **No labels on non-signal bars** (reduced clutter)
|
||||
|
||||
### SL/TP Markers
|
||||
- **SL**: Gray dot (code 159)
|
||||
- **TP**: Blue plus sign (code 160)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Integration with Universal Buffer Reader EA
|
||||
|
||||
### EA Configuration
|
||||
|
||||
Configure the Universal Buffer Reader EA with these parameters:
|
||||
|
||||
| EA Parameter | Value |
|
||||
|-------------|--------|
|
||||
| IndicatorName | "Base_EMA_Reversal" |
|
||||
| BuySignalBuffer | 0 |
|
||||
| SellSignalBuffer | 1 |
|
||||
| BuySLBuffer | 2 |
|
||||
| SellSLBuffer | 3 |
|
||||
| SellSLBuffer | 6 |
|
||||
| BuyTPBuffer | 4 |
|
||||
| SellTPBuffer | 5 |
|
||||
|
||||
### How EA Reads Signals
|
||||
|
||||
The EA's `SignalDetector.mqh` checks:
|
||||
```mql5
|
||||
bool has_buy = (buy_signal != EMPTY_VALUE && buy_signal != 0);
|
||||
bool has_sell = (sell_signal != EMPTY_VALUE && sell_signal != 0);
|
||||
```
|
||||
|
||||
Our indicator:
|
||||
- Sets **signal price** when signal occurs at bar close
|
||||
- Sets **EMPTY_VALUE** on all other bars
|
||||
- EA will only execute trades when buffers have valid values
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Recommendations
|
||||
|
||||
### 1. Demo Account Testing (REQUIRED)
|
||||
|
||||
**Always test on a demo account first!**
|
||||
|
||||
- Test for at least 1-2 weeks
|
||||
- Monitor all trades closely
|
||||
- Check all features are working:
|
||||
- EMA touch detection
|
||||
- Pullback identification
|
||||
- Signal generation
|
||||
- SL/TP levels
|
||||
- State transitions
|
||||
- ATR fallback
|
||||
|
||||
### 2. Visual Verification
|
||||
|
||||
On EURUSD H1 chart:
|
||||
1. Check EMA lines are smooth and correct colors
|
||||
2. Verify stage labels change colors as states progress
|
||||
3. Watch for signal arrows at appropriate locations
|
||||
4. Monitor Experts tab for signal print messages
|
||||
|
||||
### 3. Backtesting
|
||||
|
||||
1. Open Strategy Tester (press F4 or View → Strategy Tester)
|
||||
2. Select `Base EMA Reversal`
|
||||
3. Select symbol (EURUSD) and timeframe (H1)
|
||||
4. Select test period (last 6 months recommended)
|
||||
5. Click "Start"
|
||||
6. Review results:
|
||||
- Signal frequency
|
||||
- Win rate
|
||||
- Risk/reward ratio
|
||||
- ATR fallback usage
|
||||
|
||||
### 4. Forward Testing
|
||||
|
||||
After successful backtesting:
|
||||
- Test on demo account with live data
|
||||
- Monitor for 2-4 weeks
|
||||
- Compare results with backtest
|
||||
- Adjust parameters if needed
|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring and Analysis
|
||||
|
||||
### Experts Tab
|
||||
Watch for these messages:
|
||||
- `BUY SIGNAL at [timestamp] Price: [price] SL: [sl] TP: [tp]`
|
||||
- `SELL SIGNAL at [timestamp] Price: [price] SL: [sl] TP: [tp]`
|
||||
- `Initialization: BaseLow = [value], BaseHigh = [value]`
|
||||
- `BaseLow recalculated: [value] after buy signal`
|
||||
- `BaseHigh recalculated: [value] after sell signal`
|
||||
|
||||
### Signal Quality Indicators
|
||||
Monitor:
|
||||
- **State Transitions**: Should flow smoothly 1 → 2 → 3 → 1
|
||||
- **Timeout Frequency**: How often signals cancel due to timeout?
|
||||
- **Pullback Success Rate**: What % of EMA touches result in signals?
|
||||
- **ATR Fallback Usage**: How often is TP calculated via ATR?
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Common Issues and Solutions
|
||||
|
||||
### Issue: No Signals Appearing
|
||||
|
||||
**Symptoms**: Indicator loads but no arrows appear
|
||||
|
||||
**Solutions**:
|
||||
1. Check minimum data requirement (need 600+ bars)
|
||||
2. Verify EMA touch detection is working (watch Experts tab)
|
||||
3. Confirm base levels are updating (check print messages)
|
||||
4. Increase Lookback Period parameter
|
||||
|
||||
### Issue: Too Many False Signals
|
||||
|
||||
**Symptoms**: Signals appearing frequently but price doesn't reverse
|
||||
|
||||
**Solutions**:
|
||||
1. Increase Base Threshold (from 50 to 100+)
|
||||
2. Reduce Pullback Bars (from 2 to 1)
|
||||
3. Add additional confirmation logic (e.g., close above EMA for 2 bars)
|
||||
|
||||
### Issue: Stage Labels Too Cluttered
|
||||
|
||||
**Symptoms**: Chart difficult to read due to too many labels
|
||||
|
||||
**Solutions**:
|
||||
1. Set `Show Stage Labels = false` to disable
|
||||
2. Use smaller timeframe (H4 instead of M15)
|
||||
3. Filter by state (only show State 2-3 labels)
|
||||
|
||||
### Issue: EA Not Executing Trades
|
||||
|
||||
**Symptoms**: Universal Buffer Reader EA sees indicator but no trades
|
||||
|
||||
**Solutions**:
|
||||
1. Verify EA parameters match buffer indices (0-5)
|
||||
2. Check AutoTrading is enabled (green button)
|
||||
3. Verify EA has permission to trade
|
||||
4. Enable debug prints in EA to see signal detection
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Risk Management
|
||||
|
||||
### Important Considerations
|
||||
|
||||
1. **No Stop Loss Warning**: If SL hits immediately, BaseLow/High may be too close to entry
|
||||
2. **TP Verification**: If EMA TP seems unrealistic, ATR fallback will activate
|
||||
3. **Pullback Window**: 2 bars is narrow - may miss valid setups
|
||||
4. **Base Threshold**: 50 points may be too tight for volatile symbols
|
||||
|
||||
### Recommended Settings by Symbol
|
||||
|
||||
| Symbol | Base Threshold | Pullback Bars |
|
||||
|--------|---------------|----------------|
|
||||
| EURUSD (Majors) | 30-50 | 2 |
|
||||
| GBPUSD (Volatile) | 50-80 | 2-3 |
|
||||
| XAUUSD (Gold) | 100-200 | 3 |
|
||||
| Crypto (BTC/ETH) | 200-500 | 5 |
|
||||
|
||||
---
|
||||
|
||||
## 📝 Code Summary
|
||||
|
||||
### File Statistics
|
||||
- **Lines**: 641
|
||||
- **Functions**: 7 (OnInit, OnDeinit, OnCalculate, CalculateBuyTP, CalculateSellTP, RecalculateBaseBuy, RecalculateBaseSell, UpdateStageLabels)
|
||||
- **State Variables**: 9 (buy_state, sell_state, BaseLow, BaseHigh, last_signal_time, buy_ema_touched, sell_ema_touched, ema_touch_bar, buy_touch_ema_count, sell_touch_ema_count)
|
||||
- **Indicator Handles**: 8 (7 EMAs + 1 ATR)
|
||||
|
||||
### Key Logic Patterns
|
||||
- Array indexing: Series (index 0 = current bar)
|
||||
- State machine: Event-driven (EMA touch → Decision → Reset)
|
||||
- Buffer clearing: EMPTY_VALUE on non-signal bars
|
||||
- Object management: Unique prefix "EMA_Stage_"
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Next Steps
|
||||
|
||||
After initial testing:
|
||||
|
||||
1. ✅ **Optimize Parameters**: Use Strategy Tester to find optimal values
|
||||
2. ✅ **Add Filters**: Consider time filters, trend filters
|
||||
3. ✅ **Multi-Timeframe**: Test on H4, D1 timeframes
|
||||
4. ✅ **Performance Tuning**: Reduce object count for faster chart
|
||||
5. ✅ **Backtest Extensively**: 6-12 months of data minimum
|
||||
|
||||
---
|
||||
|
||||
## 📞 Getting Help
|
||||
|
||||
### Debug Mode
|
||||
If experiencing issues, enable `InpShowStageLabels = false` to reduce visual clutter and check Experts tab for print messages.
|
||||
|
||||
### Print Messages
|
||||
Key messages to watch:
|
||||
- Initialization messages
|
||||
- Signal generation messages
|
||||
- Base recalculation messages
|
||||
- Any error messages
|
||||
|
||||
### Log Analysis
|
||||
Review Strategy Tester logs to:
|
||||
- Count total signals
|
||||
- Analyze win/loss ratio
|
||||
- Check SL/TP effectiveness
|
||||
- Identify best performing timeframes
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-22
|
||||
**Version**: 1.0
|
||||
|
||||
**Happy Trading! 📈**
|
||||
Reference in New Issue
Block a user