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

Bad Calculation of SMA/EMA

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

    Bad Calculation of SMA/EMA

    I'm sure this is an easy syntax question, but I'm trying to get a calculation based on a SMA or EMA. I have seen several different syntaxes throughout the forums, chatgpt, and google, but am unable to make any of them work properly. Attached is the screenshot of what I'm looking at.

    The Yellow Plot on the graph is the EMA. It's listed at 14776.44. Great. The output of my calculation of FastAvg in the syntax given is showing the Fast Average as 14758.75 which isn't even close to 14776.44.

    I have no idea what the cause in shift is. The SMA is just as jacked up.

    I've tried the other Syntaxes:

    EMA(Close, FastLength)[0];

    and

    EMA(Close, Convert.ToInt32(FastLength));

    This one generated a bunch of errors saying it can't implicitly change it to a double... It is a double... ???
    I am coming up dry on how this is supposed to calculate.
    Attached Files

    #2
    Appending this post. I did find out that this primarily happens in the AM on Market Open. I can't be certain, but I think it's calculating EOD yesterday with Open today and the MA's just have to catch up before things get less ridiculous.

    Is there a way to have the MA's calculate the last (period) minutes leading up to Markets Open instead of having phantom values from yesterday?

    Comment


      #3
      Hello alphatango,

      Thanks for your post.

      Are the yellow and pink plots on the chart indicators added to the chart or are these plotting from the strategy by calling AddChartIndicator()?

      If these are indicators added to a chart, does the EMA() and SMA() calculation in your script match the same settings being used for the indicators that are added to the chart window?

      For example, are you using the same exact period in the calculations in your script?

      Is the code in the screenshot you shared being called in OnStateChange or OnBarUpdate?

      When calling the EMA() method you must provide a barsAgo value, otherwise the error you mentioned would appear.

      For example, you would need to call EMA(Close, 14)[0] where the barsAgo is 0 to get the EMA value of the current bar.

      See the help guide documentation below.

      EMA(): https://ninjatrader.com/support/help...onential_e.htm
      SMA(): https://ninjatrader.com/support/help...simple_sma.htm

      Further, you could view the SampleMACrossover strategy that comes default with NinjaTrader for an example of instantiating an SMA indicator in a NinjaScript strategy. To view the script, open a New > NinjaScript Editor window, open the Strategies folder, and double-click on the SampleMACrossover file.
      Brandon H.NinjaTrader Customer Service

      Comment


        #4
        Several great questions:

        Regarding the EMA/SMA on the chart: No those were added to the chart as indicators. Not plotted by the algo.
        They Do match the same settings as the Algo.

        As a note: I have strictures in place to only trade during trading hours, but that's only for the entries. The EMA/SMA calculation is outside of that in the OnBarUpdate section. Somehow it's not calculating even though I didn't tell it not to.

        RE: The Code in the screenshot: It's all being called by OnBarUpdate.

        What is the "BarsAgo" value? That may be what I'm missing.

        What I want the Algo to do is calculate the SMA/EMA from 20-30 minutes before market open (Pre-market), not take data from yesterday's close. How do I tell it to do that?
        Last edited by alphatango; 11-11-2023, 09:09 PM.

        Comment


          #5
          Hello alphatango,

          Thanks for your notes.

          The BarsAgo value is the value being passed into the SMA() and EMA() methods. The SMA() and EMA() syntax from the help guide could be seen below.

          SMA(ISeries<double> input, int period)[int barsAgo]

          SMA(): https://ninjatrader.com/support/help...simple_sma.htm

          EMA(ISeries<double> input, int period)[int barsAgo]

          EMA(): https://ninjatrader.com/support/help...onential_e.htm

          For example, you could call EMA(Close, 14)[0] where the barsAgo is 0 to get the EMA value of the current bar. BarsAgo 0 refers to the current bar. When running the script with Calculate.OnBarClose, this refers to the last closed bar. Note that BarsAgo value of 1 would refer to the previously closed bar. BarsAgo 2 would refer to the price 2 bars prior to the current bar on the chart.

          Please send a us simple reduced test script demonstrating the behavior you are reporting and the exact steps and settings you are using to reproduce the behavior.

          Note that a reduced copy refers to a copy of the script that contains the minimum amount of code needed to reproduce the issue. All other code is commented out or removed.

          To create a copy of your script to modify, open a New > NinjaScript Editor, select your script, right-click in the Editor, select 'Save as', name the script, and click OK.​

          To export the test script, go to Tools > Export > NinjaScript AddOn.
          Brandon H.NinjaTrader Customer Service

          Comment


            #6
            Tough question. it would be semi-difficult to rewrite a simplified algorithm, not impossible though. Let me ask: would a simplified logic be adequate (using whatever code I'm using)?


            Simplified Logic.
            ...OnBarUpdate;

            FastAvg = EMA(Close, FastLength)[0];
            SlowAvg = SMA(Close, SlowLength)[0];​

            If (Price Conditions = met)

            EnterLongLimit(1,FastAvg);


            As you can see below, its calculating "Correctly" if you push the Chart info to "RTH". The issue that I have is the SMA/EMA only calculates off of RTH. What I want it to do is calculate Extended Trading Hours so I can have the SMA/EMA be current an not pulling information from yesterday-close. Does this make sense? I don't want to calculate it from 30 bars ago, I want to calculate it now, and not bridging from close of market yesterday to open of market today.

            Click image for larger version

Name:	image.png
Views:	101
Size:	22.0 KB
ID:	1277616

            Comment


              #7
              Looks like I was able to push out the code that was just unnecessary for the troubleshooting. This is what I'm looking at.

              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.Indicators;
              using NinjaTrader.NinjaScript.Strategies;
              using NinjaTrader.NinjaScript.DrawingTools;
              #endregion
              
              namespace NinjaTrader.NinjaScript.Strategies
              {
                  public class SimplifiedStrategy : Strategy
                  {
                      public double FastAvg;
                      public double SlowAvg;
                      public bool UpDown;
              
                      protected override void OnStateChange()
                      {
                          if (State == State.SetDefaults)
                          {
                              Description                            = "Simplified Code";
                              Name                                 = "Simplified";
                              Calculate                             = Calculate.OnEachTick;
                              EntriesPerDirection                    = 1;
                              EntryHandling                        = EntryHandling.AllEntries;
                              IsExitOnSessionCloseStrategy        = true;
                              ExitOnSessionCloseSeconds            = 30;
                              IsFillLimitOnTouch                    = false;
                              MaximumBarsLookBack                    = MaximumBarsLookBack.TwoHundredFiftySix;
                              OrderFillResolution                    = OrderFillResolution.Standard;
                              Slippage                            = 0;
                              StartBehavior                        = StartBehavior.WaitUntilFlat;
                              TimeInForce                            = TimeInForce.Gtc;
                              TraceOrders                            = false;
                              RealtimeErrorHandling                = RealtimeErrorHandling.StopCancelClose;
                              StopTargetHandling                    = StopTargetHandling.PerEntryExecution;
                              BarsRequiredToTrade                    = 20;
                              IsInstantiatedOnEachOptimizationIteration = true;
                              FastLength = 9;
                              SlowLength = 25;
                              FastAvg        = 1.00;
                              SlowAvg        = 1.00;
                              UpDown        = false;
                          }
                          else if (State == State.Configure)
                          {
                              //AddDataSeries("NQ 12-23", Data.BarsPeriodType.Minute, 1, Data.MarketDataType.Last);
                          }
                      }
              
                      protected override void OnBarUpdate()
                      {
              
                          FastAvg = EMA(Close, FastLength)[0];            
                          SlowAvg = SMA(Close, SlowLength)[0];
                          UpDown = FastAvg > SlowAvg;
              
                          if  (Position.MarketPosition == MarketPosition.Flat)
              
                          {
                              if (UpDown)
                              {
                                  EnterLongLimit(1, FastAvg);
                              }
                              else
                              {
                                  EnterShortLimit(1, FastAvg);
                              }
                          }    
                      }
                  }
              }
              ​

              Comment


                #8
                Hello alphatango,

                Thanks for your notes.

                The SMA indicator is calculated by summing the closing prices of the security for a period of time and then dividing this total by the number of time periods. Sometimes called an arithmetic moving average, the SMA is basically the average stock price over time.

                In the EMA() calculation, the most recent market action is assigned greater importance as the average is calculated. The oldest pricing data in the exponential moving average is however never removed.

                SMA(Close, 14)[0] would get the currently closed bar's SMA value from the SMA indicator.

                EMA(Close, 14)[0] would get the currently closed bar's EMA value from the EMA indicator.

                I have tested the code you shared, added prints to the script that prints out the FastAvg and SlowAvg values and compared it to the SMA indicator and EMA indicator added to the chart using the same period parameters.

                I see that the FastAvg prints match the EMA indicator value and the SlowAvg prints match the SMA indicator values as expected.

                See this demonstration video: https://brandonh-ninjatrader.tinytak...Ml8yMjM4OTc3MQ

                Attached is the sample strategy used to test this.

                To understand why the script is behaving as it is, such as placing orders or not placing orders or drawing objects when expected, it is necessary to add prints to the script that print the values used for the logic of the script to understand how the script is evaluating.

                In the strategy add prints (outside of any conditions) that print the values of every variable used in every condition that places an order along with the time of that bar.

                Prints will appear in the NinjaScript Output window (New > NinjaScript Output window).​

                Below is a link to a forum post that demonstrates how to use prints to understand behavior.
                https://ninjatrader.com/support/foru...121#post791121
                Attached Files
                Brandon H.NinjaTrader Customer Service

                Comment


                  #9

                  I saw the video you sent. I see what you're saying. You're missing what I'm saying. The EMA/SMA is not calculating off of pre-market data. Something is telling the Script to only take yesterday at close to today at open for bars back. It doesn't even see the interim data between close yesterday and open today. Your video completely missed a End of day prior to Start of next day turn over. Watch the Moving Averages run to catch up (given the close and open price isn't close during after hours.

                  I pulled up the NQ. Run the same script you did but watch what happens in replay overnight. It's not correct to calculate the last bars of moving average from yesterday close to today open.

                  I was digging around and I believe I found something and I can't find it now. It had something to do with "state.configure" being a setting for what time you want the data to be between. The algo itself is capped at RTH. How do I make an algo that can trade between midnight and noon only?

                  Comment


                    #10
                    Hello alphatango,

                    Thanks for your notes.

                    If you would like to have the EMA and SMA indicator in your script calculate using an ETH trading hours template then you could call the AddDataSeries() method syntax that lets you specify a tradingHoursTemplate in State.Configure to add that secondary series to the script. You would set the 'tradingHoursName' argument to use the name of the Trading Hours template you want the data series to use.

                    AddDataSeries(string instrumentName, BarsPeriod barsPeriod, string tradingHoursName)

                    Then you could instantiate the SMA/EMA indicators in your script in State.DataLoaded so that they calculate using that added secondary series.

                    For example:

                    //class level variable
                    private SMA mySMA;

                    //State.DataLoaded
                    mySMA = SMA(BarsArray[1], 20);


                    See the help guide documentation below for more information.

                    AddDataSeries(): https://ninjatrader.com/support/help...dataseries.htm
                    Working with Multi-Timeframe/Multi-Instrument NinjaScripts: https://ninjatrader.com/support/help...nstruments.htm
                    Trading Hours: https://ninjatrader.com/support/help...ding_hours.htm
                    Brandon H.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by fx.practic, 10-15-2013, 12:53 AM
                    5 responses
                    5,404 views
                    0 likes
                    Last Post Bidder
                    by Bidder
                     
                    Started by Shai Samuel, 07-02-2022, 02:46 PM
                    4 responses
                    95 views
                    0 likes
                    Last Post Bidder
                    by Bidder
                     
                    Started by DJ888, Yesterday, 10:57 PM
                    0 responses
                    8 views
                    0 likes
                    Last Post DJ888
                    by DJ888
                     
                    Started by MacDad, 02-25-2024, 11:48 PM
                    7 responses
                    159 views
                    0 likes
                    Last Post loganjarosz123  
                    Started by Belfortbucks, Yesterday, 09:29 PM
                    0 responses
                    8 views
                    0 likes
                    Last Post Belfortbucks  
                    Working...
                    X