Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

How to draw the Bid Ask as Lines

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

    How to draw the Bid Ask as Lines

    I want a chart to display the BID and ASK thru time, but I don't know how to do that in Ninja.
    In metatrader there is a special window for this
    Click image for larger version

Name:	2023-03-22 10_31_27- [SPX500,M1].png
Views:	141
Size:	267.0 KB
ID:	1241883
    . I also saw indicators for it https://forex-station.com/attach/file/3420329

    Can somebody adapt this to Ninja ? Or is there alreadya script for this ?


    #2
    I tried to convert the mq4 indicator, but it prints only a white line (the emdian) whic doesn't update


    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 PrintBIDASK : Indicator
        {
    private Series<double> ExtMapBuffer2;
    private int tik,t;
    private double MaxB,MinB=1000;
    
    private int period=2000;
    private int width=50;
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Enter the description for your new custom Indicator here.";
                    Name                                        = "PrintBIDASK";
                    Calculate                                    = Calculate.OnEachTick;
                    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;
                    AddPlot(Brushes.Red, "Print_Bid");
                    AddPlot(Brushes.Lime, "Print_Ask");
                    AddPlot(Brushes.Ivory, "Print_Median");
                }
                else if (State == State.Configure)
                {
                }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    else if(State==State.Historical)
    {
    //Make sure our object plots behind the chart bars
     SetZOrder(-1);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
     else if (State == State.DataLoaded)//https://ninjatrader.com/support/helpGuides/nt8/NT%20HelpGuide%20English.html?seriest.htm
     {
      ExtMapBuffer2 = new Series<double>(this, MaximumBarsLookBack.Infinite);
     }
            }
    
    protected override void OnBarUpdate()
    {
    //Add your custom indicator logic here.
     int b;
    //----
     t++;
     b=period;
     if(CurrentBar<=1)
      return;
     double[]buff=new double[b];
     double[]buff2=new double[b];
     double[]buff3=new double[b];
     double currentAsk = GetCurrentAsk();
     double currentBid = GetCurrentBid();
     if(tik==0)
     {
      for(int i=0; i<b; i++)
      {
       buff[i]=currentBid;
       buff2[i]=currentAsk;
       buff3[i]=(High[0]+Low[0])/2;
      }
      ExtMapBuffer2[0]=currentBid+width*TickSize;
      ExtMapBuffer2[1]=currentBid-width*TickSize;
      tik=1;
     }
     MaxB=0;
     MinB=1000;
     for(int i=b-1; i>0; i--)
     {
      buff[i]=buff[i-1];
      if(MaxB<buff[i])MaxB=buff[i];
      if(MinB>buff[i])MinB=buff[i];
      buff2[i]=buff2[i-1];
      if(MaxB<buff2[i])MaxB=buff2[i];
      if(MinB>buff2[i])MinB=buff2[i];
      buff3[i]=buff3[i-1];
      if(MaxB<buff3[i])MaxB=buff3[i];
      if(MinB>buff3[i])MinB=buff3[i];
     }
     buff[0]=currentBid;
     buff2[0]=currentAsk;
     buff3[0]=(High[0]+Low[0])/2;
     if(CurrentBar<=b)
      return;
     for(int i=0; i<b; i++)
     {
      Print_Bid[i]=buff[i];
      Print_Ask[i]=buff2[i];
      Print_Median[i]=buff3[i];
     }
     if((int)(Math.Ceiling(t*0.1)*10)==t)
     {
      for(int i=b; i<CurrentBar; i++)//CurrentBar and NOT Bars.Count
      {
    //   Print(b+"  "+i+"  "+Bars.Count+"  "+CurrentBar+"  "+(Count - CurrentBar));
       Print_Bid[i]=currentBid;
    //2000  2000  14402
    //2000  2001  14402
    //2000  2002  14402
    //2000  2003  14402
    //2000  2004  14402
    //2000  2005  14402
    //2000  2006  14402
    //2000  2007  14402
    //2000  2008  14402
    //2000  2009  14402
    //2000  2010  14402
    //Indicator 'PrintBIDASK': Error on calling 'OnBarUpdate' method on bar 2009: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
       Print_Ask[i]=currentAsk;
       Print_Median[i]=(High[0]+Low[0])/2;
      }
      for (int j = 0; j < CurrentBar; j++)
       ExtMapBuffer2[j] = currentBid;
      if(MaxB-currentBid<width*TickSize)ExtMapBuffer2[0]=currentBid+width*TickSize;
      if(currentBid-MinB<width*TickSize)ExtMapBuffer2[1]=currentBid-width*TickSize;
     }  
    
    
    
            }
    
            #region Properties
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> Print_Bid
            {
                get { return Values[0]; }
            }
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> Print_Ask
            {
                get { return Values[1]; }
            }
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> Print_Median
            {
                get { return Values[2]; }
            }
            #endregion
    
        }
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
        {
            private PrintBIDASK[] cachePrintBIDASK;
            public PrintBIDASK PrintBIDASK()
            {
                return PrintBIDASK(Input);
            }
    
            public PrintBIDASK PrintBIDASK(ISeries<double> input)
            {
                if (cachePrintBIDASK != null)
                    for (int idx = 0; idx < cachePrintBIDASK.Length; idx++)
                        if (cachePrintBIDASK[idx] != null &&  cachePrintBIDASK[idx].EqualsInput(input))
                            return cachePrintBIDASK[idx];
                return CacheIndicator<PrintBIDASK>(new PrintBIDASK(), input, ref cachePrintBIDASK);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
        public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
        {
            public Indicators.PrintBIDASK PrintBIDASK()
            {
                return indicator.PrintBIDASK(Input);
            }
    
            public Indicators.PrintBIDASK PrintBIDASK(ISeries<double> input )
            {
                return indicator.PrintBIDASK(input);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
        {
            public Indicators.PrintBIDASK PrintBIDASK()
            {
                return indicator.PrintBIDASK(Input);
            }
    
            public Indicators.PrintBIDASK PrintBIDASK(ISeries<double> input )
            {
                return indicator.PrintBIDASK(input);
            }
        }
    }
    
    #endregion
    ​
    Click image for larger version

Name:	2023-03-22 12_39_07-Chart - ES 06-23.png
Views:	119
Size:	521.1 KB
ID:	1241908
    Attached Files
    Last edited by alanlopen; 03-22-2023, 05:39 AM.

    Comment


      #3
      Hello alanlopen,

      Thanks for your post.

      I am not aware of an existing indicator that accomplishes this specifically. That said, you could try searching the NinjaTrader Ecosystem User App Share linked below for a possible solution.

      Ecosystem User App Share: https://ninjatraderecosystem.com/user-app-share/

      If you would like to plot the current real-time bid and ask values in a chart, you could use GetCurrentBid() and GetCurrentAsk() to get the real-time bid and ask values. Those values could then be assigned to a plot so those values plot on the chart.

      See the help guide documentation below for more information and sample code.

      GetCurrentBid(): https://ninjatrader.com/support/help...currentbid.htm
      GetCurrentAsk(): https://ninjatrader.com/support/help...currentask.htm
      AddPlot(): https://ninjatrader.com/support/help...t8/addplot.htm

      The error message commented in the script you shared "You are accessing an index with a value that is invalid since it is out-of-range." indicates that you are accessing an index in your script that is invalid.

      A more simple example using one series would be on bar 5 you check for 6 BarsAgo. There are not yet 6 bars so the CurrentBar minus 6 would be a negative number or a non-existent bar.

      A CurrentBar check could be used in your indicator's logic to ensure that a certain number of bars have processed before the indicator begins calculation.

      CurrentBar - https://ninjatrader.com/support/help...currentbar.htm
      Make sure you have enough bars - https://ninjatrader.com/support/help...nough_bars.htm

      Overall, if a script is not behaving as expected then debugging steps should be taken to understand the behavior of the script. Below is a link to a forum post that demonstrates how to use prints to understand behavior.
      https://ninjatrader.com/support/foru...121#post791121​​

      Please let me know if I may assist further.

      The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.
      Brandon H.NinjaTrader Customer Service

      Comment


        #4
        if I use directly GetCurrentBid() and GetCurrentAsk() for the plots, ie

        Print_Bid[0]=GetCurrentBid();
        Print_Ask[0]=GetCurrentAsk();

        then it prints 2 lines but those are not the Bid and Ask updated at each tick right ?​

        Comment


          #5
          Hello alanlopen,

          Thanks for your notes.

          Yes, you could assign GetCurrentBid() and GetCurrentAsk() to your plots to plot the real-time bid and ask prices on the chart.

          Note that to have the plot values updated for each tick, you should set your Calculate mode to Calculate.OnEachTick.

          Prints could be added to the script one line above where you are assigning those values to the plots that prints out GetCurrentBid() and GetCurrentAsk() to see those values on a New > NinjaScript Output window.

          Calculate: https://ninjatrader.com/support/help.../calculate.htm

          Please let me know if you have further questions.
          Brandon H.NinjaTrader Customer Service

          Comment


            #6
            yeah but it's not the chart of the Bid and Ask thru time. The code

            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 AskBid : Indicator
            {
            protected override void OnStateChange()
            {
            if (State == State.SetDefaults)
            {
            Description = @"Enter the description for your new custom Indicator here.";
            Name = "AskBid";
            Calculate = Calculate.OnEachTick;
            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;
            AddPlot(Brushes.MediumSeaGreen, "Bid");
            AddPlot(Brushes.Orange, "Ask");
            }
            else if (State == State.Configure)
            {
            }
            }
            
            protected override void OnBarUpdate()
            {
            //Add your custom indicator logic here.
            
            Bid[0]=GetCurrentBid();
            Ask[0]=GetCurrentAsk();
            }
            
            [HASHTAG="t3322"]region[/HASHTAG] Properties
            
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> Bid
            {
            get { return Values[0]; }
            }
            
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> Ask
            {
            get { return Values[1]; }
            }
            #endregion
            
            }
            }
            
            [HASHTAG="t3322"]region[/HASHTAG] NinjaScript generated code. Neither change nor remove.
            
            namespace NinjaTrader.NinjaScript.Indicators
            {
            public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
            {
            private AskBid[] cacheAskBid;
            public AskBid AskBid()
            {
            return AskBid(Input);
            }
            
            public AskBid AskBid(ISeries<double> input)
            {
            if (cacheAskBid != null)
            for (int idx = 0; idx < cacheAskBid.Length; idx++)
            if (cacheAskBid[idx] != null && cacheAskBid[idx].EqualsInput(input))
            return cacheAskBid[idx];
            return CacheIndicator<AskBid>(new AskBid(), input, ref cacheAskBid);
            }
            }
            }
            
            namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
            {
            public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
            {
            public Indicators.AskBid AskBid()
            {
            return indicator.AskBid(Input);
            }
            
            public Indicators.AskBid AskBid(ISeries<double> input )
            {
            return indicator.AskBid(input);
            }
            }
            }
            
            namespace NinjaTrader.NinjaScript.Strategies
            {
            public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
            {
            public Indicators.AskBid AskBid()
            {
            return indicator.AskBid(Input);
            }
            
            public Indicators.AskBid AskBid(ISeries<double> input )
            {
            return indicator.AskBid(input);
            }
            }
            }
            
            #endregion
            ​
            just plots
            Click image for larger version

Name:	2023-03-24 09_19_51-.png
Views:	110
Size:	470.6 KB
ID:	1242366
            whereas the goal is really to plot this

            Click image for larger version

Name:	bid-ask.png?u=https%3A%2F%2Fwww.theforexguy.com%2Fwp-content%2Fuploads%2F2013%2F04%2Fbid-ask.png&amp;q=0&amp;b=1&amp;p=0&amp;a=0.png
Views:	146
Size:	159.1 KB
ID:	1242365

            Comment


              #7
              Hi alanlopen, A script is not needed to plot out the ask and bid. You can set up a chart to plot out the Ask and Bid price as "Line On Close" style by adding two more data series and setting the price type to Ask and Bid:

              Attached Files
              Chris L.NinjaTrader Customer Service

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by ScottWalsh, Today, 06:52 PM
              3 responses
              19 views
              0 likes
              Last Post NinjaTrader_Manfred  
              Started by trilliantrader, Today, 03:01 PM
              2 responses
              19 views
              0 likes
              Last Post helpwanted  
              Started by cre8able, Today, 07:24 PM
              0 responses
              1 view
              0 likes
              Last Post cre8able  
              Started by Haiasi, Today, 06:53 PM
              1 response
              4 views
              0 likes
              Last Post NinjaTrader_Manfred  
              Started by ScottW, Today, 06:09 PM
              1 response
              7 views
              0 likes
              Last Post NinjaTrader_Manfred  
              Working...
              X