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

Make variable available to strategy

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

    Make variable available to strategy

    I have an indicator that calculates the slope of a moving average and colors the line appropriate to that value.

    Code:
    maSlope = (int)(radToDegrees*(Math.Atan((SMA(Period)[0]-(SMA(Period)[1]+SMA(Period)[2])/2)/1.5/TickSize)));
    Is there a way to make the value of maSlope available to a strategy?

    #2
    Use a Static Variable. Here is the example file.
    Attached Files

    Comment


      #3
      Hello Trader_Mark,

      Thanks for opening the thread.

      Strategies can use Plots from an indicator and other variables that are exposed by an indicator.

      Below is a link to a reference sample that demonstrates how you can create a Series in an indicator and expose those values to a strategy.



      If you have any questions on the sample, please let me know.
      JimNinjaTrader Customer Service

      Comment


        #4
        Originally posted by NinjaTrader_Jim View Post
        Hello Trader_Mark,

        Thanks for opening the thread.

        Strategies can use Plots from an indicator and other variables that are exposed by an indicator.

        Below is a link to a reference sample that demonstrates how you can create a Series in an indicator and expose those values to a strategy.



        If you have any questions on the sample, please let me know.
        I have read the links and created a maSlope series with no success. I have copied the entire code here in case any mistakes stand out to you.

        Basically, the indicator lets you select 1 of 3 moving average types and period, and you enter two angles (in addition to a flat) which will color the plot based on those angles. That is for the visual part but the strategy needs to be able to know the value of the slope as well and that is where I can't read the value from.

        Code:
        #region Global Enums
        
        public enum MASlopeType { EMA, SMA,    WMA }
        
        #endregion
        
        //This namespace holds Indicators in this folder and is required. Do not change it. 
        namespace NinjaTrader.NinjaScript.Indicators
        {
            public class mpMASlope : Indicator
            {
                #region Variables
                private Series<int>    maSlope;
                private MASlopeType maType            = MASlopeType.EMA;
                private int            period            = 14;
                private int            angle1            = 15;
                private int            angle2            = 60;
                private double        ma0                = 0;
                private double        ma1                = 0;
                private bool        MAIsRising        = false;
                private double        RadiansToDegrees    = 180 / Math.PI; // Convert Radians to Degrees for slope calculation
                #endregion
                
                private void Initialize()
                {
                    maSlope = new Series<int>(this, MaximumBarsLookBack.Infinite);
                    AddPlot(new Stroke(Brushes.Green, 3), PlotStyle.Line, "MAup");
                    AddPlot(new Stroke(Brushes.Maroon, 3), PlotStyle.Line, "MAdown");
                    AddPlot(new Stroke(Brushes.Red, 3), PlotStyle.Line, "MAslopedown");
                    AddPlot(new Stroke(Brushes.LimeGreen, 3), PlotStyle.Line, "MAslopeup");
                    AddPlot(new Stroke(Brushes.Gray, 3), PlotStyle.Line, "MAflat");
                }
                
                protected override void OnStateChange()
                {
                    if (State == State.SetDefaults)
                    {
                        Description                                    = @"Plots EMA, SMA or WMA moving averages and colors the line according to the slope.";
                        Name                                        = "mpMASlope";
                        Calculate                                    = Calculate.OnPriceChange;
                        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;
                        
                        Initialize();
                    }
                    else if (State == State.Configure)
                    {
                    }
                }
                    
                protected override void OnBarUpdate()
                {
                    // Add your custom indicator logic here.
                    
                    if (CurrentBar < Period) return;
                    
                    switch (ThisMAType)
                    {
                        case MASlopeType.EMA:
                            if(IsRising(EMA(Period)))
                            { MAIsRising = true; }
                            else
                            { MAIsRising = false; }
                            ma0 = EMA(Period)[0];
                            ma1 = EMA(Period)[1];
                            maSlope[0] = (int)(RadiansToDegrees*(Math.Atan((EMA(Period)[0]-(EMA(Period)[1]+EMA(Period)[2])/2)/1.5/TickSize)));
                            break;
                        case MASlopeType.SMA:
                            if(IsRising(SMA(Period)))
                            { MAIsRising = true; }
                            else
                            { MAIsRising = false; }
                            ma0 = SMA(Period)[0];
                            ma1 = SMA(Period)[1];
                            maSlope[0] = (int)(RadiansToDegrees*(Math.Atan((SMA(Period)[0]-(SMA(Period)[1]+SMA(Period)[2])/2)/1.5/TickSize)));
                            break;
                        case MASlopeType.WMA:
                            if(IsRising(WMA(Period)))
                            { MAIsRising = true; }
                            else
                            { MAIsRising = false; }
                            ma0 = WMA(Period)[0];
                            ma1 = WMA(Period)[1];
                            maSlope[0] = (int)(RadiansToDegrees*(Math.Atan((WMA(Period)[0]-(WMA(Period)[1]+WMA(Period)[2])/2)/1.5/TickSize)));
                            break;
                    }
                    
                    if(MAIsRising)
                    {
                        if (maSlope[0] >= angle2)
                        {
                            MAslopeup[1] = ma1;
                            MAslopeup[0] = ma0;
                        }
                        else
                        if (maSlope[0] >= angle1)
                        {
                            MAup[1] = ma1;
                            MAup[0] = ma0;
                        }
                        else
                        if (maSlope[0] < angle1)
                        {
                            MAflat[1] = ma1;
                            MAflat[0] = ma0;
                        }
                    }
                    else
                    {
                        if (maSlope[0] <= -angle2)
                        {
                            MAslopedown[1] = ma1;
                            MAslopedown[0] = ma0;
                        }
                        else
                        if (maSlope[0] <= -angle1)
                        {
                            MAdown[1] = ma1;
                            MAdown[0] = ma0;
                        }
                        else
                        if (maSlope[0] > -angle1)
                        {
                            MAflat[1] = ma1;
                            MAflat[0] = ma0;
                        }
                    }
                    
                    Draw.TextFixed(this, "NinjaScriptInfo", "Slope angle: " + maSlope[0].ToString(), TextPosition.BottomRight);
                }
                
                #region Properties
                
                [NinjaScriptProperty]
                [Display(Name = "MA Type", Description = "Type of moving average to plot", GroupName = "Parameters", Order = 1)]
                public MASlopeType ThisMAType
                {
                    get { return maType; }
                    set { maType = value; }
                }
                
                [NinjaScriptProperty]
                [Display(Description = "Numbers of bars used for calculations", GroupName = "Parameters", Order = 1)]
                public int Period
                {
                    get { return period; }
                    set { period = Math.Max(1, value); }
                }
        
                [NinjaScriptProperty]
                [Display(Name = "Angle 1", Description = "MA angle between Flat and Sloping zones.", GroupName = "Parameters", Order = 1)]
                public int Angle1
                {
                    get { return angle1; }
                    set { angle1 = Math.Max(0, value); }
                }
        
                [NinjaScriptProperty]
                [Display(Name = "Angle 2", Description = "MA angle between Sloping and Steep zones.", GroupName = "Parameters", Order = 1)]
                public int Angle2
                {
                    get { return angle2; }
                    set { angle2 = Math.Max(0, value); }
                }
        
                [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public Series<double> MAup
                {
                    get { return Values[0]; }
                }
        
                [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public Series<double> MAdown
                {
                    get { return Values[1]; }
                }
        
                [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public Series<double> MAslopedown
                {
                    get { return Values[2]; }
                }
        
                [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public Series<double> MAslopeup
                {
                    get { return Values[3]; }
                }
        
                [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public Series<double> MAflat
                {
                    get { return Values[4]; }
                }
                
                #endregion
            }
        }

        Comment


          #5
          Hello Trader_Mark,

          Thanks for your reply.

          I see that you are creating a private Series for maSlope. This will keep the variable locked in the context of the class it was created. If you would like to have this variable accessible, you will need to make a public variable, like the properties you added to the script, and access the private variable from there.

          Please see the source code for the SampleBoolSeries indicator for a demonstration. See the Series named BullIndication and BearIndication. These variables are declared publicly along side the input properties except with [Browsable(false)] and [XmlIgnore] to prevent the public variable from listing as a parameter.

          Code:
          // Important code segment in the Properties section. Please expand to view.
          #region Properties
          // Creating public properties that access our internal Series<bool> allows external access to this indicator's Series<bool>
          [Browsable(false)]
          [XmlIgnore]
          public Series<bool> BearIndication
          {
              get { return bearIndication; }	// Allows our public BearIndication Series<bool> to access and expose our interal bearIndication Series<bool>
          }
          [Browsable(false)]
          [XmlIgnore]		
          public Series<bool>  BullIndication
          {
              get { return bullIndication; }	// Allows our public BullIndication Series<bool> to access and expose our interal bullIndication Series<bool>
          }
          public double ExposedVariable
          {
          	// We need to call the Update() method to ensure our exposed variable is in up-to-date.
          Please let me know if I can be of further help.
          JimNinjaTrader Customer Service

          Comment


            #6
            I have looked at the Bool example and made the necessary changes but still no joy.

            Maybe I am not explaining things correctly or I am expecting a different result. My goal is to be able to add a condition to a strategy based on the mpMASlope indicator (attached) and the SlopeAngle variable by comparing SlopeAngle to be > X.

            After following your examples, I can see the exposedVariable variable on the indicator properties page but never from within the Strategy Builder. I never see the, now public int series, SlopeAngle variable.
            Attached Files

            Comment


              #7
              Hello Trader_Mark,

              The Strategy Builder is only designed for developing simple strategies and would not be able to access exposed variables from an indicator. You will have to unlock the code and use the syntax from the SampleBoolSeriesStrategy.

              Code:
              protected override void OnBarUpdate()
              {
              	/* When our indicator gives us a bull signal we enter long. Notice that we are accessing the
              	public BoolSeries we made in the indicator. */
              	if (SampleBoolSeries().BullIndication[0])
              		EnterLong();
              	
              	// When our indicator gives us a bear signal we enter short
              	if (SampleBoolSeries().BearIndication[0])
              		EnterShort();
              	
              	/* NOTE: This strategy is based on reversals thus there are no explicit exit orders. When you
              	are long you will be closed and reversed into a short when the bear signal is received. The vice
              	versa is true if you are short. */
              	
              	/* Print our exposed variable. Because we manually kept it up-to-date it will print values that
              	match the bars object. */
              	Print(SampleBoolSeries().ExposedVariable);
              }
              For example, you can change the reference from SampleBoolSeries().BearIndication[0] to the public SlopeAngle Series from your indicator.

              I look forward to being of further help.
              JimNinjaTrader Customer Service

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by wzgy0920, 04-20-2024, 06:09 PM
              2 responses
              26 views
              0 likes
              Last Post wzgy0920  
              Started by wzgy0920, 02-22-2024, 01:11 AM
              5 responses
              32 views
              0 likes
              Last Post wzgy0920  
              Started by wzgy0920, 04-23-2024, 09:53 PM
              2 responses
              49 views
              0 likes
              Last Post wzgy0920  
              Started by Kensonprib, 04-28-2021, 10:11 AM
              5 responses
              193 views
              0 likes
              Last Post Hasadafa  
              Started by GussJ, 03-04-2020, 03:11 PM
              11 responses
              3,235 views
              0 likes
              Last Post xiinteractive  
              Working...
              X