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

Trying to write a SMA class

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

    Trying to write a SMA class

    Hi,

    I wrote an SMA class, by basically moving the built in SMA Indicator code that comes with Ninjatrader into an object that uses no Indicator.

    I am having an issue though as the output is not correct. I was able to successfully do the EMA, but the SMA is not working... here is the code, any help is appreciated...

    Code:
    	#region Khaos_Virtual_Indicator_SMAz
    	public class Khaos_Virtual_Indicator_SMAz
    	{
    		
    		private NinjaScriptBase NinjaScriptBase;
    		private int Period;
    		
    		private double priorSum;
    		private double sum;
    
    		public Series<double> Value { get; private set; }
    		
    		
    		
    		public Khaos_Virtual_Indicator_SMAz(NinjaScriptBase NinjaScriptBase, int Period)
    		{
    			this.NinjaScriptBase = NinjaScriptBase;
    			this.Period = Period;
    			Value = new Series<double>(NinjaScriptBase);
    			
    			priorSum	= 0;
    			sum			= 0;
    		}
    		
    		
    		public Series<double> TickTock(ISeries <double> Input)
    		{
    			
    			
    			try
    			{
    			
    			if (NinjaScriptBase.BarsArray[0].BarsType.IsRemoveLastBarSupported)
    			{
    				if (NinjaScriptBase.CurrentBar == 0)
    					Value[0] = Input[0];
    				else
    				{
    					double last = Value[1] * Math.Min(NinjaScriptBase.CurrentBar, Period);
    
    					if (NinjaScriptBase.CurrentBar >= Period)
    						Value[0] = (last + Input[0] - Input[Period]) / Math.Min(NinjaScriptBase.CurrentBar, Period);
    					else
    						Value[0] = ((last + Input[0]) / (Math.Min(NinjaScriptBase.CurrentBar, Period) + 1));
    				}
    			}
    			else
    			{
    				if (NinjaScriptBase.IsFirstTickOfBar)
    					priorSum = sum;
    
    				sum = priorSum + Input[0] - (NinjaScriptBase.CurrentBar >= Period ? Input[Period] : 0);
    				Value[0] = sum / (NinjaScriptBase.CurrentBar < Period ? NinjaScriptBase.CurrentBar + 1 : Period);
    			}
    			
    			return Value;
    				
    			}
    			
    			catch (Exception e)
    			{
    				NinjaScriptBase.Log ("Cought Error Khaos Moving Average = " + e.ToString(), NinjaTrader.Cbi.LogLevel.Warning);
    				NinjaScriptBase.Print(NinjaScriptBase.Time[0] +  " " + e.ToString());
    				return Value;
    			}				
    		}
    	}
    	#endregion

    Here is a project that invokes the class

    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;
    using Khaos_Elements;
    #endregion
    
    //This namespace holds Indicators in this folder and is required. Do not change it. 
    namespace NinjaTrader.NinjaScript.Indicators.KhaosIndicators
    {
    	public class Test : Indicator
    	{
    	//	private  Khaos_Virtual_Indicator_QQE_v1 Khaos_Virtual_Indicator_QQE;
    		private Khaos_Virtual_Indicator_SMAz Khaos_Virtual_Indicator_SMAz;	
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{
    				Description									= @"test";
    				Name										= "Test";
    				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					= false;
    				AddPlot(Brushes.Orange, "Signal");
    
    			}
    			else if (State == State.Configure)
    			{
    
    				Khaos_Virtual_Indicator_SMAz = new Khaos_Virtual_Indicator_SMAz((NinjaScriptBase)this,20);
    			}
    		}
    
    		protected override void OnBarUpdate()
    		{
    			if (CurrentBar < 15) {return;}
    			Khaos_Virtual_Indicator_SMAz.TickTock(Close);
    			Signal[0] = Khaos_Virtual_Indicator_SMAz.Value[0];
    
    		}
    
    		#region Properties
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> Signal
    		{
    			get { return Values[0]; }
    		}
    
    		#endregion
    
    	}
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
    	public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
    	{
    		private KhaosIndicators.Test[] cacheTest;
    		public KhaosIndicators.Test Test()
    		{
    			return Test(Input);
    		}
    
    		public KhaosIndicators.Test Test(ISeries<double> input)
    		{
    			if (cacheTest != null)
    				for (int idx = 0; idx < cacheTest.Length; idx++)
    					if (cacheTest[idx] != null &&  cacheTest[idx].EqualsInput(input))
    						return cacheTest[idx];
    			return CacheIndicator<KhaosIndicators.Test>(new KhaosIndicators.Test(), input, ref cacheTest);
    		}
    	}
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    	public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
    	{
    		public Indicators.KhaosIndicators.Test Test()
    		{
    			return indicator.Test(Input);
    		}
    
    		public Indicators.KhaosIndicators.Test Test(ISeries<double> input )
    		{
    			return indicator.Test(input);
    		}
    	}
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
    	public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
    	{
    		public Indicators.KhaosIndicators.Test Test()
    		{
    			return indicator.Test(Input);
    		}
    
    		public Indicators.KhaosIndicators.Test Test(ISeries<double> input )
    		{
    			return indicator.Test(input);
    		}
    	}
    }
    
    #endregion
    Last edited by KhaosTrader; 12-27-2016, 02:33 PM.

    #2
    Hello KhaosTrader, and thank you for your question.

    While direct development services are beyond the scope of the services we may provide, we will be happy to provide advice as far as debugging your strategy. I recommend first when dealing with series in nested objects reviewing this section of the help guide.

    Originally posted by http://ninjatrader.com/support/helpGuides/nt8/en-us/multi-time_frame__instruments.htm
    ...
    True Event Driven OnBarUpdate() Method
    ...
    Notes:
    • A multi-series script only processes bar update events from the primary Bars (the series the script is applied to) and any additional Bars objects the script adds itself. Additional Bars objects from a multi-series chart or from other multi-series scripts that may be running concurrently will not be processed by this multi-series script.


    • If a multi-series script adds an additional Bars object that already exists on the chart, the script will use the preexisting series instead of creating a new one to conserve memory. This includes that series' session template as applied from the chart. If the Bars object does not exist on the chart, the session template of the added Bars object will be the session template of the primary Bars object. If the primary Bars object is using the "<Use instrument settings>" session template, then the additional Bars objects will use the default session templates as defined for their particular instruments in the Instruments window.


    • In a multi-series script, real-time bar update events for a particular Bars object are only received when that Bars object has satisfied the BarsRequiredToPlot requirement. To ensure you have satisfied this requirement on all your Bars objects, it is recommend you start your OnBarUpdate() method with CurrentBars checks, as seen in the code sample above.


    • A multi-series indicator will hold the same number of data points for plots as the primary series. Setting values to plots should be done in the primary series in OnBarUpdate(). If you are using calculations based off of a larger secondary series, it may plot like a step ladder because there are more data points available than there are actual meaningful data values.
    I would also recommend that you set up Visual Studio debugging, and place several breakpoints along the code execution path you expect your code to take.



    We are happy to help with any specific questions that come up.
    Jessica P.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by fitspressoburnfat, Today, 04:25 AM
    0 responses
    2 views
    0 likes
    Last Post fitspressoburnfat  
    Started by Skifree, Today, 03:41 AM
    1 response
    4 views
    0 likes
    Last Post Skifree
    by Skifree
     
    Started by usazencort, Today, 01:16 AM
    0 responses
    1 view
    0 likes
    Last Post usazencort  
    Started by kaywai, 09-01-2023, 08:44 PM
    5 responses
    604 views
    0 likes
    Last Post NinjaTrader_Jason  
    Started by xiinteractive, 04-09-2024, 08:08 AM
    6 responses
    23 views
    0 likes
    Last Post xiinteractive  
    Working...
    X