Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

OnMarketDepth

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

    #16
    Thanks Ray. That is exactly what I expected to be the situation. Now, maybe I've missed something, but I don't understand this situation. This is from the NT forum SampleMarketDepth example in the original scenario I mentioned - I've cut out some logging

    Code:
    21/10/2010 06:03:55  InsertBid position = 0  price = 1.035  volume = 1   GetCurrentBid = 1.035
    21/10/2010 06:03:55  Bid Price=1.0349 Volume=2 Position=1 Bid = 1.035
    
    21/10/2010 06:03:55  RemoveBid position = 0  price = 0  volume = 0   GetCurrentBid = 1.035
    21/10/2010 06:03:55  Bid Price=1.0349 Volume=2 Position=0 Bid = 1.035
    
    
    21/10/2010 06:03:55  UpdateBid position = 0  price = 1.0349  volume = 1   GetCurrentBid = 1.035
    21/10/2010 06:03:55  Bid Price=1.0349 Volume=1 Position=0 Bid = 1.035
    21/10/2010 06:03:55  Bid Price=1.0349 Volume=1 Position=0 Bid = 1.035
    As you can see, even when L2 data is saying bid = 1.0349, GetCurrentBid is still saying 1.035.

    My altered strat is copied below

    regards
    Dave



    #region Using declarations
    using System;
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.ComponentModel;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Data;
    using NinjaTrader.Gui.Chart;
    #endregion

    // Add this to the declarations. It allows for the use of ArrayLists.
    using System.Collections.Generic;


    namespace NinjaTrader.Indicator
    {

    [Description("Sample demonstrating how you can create your own Level II data book.")]
    public class SampleMarketDepth : Indicator
    {
    #region Variables
    private List<LadderRow> askRows = new List<LadderRow>();
    private List<LadderRow> bidRows = new List<LadderRow>();

    private string sp = " | ";
    #endregion

    private class LadderRow
    {
    public string MarketMaker; // relevant for stocks only
    public double Price;
    public long Volume;

    public LadderRow(double myPrice, long myVolume, string myMarketMaker)
    {
    MarketMaker = myMarketMaker;
    Price = myPrice;
    Volume = myVolume;
    }
    }

    protected override void Initialize()
    {
    CalculateOnBarClose = true;
    Overlay = false;
    PriceTypeSupported = false;
    }


    protected override void OnBarUpdate()
    {
    // Since the L2 data is only stored on real-time bars, there is no need to print L2 books on historical data
    if (Historical)
    return;


    }


    protected override void OnMarketDepth(MarketDepthEventArgs e)
    {


    List<LadderRow> rows = null;

    // Checks to see if the Market Data is of the Ask type
    if (e.MarketDataType == MarketDataType.Ask)
    rows = askRows;

    // Checks to see if the Market Data is of the Bid type
    else if (e.MarketDataType == MarketDataType.Bid) {

    rows = bidRows;
    }

    if (rows == null)
    return;

    if (e.MarketDataType == MarketDataType.Bid && e.Position < 2)
    Print(Time[0]+" "+e.Operation.ToString()+e.MarketDataType.ToString ()+" position = "+
    e.Position+" price = "+e.Price+" volume = "+e.Volume+" GetCurrentBid = "+GetCurrentBid());

    if (e.Operation == Operation.Insert)
    {

    if (e.Position >= rows.Count)
    rows.Add(new LadderRow(e.Price, e.Volume, e.MarketMaker));


    else
    rows.Insert(e.Position, new LadderRow(e.Price, e.Volume, e.MarketMaker));
    }


    else if (e.Operation == Operation.Remove && e.Position < rows.Count)
    rows.RemoveAt(e.Position);


    else if (e.Operation == Operation.Update)
    {
    rows[e.Position].MarketMaker = e.MarketMaker;
    rows[e.Position].Price = e.Price;
    rows[e.Position].Volume = e.Volume;
    }


    for (int idx = 0; idx < bidRows.Count; idx++)
    if (bidRows[idx].Price == 1.0349)
    Print(Time[0]+" "+"Bid Price=" + bidRows[idx].Price + " Volume=" + bidRows[idx].Volume + " Position=" + idx + " Bid = "+GetCurrentBid());
    }

    #region Properties

    #endregion
    }
    }

    #region NinjaScript generated code. Neither change nor remove.
    // This namespace holds all indicators and is required. Do not change it.
    namespace NinjaTrader.Indicator
    {
    public partial class Indicator : IndicatorBase
    {
    private SampleMarketDepth[] cacheSampleMarketDepth = null;

    private static SampleMarketDepth checkSampleMarketDepth = new SampleMarketDepth();

    /// <summary>
    /// Sample demonstrating how you can create your own Level II data book.
    /// </summary>
    /// <returns></returns>
    public SampleMarketDepth SampleMarketDepth()
    {
    return SampleMarketDepth(Input);
    }

    /// <summary>
    /// Sample demonstrating how you can create your own Level II data book.
    /// </summary>
    /// <returns></returns>
    public SampleMarketDepth SampleMarketDepth(Data.IDataSeries input)
    {
    if (cacheSampleMarketDepth != null)
    for (int idx = 0; idx < cacheSampleMarketDepth.Length; idx++)
    if (cacheSampleMarketDepth[idx].EqualsInput(input))
    return cacheSampleMarketDepth[idx];

    lock (checkSampleMarketDepth)
    {
    if (cacheSampleMarketDepth != null)
    for (int idx = 0; idx < cacheSampleMarketDepth.Length; idx++)
    if (cacheSampleMarketDepth[idx].EqualsInput(input))
    return cacheSampleMarketDepth[idx];

    SampleMarketDepth indicator = new SampleMarketDepth();
    indicator.BarsRequired = BarsRequired;
    indicator.CalculateOnBarClose = CalculateOnBarClose;
    #if NT7
    indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
    indicator.MaximumBarsLookBack = MaximumBarsLookBack;
    #endif
    indicator.Input = input;
    Indicators.Add(indicator);
    indicator.SetUp();

    SampleMarketDepth[] tmp = new SampleMarketDepth[cacheSampleMarketDepth == null ? 1 : cacheSampleMarketDepth.Length + 1];
    if (cacheSampleMarketDepth != null)
    cacheSampleMarketDepth.CopyTo(tmp, 0);
    tmp[tmp.Length - 1] = indicator;
    cacheSampleMarketDepth = tmp;
    return indicator;
    }
    }
    }
    }

    // This namespace holds all market analyzer column definitions and is required. Do not change it.
    namespace NinjaTrader.MarketAnalyzer
    {
    public partial class Column : ColumnBase
    {
    /// <summary>
    /// Sample demonstrating how you can create your own Level II data book.
    /// </summary>
    /// <returns></returns>
    [Gui.Design.WizardCondition("Indicator")]
    public Indicator.SampleMarketDepth SampleMarketDepth()
    {
    return _indicator.SampleMarketDepth(Input);
    }

    /// <summary>
    /// Sample demonstrating how you can create your own Level II data book.
    /// </summary>
    /// <returns></returns>
    public Indicator.SampleMarketDepth SampleMarketDepth(Data.IDataSeries input)
    {
    return _indicator.SampleMarketDepth(input);
    }
    }
    }

    // This namespace holds all strategies and is required. Do not change it.
    namespace NinjaTrader.Strategy
    {
    public partial class Strategy : StrategyBase
    {
    /// <summary>
    /// Sample demonstrating how you can create your own Level II data book.
    /// </summary>
    /// <returns></returns>
    [Gui.Design.WizardCondition("Indicator")]
    public Indicator.SampleMarketDepth SampleMarketDepth()
    {
    return _indicator.SampleMarketDepth(Input);
    }

    /// <summary>
    /// Sample demonstrating how you can create your own Level II data book.
    /// </summary>
    /// <returns></returns>
    public Indicator.SampleMarketDepth SampleMarketDepth(Data.IDataSeries input)
    {
    if (InInitialize && input == null)
    throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

    return _indicator.SampleMarketDepth(input);
    }
    }
    }
    #endregion

    Comment


      #17
      Dave,

      This can be expected. GetCurrentBid/Ask returns the Market Data object which can have a more recent bid/ask info than the one currently being processed by OnMarketData/Depth yet.
      Josh P.NinjaTrader Customer Service

      Comment


        #18
        In which case I'm maybe falling foul of the filtering problem in this thread http://www.ninjatrader.com/support/f...ad.php?t=34703


        I'm not completely sure that would explain a load of bid updates before their level 2 equivalents, as below. Surely the level2 would just never happen if they are filtered.

        In any case, if the marketdata object is updated so much quicker than OnMarketDepths can be processed, it would be nice if level 2 was in the object and it could be queried directly?

        Code:
        21/10/2010 06:03:54    Bid = 1.0351
        21/10/2010 06:03:54    Bid = 1.035
        21/10/2010 06:03:54    Bid = 1.0349
        21/10/2010 06:03:54    Bid = 1.0349
        21/10/2010 06:03:54    Bid = 1.0349
        21/10/2010 06:03:54    Bid = 1.0348
        21/10/2010 06:03:54    Bid = 1.0348
        21/10/2010 06:03:54    Bid = 1.0348
        21/10/2010 06:03:54    Bid = 1.0349
        21/10/2010 06:03:54    Bid = 1.0349
        21/10/2010 06:03:54    Bid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0351    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Remove    Bid    price = 0    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Remove    Bid    price = 0    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0349    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0349    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Remove    Bid    price = 0    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0348    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0348    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Insert    Bid    price = 1.0349    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0349    GetCurrentBid = 1.0349
        21/10/2010 06:03:54  Update    Bid    price = 1.0349    GetCurrentBid = 1.0349

        Comment


          #19
          A question:

          If Level 2 is unfiltered, do the events get processed by the relevant Ninja overrides in the correct order - e.g. if a trade for 200 occurs (and let's say nothing else in the level2) can I expect the trade to fire and then a level2 update of the volume for -200 before the next trade comes in?

          Comment


            #20
            dave1992,

            When you are using replay files that may not necessarily be the case. The L1 and L2 data are stored on different files and the granularity is recorded down to the second. These two files are only synced to the second and the exact intra-second sequencing would not be there.

            This is an area we are going to be looking to improve post NT7 by combining both L1 and L2 into the same file where everything will be preserved as they occurred in real-time.
            Josh P.NinjaTrader Customer Service

            Comment


              #21
              NT_Josh,

              Do you know if the addition of milli/microsecond timestamps is being considered in order to accomplish this? I capture millisecond timestamps today using the system clock and then build my own book but having the timestamp data from the broker would improve the data integrity, not to mention it would make NT a better platform for HFT development.
              Last edited by mgin98; 10-27-2010, 11:18 AM.

              Comment


                #22
                It is indeed on the plate being considered for post NT7.
                Josh P.NinjaTrader Customer Service

                Comment


                  #23
                  Originally posted by NinjaTrader_Josh View Post
                  dave1992,

                  When you are using replay files that may not necessarily be the case. The L1 and L2 data are stored on different files and the granularity is recorded down to the second. These two files are only synced to the second and the exact intra-second sequencing would not be there.

                  This is an area we are going to be looking to improve post NT7 by combining both L1 and L2 into the same file where everything will be preserved as they occurred in real-time.
                  Thanks Josh. So how does Ninja decide what to process next from the two files for each second? Random? All level 1 first then level 2?

                  Comment


                    #24
                    It would be random. The sequence is not hard set defined.
                    Josh P.NinjaTrader Customer Service

                    Comment


                      #25
                      Originally posted by NinjaTrader_Josh View Post
                      It would be random. The sequence is not hard set defined.
                      Oh dear ;-) Good luck with the development work.

                      OK, so switching to real time data, ZF and DTN are supposed to be sending bid/ask data and trades in the correct order, such that each trade can be properly determined to have been at the bid or ask?

                      thanks
                      Dave

                      Comment


                        #26
                        Yes, in real-time you will receive the events as they come in. There is no "syncing" to speak of because they come however the feed pushes them out.
                        Josh P.NinjaTrader Customer Service

                        Comment


                          #27
                          Originally posted by NinjaTrader_Josh View Post
                          dave1992,

                          When you are using replay files that may not necessarily be the case. The L1 and L2 data are stored on different files and the granularity is recorded down to the second. These two files are only synced to the second and the exact intra-second sequencing would not be there.
                          The L1 and L2 data doesn't appear to be synced at all to the trade data

                          21/10/2010 07:05:39 UpdateBid | | 0 | 129.89 | 56
                          21/10/2010 07:05:41 Trade 1 at 129.9
                          21/10/2010 07:05:41 Trade 110 at 129.89
                          21/10/2010 07:05:41 Trade 113 at 129.89
                          21/10/2010 07:05:40 UpdateBid | | 0 | 129.89 | 52
                          21/10/2010 07:05:40 UpdateAsk | | 0 | 129.9 | 115
                          21/10/2010 07:05:40 UpdateBid | | 0 | 129.89 | 51

                          I'm not sure how to do anything meaningful with this at all. Could the trade data not be synced to the same second as the L1/L2??

                          Comment


                            #28
                            That is because you are printing Bar time which is not relevant from within OnMarketDepth or OnMarketData. Instead you should print the event time since Bars series are not relevant in the OnMarketData/Depth methods.

                            Code:
                            OnMarketData: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:38 AM
                            OnMarketDepth: 10/21/2010 7:05:39 AM
                            OnMarketData: 10/21/2010 7:05:40 AM
                            OnMarketData: 10/21/2010 7:05:40 AM
                            OnMarketDepth: 10/21/2010 7:05:40 AM
                            OnMarketDepth: 10/21/2010 7:05:40 AM
                            OnMarketDepth: 10/21/2010 7:05:40 AM
                            OnMarketDepth: 10/21/2010 7:05:40 AM
                            OnMarketDepth: 10/21/2010 7:05:40 AM
                            OnMarketData: 10/21/2010 7:05:41 AM
                            Attached Files
                            Josh P.NinjaTrader Customer Service

                            Comment


                              #29
                              No, I'm not doing that. I am using event time.

                              Comment


                                #30
                                From your code in Post #16 you are printing Bar time, not event time.
                                Code:
                                for (int idx = 0; idx < bidRows.Count; idx++)
                                                    if (bidRows[idx].Price == 1.0349)
                                                    Print([SIZE=4][COLOR=Red][B]Time[0][/B][/COLOR][/SIZE]+"  "+"Bid Price=" + bidRows[idx].Price  + " Volume=" + bidRows[idx].Volume + " Position=" + idx + " Bid =  "+GetCurrentBid());
                                        }
                                Josh P.NinjaTrader Customer Service

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by llanqui, Yesterday, 09:59 AM
                                3 responses
                                22 views
                                0 likes
                                Last Post llanqui
                                by llanqui
                                 
                                Started by smartromain, 03-13-2024, 01:42 AM
                                5 responses
                                93 views
                                0 likes
                                Last Post AndreiBig  
                                Started by Noerclou, Today, 04:55 AM
                                0 responses
                                4 views
                                0 likes
                                Last Post Noerclou  
                                Started by ThoriSten, Today, 03:56 AM
                                0 responses
                                6 views
                                0 likes
                                Last Post ThoriSten  
                                Started by PhillT, 04-19-2024, 02:16 PM
                                3 responses
                                26 views
                                0 likes
                                Last Post mangel2000  
                                Working...
                                X