Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Time & Sales Count

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

    Time & Sales Count

    I am working on a indicator that counts the times when the time & sales volume is greater than 3.

    Questions 1: Normally, you see the time & sales in either a green or orange color. I assume when it is green, that means the trade was executed at the Ask price whereas when it is orange, that means the trade was executed at the Bid price. Please confirm that I have this correct.

    Click image for larger version

Name:	image.png
Views:	153
Size:	10.2 KB
ID:	1335424

    Question 2: In my custom indicator, how do I determine whether the Last Price was executed at the Bid or Ask price (i.e. whether it was green or orange on the Time & Sales window)? I want to have the ability to count the number of times the volume was greater than 3 when the Last Price was executed at the Bid price compared to the number of times the volume was greater than 3 when the Last Price was executed at the Ask Price. As you can see in below pic, there was a volume of 3 that was executed at the Bid Price and then there was another time where the volume was 4 but it was executed at the Ask Price but they both contributed to my "Count" . I want to count them separately. How do I go about doing that? I attached the code below:
    Click image for larger version

Name:	image.png
Views:	81
Size:	59.3 KB
ID:	1335425
    HTML 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 TEST2 : Indicator
        {
            private int Count;
            
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Enter the description for your new custom Indicator here.";
                    Name                                        = "TEST2";
                    Calculate                                    = Calculate.OnEachTick;
                    IsOverlay                                    = true;
                    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;
                    Count = 0;
                }
                else if (State == State.Configure)
                {
                }
            }
    
            protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
            {
                if(marketDataUpdate.MarketDataType == MarketDataType.Last)
                {
                    Print(Time[0].ToString() + string.Format("Last = {0} {1} ", marketDataUpdate.Last, marketDataUpdate.Volume));
                    if(marketDataUpdate.Volume >= 3)
                    {
                        Count = Count + 1;
                        Print(Time[0].ToString() + "Count = " + Count);
                    }
                }            
            }
            protected override void OnBarUpdate()
            {
                
            }
            
            #region Properties
            [NinjaScriptProperty]
            [Display(ResourceType = typeof(Custom.Resource), Name = "Enter Minute Bar Chart", GroupName = "NinjaScriptStrategyParameters", Order = 3)]
            public int MinuteBar
            { get; set; }
            #endregion
        }
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
        {
            private TEST2[] cacheTEST2;
            public TEST2 TEST2(int minuteBar)
            {
                return TEST2(Input, minuteBar);
            }
    
            public TEST2 TEST2(ISeries<double> input, int minuteBar)
            {
                if (cacheTEST2 != null)
                    for (int idx = 0; idx < cacheTEST2.Length; idx++)
                        if (cacheTEST2[idx] != null && cacheTEST2[idx].MinuteBar == minuteBar && cacheTEST2[idx].EqualsInput(input))
                            return cacheTEST2[idx];
                return CacheIndicator<TEST2>(new TEST2(){ MinuteBar = minuteBar }, input, ref cacheTEST2);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
        public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
        {
            public Indicators.TEST2 TEST2(int minuteBar)
            {
                return indicator.TEST2(Input, minuteBar);
            }
    
            public Indicators.TEST2 TEST2(ISeries<double> input , int minuteBar)
            {
                return indicator.TEST2(input, minuteBar);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
        {
            public Indicators.TEST2 TEST2(int minuteBar)
            {
                return indicator.TEST2(Input, minuteBar);
            }
    
            public Indicators.TEST2 TEST2(ISeries<double> input , int minuteBar)
            {
                return indicator.TEST2(input, minuteBar);
            }
        }
    }
    
    #endregion
    
    ​
    Question 3: How do i get my print to include time down to the seconds? See previous pic. The print only does hours and minutes whereas the Time & Sales does hours, minutes & seconds

    #2
    good questions

    Comment


      #3
      Hello algospoke,

      Below is a link to an example that processes market data like the time and sales window.


      Use a date and time format string to show milliseconds.
      Learn to use custom date and time format strings to convert DateTime or DateTimeOffset values into text representations, or to parse strings for dates & times.

      Comment


        #4
        Chelsea,

        This was very helpful. On the T&S screen, a line will be pink whenever the sell order occurs below the bid price (similar for when there is buy order over the ask price and its colored in gold). See below pic. I modified the TnSPrintsExample to print whenever this occurs however it seems the print always says Last is always same as the Bid even though the T&S screen is saying the last order was below the Bid price (i.e. pink). Why is there a difference? I included the updated TnSPrintsExample and I took a snip of the code that I changed.
        Click image for larger version

Name:	image.png
Views:	74
Size:	94.6 KB
ID:	1335822
        Click image for larger version

Name:	image.png
Views:	64
Size:	26.7 KB
ID:	1335823

        Comment


          #5
          Hello algospoke,

          From testing I see the Time & Sales window must be using GetCurrentAsk(), GetCurrentBid() for comparisons to 'jump the line' and get the ask from the instrument instead of the most recent market update.

          I've modified the script to reflect this.
          TimeAndSalesExamples_NT8.zip

          Comment


            #6
            Chelsea,

            This makes sense however I am seeing some discrepancies when I run your updated indicator on Playback. See below pic. I ran the indicator on Playback on ES 03-25 for 2/18/25 at 10:00:54 EST. As you can see from the output window, right when time changes from 10:00:53 to 10:00:54, the print says "gold - above ask" however the T&S window is showing chocolate. Do you know what the issue is? Is it a data issue on Playback? Do I the correct data plan to run this Playback accurately? Can you try the same instrument and date/time and see if you are seeing the same prints that I shown below?

            Click image for larger version

Name:	image.png
Views:	66
Size:	185.3 KB
ID:	1335943

            Comment


              #7
              Hello algospoke,

              Playback with Market Replay data is not part of a data plan.

              The update is 6133.25 the instrument ask is 6132.25 while the last market data update ask is 6133.50.

              If we compare with the instrument direct ask (GetCurrentAsk()) the market update was above the ask.
              If we compare with the most recent ask market update push the market update was below the ask.

              We may have an issue of when the ninjascript thread is getting pushed an update and when the instrument itself has new information.
              I'm not certain which is more accurate. However, testing with real-time data using the instrument ask appears to be more accurate.

              Comment


                #8
                Originally posted by NinjaTrader_ChelseaB View Post
                Hello algospoke,

                Playback with Market Replay data is not part of a data plan.

                The update is 6133.25 the instrument ask is 6132.25 while the last market data update ask is 6133.50.

                If we compare with the instrument direct ask (GetCurrentAsk()) the market update was above the ask.
                If we compare with the most recent ask market update push the market update was below the ask.

                We may have an issue of when the ninjascript thread is getting pushed an update and when the instrument itself has new information.
                I'm not certain which is more accurate. However, testing with real-time data using the instrument ask appears to be more accurate.
                I've made an indicator based on GetCurrentAsk/Bid as per your code and it does not match T&S on live data (indicator on the left should have green bars, not yellow):

                Click image for larger version  Name:	image.png Views:	0 Size:	13.7 KB ID:	1341261

                another example:
                Click image for larger version

Name:	image.png
Views:	23
Size:	4.7 KB
ID:	1341262

                my code:
                PHP Code:
                        protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
                        {
                            if (marketDataUpdate.MarketDataType != MarketDataType.Last)
                                return;
                            
                
                                
                            // Create a new trade record
                            TradeRecord trade = new TradeRecord
                            {
                                Price = marketDataUpdate.Price,
                                Volume = marketDataUpdate.Volume,
                                Timestamp = marketDataUpdate.Time
                            };
                            
                            // Get current bid and ask
                            currentAsk = GetCurrentAsk();
                            currentBid = GetCurrentBid();
                            // Determine trade type - follow the exact logic from the example
                            if (marketDataUpdate.Price == currentAsk)
                            {
                                trade.Type = TradeType.AtAsk;
                            }
                            else if (marketDataUpdate.Price == currentBid)
                            {
                                trade.Type = TradeType.AtBid;
                            }
                            else if (marketDataUpdate.Price > currentAsk)
                            {
                                trade.Type = TradeType.AboveAsk;
                            }
                            else if (marketDataUpdate.Price < currentBid)
                            {
                                trade.Type = TradeType.BelowBid;
                            }
                            
                            // Block alert takes precedence over all other types
                            if (marketDataUpdate.Volume > BlockSize)
                            {
                               // trade.Type = TradeType.Block;
                            }
                            
                            // Add to buffer
                            tradeBuffer.Add(trade);
                        }&#8203; 
                
                Last edited by MiCe1999; 04-23-2025, 07:33 PM.

                Comment


                  #9
                  Hello MiCe1999,

                  The logic you have is not the same as mine as the branching commands are in a different sequence.

                  That said, as mentioned in post # 7 I'm seeing the instrument market update (marketUpdate.Ask / marketUpdate.Bid) appears to be more accurate than GetCurrentAsk() / GetCurrentBid() just due to when the script updates and when the Time & Sales window updates.

                  Comment


                    #10
                    Originally posted by NinjaTrader_ChelseaB View Post
                    Hello MiCe1999,

                    The logic you have is not the same as mine as the branching commands are in a different sequence.

                    That said, as mentioned in post # 7 I'm seeing the instrument market update (marketUpdate.Ask / marketUpdate.Bid) appears to be more accurate than GetCurrentAsk() / GetCurrentBid() just due to when the script updates and when the Time & Sales window updates.
                    Hi. Thank you for your reply. As far as I know, branching is one level deep so order does not matter - I just reordered it so more likely scenario get tested sooner. I guess this are the best results we can get. In another post I discovered an issue with Now time being behind tick time (Now - time stamp is negative) which maybe one of the reasons results are off.

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by abelsheila, 05-14-2025, 07:38 PM
                    2 responses
                    30 views
                    0 likes
                    Last Post hglover945  
                    Started by nailz420, 05-14-2025, 09:14 AM
                    1 response
                    57 views
                    0 likes
                    Last Post NinjaTrader_ChristopherJ  
                    Started by NinjaTrader_Brett, 05-12-2025, 03:19 PM
                    0 responses
                    327 views
                    1 like
                    Last Post NinjaTrader_Brett  
                    Started by domjabs, 05-12-2025, 01:55 PM
                    2 responses
                    62 views
                    0 likes
                    Last Post domjabs
                    by domjabs
                     
                    Started by Morning Cup Of Trades, 05-12-2025, 11:50 AM
                    1 response
                    81 views
                    0 likes
                    Last Post NinjaTrader_ChristopherJ  
                    Working...
                    X