else if (State == State.Configure) { // Add the different data series. AddDataSeries(Data.BarsPeriodType.Minute, 60); AddDataSeries(Data.BarsPeriodType.Minute, 240); AddDataSeries(Data.BarsPeriodType.Day, 1); // Initialize the indicators. _60MinuteHighEMA = EMA(Highs[1], 300); _60MinuteLowEMA = EMA(Lows[1], 300); _1DayHighEMA = EMA(Highs[3], 300); _1DayLowEMA = EMA(Lows[3], 300);[ATTACH=JSON]{"data-align":"none","data-size":"full","title":"EMA Similar Values.PNG","data-attachmentid":1114609}[/ATTACH] }
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!
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
NinjaTrader
Same values from different time frames on EMA
Collapse
X
-
Same values from different time frames on EMA
I'm comparing EMA's from different time frames but, debugging reveals the indicator variables have the same value. I must be doing something wrong. Can you point me in the right direction?
Code:Tags: None
-
Hello Herrwolf1,
Its difficult to say from the given details, you may want to try and call the indicator prior to the print by copying the code from OnStateChange to OnBarUpdate:
Code:_60MinuteHighEMA = EMA(Highs[1], 300); Print(....);
If not I would suggest making a new empty indicator and add 1 extra data series/prints as you have in your current script and then attach that sample. We can go over that excluding the other items you had in the script previously.
I look forward to being of further assistance.
JesseNinjaTrader Customer Service
- Likes 1
-
Pursuant to this issue, I'm having a difficult time obtaining a repeating outcome. If I add the following indicator to a 60 minute chart, and set the "Bars Period Type" to "Minute" and the period property to 240, I get the proper outcome. To that end, it always works when initially adding the indicator to a chart. If I change either of those properties, the plotted line matches the 60 minute EMA indicators. This leads me to believe the indicator values are incorrect. You can see this from the attached pictures. What should I be doing differently? I've copied the entire indicator text for your review.
Thanks,
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 Filter : Indicator { private EMA _300HighEma = null; private EMA _300LowEma = null; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"This indicator serves as a trade filter."; Name = "Filter"; Calculate = Calculate.OnBarClose; IsOverlay = true; 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(new Stroke(Brushes.Blue, 1), PlotStyle.Line, "Line1"); AddPlot(new Stroke(Brushes.Khaki, 1), PlotStyle.Line, "Line2"); } else if (State == State.Configure) { AddDataSeries(PeriodType, Period); _300HighEma = EMA(Highs[1], 300); _300LowEma = EMA(Lows[1], 300); } else if (State == State.DataLoaded) { } } protected override void OnBarUpdate() { FilterMarketPosition = MarketPosition.Flat; //Add your custom indicator logic here. if (CurrentBars[1] < 301) return; if (BarsInProgress != 0) return; // Reset the parameters. _300HighEma = EMA(Highs[1], 300); _300LowEma = EMA(Lows[1], 300); Line1[0] = _300HighEma[0]; Line2[0] = _300LowEma[0]; } #region <==========Properties==========> [NinjaScriptProperty] [Display(ResourceType = typeof(Custom.Resource), Name = "BarsPeriodType", Order = 0)] public BarsPeriodType PeriodType { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Description = "Quantity of period type.", Order = 0)] public int Period { get; set; } [Browsable(false)] [XmlIgnore] public Series<double> Line1 { get { return Values[0]; } } [Browsable(false)] [XmlIgnore] public Series<double> Line2 { get { return Values[1]; } } [Browsable(false)] [XmlIgnore] public MarketPosition FilterMarketPosition { get; set; } #endregion } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private Filter[] cacheFilter; public Filter Filter(BarsPeriodType periodType, int period) { return Filter(Input, periodType, period); } public Filter Filter(ISeries<double> input, BarsPeriodType periodType, int period) { if (cacheFilter != null) for (int idx = 0; idx < cacheFilter.Length; idx++) if (cacheFilter[idx] != null && cacheFilter[idx].PeriodType == periodType && cacheFilter[idx].Period == period && cacheFilter[idx].EqualsInput(input)) return cacheFilter[idx]; return CacheIndicator<Filter>(new Filter(){ PeriodType = periodType, Period = period }, input, ref cacheFilter); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.Filter Filter(BarsPeriodType periodType, int period) { return indicator.Filter(Input, periodType, period); } public Indicators.Filter Filter(ISeries<double> input , BarsPeriodType periodType, int period) { return indicator.Filter(input, periodType, period); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.Filter Filter(BarsPeriodType periodType, int period) { return indicator.Filter(Input, periodType, period); } public Indicators.Filter Filter(ISeries<double> input , BarsPeriodType periodType, int period) { return indicator.Filter(input, periodType, period); } } } #endregion
Comment
-
Hello Herrwolf1,
Thank you for the post.
Its possible that you are running into the warning listed on the AddDataSeries page:
•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. Trying to load bars dynamically may result in an error similar to: Unable to load bars series. Your NinjaScript may be trying to use an additional data series dynamically in an unsupported manner.
For this issue I would suggest to run the following steps and see if that makes a difference:
Hard code the first test period in the indicator: 240 minute
Compile
Remove the indicator from where it was applied
Re apply the indicator
Hard code the different period: 300 minute
Compile
Remove the indicator from where it was applied
Re apply the indicator
If you see that is working by following that process we can confirm that is related to the variables. You have the options to hard code the secondary series or know this situation is affected and always remove and add the indicator instead of making changes and relying on it to reload.
JesseNinjaTrader Customer Service
Comment
-
Jesse,
Thanks for the response.
I've done as you asked. It still works as expected every time the indicator is removed and re-applied. This time I applied the indicator and then hit the F5 key and that resulted in the same issue.
P.S.: I applied the indicator while using the "Data Box" and took a picture of the data box w/ my phone. After I hit F5, indeed the values do change.
P.P.S.: I added the PSAR to my indicator as such " _psar = ParabolicSAR(BarsArray[1], 0.02, 0.2, 0.02);" and when I refresh via the F5 key it stays the same. I'm thinking the issue is w/ using the "Highs" or "Lows" etc...Last edited by Herrwolf1; 10-16-2020, 03:50 PM.
Comment
-
Hello Herrwolf1,
Thank you for the reply.
Can you attach what you had tested this far so I can test the steps you listed on my end?
And to clarify, the data box value is changing but the chart is not, is that correct?
I look forward to being of further assistance.JesseNinjaTrader Customer Service
Comment
-
It's basically the same indicator as before.- Create a 60 minute chart.
- Add two 300 EMA indicators. One references the highs and the other references the lows.
- Add this "Filter" indicator to the chart.
- Set the "Bars Period Type" to minute.
- Set the "Period" to 240.
You should see results similar to the attached pictures.
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 Filter : Indicator { private EMA _ema300 = null; private EMA _ema300High = null; private EMA _ema300Low = null; private ParabolicSAR _psar = null; private SMA _sma20 = null; private VWMA _vwma20 = null; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"This indicator serves as a trade filter."; Name = "Filter"; Calculate = Calculate.OnBarClose; IsOverlay = true; 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(new Stroke(Brushes.AliceBlue, 5), PlotStyle.Dot, "PSAR"); AddPlot(new Stroke(Brushes.GreenYellow, DashStyleHelper.Dot, 4), PlotStyle.Line, "Line20VWMA"); AddPlot(new Stroke(Brushes.IndianRed, DashStyleHelper.Dash, 4), PlotStyle.Line, "Line20SMA"); AddPlot(new Stroke(Brushes.Orange, 1), PlotStyle.Line, "Line300"); AddPlot(new Stroke(Brushes.DarkOrange, 1), PlotStyle.Line, "Line300High"); AddPlot(new Stroke(Brushes.DarkOrange, 1), PlotStyle.Line, "Line300Low"); } else if (State == State.Configure) { AddDataSeries(PeriodType, Period); //AddDataSeries(BarsPeriodType.Minute, 480); _ema300 = EMA(BarsArray[1], 300); _ema300High = EMA(Highs[1], 300); // This is the problem _ema300Low = EMA(Lows[1], 300); // This is the problem. _psar = ParabolicSAR(BarsArray[1], 0.02, 0.2, 0.02); _sma20 = SMA(BarsArray[1], 20); _vwma20 = VWMA(BarsArray[1], 20); } else if (State == State.DataLoaded) { } } protected override void OnBarUpdate() { FilterMarketPosition = MarketPosition.Flat; //Add your custom indicator logic here. if (CurrentBars[1] < 21) return; if (BarsInProgress != 0) return; // Reset the parameters. _ema300 = EMA(BarsArray[1], 300); _psar = ParabolicSAR(BarsArray[1], 0.02, 0.2, 0.02); _sma20 = SMA(BarsArray[1], 20); _vwma20 = VWMA(BarsArray[1], 20); _ema300High = EMA(Highs[1], 300); _ema300Low = EMA(Lows[1], 300); if (CurrentBars[1] > 300) { Line300[0] = _ema300.Value[0]; Line300High[0] = _ema300High.Value[0]; Line300Low[0] = _ema300Low.Value[0]; } PSAR[0] = _psar.Value[0]; Line20SMA[0] = _sma20.Value[0]; Line20VWMA[0] = _vwma20.Value[0]; FilterMarketPosition = _vwma20[0] > _sma20[0] ? MarketPosition.Long : MarketPosition.Short; } #region <==========Properties==========> [NinjaScriptProperty] [Display(ResourceType = typeof(Custom.Resource), Name = "BarsPeriodType", Order = 0)] public BarsPeriodType PeriodType { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Description = "Quantity of period type.", Order = 0)] public int Period { get; set; } [Browsable(false)] [XmlIgnore] public Series<double> PSAR { get { return Values[0]; } } [Browsable(false)] [XmlIgnore] public Series<double> Line20VWMA { get { return Values[1]; } } [Browsable(false)] [XmlIgnore] public Series<double> Line20SMA { get { return Values[2]; } } [Browsable(false)] [XmlIgnore] public Series<double> Line300 { get { return Values[3]; } } [Browsable(false)] [XmlIgnore] public Series<double> Line300High { get { return Values[4]; } } [Browsable(false)] [XmlIgnore] public Series<double> Line300Low { get { return Values[5]; } } [Browsable(false)] [XmlIgnore] public MarketPosition FilterMarketPosition { get; set; } #endregion } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private Filter[] cacheFilter; public Filter Filter(BarsPeriodType periodType, int period) { return Filter(Input, periodType, period); } public Filter Filter(ISeries<double> input, BarsPeriodType periodType, int period) { if (cacheFilter != null) for (int idx = 0; idx < cacheFilter.Length; idx++) if (cacheFilter[idx] != null && cacheFilter[idx].PeriodType == periodType && cacheFilter[idx].Period == period && cacheFilter[idx].EqualsInput(input)) return cacheFilter[idx]; return CacheIndicator<Filter>(new Filter(){ PeriodType = periodType, Period = period }, input, ref cacheFilter); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.Filter Filter(BarsPeriodType periodType, int period) { return indicator.Filter(Input, periodType, period); } public Indicators.Filter Filter(ISeries<double> input , BarsPeriodType periodType, int period) { return indicator.Filter(input, periodType, period); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.Filter Filter(BarsPeriodType periodType, int period) { return indicator.Filter(Input, periodType, period); } public Indicators.Filter Filter(ISeries<double> input , BarsPeriodType periodType, int period) { return indicator.Filter(input, periodType, period); } } } #endregion
Comment
-
Hello Herrwolf1,
Thanks for the reply.
Do you still see this using the AddDataSeries that is non-variable?
Using AddDataSeries as you have is documented to have issues, are you still able to see the problem using AddDataSeries(BarsPeriodType.Minute, 240); instead?
Its really not expected for public properties to be used with AddDataSeries and have it work successfully, that mainly happens in backtesting tools but can really happen anywhere the script is applied.
I look forward to being of further assistance.JesseNinjaTrader Customer Service
Comment
-
Hello Herrwolf1,
Thank you for clarifying that. Going forward I would suggest removing any dynamic uses of AddDataSeries for forum samples as we will always ask that you change that before testing, it just speeds up finding the problem.
In regard to the ParabolicSAR, passing a series to it would be unexpected because it does not take an input in its code. All indicators have an overload which you can pass an input but not all make use of that. The ParabolicSAR does not use Input in its code and uses specific Price series. To have this indicator calculate for the second series you would have to call it from that BarsInProgress:
Code:if(BarsInProgress == 1) { _psar = ParabolicSAR(0.02, 0.2, 0.02); }
For this type of use case I would likely suggest to use the BarsInProgress property for those indicators to call them on each OBU:
Code://if (BarsInProgress != 0) return; if(BarsInProgress == 0) { existing logic } if(BarsInProgress == 1) { // Reset the parameters. _ema300 = EMA(300); _psar = ParabolicSAR(0.02, 0.2, 0.02); _sma20 = SMA(20); _vwma20 = VWMA( 20); _ema300High = EMA(300); _ema300Low = EMA( 300); }
I was unable to test the code you provided to see if that changes the result, the code you pasted got formatted and is no longer completely valid. You can instead attach the .cs file directly if another sample is still needed.
I look forward to being of further assistance.JesseNinjaTrader Customer Service
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by Kaledus, Today, 01:29 PM
|
1 response
6 views
0 likes
|
Last Post Today, 01:53 PM | ||
Started by frankthearm, Yesterday, 09:08 AM
|
13 responses
45 views
0 likes
|
Last Post
by frankthearm
Today, 01:52 PM
|
||
Started by PaulMohn, Today, 12:36 PM
|
2 responses
16 views
0 likes
|
Last Post
by PaulMohn
Today, 01:48 PM
|
||
Started by Conceptzx, 10-11-2022, 06:38 AM
|
2 responses
55 views
0 likes
|
Last Post
by PhillT
Today, 01:47 PM
|
||
Started by yertle, Yesterday, 08:38 AM
|
8 responses
37 views
0 likes
|
Last Post
by ryjoga
Today, 01:22 PM
|
Comment