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

Custom Bars Type with additional Data

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

    Custom Bars Type with additional Data

    Dear NinjaTrader Support Team,

    i am trying to create a custom bars type which includes additional data in the form of a list of custom objects.
    This seems to work pretty well but i am not able to serialize the custom list with my bars type.
    So currently i need to put an XmlIgnore in Front of my list to make this work.

    [XmlIgnore()]
    public List<BarItem> BarItems = new List<BarItem>();

    Is there a way to serialize this list together with the bars type?

    Best would be if i could send the file over to one of you, so you get a better idea of the whole context.

    Thank you and best regards,
    Mike

    #2
    Hello mk77ch,

    Thanks for your post.

    I don't have a ready example to provide, but we do offer some direction for serializing collections in our SampleIndicatorTypeConverter example. I'll provide a link and to an indicator that applies serialization to collections as well.

    SampleIndicatorTypeConverter - https://ninjatrader.com/support/help...r_to_custo.htm

    A1ChartNotes - https://ninjatraderecosystem.com/use.../a1chartnotes/

    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.

    If you get stuck, could you attach a small example of what you have attempted and we can take a closer look at what you are trying to serialize within the List?

    I look forward to assisting.
    JimNinjaTrader Customer Service

    Comment


      #3
      Hello NinjaTrader_Jim,

      thank you very much for your reply.
      I looked at the resources you provided but i am not sure how far these can be applied for bar types.

      I am trying to explain in more detail what i try to do.
      The main goal would be to have a custom bars type which includes additional information for each generated bar.
      In my case i would like to create a bar type which creates a new bar when the current bars bid ask delta exceeds a given threshold value defined by the period value.

      By working with the close, bid and ask values in OnDataPoint i am able to do this.
      Now the problems start if i would like to create an indicator for this bars type which shows the historical bid ask delta.
      The calls to OnDataPoint are out of sync with the actual data series of the chart and the bid ask values doesn't seem to match the values i get when creating the bars in OnDataPoint.

      So my idea was to create a list of BarItems to store the actual data within the custom bars type and manage this list items while i am creating the actual bars.
      Something like this:

      Code:
      namespace NinjaTrader.NinjaScript.BarsTypes
      {
          public class DeltaBarsType : BarsType
          {
              int    barIndex  = 0;
              double maxDelta  = 0.0;
              double prevDelta = 0.0;
              double restDelta = 0.0;
              double deltaDiff = 0.0;
              double askVolume = 0.0;
              double bidVolume = 0.0;
              double currDelta = 0.0;
      
              public List<BarItem> BarItems = new List<BarItem>();
      
              public class BarItem
              {
                  public double prcMin = double.MaxValue;
                  public double prcMax = double.MinValue;
                  public double prcRng = 0.0;
                  public double volume = 0.0;
                  public double askVol = 0.0;
                  public double bidVol = 0.0;
                  public double deltaH = 0.0;
                  public double deltaL = 0.0;
                  public double deltaC = 0.0;
      
                  public void addAsk(double prc, double vol)
                  {
                      this.askVol += vol;
                      this.deltaC  = this.askVol - this.bidVol;
                      this.deltaH  = (this.deltaC > this.deltaH) ? this.deltaC : this.deltaH;
                      this.deltaL  = (this.deltaC < this.deltaL) ? this.deltaC : this.deltaL;
                  }
      
                  public void addBid(double prc, double vol)
                  {
                      this.bidVol += vol;
                      this.deltaC  = this.askVol - this.bidVol;
                      this.deltaH  = (this.deltaC > this.deltaH) ? this.deltaC : this.deltaH;
                      this.deltaL  = (this.deltaC < this.deltaL) ? this.deltaC : this.deltaL;
                  }
      
                  public void addVol(double prc, double vol)
                  {
                      this.volume += vol;
                      this.prcMin  = (prc < this.prcMin) ? prc : this.prcMin;
                      this.prcMax  = (prc > this.prcMax) ? prc : this.prcMax;
                      this.prcRng  = this.prcMax = this.prcMin;
                  }
              }
      
              protected override void OnStateChange()
              {
      Then from my indicator i could just do something like this:

      Code:
      NinjaTrader.NinjaScript.BarsTypes.DeltaBarsType barsType = Bars.BarsSeries.BarsType as NinjaTrader.NinjaScript.BarsTypes.DeltaBarsType;
      
      if(barsType == null)
      {
          return;
      }
      
      if(barsType.BarItems.ElementAtOrDefault(CurrentBar) != null)
      {
          DeltaBody[0] = barsType.BarItems[CurrentBar].deltaC;
          UpperWick[0] = barsType.BarItems[CurrentBar].deltaH;
          LowerWick[0] = barsType.BarItems[CurrentBar].deltaL;
      This works to some degree but not really well as it looks like the actual serialization/deserialization of the bars type is broken or at least i have to "Reload all historical data" each time i open a new chart. Further i frequently get an exception with the Add method of the bar type.

      So maybe you have an idea how something like this could be done properly.
      At least in the volumetric bars type this seems to work: https://ninjatrader.com/support/help...etric_bars.htm

      Thank you,
      Mike
      Last edited by mk77ch; 03-20-2020, 07:07 AM.

      Comment


        #4
        Dear NinjaTrader_Jim,

        The NinjaTrader Help Guide for Volumetric Bars shows this example on how to access data and methods for the bar type:

        Code:
        protected override void OnBarUpdate()
        {
                if (Bars == null)
                  return;
        
               // This sample assumes the Volumetric series is the primary DataSeries on the chart, if you would want to add a Volumetric series to a  
               // script, you could call AddVolumetric() in State.Configure and then for example use
               // NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType barsType = BarsArray[1].BarsType as
               // NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType;
        
                NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType barsType = Bars.BarsSeries.BarsType as    
                NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType;
        
                if (barsType == null)
                  return;
        
                try
                {
                  double price;
                  Print("=========================================================================");
                  Print("Bar: " + CurrentBar);
                  Print("Trades: " + barsType.Volumes[CurrentBar].Trades);
                  Print("Total Volume: " + barsType.Volumes[CurrentBar].TotalVolume);
                  Print("Total Buying Volume: " + barsType.Volumes[CurrentBar].TotalBuyingVolume);
                  Print("Total Selling Volume: " + barsType.Volumes[CurrentBar].TotalSellingVolume);
                  Print("Delta for bar: " + barsType.Volumes[CurrentBar].BarDelta);
                  Print("Delta for bar (%): " + barsType.Volumes[CurrentBar].GetDeltaPercent());
                  Print("Delta for Close: " + barsType.Volumes[CurrentBar].GetDeltaForPrice(Close[0]));
                  Print("Ask for Close: " + barsType.Volumes[CurrentBar].GetAskVolumeForPrice(Close[0]));
                  Print("Bid for Close: " + barsType.Volumes[CurrentBar].GetBidVolumeForPrice(Close[0]));
                  Print("Volume for Close: " + barsType.Volumes[CurrentBar].GetTotalVolumeForPrice(Close[0]));
                  Print("Maximum Ask: " + barsType.Volumes[CurrentBar].GetMaximumVolume(true, out price) + " at price: " + price);
                  Print("Maximum Bid: " + barsType.Volumes[CurrentBar].GetMaximumVolume(false, out price) + " at price: " + price);
                  Print("Maximum Combined: " + barsType.Volumes[CurrentBar].GetMaximumVolume(null, out price) + " at price: " + price);
                  Print("Maximum Positive Delta: " + barsType.Volumes[CurrentBar].GetMaximumPositiveDelta());
                  Print("Maximum Negative Delta: " + barsType.Volumes[CurrentBar].GetMaximumNegativeDelta());
                  Print("Max seen delta (bar): " + barsType.Volumes[CurrentBar].MaxSeenDelta);
                  Print("Min seen delta (bar): " + barsType.Volumes[CurrentBar].MinSeenDelta);
                  Print("Cumulative delta (bar): " + barsType.Volumes[CurrentBar].CumulativeDelta);
                }
                catch{}
        }
        So it seems that the Volumetric bar type provides a list of objects with the name of "Volumes".
        That's pretty much what I try to achieve in my custom bar type.

        I guess that this is far from supported by the NinjaTrader Support but I would be really thankful if you could provide a snippet or a little help in how to get this properly set up in the bars type itself.

        Thank you,
        Mike

        Comment


          #5
          Hello mk77ch,

          I put in a question to development about this and the way that this is done with the volumetric uses some undocumented overrides from the BarsType base.

          The Merge,TrimStart/TrimEnd overrides are used to resize the collection and the override property SkipCaching is set to true.

          While I don't have anything documented that I can provide on these you can explore using those overrides in your script, unfortunately I won't be able to answer any questions surrounding these overrides.

          This is the sample that was provided, you can review this to see what is being done with the list and then experiment further with your bars type:

          Code:
                  public override bool SkipCaching { get { return true; } }
          
                  public override void Merge(BarsType barsType)
                  {
                      MyBarsType mergeBars = barsType as MyBarsType;
                      NinjaTrader.Code.Output.Process("(BarsType) Merge: " + (mergeBars == null), PrintTo.OutputTab1);
                      if (mergeBars == null)
                          return;
          
                      for (int i = 0; i < mergeBars.TestVolumes.Count; i++)
                          TestVolumes.Add(mergeBars.TestVolumes[i]);
                  }
          
                  public override void TrimEnd(int numBars)
                  {
                      NinjaTrader.Code.Output.Process("(BarsType) TrimEnd: " + numBars + " of " + TestVolumes.Count, PrintTo.OutputTab1);
                      if (TestVolumes.Count - numBars > 0)
                          TestVolumes.RemoveRange(numBars, TestVolumes.Count - numBars);
                  }
          
                  public override void TrimStart(int numBars)
                  {
                      NinjaTrader.Code.Output.Process("(BarsType) TrimStart: " + numBars + " of " + TestVolumes.Count, PrintTo.OutputTab1);
                      if (TestVolumes.Count - numBars > 0)
                          TestVolumes.RemoveRange(0, TestVolumes.Count - numBars);
                  }
          
                  [System.Xml.Serialization.XmlIgnore]
                  public List<long> TestVolumes = new List<long>();
          I look forward to being of further assistance.
          JesseNinjaTrader Customer Service

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by port119, Today, 02:43 PM
          0 responses
          1 view
          0 likes
          Last Post port119
          by port119
           
          Started by Philippe56140, Today, 02:35 PM
          0 responses
          2 views
          0 likes
          Last Post Philippe56140  
          Started by 00nevest, Today, 02:27 PM
          0 responses
          1 view
          0 likes
          Last Post 00nevest  
          Started by Jonafare, 12-06-2012, 03:48 PM
          5 responses
          3,986 views
          0 likes
          Last Post rene69851  
          Started by Fitspressorest, Today, 01:38 PM
          0 responses
          2 views
          0 likes
          Last Post Fitspressorest  
          Working...
          X