Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

How should I approach measuring the time span for price to change?

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

    How should I approach measuring the time span for price to change?

    NinjaTrader_ChelseaB thanks for this code
    UpDownTickTest_NT8.zip
    Hello All, Hope you are well, I have a quick question! I am developing an indicator that can use Tick Replay to get the Delta values of bars. I have already developed the Bid/Ask Delta. I am having issues calculating the UpDownTick Delta. I have tried all the combinations I could think of, closest I came to the actual


    I'm interested in using Chris snippet with yours
    Is their a builtin method that allows one to get the speed at which a price changed? Not really bid/ask change but when a price is changed as a result of


    Yours shows these lines 143-150 of interest

    double price = BarsArray[1].GetClose(whatBar);

    // This is where we decide what index to use
    int whatBar = useCurrentBar ? CurrentBars[1] : Math.Min(CurrentBars[1] + 1, BarsArray[1].Count - 1);

    // This is how we get the right tick values
    double volume = BarsArray[1].GetVolume(whatBar);
    double price = BarsArray[1].GetClose(whatBar);

    if (price > BarsArray[1].GetClose(whatBar - 1) || (price == BarsArray[1].GetClose(whatBar - 1) && up))
    {
    ​​


    Chris's snippet of interest

    private Stopwatch stopWatch = new Stopwatch();

    protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
    {
    stopWatch.Stop();

    TimeSpan ts = stopWatch.Elapsed;
    Print(String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
    ts.Hours, ts.Minutes, ts.Seconds,
    ts.Milliseconds / 10));
    stopWatch.Reset();
    stopWatch.Start();
    }


    How should I approach measuring the time span for price to change?

    I checked how stopwatch timer work

    I have created a simple console application where the User must complete a certain task and the time take to do this is measured. To measure the time take I am using the Stopwatch class and have cr...

    In this article, we will see how to use the Stopwatch object in C# to find the time taken to perform a specific task using the public timespan elapsed time property

    This article provides an introduction to Stopwatch, a simple tool for accurately measuring elapsed time.


    But not sure how to apply this knowledge to current case​​​​

    #2
    Hello PaulMohn,

    The example from Chris is measuring how much time has elapsed from one market up date the to next.

    This thread is about using a 1 tick series in OnBarUpdate to collect volume similar to the Volumetric bars with UpDownTick selected.

    What are you trying to accomplish?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Accomplish this
      measuring how much time has elapsed from price change up and/or down, same as the OP bc24fl here
      Is their a builtin method that allows one to get the speed at which a price changed? Not really bid/ask change but when a price is changed as a result of


      How can the stopwatch do this with your example?

      double price = BarsArray[1].GetClose(whatBar);

      if (price > BarsArray[1].GetClose(whatBar - 1) || price < BarsArray[1].GetClose(whatBar - 1))


      I thought of this but still not sure


      double price = BarsArray[1].GetClose(whatBar);

      if (price > BarsArray[1].GetClose(whatBar - 1) || price < BarsArray[1].GetClose(whatBar - 1))
      {
      // measure time elapsed for price to uptick or downtick
      }​​

      Comment


        #4
        Hello PaulMohn,

        I've moved this to a separate thread as this is not on the same topic of the other thread.

        Using a stopwatch (for real-time only and not historical), you could use in the CalculateValues() method under where price is declared:

        if (State == State.Realtime && price != BarsArray[1].GetClose(whatBar - 1))
        {
        stopWatch.Stop();

        TimeSpan ts = stopWatch.Elapsed;
        Print(String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10));
        stopWatch.Reset();
        stopWatch.Start();​
        }
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          NinjaTrader_ChelseaB Hello,

          It's only printing "00:00:00.00"

          with this

          if (State == State.Realtime && price != BarsArray[1].GetClose(whatBar - 1))
          {
          System.Diagnostics.Stopwatch myStopWatch = new System.Diagnostics.Stopwatch();

          myStopWatch.Stop();

          TimeSpan ts = myStopWatch.Elapsed;
          Print(String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10));
          myStopWatch.Reset();
          myStopWatch.Start();​
          }

          Why no laps is returned?​
          Attached Files

          Comment


            #6
            Hello PaulMohn,

            The StopWatch variable would be declared in the scope of the class, an object instantiated and assigned from State.DataLoaded, and then would be enabled from OnBarUpdate().

            (Otherwise you are creating a new stop watch every bar update and disregarding the timer that was running from the previous bar)
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Originally posted by NinjaTrader_ChelseaB View Post
              Hello PaulMohn,

              The StopWatch variable would be declared in the scope of the class, an object instantiated and assigned from State.DataLoaded, and then would be enabled from OnBarUpdate().

              (Otherwise you are creating a new stop watch every bar update and disregarding the timer that was running from the previous bar)
              That worked, thanks!
              Attached Files

              Comment


                #8
                Contribute to calebsandfort/ninjatrader development by creating an account on GitHub.


                Code:
                #region Using declarations
                using System;
                using System.Collections.Generic;
                using System.ComponentModel;
                using System.ComponentModel.DataAnnotations;
                using System.Linq;
                using System.Text;
                using System.Threading.Tasks;
                using System.Windows;
                using System.Windows.Input;
                using System.Windows.Media;
                using System.Xml.Serialization;
                using NinjaTrader.Cbi;
                using NinjaTrader.Gui;
                using NinjaTrader.Gui.Chart;
                using NinjaTrader.Gui.SuperDom;
                using NinjaTrader.Gui.Tools;
                using NinjaTrader.Data;
                using NinjaTrader.NinjaScript;
                using NinjaTrader.Core.FloatingPoint;
                using NinjaTrader.NinjaScript.DrawingTools;
                #endregion
                
                //This namespace holds Indicators in this folder and is required. Do not change it.
                namespace NinjaTrader.NinjaScript.Indicators
                {
                    public class BarVelocity : Indicator
                    {
                        private Series<double> timeDiff;
                        private EMA timeDiffEma;
                
                        protected override void OnStateChange()
                        {
                            if (State == State.SetDefaults)
                            {
                                Description                                    = @"Enter the description for your new custom Indicator here.";
                                Name                                        = "BarVelocity";
                                Calculate                                    = Calculate.OnBarClose;
                                IsOverlay                                    = false;
                                DisplayInDataBox                            = true;
                                DrawOnPricePanel                            = true;
                                DrawHorizontalGridLines                        = true;
                                DrawVerticalGridLines                        = true;
                                PaintPriceMarkers                            = true;
                                ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                                //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                                //See Help Guide for additional information.
                                IsSuspendedWhileInactive                    = true;
                                Period                    = 6;
                                AddPlot(Brushes.HotPink, "BarVelocityPlot");
                            }
                            else if (State == State.DataLoaded)
                            {
                                timeDiff = new Series<double>(this);
                                timeDiffEma = EMA(timeDiff, Period);
                            }
                        }
                
                        protected override void OnBarUpdate()
                        {
                            if (CurrentBar == 0) return;
                
                            timeDiff[0] = (Time[0] - Time[1]).TotalMilliseconds;
                            BarVelocityPlot[0] = timeDiffEma[0];
                        }
                
                        #region Properties
                        [NinjaScriptProperty]
                        [Range(1, int.MaxValue)]
                        [Display(Name="Period", Order=1, GroupName="Parameters")]
                        public int Period
                        { get; set; }
                
                        [Browsable(false)]
                        [XmlIgnore]
                        public Series<double> BarVelocityPlot
                        {
                            get { return Values[0]; }
                        }
                        #endregion
                
                    }
                }
                
                #region NinjaScript generated code. Neither change nor remove.
                
                namespace NinjaTrader.NinjaScript.Indicators
                {
                    public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
                    {
                        private BarVelocity[] cacheBarVelocity;
                        public BarVelocity BarVelocity(int period)
                        {
                            return BarVelocity(Input, period);
                        }
                
                        public BarVelocity BarVelocity(ISeries<double> input, int period)
                        {
                            if (cacheBarVelocity != null)
                                for (int idx = 0; idx < cacheBarVelocity.Length; idx++)
                                    if (cacheBarVelocity[idx] != null && cacheBarVelocity[idx].Period == period && cacheBarVelocity[idx].EqualsInput(input))
                                        return cacheBarVelocity[idx];
                            return CacheIndicator<BarVelocity>(new BarVelocity(){ Period = period }, input, ref cacheBarVelocity);
                        }
                    }
                }
                
                namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
                {
                    public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
                    {
                        public Indicators.BarVelocity BarVelocity(int period)
                        {
                            return indicator.BarVelocity(Input, period);
                        }
                
                        public Indicators.BarVelocity BarVelocity(ISeries<double> input , int period)
                        {
                            return indicator.BarVelocity(input, period);
                        }
                    }
                }
                
                namespace NinjaTrader.NinjaScript.Strategies
                {
                    public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                    {
                        public Indicators.BarVelocity BarVelocity(int period)
                        {
                            return indicator.BarVelocity(Input, period);
                        }
                
                        public Indicators.BarVelocity BarVelocity(ISeries<double> input , int period)
                        {
                            return indicator.BarVelocity(input, period);
                        }
                    }
                }
                
                #endregion​

                Comment


                  #9
                  Code:
                  float highVol = 0;
                  
                  float smallWidthTrigger = 0;
                  float largeWidthTrigger = 0;
                  
                  // Set highVol outside of loop that paints bars
                  for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
                  {
                      float curVol = bars.GetVolume(idx);
                  
                      if (curVol > highVol)
                          highVol = curVol;
                  
                      smallWidthTrigger = highVol * (float)0.3333;
                      largeWidthTrigger = highVol * (float)0.6666;
                  }​
                  Update: 03-19-2019, changed the chartstyletype value from 8 to 1197, to avoid conflict with Volumetric chart style. This is an EquiVolume chart style for NinjaTrader 8. Based on traditional Japanese Candlesticks, the EquiVolume chart style alters the width of price bars dynamically based on the relative volume seen during each bar. Wider bars indicate that [&#8230;]


                  Code:
                  #region Using declarations
                  using System;
                  using System.Collections.Generic;
                  using System.ComponentModel;
                  using System.ComponentModel.DataAnnotations;
                  using System.Linq;
                  using System.Text;
                  using System.Threading.Tasks;
                  using System.Windows;
                  using System.Windows.Input;
                  
                  using System.Xml.Serialization;
                  using NinjaTrader.Cbi;
                  using NinjaTrader.Gui;
                  using NinjaTrader.Gui.Chart;
                  using NinjaTrader.Gui.SuperDom;
                  using NinjaTrader.Data;
                  using NinjaTrader.NinjaScript;
                  using NinjaTrader.Core.FloatingPoint;
                  
                  using SharpDX;
                  using SharpDX.Direct2D1;
                  
                  
                  #endregion
                  
                  //This namespace holds Chart styles in this folder and is required. Do not change it.
                  namespace NinjaTrader.NinjaScript.ChartStyles
                  {
                      public class EquiVolume : ChartStyle
                      {
                  
                          private int smallWidthModifier = -8;
                          private int midWidthModifier = 1;
                          private int largeWidthModifier = 6;
                  
                          protected override void OnStateChange()
                          {
                              if (State == State.SetDefaults)
                              {
                                  Description                    = @"EquiVolume Chart Style";
                                  Name                        = "EquiVolume";
                                  ChartStyleType                = (ChartStyleType) 1197;
                                  BarWidth                    = 2;
                              }
                              else if (State == State.Configure)
                              {
                                  Properties.Remove(Properties.Find("Stroke", false));
                                  Properties.Remove(Properties.Find("Stroke2", false));
                  
                                  SetPropertyName("DownBrush", "Down Bar Color");
                                  SetPropertyName("UpBrush", "Up Bar Color");
                                  SetPropertyName("BarWidthUI", "Base Width");
                              }
                          }
                  
                          public override int GetBarPaintWidth(int barWidth)
                          {
                              return 1 + 2 * (barWidth - 1) + 2 * (int)Math.Round(Stroke.Width);
                          }
                  
                          public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
                          {
                              Bars bars = chartBars.Bars;
                              float barWidth = GetBarPaintWidth(BarWidthUI);
                              Vector2 point0 = new Vector2();
                              Vector2 point1 = new Vector2();
                              RectangleF rect = new RectangleF();
                  
                              float highVol = 0;
                              float smallWidth = barWidth + smallWidthModifier;
                              float midWidth = barWidth + midWidthModifier;
                              float largeWidth = barWidth + largeWidthModifier;
                              float wickOffset = 0;
                  
                              float smallWidthTrigger = 0;
                              float largeWidthTrigger = 0;
                  
                              // Set highVol outside of loop that paints bars
                              for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
                              {
                                  float curVol = bars.GetVolume(idx);
                  
                                  if (curVol > highVol)
                                      highVol = curVol;
                  
                                  smallWidthTrigger = highVol * (float)0.3333;
                                  largeWidthTrigger = highVol * (float)0.6666;
                              }
                  
                              //Draw candles and wicks
                              for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
                              {
                                  Brush overriddenBarBrush = chartControl.GetBarOverrideBrush(chartBars, idx);
                                  Brush overriddenOutlineBrush = chartControl.GetCandleOutlineOverrideBrush(chartBars, idx);
                                  double closeValue = bars.GetClose(idx);
                                  float close = chartScale.GetYByValue(closeValue);
                                  float high = chartScale.GetYByValue(bars.GetHigh(idx));
                                  float low = chartScale.GetYByValue(bars.GetLow(idx));
                                  double openValue = bars.GetOpen(idx);
                                  float open = chartScale.GetYByValue(openValue);
                                  float x = chartControl.GetXByBarIndex(chartBars, idx);
                                  float curVol = bars.GetVolume(idx);
                                  
                                  if (Math.Abs(open - close) < 0.0000001)
                                  {
                                      // Line
                                      point0.X = x - barWidth * 0.5f;
                                      point0.Y = close;
                                      point1.X = x + barWidth * 0.5f;
                                      point1.Y = close;
                                      TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, new RectangleF(point0.X, point0.Y - Stroke.Width, barWidth, Stroke.Width));
                                      RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                                  }
                                  else
                                  {
                                      // Candle
                                      Brush brush = closeValue >= openValue ? UpBrushDX : DownBrushDX;
                                      rect.X = (x - barWidth * 0.5f + 0.5f);
                                      rect.Y = Math.Min(close, open);
                  
                                      if (curVol < smallWidthTrigger)
                                      {
                                          rect.Width = smallWidth;
                                          wickOffset = smallWidth;
                                      }
                                      else if (curVol > largeWidthTrigger)
                                      {
                                          rect.Width = largeWidth;
                                          wickOffset = largeWidth;
                                      }
                                      else
                                      {
                                          rect.Width = midWidth;
                                          wickOffset = midWidth;
                                      }
                   
                                      rect.Height = Math.Max(open, close) - Math.Min(close, open);
                                      TransformBrush(overriddenBarBrush ?? brush, rect);
                                      TransformBrush(overriddenOutlineBrush ?? Stroke.BrushDX, rect);
                                      RenderTarget.FillRectangle(rect, overriddenBarBrush ?? brush);
                                      RenderTarget.DrawRectangle(rect, overriddenOutlineBrush ?? Stroke.BrushDX, Stroke.Width, Stroke.StrokeStyle);
                  
                                      // High wick
                                      if (high < Math.Min(open, close))
                                      {
                                          point0.X = rect.X + wickOffset / 2;
                                          point1.X = rect.X + wickOffset / 2;
                                          point0.Y = high;
                                          point1.Y = Math.Min(open, close);
                                          TransformBrush(overriddenOutlineBrush ?? Stroke2.BrushDX, new RectangleF(point0.X - Stroke2.Width, point0.Y, Stroke2.Width, point1.Y - point0.Y));
                                          RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                                      }
                  
                                      // Low wick
                                      if (low > Math.Max(open, close))
                                      {
                                          point0.X = rect.X + wickOffset / 2;
                                          point1.X = rect.X + wickOffset / 2;
                                          point0.Y = low;
                                          point1.Y = Math.Max(open, close);
                                          TransformBrush(overriddenOutlineBrush ?? Stroke2.BrushDX, new RectangleF(point1.X - Stroke2.Width, point1.Y, Stroke2.Width, point0.Y - point1.Y));
                                          RenderTarget.DrawLine(point0, point1, overriddenOutlineBrush ?? Stroke2.BrushDX, Stroke2.Width, Stroke2.StrokeStyle);
                                      }
                                  }
                              }
                  
                  
                  
                          }
                          [NinjaScriptProperty]
                          [Display(ResourceType = typeof(Custom.Resource), Name = "Low Volume Modifier", GroupName = "NinjaScriptParameters", Order = 0)]
                          public int SmallWidthModifier
                          {
                              get { return smallWidthModifier; }
                              set { smallWidthModifier = value; }
                          }
                  
                          [NinjaScriptProperty]
                          [Display(ResourceType = typeof(Custom.Resource), Name = "Medium Volume Modifier", GroupName = "NinjaScriptParameters", Order = 1)]
                          public int MidWidthModifier
                          {
                              get { return midWidthModifier; }
                              set { midWidthModifier = value; }
                          }
                  
                          [NinjaScriptProperty]
                          [Display(ResourceType = typeof(Custom.Resource), Name = "High Volume Modifier", GroupName = "NinjaScriptParameters", Order = 2)]
                          public int LargeWidthModifier
                          {
                              get { return largeWidthModifier; }
                              set { largeWidthModifier = value; }
                          }
                      }
                  }
                  
                  ​

                  Comment


                    #10
                    LargeTrades Strategy NT8

                    https://ninjatraderecosystem.com/user-app-share-download/largetrades-strategy-nt8/


                    https://ninjatraderecosystem.com/user-app-share-download/largetrades-strategy-nt8/

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                    0 responses
                    597 views
                    0 likes
                    Last Post Geovanny Suaza  
                    Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                    0 responses
                    343 views
                    1 like
                    Last Post Geovanny Suaza  
                    Started by Mindset, 02-09-2026, 11:44 AM
                    0 responses
                    103 views
                    0 likes
                    Last Post Mindset
                    by Mindset
                     
                    Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                    0 responses
                    556 views
                    1 like
                    Last Post Geovanny Suaza  
                    Started by RFrosty, 01-28-2026, 06:49 PM
                    0 responses
                    555 views
                    1 like
                    Last Post RFrosty
                    by RFrosty
                     
                    Working...
                    X