Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Custom Defined Pivots

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

    Custom Defined Pivots

    I am C# self-taught... very basic mostly just modifying existing indicators. I am trying to find information on where I might start to learn how to define market structure pivots. I have been experimenting with defining pivots a bunch of different ways, but tbh they don't really matter or will probably change. What I want to do is start working on something that I can plug that information into to work with.

    Most of the pivot calculation methods are based on some oscillator type definition. For example when the oscillator is above zero, that would be price action that I am ascribing to an upper pivot, and below zero to a lower pivot.

    What I am trying to do is look back at the last "pivot" to get OHLC information. So all of the recent bars for which the oscillator is above 0 would be distilled down to a single data point for an upper pivot, and conversely as the oscillator then starts working on the lower pivot. The end point being working on defining a series of higher highs/lows, lower highs/lows.

    It would seem to me there is some basic C# skill that I haven't worked with yet that can do this pretty easily. Maybe a list that it gets dumped into? If you can just point me in the right direction I want somewhere to start with a little more self-education. Thanks!

    #2
    Hello Mabba, thanks for writing in.

    We have the Pivots indicator by default in the platform:



    If you are wanting to get the bar where the pivots change, that would need to be done in the custom code as well e.g.

    private Pivots MyPivots;
    private double CurrentR1 = -1;
    private List<int> PivotStartList;
    protected override void OnBarUpdate()
    {

    if(CurrentR1 != MyPivots.R1[0])
    {
    CurrentR1 = MyPivots.R1[0];
    PivotStartList.Add(CurrentBar);
    }
    }



    Please let me know if you have any further questions on this material.

    Comment


      #3
      Thanks for the reply Chris,
      Are you suggesting that I look into modifying the Pivots indicator to be based on my own calculations? For example...

      I want a paint bar and I want to use the Aroon Oscillator to calculate my pivots. I have an Upper Pivot color and a Lower Pivot color defined. Where every time Aroon is above 0, I want to trigger the Upper Pivot color for paint bars and every time Aroon is below 0, I want to trigger the Lower Pivot color for paint bars.

      I am currently having no issues with the above (see attached). What I need help on is as follows: I want to be able to reference all of the bars that were colored for the Upper Pivot. The Open price of when Aroon first went over 0, the highest high from the whole section Aroon was over 0, etc.

      Can I use my 'custom pivot calculator' with the existing Pivots indicator? Or is there a simpler way to do what I am want?

      Comment


        #4
        Hello Mabba, thanks for the follow up.

        I would recommend using an extra series to mark the needed bars. So you can use either a boolean series or an integer series in this case. If you use a bool series you will need two of them (one for upper and one for lower)

        The main idea is to mark every slot index of the series when your condition is true. e.g. for every bar, check for the upper pivot condition. If it's true, set your bool series to true. With the boolean series, it will make it simple to check if the condition was true or not for that bar. We have a related example here:



        Please let me know if you have any questions on this material.

        Comment


          #5
          Thank you Chris, I think I have a few questions still, but let me play around with this for a couple days to try and make some progress.

          Comment


            #6
            Chris,
            So I took a crack at use the bool series to just replicate what I was doing before moving on. I am getting some inconsistencies with the result.

            I intended to have the indicator just alternate setting each bool (Upper and Lower) to true, so when one is true the other false, etc. Then just checking to see if one was true to determine which color to paint. It seemed simple enough, but sometimes it triggers as expected and other times not. Would you be able to see where I went wrong? Thanks!

            I attached some pics of my settings, and what the chart is printing. See code below:

            Code:
            namespace NinjaTrader.NinjaScript.Indicators
            {
            public class SampleOscPivots : Indicator
            {
            
            private Series<bool> UpperPivot;
            private Series<bool> LowerPivot;
            
            protected override void OnStateChange()
            {
            if (State == State.SetDefaults)
            {
            Description = @"Calculates the difference between two moving averages and uses that to paint upper and lower pivots.";
            Name = "Sample Osc Diff";
            Calculate = Calculate.OnBarClose;
            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 = true;
            Fast = 14;
            Slow = 21;
            Trigger = 10;
            PaintBars = true;
            
            UpColor = Brushes.DarkGreen;
            DwnColor = Brushes.Firebrick;
            
            AddPlot(new Stroke(Brushes.DeepSkyBlue, 2), PlotStyle.Bar, "Diff");
            
            }
            else if (State == State.Configure)
            {
            UpperPivot = new Series<bool>(this);
            LowerPivot = new Series<bool>(this);
            }
            }
            
            protected override void OnBarUpdate()
            { if( CurrentBar < 2 ) return;
            
            Diff[0] = 1000 * ( EMA(Fast)[0] - SMA(Slow)[0]);
            
            if ( Diff[0] > Trigger )
            {
            UpperPivot[0] = (true);
            LowerPivot[0] = (false);
            }
            else if ( Diff[0] < -Trigger )
            {
            UpperPivot[0] = (false);
            LowerPivot[0] = (true);
            }
            
            
            if ( UpperPivot[0] == (true) )
            PlotBrushes[0][0] = UpColor;
            else
            PlotBrushes[0][0] = DwnColor;
            
            
            if ( PaintBars )
            BarBrush = PlotBrushes[0][0];
            
            
            
            }
            
            #region Properties
            [NinjaScriptProperty]
            [Range(1, int.MaxValue)]
            [Display(Name="Fast", Order=1, GroupName="Parameters")]
            public int Fast
            { get; set; }
            
            [Range(1, int.MaxValue)]
            [Display(Name="Slow", Order=2, GroupName="Parameters")]
            public int Slow
            { get; set; }
            
            [NinjaScriptProperty]
            [Range(1, int.MaxValue)]
            [Display(Name="Trigger Level", Description="Trigger Level for a new pivot", Order=3, GroupName="Parameters")]
            public int Trigger
            { get; set; }
            
            
            [NinjaScriptProperty]
            [Display(Name="PaintBars", Description="", Order=4, GroupName="Parameters")]
            public bool PaintBars
            { get; set; }
            
            
            [NinjaScriptProperty]
            [XmlIgnore]
            [Display(Name="Up Color", Description="", Order=1, GroupName="Plot Colors")]
            public Brush UpColor
            { get; set; }
            
            [Browsable(false)]
            public string UpColorSerializable
            {
            get { return Serialize.BrushToString(UpColor); }
            set { UpColor = Serialize.StringToBrush(value); }
            }
            
            [NinjaScriptProperty]
            [XmlIgnore]
            [Display(Name="Down Color", Description="", Order=2, GroupName="Plot Colors")]
            public Brush DwnColor
            { get; set; }
            
            [Browsable(false)]
            public string DwnColorSerializable
            {
            get { return Serialize.BrushToString(DwnColor); }
            set { DwnColor = Serialize.StringToBrush(value); }
            }
            
            [Browsable(false)]
            [XmlIgnore]
            public Series<bool> upperPivot
            {
            get { return UpperPivot; }
            }
            
            [Browsable(false)]
            [XmlIgnore]
            public Series<bool> lowerPivot
            {
            get { return LowerPivot; }
            }
            
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> Diff
            {
            get { return Values[0]; }
            }
            #endregion

            Comment


              #7
              Hello Mabba, thanks for the follow up.

              The code is not considering the value in between the trigger values e.g.

              Code:
              if (Diff[0] > Trigger) {
                  UpperPivot[0] = (true);
                  LowerPivot[0] = (false);
              }
              else if (Diff[0] < -Trigger) {
                  UpperPivot[0] = (false);
                  LowerPivot[0] = (true);
              }
              else if (Diff[0] < Trigger && Diff[0] > -Trigger)
              {
                  UpperPivot[0] = (false);
                  LowerPivot[0] = (false);
              }
              
              if(UpperPivot[0] == true)
              {
                  PlotBrushes[0][0] = UpColor;
              }
              else if(LowerPivot[0] == true)
              {
                  PlotBrushes[0][0] = DwnColor;
              }
              else
              {
                  PlotBrushes[0][0] = Brushes.White;
              }
              Please let me know if any other questions come up.

              Comment


                #8
                Chris,
                I modified the code and it now prints as expected, thank you. Now that's working, could you please help me with how I would identify the highs and lows of prior true/false sections?

                Question #1
                When I write UpperPivot[6] is that accessing 6 instances ago of UpperPivot, or just checking the price bar 6 instances ago to see what the state of UpperPivot was? Or neither?

                Because what I am trying to do is access the entire last instance of UpperPivot, what was the highest high within that entire true section? Any any instance of UpperPivot for that matter... Does that make sense? Thanks!

                I attached more pics for reference.

                Comment


                  #9
                  Hello Mabba, thanks for your reply.

                  Referencing UpperPivots[6] will reference 6 bars ago. To find the most recent occurrence of the last instance UpperPivots was true you can use the MRO method:

                  https://ninjatrader.com/support/help...urence_mro.htm

                  MRO returns a BarsAgo index

                  To find the highest high of a series (in this case the Price series) you should use the MAX method.

                  https://ninjatrader.com/support/help...aximum_max.htm

                  There is an example on that page where they get the highest High price for a 20 bar period.

                  Please let me know if I can assist any further.

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                  0 responses
                  581 views
                  0 likes
                  Last Post Geovanny Suaza  
                  Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                  0 responses
                  338 views
                  1 like
                  Last Post Geovanny Suaza  
                  Started by Mindset, 02-09-2026, 11:44 AM
                  0 responses
                  103 views
                  0 likes
                  Last Post Mindset
                  by Mindset
                   
                  Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                  0 responses
                  554 views
                  1 like
                  Last Post Geovanny Suaza  
                  Started by RFrosty, 01-28-2026, 06:49 PM
                  0 responses
                  552 views
                  1 like
                  Last Post RFrosty
                  by RFrosty
                   
                  Working...
                  X