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

SMA with custome data series [INPUT] assembly missing

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

    #16
    Hello Marble,

    You would need to use prints to know why the value is the way it is. I can't answer that from a picture.
    JesseNinjaTrader Customer Service

    Comment


      #17
      I now want to use close price for two DataSeries, GC 12-23 and SI 12-23.
      And Print returns
      Inst1 Close[0][0]: 1943.1 //GC 12-23 price
      Inst2 Close[1][0]: 1943.1 //GC 12-23 price, should be SI 12-23
      Price Difference[0]: 0

      What is wrong with my code?

      Code:
      namespace NinjaTrader.NinjaScript.Indicators
      {
      public class GC2 : Indicator
      {
      //private int smaPeriod = 1; // Default SMA period
      private Series<double> Inst1SMA;
      private Series<double> Inst2SMA;
      private Series<double> PriceDifferenceSeries;
      
      // Declare properties
      private double multip1 = 1.0; // Default value for Multip1
      private double multip2 = 1.0; // Default value for Multip2
      
      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enter the description for your new custom Indicator here.";
      Name = "GC2";
      Calculate = Calculate.OnEachTick;
      IsOverlay = true;
      DisplayInDataBox = true;
      DrawOnPricePanel = true;
      DrawHorizontalGridLines = false;
      DrawVerticalGridLines = false;
      PaintPriceMarkers = false;
      ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay;
      IsSuspendedWhileInactive = true;
      //smaPeriod = 1;
      AddPlot(Brushes.Magenta, "PriceDifference");
      
      // Set default values here
      multip1 = 1.0;
      multip2 = 1.0;
      
      }
      else if (State == State.Configure)
      {
      // Add two data Series
      AddDataSeries("GC 12-23", Data.BarsPeriodType.Second, 60, Data.MarketDataType.Last);
      AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, 60, Data.MarketDataType.Last);
      
      
      // Initialize the Series for SMA(Simply Close)
      Inst1SMA = new Series<double>(this);
      Inst2SMA = new Series<double>(this);
      
      PriceDifferenceSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);
      
      
      }
      
      }
      
      protected override void OnBarUpdate()
      {
      // Calculate the SMA-based difference between the instruments
      if (BarsInProgress == 0)
      {
      
      double inst1Close = Closes[0][0];
      double inst2Close = Closes[1][0];
      double priceDifference = (inst1Close * multip1) - (inst2Close * multip2);
      
      // Print the values for monitoring
      Print("Inst1 Close[0][0]: " + inst1Close);
      Print("Inst2 Close[1][0]: " + inst2Close);
      Print("Price Difference[0]: " + priceDifference);
      
      // Set the Value for plotting
      Value[0] = priceDifference;
      
      // Print the price for PriceDifference
      Print("Price Difference Value[0]: " + Value[0]);
      
      }
      }​​

      Comment


        #18
        Hello Marble,

        Closes[0] is your primary series, if you are trying to access the two secondary series that would be Closes[1] and Closes[2].
        JesseNinjaTrader Customer Service

        Comment


          #19
          Hello Jesse,
          Thank you now working.
          Marble

          Comment


            #20
            Hello.
            I found the value for 2 series and difference is working in Output screen. But if I apply in chart, databox PriceDifference screen shows n/a and line are not shown.
            Here is the latest, What is wrong with below PriceDifference Assignment to Addplot to draw the line?

            Code:
            public class GC2 : Indicator
            {
            private Series<double> Inst1SMA;
            private Series<double> Inst2SMA;
            private Series<double> PriceDifferenceSeries;
            
            // Declare properties with unique names
            private double _multip1 = 1.0;
            private double _multip2 = 1.0;
            
            protected override void OnStateChange()
            {
            if (State == State.SetDefaults)
            {
            Description = @"Enter the description for your new custom Indicator here.";
            Name = "GC2";
            Calculate = Calculate.OnEachTick;
            IsOverlay = true;
            DisplayInDataBox = true;
            DrawOnPricePanel = true;
            DrawHorizontalGridLines = false;
            DrawVerticalGridLines = false;
            PaintPriceMarkers = false;
            ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay;
            IsSuspendedWhileInactive = true;
            
            AddPlot(new Stroke(Brushes.Magenta, 3), PlotStyle.Line,"PriceDifference");
            
            // Set default values for properties
            _multip1 = 1.0;
            _multip2 = 60.0;
            }
            else if (State == State.Configure)
            {
            // Add two data Series
            AddDataSeries("GC 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last);
            AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last);
            
            
            // Initialize the Series
            Inst1SMA = new Series<double>(this);
            Inst2SMA = new Series<double>(this);
            PriceDifferenceSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);
            }
            }
            
            protected override void OnBarUpdate()
            {
            if (BarsInProgress == 0)
            {
            double inst1Close = Closes[1][0]; // Use 1 to access "GC 12-23"
            double inst2Close = Closes[2][0]; // Use 2 to access "SI 12-23"
            double priceDifference = (inst1Close * _multip1) - (inst2Close * _multip2);
            
            // Print the values for monitoring
            Print("Inst1 Close[0][0]: " + inst1Close);
            Print("Inst2 Close[0][0]: " + inst2Close);
            Print("Price Difference[0]: " + priceDifference);
            
            // Set the Value for plotting
            PriceDifferenceSeries[0] = priceDifference;
            
            // Print the price for PriceDifference
            Print("Price Difference Value[0]: " + PriceDifferenceSeries[0]);
            }
            }
            
            [HASHTAG="t3322"]region[/HASHTAG] Properties
            
            [Range(1, double.MaxValue)]
            [Display(Name = "Multip1", Order = 3, GroupName = "Parameters")]
            public double Multip1
            {
            get { return _multip1; }
            set { _multip1 = value; }
            }
            
            [NinjaScriptProperty]
            [Range(1, double.MaxValue)]
            [Display(Name = "Multip2", Order = 4, GroupName = "Parameters")]
            public double Multip2
            {
            get { return _multip2; }
            set { _multip2 = value; }
            }
            
            #endregion
            }​
            Last edited by Marble; 09-08-2023, 11:24 AM.

            Comment


              #21
              Hello Marble,

              You need to plot the value, you are using private series which are not plots. PriceDifferenceSeries just holds values, you still need to plot a value for it to appear on the chart.
              JesseNinjaTrader Customer Service

              Comment


                #22
                Hi Jesse,
                I see. I have added below and worked.
                Value[0] = priceDifference;

                I have reviewed the code and found that multp1 is not mentioned NinjaScript generated code.
                Assuming this would cause multip1 input not available in strategy. How can I generated code show multip1?


                Code:
                [HASHTAG="t3322"]region[/HASHTAG] NinjaScript generated code. Neither change nor remove.
                
                namespace NinjaTrader.NinjaScript.Indicators
                {
                public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
                {
                private GC2[] cacheGC2;
                public GC2 GC2(double multip2)
                {
                return GC2(Input, multip2);
                }
                
                public GC2 GC2(ISeries<double> input, double multip2)
                {
                if (cacheGC2 != null)
                for (int idx = 0; idx < cacheGC2.Length; idx++)
                if (cacheGC2[idx] != null && cacheGC2[idx].Multip2 == multip2 && cacheGC2[idx].EqualsInput(input))
                return cacheGC2[idx];
                return CacheIndicator<GC2>(new GC2(){ Multip2 = multip2 }, input, ref cacheGC2);
                }
                }
                }
                
                namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
                {
                public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
                {
                public Indicators.GC2 GC2(double multip2)
                {
                return indicator.GC2(Input, multip2);
                }
                
                public Indicators.GC2 GC2(ISeries<double> input , double multip2)
                {
                return indicator.GC2(input, multip2);
                }
                }
                }
                
                namespace NinjaTrader.NinjaScript.Strategies
                {
                public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                {
                public Indicators.GC2 GC2(double multip2)
                {
                return indicator.GC2(Input, multip2);
                }
                
                public Indicators.GC2 GC2(ISeries<double> input , double multip2)
                {
                return indicator.GC2(input, multip2);
                }
                }
                }
                
                #endregion

                Comment


                  #23
                  Hello Marble,

                  Anything that should be a user input and also in the generate code needs to be a public property marked with NinjaScriptProperty

                  JesseNinjaTrader Customer Service

                  Comment


                    #24
                    Yes, I am aware, Both multip1 and multip2 are set as Public in Property region. But only multip2 is generated under do not edit region,
                    These are always declared together. Why only multip2 is generated for public accessable and how can I have multip1 the same way.
                    If I edit do not generate, if would just disregarded when compiled/

                    Code:
                    namespace NinjaTrader.NinjaScript.Indicators
                    {
                    public class GC2 : Indicator
                    {
                    private Series<double> Inst1SMA;
                    private Series<double> Inst2SMA;
                    private Series<double> PriceDifferenceSeries;
                    
                    // Declare properties with unique names
                    private double _multip1 = 1.0;
                    private double _multip2 = 1.0;
                    
                    protected override void OnStateChange()
                    {
                    if (State == State.SetDefaults)
                    {
                    Description = @"Enter the description for your new custom Indicator here.";
                    Name = "GC2";
                    Calculate = Calculate.OnEachTick;
                    IsOverlay = true;
                    DisplayInDataBox = true;
                    DrawOnPricePanel = true;
                    DrawHorizontalGridLines = false;
                    DrawVerticalGridLines = false;
                    PaintPriceMarkers = false;
                    ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay;
                    IsSuspendedWhileInactive = true;
                    
                    AddPlot(new Stroke(Brushes.Magenta, 3), PlotStyle.Line,"PriceDifference");
                    
                    // Set default values for properties
                    _multip1 = 1.0;
                    _multip2 = 60.0;
                    }
                    else if (State == State.Configure)
                    {
                    // Add two data Series
                    AddDataSeries("GC 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last);
                    AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last);
                    
                    
                    // Initialize the Series
                    Inst1SMA = new Series<double>(this);
                    Inst2SMA = new Series<double>(this);
                    PriceDifferenceSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);
                    }
                    }
                    
                    protected override void OnBarUpdate()
                    {
                    if (BarsInProgress == 0)
                    {
                    double inst1Close = Closes[1][0]; // Use 1 to access "GC 12-23"
                    double inst2Close = Closes[2][0]; // Use 2 to access "SI 12-23"
                    double priceDifference = (inst1Close * _multip1) - (inst2Close * _multip2);
                    
                    // Print the values for monitoring
                    Print("Inst1 Close[0][0]: " + inst1Close);
                    Print("Inst2 Close[0][0]: " + inst2Close);
                    Print("Price Difference[0]: " + priceDifference);
                    
                    // Set the Value for plotting
                    PriceDifferenceSeries[0] = priceDifference;
                    
                    // Plot the price for PriceDifferenceSeries
                    Value[0] = priceDifference;
                    
                    // Print the price for PriceDifference
                    Print("Price Difference Value[0]: " + PriceDifferenceSeries[0]);
                    }
                    }
                    
                    [HASHTAG="t3322"]region[/HASHTAG] Properties
                    
                    [Range(1, double.MaxValue)]
                    [Display(Name = "Multip1", Order = 3, GroupName = "Parameters")]
                    public double Multip1
                    {
                    get { return _multip1; }
                    set { _multip1 = value; }
                    }
                    
                    [NinjaScriptProperty]
                    [Range(1, double.MaxValue)]
                    [Display(Name = "Multip2", Order = 4, GroupName = "Parameters")]
                    public double Multip2
                    {
                    get { return _multip2; }
                    set { _multip2 = value; }
                    }
                    
                    #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 GC2[] cacheGC2;
                    public GC2 GC2(double multip2)
                    {
                    return GC2(Input, multip2);
                    }
                    
                    public GC2 GC2(ISeries<double> input, double multip2)
                    {
                    if (cacheGC2 != null)
                    for (int idx = 0; idx < cacheGC2.Length; idx++)
                    if (cacheGC2[idx] != null && cacheGC2[idx].Multip2 == multip2 && cacheGC2[idx].EqualsInput(input))
                    return cacheGC2[idx];
                    return CacheIndicator<GC2>(new GC2(){ Multip2 = multip2 }, input, ref cacheGC2);
                    }
                    }
                    }
                    
                    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
                    {
                    public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
                    {
                    public Indicators.GC2 GC2(double multip2)
                    {
                    return indicator.GC2(Input, multip2);
                    }
                    
                    public Indicators.GC2 GC2(ISeries<double> input , double multip2)
                    {
                    return indicator.GC2(input, multip2);
                    }
                    }
                    }
                    
                    namespace NinjaTrader.NinjaScript.Strategies
                    {
                    public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                    {
                    public Indicators.GC2 GC2(double multip2)
                    {
                    return indicator.GC2(Input, multip2);
                    }
                    
                    public Indicators.GC2 GC2(ISeries<double> input , double multip2)
                    {
                    return indicator.GC2(input, multip2);
                    }
                    }
                    }
                    
                    #endregion​
                    Last edited by Marble; 09-08-2023, 12:47 PM.

                    Comment


                      #25
                      Hello Marble,

                      If you are having some kind of problem with the inputs I would suggest making a new indicator using the indicator wizard and add the inputs in the wizard. That will make sure all the code is valid.
                      JesseNinjaTrader Customer Service

                      Comment


                        #26
                        The line and calculation seems to be working fine under if the chart is for period= second (when loaded, it is usually 60 second), but but if chart switched to minute or else, does not work.
                        control log error is "accessing in an index with a value out of range”

                        I have updated AddBarSeries to match primary BarsPeriod as below. But still, the line dissapears assuming the BarPeriod the issue. but no error in compiling but does not work.

                        How can I set the AddBarSeries DataBarsPeriodType to align primary chart period type?

                        Code:
                        // Access the current chart's BarsPeriodType and use it for data series
                        BarsPeriodType currentBarsPeriodType = BarsArray[0].BarsPeriod.BarsPeriodType;
                        
                        
                        // Add two data Series
                        AddDataSeries("GC 12-23", currentBarsPeriodType, BarsPeriod.Value, Data.MarketDataType.Last);
                        AddDataSeries("SI 12-23", currentBarsPeriodType, BarsPeriod.Value, Data.MarketDataType.Last);​
                        //AddDataSeries("SI 12-23", Data.BarsPeriodType.Second, BarsPeriod.Value, Data.MarketDataType.Last);

                        Comment


                          #27
                          Hello Marble,

                          AddDataSeries needs to be hard coded, it does not have a overload set to match the primary bars type. You would need to type in the values you want, this is mentioned in the help guide:

                          Arguments supplied to AddDataSeries() should be hardcoded and NOT dependent on run-time variables which cannot be reliably obtained during State.Configure (e.g., Instrument, Bars, or user input). Attempting to add a data series dynamically is NOT guaranteed and therefore should be avoided.


                          After making sure no variables are being used with AddDataSeries you can then go through your logic to see which line is having an error in that use case so that you can correct it or add error handling to prevent the error.
                          JesseNinjaTrader Customer Service

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by halgo_boulder, 04-20-2024, 08:44 AM
                          2 responses
                          21 views
                          0 likes
                          Last Post halgo_boulder  
                          Started by mishhh, 05-25-2010, 08:54 AM
                          19 responses
                          6,189 views
                          0 likes
                          Last Post rene69851  
                          Started by gwenael, Today, 09:29 AM
                          0 responses
                          5 views
                          0 likes
                          Last Post gwenael
                          by gwenael
                           
                          Started by Karado58, 11-26-2012, 02:57 PM
                          8 responses
                          14,830 views
                          0 likes
                          Last Post Option Whisperer  
                          Started by Option Whisperer, Today, 09:05 AM
                          0 responses
                          2 views
                          0 likes
                          Last Post Option Whisperer  
                          Working...
                          X