Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

What is the core event for time based bars?

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

    What is the core event for time based bars?

    I´m trying to find info on what "core timer" drives the time event triggering the OnBarUpdate() method. Is it the dataprovider server? If so, is it synced to the Pillar technology? What timer stamps the ticks? Pillar platform or dataprovider?

    My main issue here is that Calculate.OnBarClose (from what I once leared) is not triggered on some circumstances on low trading activity. Hence, "cartesian precition" is not guaranteed and the timebars count in a trading day could vary wildly.

    A follow-up question on this is; What technique should I use the get mathematical/cartesian precition for time based bars in NT8? Or refraced; How do I get the OnBarUpdate() method to behave as exactly and predictable as a Pillar platform synced clock/timer?
    Last edited by FREEN; 10-11-2018, 03:21 PM.

    #2
    Hello FREEN,

    There are instrument threads in the core of NinjaTrader. These work with the connection adapter to receive information and push these to consumer threads such as charts and NinjaScripts.

    We do not provide the internal workings of these core methods and we do not provide the internal code that runs these internal methods.

    OnBarUpdate, OnMarketData, and OnMarketDepth are all data driven methods. These are triggered when data is received on the instrument thread and pushed to consumer threads.

    If no ticks are received, OnBarUpdate does not trigger.

    If you want to trigger events when there is no data you would need to use a timer using general C# code that is not specific to NinjaScript.

    Below is a public link to an example of a timer.
    https://ninjatrader.com/support/foru...445#post496445
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Thanks Chelsea,

      I still don´t get in what way time bars are connected to a timing event and what that event emanates from. I´m not after the code or methods, just what logic I can count on here. Is it the tick event that initiates the bar and the time stamp that defines it "size"? If so; if there´s a laps of ticks for >1 sec duration, will that 1 sec bar not be created at all? Do you have any reading clearifying the logic?

      Yes, I guess I´ll have to go for some proprietary timing logic to ensure reliability and predictability.
      Last edited by FREEN; 10-12-2018, 06:34 AM.

      Comment


        #4
        Hello FREEN,

        Thank you for your response.

        You can find details on how bars are built at the following link: https://ninjatrader.com/support/help..._are_built.htm

        Time based bars build until their size is reached. If there is no tick then a bar does not update. If a 1 Second chart does not receive a tick for a second or more you can expect there will not be bars on the chart for those times.

        Please let me know if you have any questions.

        Comment


          #5
          Sorry to be persistent on this query;

          Is a bar time (Time[0]) stamped with the time of my local machine (my PC´s system time)?

          (Alternatives beeing the Pillar of NYSE/Nasdaq or a data provider like Kinetick).
          Last edited by FREEN; 02-04-2019, 10:17 AM.

          Comment


            #6
            Hello FREEN,

            Yes, as real-time and historical data is received this is converted to your local time zone your using your local computers PC Clock.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              I would appreciate some further guidance in the theme of this query:

              I have an indicator code snippet extracting 8 series (market stats/equities), all at 1 sec bars. This gives 23400 secs in a trading day. The bar count on each series will vary wildly so that:

              if (BarsInProgress == 0) dateTimeA = Time[0]
              if (BarsInProgress == 1) dateTimeB = Time[0]

              ...most likely will have different time stamps. In other words they´re out of time sync (as implied in the theme of this thread).

              Question:

              Is there a golden standard solution for making a multi series (same time frame/bar size) indicator time synced? Programatically it would mean all series have a count of 23400 and that some are "empty slots" since no market event occoured at that point in time.


              (I have my own solution that I will be happy to share if there´s interest for it.)
              Last edited by FREEN; 02-25-2019, 03:52 AM.

              Comment


                #8
                Hello FREEN,

                Two series are not synchronized. They are their own series.

                Only time based bars such as second, minute, day, etc would close at the same time when using the same trading hours template.

                Any tick based bars would depend on the tick data building the bars.

                May I confirm you are comparing time based bars with the same bar type and interval with the same trading hours template and these are closing at different times?
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Yes, I confirm that. All series are added as 1 sec time bars at the same templates. Axcessing them by index will return values with different time stamps, as intended by inbuilt NT logic at market inactivity. My goal is to output a custom series (List<prices>) with multiple price properties reflecting each series. Axessing an index in this custom list/series will guarantee that the values (if not void due to no market activity) are in time sync. Did I clearify my question?!

                  Hence, this custom price series/list will always have a count of 23400 for a trade day. In contrast to NT dataseries it will have "empty slots" at market inactivity rather than "no slots".

                  My question repeated: would there be a golden standard/best practice suggested for this purpose?

                  (I might add its the kinetic market data at 1 sec that drives and guarantees the "new second time event". This far it hasn´t failed any second. If it does I´ll dodge that with in-code timer events.)


                  Code:
                  protected override void OnStateChange()
                  {
                       if (State == State.Configure)
                       {
                    AddDataSeries("A", BarsPeriodType.Second, 1);
                    AddDataSeries("B", BarsPeriodType.Second, 1);
                    AddDataSeries("C", BarsPeriodType.Second, 1);
                    AddDataSeries("D", BarsPeriodType.Second, 1);
                    AddDataSeries("E", BarsPeriodType.Second, 1);
                   ....
                       }
                  }
                  Last edited by FREEN; 02-25-2019, 09:50 AM.

                  Comment


                    #10
                    Hello FREEN,

                    To confirm, your inquiry is:
                    If no data is received for a time period on a time based bar, can an empty slot be added in place of that period of no data?

                    This is not possible with DataSeries objects. Bar type scripts are not able to add a bar without data points. You could with custom logic a custom bar type that uses 0's instead, however, this would affect calculations of indicators which would need to be explicitly written to ignore 0 values.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Thanks Chelsea, you get me right. It seems I´m the only one bugged by that behaviour Maybe most people access multiseries datapoints by timestamp rather than by index?

                      Kindly, Fredrik

                      Comment


                        #12
                        Hello FREEN,

                        Yes you could compare the time stamps. If Times[0][1] != Times[0][0] then its not the same bar and stop processing.
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          I doubt its of interest for anybody... but this is the technique I used for the purpose. It renders copies of last value rather than "empty slots" if there is no market event. For me this guarantees "cartesian precision" in subsequent logic. The code is optimized for readabiliy, so no need for explanations I guess:

                          Code:
                                  // FIELDS
                                  int barCounter = 0;
                                  bool firstPrimary = true;
                                  int primaryBlanks = 0;
                                  bool firstPriceBar = true;    
                                  PriceBars priceBars = new PriceBars();
                                  bool writeFile = true;
                          
                          
                                  protected override void OnStateChange()
                                  {
                                      if (State == State.SetDefaults)
                                      {
                                       ...
                                      }
                                      else if (State == State.Configure)
                                      {
                                          // Market stats:
                                          // Primary: AI5T.Z - Index.Simple average price of all Nasdaq100 components.
                                          AddDataSeries("JTQTZ", Data.BarsPeriodType.Second, 1, Data.MarketDataType.Last); //1
                                          AddDataSeries("VIQT", Data.BarsPeriodType.Second, 1, Data.MarketDataType.Last); //2
                                          AddDataSeries("PRNQZ", Data.BarsPeriodType.Second, 1, Data.MarketDataType.Last); //3
                                          etc...
                                      }
                                  }
                          
                                  protected override void OnBarUpdate()
                                  {                
                                      // Market stats:
                                      // 0: AI5T.Z - Index
                                      // 1: JT5T.Z - Tick
                                      // 2: VI5T.Z - Volume.
                                      // 3: PRNQ.Z - Premium.
                                      // 4: JI5T.Z - Issue.
                                      // Equities:
                                      // 5: QQQ    - Open, Close, High, Low, Vol
                                      // 6: TQQQ - Open, Close, High, Low, Vol
                                      // 7: SQQQ - Open, Close, High, Low, Vol    
                          
                          
                                      // 0) THE VERY FIRST BAR
                                      if (firstPriceBar) // can´t use CurrentBar == 0 since there might be(8) occourances
                                      {
                                          firstPriceBar = false;
                                          priceBars.Add(new PriceBar());
                          
                                          // initiate first values from ???
                                          priceBars[0].IndexHigh = 0;
                                          priceBars[0].IndexLow = 0;
                                          priceBars[0].NetTick = 0; //1
                                          priceBars[0].NasdaqVolume = 0; //2
                                          priceBars[0].NasdaqPremium = 0; //3
                                          priceBars[0].NasdaqIssue = 0; //4
                          
                                          priceBars[0].QqqOpen = 0;
                                          priceBars[0].QqqHigh = 0;
                                          priceBars[0].QqqLow = 0;
                                          priceBars[0].QqqClose = 0;
                                          priceBars[0].QqqVol = 0;
                          
                                          priceBars[0].TqqqOpen = 0;
                                          priceBars[0].TqqqHigh = 0;
                                          priceBars[0].TqqqLow = 0;
                                          priceBars[0].TqqqClose = 0;
                                          priceBars[0].TqqqVol = 0;    
                          
                                          etc...
                                      }
                          
                                      // 1) SUBSEQUENT BARS - INITIATE FROM PREVIOUS PriceBar
                                      if (CurrentBar == barCounter + 1)
                                      {
                                          barCounter = CurrentBar;
                                          priceBars.Add(new PriceBar());
                          
                                          // initiate subsequent values from previous bars
                                          priceBars[barCounter].IndexHigh = priceBars[barCounter - 1].IndexHigh;
                                          priceBars[barCounter].IndexLow = priceBars[barCounter - 1].IndexLow;
                                          priceBars[barCounter].NetTick = priceBars[barCounter - 1].NetTick;
                                          priceBars[barCounter].NasdaqVolume = priceBars[barCounter - 1].NasdaqVolume;
                                          priceBars[barCounter].NasdaqPremium = priceBars[barCounter - 1].NasdaqPremium;
                                          priceBars[barCounter].NasdaqIssue = priceBars[barCounter - 1].NasdaqIssue;
                          
                                          priceBars[barCounter].QqqOpen = priceBars[barCounter - 1].QqqOpen;
                                          priceBars[barCounter].QqqHigh = priceBars[barCounter - 1].QqqHigh;
                                          priceBars[barCounter].QqqLow = priceBars[barCounter - 1].QqqLow;
                                          priceBars[barCounter].QqqClose = priceBars[barCounter - 1].QqqClose;
                                          priceBars[barCounter].QqqVol = 0; // no tradevolume is default
                          
                                          etc...
                                      }
                          
                          
                                      // 2) OVERWRITE WITH CURRENT VALUES - (if there are):
                          
                                      // 0: AI5T.Z - Index.
                                      if (BarsInProgress == 0)
                                      {
                                          priceBars[barCounter].IndexHigh = High[0];
                                          priceBars[barCounter].IndexLow = Low[0];
                          
                                          // count the number of primary blank values to remove from the list before it´s written to file
                                          if (firstPrimary)
                                          {
                                              primaryBlanks = barCounter;
                                              firstPrimary = false;
                                          }    
                                      }
                          
                                      // 1: JT5T.Z - Tick.
                                      if (BarsInProgress == 1) priceBars[barCounter].NetTick = Close[0];
                          
                                      // 2: VI5T.Z - Volume.
                                      if (BarsInProgress == 2)
                                      {
                                          if (CurrentBar == 0) priceBars[barCounter].NasdaqVolume = Close[0];
                                          else if (Close[0] - Close[1] < 0) priceBars[barCounter].NasdaqVolume = Close[0];
                                          else priceBars[barCounter].NasdaqVolume = Close[0] - Close[1];
                                      }
                          
                                      // 3: PRNQ.Z - Premium.
                                      if (BarsInProgress == 3) priceBars[barCounter].NasdaqPremium = Close[0];
                          
                                      // 4: JI5T.Z - Issue.
                                      if (BarsInProgress == 4) priceBars[barCounter].NasdaqIssue = Close[0];
                          
                                      // 5: QQQ
                                      if (BarsInProgress == 5)
                                      {
                                          priceBars[barCounter].QqqOpen = Open[0];
                                          priceBars[barCounter].QqqHigh = High[0];
                                          priceBars[barCounter].QqqLow = Low[0];
                                          priceBars[barCounter].QqqClose = Close[0];
                                          priceBars[barCounter].QqqVol = Volume[0];
                                      }
                          
                                      etc...
                                  }
                          Last edited by FREEN; 02-25-2019, 11:22 AM.

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by Barry Milan, Today, 10:35 PM
                          1 response
                          6 views
                          0 likes
                          Last Post NinjaTrader_Manfred  
                          Started by WeyldFalcon, 12-10-2020, 06:48 PM
                          14 responses
                          1,427 views
                          0 likes
                          Last Post Handclap0241  
                          Started by DJ888, Yesterday, 06:09 PM
                          2 responses
                          9 views
                          0 likes
                          Last Post DJ888
                          by DJ888
                           
                          Started by jeronymite, 04-12-2024, 04:26 PM
                          3 responses
                          40 views
                          0 likes
                          Last Post jeronymite  
                          Started by bill2023, Today, 08:51 AM
                          2 responses
                          16 views
                          0 likes
                          Last Post bill2023  
                          Working...
                          X