//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+