Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

IsFirstTickOfBar not working

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    IsFirstTickOfBar not working

    Hello
    I have the code below triggering dozens of times every time the conditions are met, instead of just once at the FirstTickOfBar and I would appreciate some help in figuring out why.
    The prints look like this:

    Neg Div | 16/12/2019 09:10:00 | Current Bar = 949 | j = 2 | b = 7
    LastHSwDMI -1 = 0.6667 | LastHSwDMI = 0.6842 | HSwDMI = 0.6250
    .....
    Neg Div | 16/12/2019 09:10:00 | Current Bar = 949 | j = 2 | b = 7
    LastHSwDMI -1 = 0.6667 | LastHSwDMI = 0.6842 | HSwDMI = 0.6250
    ......
    Neg Div | 16/12/2019 09:10:00 | Current Bar = 949 | j = 2 | b = 7
    LastHSwDMI -1 = 0.6667 | LastHSwDMI = 0.6842 | HSwDMI = 0.6250
    ......
    About 25 times this print is repeated!?!

    Code:
    public class Divergence5min : Strategy
    {
        private ObservableCollection <double> HSwDMI, LSwDMI, LastHSwDMI, LastLSwDMI;
    .........
        protected override void OnStateChange()
        {
             if (State == State.SetDefaults)
            {
                    Description                                    = @"Enter the description for your new custom Strategy here.";
                    Name                                        = "Divergence5min";
                    Calculate                                    = Calculate.OnEachTick;
    .......
            }
             else if (State == State.Configure)                
             {  
                  LSwDMI = new ObservableCollection <double>();      LastLSwDMI = new ObservableCollection <double>();
                  HSwDMI = new ObservableCollection <double>();     LastHSwDMI = new ObservableCollection <double>();
             }
             else if (State == State.DataLoaded)
             {  
                    DMI1            = DMI(Closes[0], Convert.ToInt32(DmiPeriod));  
                    T31b0           = T3(Closes[0], 5, 3, 0.7);                
                    T32b0           = T3(Closes[0], 8, 3, 0.7);    
    
                    DMI1.Plots[0].Brush = Brushes.Lime;        
                    T31b0.Plots[0].Brush = Brushes.Yellow;                            
                    T32b0.Plots[0].Brush = Brushes.White;                
    
                    AddChartIndicator(DMI1);                  
                    AddChartIndicator(T31b0);                
                    AddChartIndicator(T32b0);    
    
                    DMI1.Panel = 1;            
             }
       protected override void OnBarUpdate()
       {
                 if (IsFirstTickOfBar)
                {
             ....
                    NegativeDivergence();
                }
            } // OnBarUpdate end
    
       private void NegativeDivergence()
       {
                HSwDMI.CollectionChanged += (s, e) =>
                {
                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                    {
                        //Print("Action for NegativeDivergence: {0}" + e.Action);
                        if (/*!NegDiv &&*/ j > 1 && b > 1  && BarsInProgress == 0 && IsFirstTickOfBar && (highSwBarDiffA <= BarDiff || highSwBarDiffB <= BarDiff))
                        {
                            if (!negDiv && ((LastHSwDMI[j-2] - LastHSwDMI[j-1] > 0.001 && LastHSwDMIprice[j-1] - LastHSwDMIprice[j - 2] > TickSize)   // ND 1  
                                || (LastHSwDMI[j-1] - HSwDMI[b-1] > 0.001 && HSwDMIprice[b-1] - LastHSwDMIprice[j - 1] > TickSize)))    // ND 2                          
                            {
                                PrintNegDiv();
                                negDiv = true;    // NEG DIV = Reversal
                            }
                            else
                            {
                                negDiv = false;            
                            }                            
                            if (!hidNegDiv && ((LastHSwDMI[j-1] - LastHSwDMI[j-2] > 0.001 && LastHSwDMIprice[j - 2]  > LastHSwDMIprice[j - 1]  && LastHSwDMIprice[j - 2] - LastHSwDMIprice[j - 1] <= (int) HidDivOffset * TickSize) // HND 1                    
                                || (HSwDMI[b-1] - LastHSwDMI[j-1] > 0.001 && LastHSwDMIprice[j - 1] > HSwDMIprice[b - 1]  && LastHSwDMIprice[j - 1] - HSwDMIprice[b - 1] <= (int) HidDivOffset * TickSize))) // HND 2
                            {
                                PrintHidNegDiv();
                                hidNegDiv = true;    // HID NEG DIV = Continuation
                            }
                            else
                            {
                                hidNegDiv = false;        
                            }                        
                        }
                   }
               };
         }
        private void PrintNegDiv()
        {
                if (PrintDmiSwing)
                    Print("Neg Div |    " + Time[0] + " |   Current Bar = " + CurrentBar + " |      j = " + j  + " |    b = " + b + string.Format("\r\nLastHSwDMI -1 = {0:F4} |     LastHSwDMI = {1:F4} |    HSwDMI = {2:F4}",
                        LastHSwDMI[j-2], LastHSwDMI[j-1], HSwDMI[b-1]) + "\r\nLastHSwDMIbar -1 = " + LastHSwDMIbar[j - 2] + " |    LastHSwDMIbar = " + LastHSwDMIbar[j - 1] + " |    HSwDMIbar = " + HSwDMIbar[b - 1] +
                        "\r\nLast High -1 = " + LastHSwDMIprice[j - 2] + " |   Last High = " + LastHSwDMIprice[j - 1] + " |       Price DMI High = " + HSwDMIprice[b - 1] +
                        "\r\nLast High Bar -1 = " + LastHSwDMIpriceBar[j-2] + " |   Last High Bar = " + LastHSwDMIpriceBar[j-1] + " |   PriceHighBar = " + PriceHighBar[b-1] +
                        "\r\nND 1 = " + (LastHSwDMI[j - 2] - LastHSwDMI[j - 1] > 0.001 && LastHSwDMIprice[j - 1] - LastHSwDMIprice[j - 2] > TickSize) +  
                        "\r\nND 2 = " + (LastHSwDMI[j - 1] - HSwDMI[b - 1] > 0.001 && HSwDMIprice[b - 1] - LastHSwDMIprice[j - 1] > TickSize) + "\r\n-");
        }
        private void PrintHidNegDiv()
        {
                if (PrintDmiSwing)
                    Print("Hid Neg Div |    " + Time[0] + " |    Current Bar = " + CurrentBar + " |        j = " + j  + " |     b = " + b + string.Format("\r\nLastHSwDMI -1 = {0:F4} |    LastHSwDMI = {1:F4} |    HSwDMI = {2:F4}",
                        LastHSwDMI[j-2], LastHSwDMI[j-1], HSwDMI[b-1]) + "\r\nLastHSwDMIbar -1 = " + LastHSwDMIbar[j-2] + " |     LastHSwDMIbar = " + LastHSwDMIbar[j-1] + " |     HSwDMIbar = " + HSwDMIbar[b-1] +
                        "\r\nLast high -1 = " + LastHSwDMIprice[j - 2] + " |    Last High = " + LastHSwDMIprice[j - 1] + " |    Price DMI High = " + HSwDMIprice[b - 1] +
                        "\r\nLast High Bar -1 = " + LastHSwDMIpriceBar[j - 2] + " |     Last High Bar = " + LastHSwDMIpriceBar[j - 1] + " |   PriceHighBar = " + PriceHighBar[b - 1] +
                        "\r\nHND 1 = " + (LastHSwDMI[j - 1] - LastHSwDMI[j - 2] > 0.001&& LastHSwDMIprice[j - 2]  > LastHSwDMIprice[j - 1]  && LastHSwDMIprice[j - 2] - LastHSwDMIprice[j - 1] <= (int) HidDivOffset * TickSize) +
                        "\r\nHND 2 = " + (HSwDMI[b - 1] - LastHSwDMI[j - 1] > 0.001 && LastHSwDMIprice[j - 1] > HSwDMIprice[b - 1]  && LastHSwDMIprice[j - 1] - HSwDMIprice[b - 1] <= (int) HidDivOffset * TickSize) + "\r\n-");
        }  
    }
    Last edited by itrader46; 01-21-2020, 10:59 AM.

    #2
    Hello itrader46,

    In your OnBarUpdate you are calling the NegativeDivergence method which leads to a event subscription. It would not be expected to call that logic more than one time total as you are subscribing to an event, that is possibly why you are getting duplicate prints. I also can't say what the expectation would be here for that event, I don't know how many times the event you are using should be called.

    Did you mean to call one of the other methods shown from OnBarUpdate instead of re subscribing to the event over and over? You likely need to move your call to NegativeDivergence to State.DataLoaded so the subscription happens only one time.

    As for your IsFirstTickOfBar condition In OnBarUpdate, what was the intention with that condition? It appears to not be doing anything aside from calling the event subscription over and over, was that intended to be a print instead?

    I am not certain if your other NinjaScript properties will be in sync inside the event handler as that is not a NinjaScript event. You may be required to use a TriggerCustomEvent in there to get the actual values from your script if you see the values are not correct.


    Please let me know if I may be of further assistance.

    JesseNinjaTrader Customer Service

    Comment


      #3
      Hi Jesse.
      Well, I was hoping to get the prints once, at the start of every new bar, after HSwDMI.CollectionChanged event (which obviously doesn't happen on every bar) and if the triggering conditions are met.

      I'm a bit confused by this, though:
      It would not be expected to call that logic more than one time total as you are subscribing to an event, that is possibly why you are getting duplicate prints.
      It would not be expected
      doesn't seem to belong next to
      that is possibly why...
      Can you please explain what you meant by that?

      The IsFirstTickOfBar was there because this code is part of a larger one that will have a part needed to execute on every tick, with a secondary Tick series added to it. Without that, the code executes on every tick, due to Calculate.OnEachTick.

      Can you please explain what you meant by
      It appears to not be doing anything aside from calling the event subscription over and over?
      I thought IsFirstTickOfBar would call the logic once at the start of bar, not over and over.

      Finally, the values I'm getting are correct.

      Thank you

      Comment


        #4
        Hello itrader46,

        Well, I was hoping to get the prints once, at the start of every new bar, after HSwDMI.CollectionChanged event (which obviously doesn't happen on every bar) and if the triggering conditions are met.
        Before we go on I would need more information about what your goal is. Using an observable collection from NinjaScript would not be a normal type to use. I am not clear on what you are trying to do here, are you trying to detect when new items are added to the collection and only recalculate when new items were added?


        It would not be expected
        doesn't seem to belong next to
        that is possibly why...
        I am not certain what is unclear from your comments, I will try to re word this.

        You used an event subscription from OnBarUpdate but the event only needs to only be called one time ever to subscribe to it. You are possibly seeing more than one print because you subscribed to the event an unknown amount of times (I say possibly here because I am not going to go through and debug this for you to try and confirm that). This is possibly why you are seeing so many prints with the same information because the subscription would need to execute for each subscribed handler (this is something you can confirm if you wanted to by debugging however it would likely be better to first understand why this event is being used to see if that can be excluded).


        The IsFirstTickOfBar was there because this code is part of a larger one that will have a part needed to execute on every tick, with a secondary Tick series added to it. Without that, the code executes on every tick, due to Calculate.OnEachTick.

        Can you please explain what you meant by
        It appears to not be doing anything aside from calling the event subscription over and over?
        I thought IsFirstTickOfBar would call the logic once at the start of bar, not over and over.

        What I had referred to was the following code:

        Code:
         if (IsFirstTickOfBar)
                    {
                 ....
                        NegativeDivergence();
                    }
        You are calling the event subscription over and over in the method, each time a new first bar is seen:


        Code:
                    HSwDMI.CollectionChanged += (s, e) =>
                    {
        Each time you call that you are going to have another new event, if you call this two times you will have two prints for every one change your collection has. The more you call this the more times a single change to the collection will print.

        At the start of each bar you will see IsFirstTickOfBar true in OnBarUpdate however there are more than just one bar on a chart so you are subscribing to the event an unknown amount of times if this happens for every IsFirstTick event.



        I look forward to being of further assistance.
        JesseNinjaTrader Customer Service

        Comment


          #5
          Hi Jesse.

          I am indeed trying to detect when an element is added to the Collection HSwDMI and I am using ObservableCollection as I could find no way of being notified when the Collection changes with a standard NT8 method so I can trigger the code only after that, but only once, rather than 25 times.

          Maybe that would be a point to forward to the developers for a future update.

          I have moved the NegativeDivergence to State.DataLoaded, but all it does is stopping it from triggering at all.

          Is there a specific way of triggering this only once per bar when the conditions call for it, as I thought IsFirstTickOfBar would do that?
          Last edited by itrader46; 01-21-2020, 03:51 PM.

          Comment


            #6
            Hello itrader46,

            Thank you for the details that helps.

            IsFirstTickOfBar would be what you can use for the use case of once per bar. How you used it in your script is part of the problem. It is being executed once per bar but you used an event handler and subscribed to it more than once.

            In your script you should get more than one print once you are past 1 bar. Just to detail this further lets assume you are on bar 0 and NegativeDivergence was called once for the first tick. Now lets assume we moved to the next bar 1, NegativeDivergence get called again for the first tick. Now you have two open events for the same collection changed event. If you now add one element to the collection you should now see two prints. It will increase for every bar you process where the event is subscribed to again. If you saw 25 prints for 1 add event, you likely were around bar 25 in processing or had this called around 25 times before the collection had an item added.

            If you are looking to execute a calculation only when you add an element you should just check the Count of your collection and see if it changed.

            For what you are asking I would suggest using an approach like the following. This includes FirstTickOfBar handling and executes a calculation only when the collection had changed on the next first tick.

            Code:
            private List<double> myCollection; 
            
            if (State == State.DataLoaded)
            {
                  myCollection = new List<double>();
              }
            
            
            private int lastCount = 0;
            protected override void OnBarUpdate()
            {
                if(IsFirstTickOfBar)
                {
                     if(myCollection.Count != lastCount)
                    {
                        //do your processing once for the change
                        lastCount = myCollection.Count; // reset the stored count so we can see the change next time around
                    }
                }
            
            
            // at some point you add a element: 
            myCollection.Add(200); 
            // on the next call to OnBarUpdate where IsFirstTickOfBar is true it will check the conditions/run your calculation because the count is now increased
            
            }


            I look forward to being of further assistance.
            JesseNinjaTrader Customer Service

            Comment


              #7
              Jesse, you're a star. Thanks a lot. Damn, that was so simple!

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by CortexZenUSA, Today, 12:53 AM
              0 responses
              1 view
              0 likes
              Last Post CortexZenUSA  
              Started by CortexZenUSA, Today, 12:46 AM
              0 responses
              1 view
              0 likes
              Last Post CortexZenUSA  
              Started by usazencortex, Today, 12:43 AM
              0 responses
              5 views
              0 likes
              Last Post usazencortex  
              Started by sidlercom80, 10-28-2023, 08:49 AM
              168 responses
              2,265 views
              0 likes
              Last Post sidlercom80  
              Started by Barry Milan, Yesterday, 10:35 PM
              3 responses
              12 views
              0 likes
              Last Post NinjaTrader_Manfred  
              Working...
              X