How could make indicator only show signal on the first bar?
-
Dear coder,
I am writing an indicator (checking signal from MACD + MACD of highger timflame)
But I could not find the method only add one arrow on the first bar when the signal appear
So the chart as image below.
Could you please check and give me some advice to revise my code.
Thank you so much.
#property copyright "Copyright © 2005, Mr.Sun" #property link "mailto:[email protected]" #property indicator_separate_window #property indicator_buffers 6 #property indicator_color1 Blue #property indicator_color2 Coral #property indicator_color3 Red #property indicator_color4 Magenta #property indicator_color5 clrChocolate #property indicator_color6 clrSilver #property indicator_level1 0 #property indicator_levelcolor clrSilver #property indicator_levelstyle STYLE_SOLID //#include <kholuutru.mqh> //---- input parameters extern int Fast =12; extern int Slow =26; extern int Signal =9; extern int Fast_TF1 =12; extern int Slow_TF1 =26; extern int Signal_TF1 =9; //---- buffers double MACDLineBuffer[], SignalLineBuffer[], main_TF1[], sign_TF1[]; double SignalDown[]; double SignalUp[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { IndicatorShortName("Check Only one Signal"); SetIndexBuffer(0,MACDLineBuffer); SetIndexStyle(0,DRAW_LINE,1,2,Blue); SetIndexDrawBegin (0,Slow); SetIndexBuffer(1,SignalLineBuffer); SetIndexStyle(1,DRAW_LINE,1,2,clrCoral); SetIndexDrawBegin (1,Slow+Signal); //Arrow SetIndexBuffer(2, SignalDown); SetIndexStyle(2,DRAW_ARROW,0,1); SetIndexDrawBegin (2,Slow+Signal); SetIndexArrow(2, 234); SetIndexBuffer(3, SignalUp); SetIndexStyle(3,DRAW_ARROW,0,1); SetIndexDrawBegin (3,Slow+Signal); SetIndexArrow(3,233); //Check main + sign off TF1 SetIndexBuffer(4,main_TF1); SetIndexStyle(4,DRAW_LINE,2,0,clrBlue); SetIndexDrawBegin (4,Slow+Signal); SetIndexBuffer(5,sign_TF1); SetIndexStyle(5,DRAW_LINE,2,0,clrCoral); SetIndexDrawBegin (5,Slow+Signal); return(0); } int TF1() { int TF=0; switch (Period()) { case 1: TF= 15; break; case 5: TF= 30; break; case 15: TF= 60; break; case 30: TF= 240; break; case 60: TF= 240; break; case 240: TF= 1440; break; case 1440: TF= PERIOD_W1; break; case 10080: TF= PERIOD_MN1;break; case 43200: TF= 43200; break; } return(TF); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars = IndicatorCounted(); if(counted_bars < 0) return(0); if(counted_bars > 0) counted_bars--; int limit = fmin(Bars - counted_bars,Bars-1); for(int i=limit; i>=0; i--) { int shift = iBarShift(Symbol(),TF1(), Time[i], true); if (shift == -1) continue; { main_TF1[i]= iMACD(Symbol(), TF1(), Fast_TF1, Slow_TF1, 2,PRICE_CLOSE,MODE_SIGNAL,shift); sign_TF1[i]= iMACD(Symbol(), TF1(), Fast_TF1, Slow_TF1, Signal_TF1,PRICE_CLOSE,MODE_SIGNAL,shift); if(main_TF1[i] > sign_TF1[i]) int tin_hieu_TF1 =0; else tin_hieu_TF1 =1; } MACDLineBuffer[i] = iMACD(Symbol(),0,Fast,Slow,2,PRICE_CLOSE,MODE_SIGNAL,i); SignalLineBuffer[i] = iMACD(Symbol(),0,Fast,Slow,Signal,PRICE_CLOSE,MODE_SIGNAL,i); //SELL signal if (MACDLineBuffer[i]<SignalLineBuffer[i]) SignalDown[i]= SignalLineBuffer[i] ; //BUY signal if (MACDLineBuffer[i]>SignalLineBuffer[i]) SignalUp[i+1]= MACDLineBuffer[i] ; } return(0); } -
Hi Chris,
It looks like you're trying to ensure that your indicator only plots a signal arrow on the first bar where the condition is met, rather than continuously adding arrows on subsequent bars. One way to achieve this is by introducing a flag to track whether the signal has already appeared.
Try modifying your loop to check if a signal was already placed on a previous bar and only set the arrow on the first occurrence:
bool signalPlaced = false; for (int i = limit; i >= 0; i--) { if (signalPlaced) break; // Stop once a signal has been set if (MACDLineBuffer[i] < SignalLineBuffer[i]) { SignalDown[i] = SignalLineBuffer[i]; signalPlaced = true; } else if (MACDLineBuffer[i] > SignalLineBuffer[i]) { SignalUp[i] = MACDLineBuffer[i]; signalPlaced = true; } }This prevents additional arrows after the first valid signal. Have you tried implementing a similar logic, or do you need help refining it further? Let me know how it works for you!

-
Hi Chris,
It looks like you're trying to ensure that your indicator only plots a signal arrow on the first bar where the condition is met, rather than continuously adding arrows on subsequent bars. One way to achieve this is by introducing a flag to track whether the signal has already appeared.
Try modifying your loop to check if a signal was already placed on a previous bar and only set the arrow on the first occurrence:
bool signalPlaced = false; for (int i = limit; i >= 0; i--) { if (signalPlaced) break; // Stop once a signal has been set if (MACDLineBuffer[i] < SignalLineBuffer[i]) { SignalDown[i] = SignalLineBuffer[i]; signalPlaced = true; } else if (MACDLineBuffer[i] > SignalLineBuffer[i]) { SignalUp[i] = MACDLineBuffer[i]; signalPlaced = true; } }This prevents additional arrows after the first valid signal. Have you tried implementing a similar logic, or do you need help refining it further? Let me know how it works for you!

Thanks for the suggestion, @manager! Your approach with the
signalPlacedflag makes a lot of sense to prevent multiple arrows from appearing. I hadn’t considered breaking out of the loop once a signal is placed, which should help improve efficiency as well.I’ll implement this and test how it behaves in live conditions. One question—would this logic work consistently across different timeframes, especially when referencing the higher timeframe MACD? I want to make sure the signal doesn’t get skipped due to shifting bar alignments.
Appreciate your input! I’ll share my results after testing.

-
It looks like you're trying to ensure that your indicator only displays a signal arrow on the first bar when a condition is met, rather than continuously adding arrows. One way to achieve this is by introducing a flag variable that tracks whether a signal has been placed.
In your
start()function, you could modify your loop to check if a signal was already triggered before placing an arrow:bool signalPlaced = false; for (int i = limit; i >= 0; i--) { if (signalPlaced) break; // Stop once a signal has been set if (MACDLineBuffer[i] < SignalLineBuffer[i]) { SignalDown[i] = SignalLineBuffer[i]; signalPlaced = true; } else if (MACDLineBuffer[i] > SignalLineBuffer[i]) { SignalUp[i] = MACDLineBuffer[i]; signalPlaced = true; } }This ensures that only the first occurrence of a signal gets an arrow. Let me know if you’ve tried something similar or if you need further refinements!
-
Hi Chris,
It looks like you're on the right track with your indicator, but I see where the issue might be. Based on your code, your logic currently checks for a signal every bar, so arrows may continue appearing as long as the conditions are met. If you want to display the signal only on the first bar where the condition is true, you could introduce a flag that ensures the signal only triggers once per trend change.
One way to do this is by storing the previous signal state and only plotting an arrow when the condition changes from false to true. For example:
static int lastSignal = -1; if (MACDLineBuffer[i] < SignalLineBuffer[i] && lastSignal != 0) { SignalDown[i] = SignalLineBuffer[i]; lastSignal = 0; } else if (MACDLineBuffer[i] > SignalLineBuffer[i] && lastSignal != 1) { SignalUp[i] = MACDLineBuffer[i]; lastSignal = 1; }This ensures an arrow is placed only when the signal first appears rather than on every bar. Let me know if this helps, or if you'd like more refinements!
-
Thanks for the suggestion, @manager! Your approach with the
signalPlacedflag makes a lot of sense to prevent multiple arrows from appearing. I hadn’t considered breaking out of the loop once a signal is placed, which should help improve efficiency as well.I’ll implement this and test how it behaves in live conditions. One question—would this logic work consistently across different timeframes, especially when referencing the higher timeframe MACD? I want to make sure the signal doesn’t get skipped due to shifting bar alignments.
Appreciate your input! I’ll share my results after testing.

@Chris You bring up a great point about ensuring consistency across different timeframes. Since higher timeframe bars don’t align perfectly with lower ones, a good approach is to verify the signal using the last completed bar of the higher timeframe. You might want to use
iBarShift()carefully to make sure you're referencing the correct bar, avoiding unexpected skips due to slight timing mismatches. Logging the values during live testing can help confirm whether the logic behaves as expected. Let us know how your testing goes!