Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Level 2 Market Data Simulator

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

    Level 2 Market Data Simulator

    I'm interested in knowing how to provide test data that I generate programmatically to the Level II window. I have developed the following code, but it won't compile without errors:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using NinjaTrader.Cbi;

    using NinjaTrader.Data;
    using System.Runtime.InteropServices;
    using System.Threading;
    using NinjaTrader.Client;

    namespace NT8ExternalDataFeed
    {
    class Program
    {
    [DllImport("NTDirect.dll")]
    public static extern int Last(string instrument, double price, int size);

    [DllImport("NTDirect.dll")]
    public static extern int Ask(string instrument, double price, int size);

    [DllImport("NTDirect.dll")]
    public static extern int Bid(string instrument, double price, int size);

    static NinjaTrader.Client.Client NTClient;
    static Object _ATILock = new Object();
    public static int sequenceNumber;

    // Static constructor to initialize the connection with NinjaTrader
    static void ClientConnect()
    {
    // Initialize the client instance only once
    if (NTClient == null)
    {
    NTClient = new NinjaTrader.Client.Client();
    sequenceNumber = 0;
    }
    }

    // Method to send Level 2 data
    public static void SendLevel2Data(string instrument, double bidPrice, double bidSize, double askPrice, double askSize, double lastPrice, double lastSize)
    {
    lock (_ATILock)
    {
    // Ensure the client instance is not null
    if (NTClient != null)
    {
    NTClient.Bid(instrument, bidPrice, (int)bidSize);
    NTClient.Ask(instrument, askPrice, (int)askSize);
    NTClient.Last(instrument, lastPrice, (int)lastSize);
    }
    }
    }

    // Method to tear down the connection with NinjaTrader
    public static void TearDown()
    {
    if (NTClient != null)
    {
    NTClient.TearDown();
    NTClient = null;
    }
    }



    public class Level2DataSimulator : MarketDepthProvider
    {
    private double bidPrice;
    private int bidSize;
    private double askPrice;
    private int askSize;

    protected override void OnMarketDepth(MarketDepthEventArgs e)
    {
    // Simulating Level 2 data for instrument "AAPL"
    if (e.MarketData != null && e.MarketData.Instrument.Symbol == "AAPL")
    {
    // Update the bid and ask prices and sizes with the stored values
    e.MarketData.Update(0, bidPrice, bidSize, askPrice, askSize);
    }
    }

    public void UpdateBidAsk(double bidPrice, int bidSize, double askPrice, int askSize)
    {
    // Store the updated bid and ask prices and sizes
    this.bidPrice = bidPrice;
    this.bidSize = bidSize;
    this.askPrice = askPrice;
    this.askSize = askSize;
    }
    }​

    static void Main(string[] args)
    {
    Random rDelta = new Random();

    double lastPrice = 14852.00;
    double askPrice = 14852.75;
    double ask2Price = 14852.50;
    double bidPrice = 14851.75;
    double bid2Price = 14850.25;
    double last2Price = 14852.00;
    double askIncrement = 0.25;
    double bidIncrement = 0.25;
    double lastIncrement = 0.25;
    int askSize = 0;
    int ask2Size = 0;
    int bidSize = 0;
    int bid2Size = 0;
    int last2Size = 0;
    int lastSize = 0;

    // Create an instance of the Level2DataSimulator
    var simulator = new Level2DataSimulator();

    bool go = true;
    while (go == true)
    {
    Thread.Sleep(300);

    // Start the simulation
    simulator.Start();

    ​ if (rDelta.Next(1000) >= 100)
    {
    ClientConnect();
    bid2Price = bidPrice + rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice + rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice + rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice + rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice + rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice + rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice + rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice + rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice + rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice + rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice + rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice + rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice - rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice - rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice - rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice - rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice - rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice - rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice - rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice - rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice - rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    bid2Price = bidPrice - rDelta.Next(4) * bidIncrement * rDelta.Next(3);
    ask2Price = askPrice - rDelta.Next(4) * askIncrement * rDelta.Next(3);
    last2Price = lastPrice - rDelta.Next(4) * lastIncrement * rDelta.Next(3);
    ask2Size = rDelta.Next(100);
    bid2Size = rDelta.Next(100);
    last2Size = rDelta.Next(100);
    SendLevel2Data("TESTFTR 11-24", bid2Price, bid2Size, ask2Price, ask2Size, last2Price, last2Size);
    // TearDown();

    // Update bid and ask prices and sizes
    simulator.UpdateBidAsk(bid2Price, bid2Size, ask2Price, ask2Size);

    simulator.Stop();

    TearDown();
    }
    }
    }
    }
    }


    In what DLL do I find the MarketDataProvider class? I assume this code will populate part of the Level II Window. Your guidance will be greatly appreciated. I'm developing this for educational purposes in my economics course.

    #2
    Hello hirezsqwave,

    The ntdirect dll has been discontinued. You can see the following forum post which has a C# unsupported sample of working with the ninjatrader.client dll instead.

    https://ninjatrader.com/support/foru...442#post514442

    Level 2 data is not something which can be provided through the dll api, you would need to use the playback connection to replay actual level 2 data to test a script which uses level 2 data. The Ask/Bid/Last are level 1 data so you would only see those values while using the external data feed in a chart or other tool that uses level 1 data.

    Comment


      #3
      Hi Jesse,

      Is there an API Function manual that describes how I can send Level 2 synthesized data along with my Level 1 synthesized data? If so, I'd appreciate receiving that documentation at my registered email address. Thank you very much. Also, are you saying that the Playback mechanism would respond to my Level one data to produce data in the Level II Window?

      Comment


        #4
        Hello hirezsqwave

        No there is not, in general there is no support for creating customized connections.

        The playback window can use downloaded or recorded playback data, playback data is recorded realtime data. There is not a way to create playback data, it needs to be downloaded or recorded from a live data feed.

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by argusthome, 03-08-2026, 10:06 AM
        0 responses
        79 views
        0 likes
        Last Post argusthome  
        Started by NabilKhattabi, 03-06-2026, 11:18 AM
        0 responses
        45 views
        0 likes
        Last Post NabilKhattabi  
        Started by Deep42, 03-06-2026, 12:28 AM
        0 responses
        29 views
        0 likes
        Last Post Deep42
        by Deep42
         
        Started by TheRealMorford, 03-05-2026, 06:15 PM
        0 responses
        32 views
        0 likes
        Last Post TheRealMorford  
        Started by Mindset, 02-28-2026, 06:16 AM
        0 responses
        66 views
        0 likes
        Last Post Mindset
        by Mindset
         
        Working...
        X