Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

BotiTrader

  1. Home
  2. General Discussion
  3. How could make indicator only show signal on the first bar?

How could make indicator only show signal on the first bar?

Scheduled Pinned Locked Moved General Discussion
6 Posts 2 Posters 125 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Chris
    wrote on last edited by
    #1

    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);
    }
    
    1 Reply Last reply
    0
    • M Offline
      M Offline
      manager
      wrote on last edited by
      #2

      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! 🚀

      C 1 Reply Last reply
      0
      • M manager

        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! 🚀

        C Offline
        C Offline
        Chris
        wrote on last edited by
        #3

        Thanks for the suggestion, @manager! Your approach with the signalPlaced flag 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. 🚀

        M 1 Reply Last reply
        0
        • M Offline
          M Offline
          manager
          wrote on last edited by
          #4

          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!

          1 Reply Last reply
          0
          • M Offline
            M Offline
            manager
            wrote on last edited by
            #5

            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!

            1 Reply Last reply
            0
            • C Chris

              Thanks for the suggestion, @manager! Your approach with the signalPlaced flag 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. 🚀

              M Offline
              M Offline
              manager
              wrote on last edited by
              #6

              @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!

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              Powered by NodeBB Contributors
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Groups