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

Keltner Channel w/adjustable ATR period

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

    Keltner Channel w/adjustable ATR period

    I need to develop a keltner channel which uses an ATR period in its calculation that can be adjusted. Initially I thought this would be as simple as substituting the emadiff variable in the code below with an adjustable ATR, but I can't seem to get that to work no matter how many different ways I try it. I have little to no coding experience, so perhaps that is the way to go about it, but I am making a simple error.

    Here is the keltner code...

    diff = new Series<double>(this);
    emaDiff = EMA(diff, Period); <<This needs to be changed, but how?
    emaTypical = EMA(Typical, Period);
    }
    }

    protected override void OnBarUpdate()
    {
    diff[0] = High[0] - Low[0];

    double middle = emaTypical[0];
    double offset = emaDiff[0] * OffsetMultiplier;

    double upper = middle + offset;
    double lower = middle - offset;

    Midline[0] = middle;
    Upper[0] = upper;
    Lower[0] = lower;

    BELOW IS THE PINESCRIPT CODE FOR THE KELTNER VARIANT I WANT....

    source = close
    length = input(125, minval=1, title = "EMA Length")
    atrlen = input(500, minval=1, title = "ATR Length")
    mult1 = input(3.2, minval=1, title = "Deviation multiplier 1")
    mult2 = input(6.4, minval=1, title = "Deviation multiplier 2")
    mult3 = input(9.5, minval=1, title = "Deviation multiplier 3")
    ma = ema(source, length)
    range = tr
    rangema = ema(range, atrlen)

    up1 = ma + rangema * mult1
    up2 = ma + rangema * mult2
    up3 = ma + rangema * mult3

    dn1 = ma - rangema * mult1
    dn2 = ma - rangema * mult2
    dn3 = ma - rangema * mult3

    plot(ma, color=white)


    I also want to add 3 multiples for the bands calculation instead of the 1, but I think I know how to do that part once I integrate the ATR.

    The final product should look like this....

    Click image for larger version

Name:	Yacine example.PNG
Views:	1004
Size:	14.9 KB
ID:	1078897

    Thanks in advance for any help you can offer!


    #2
    Originally posted by lunardiplomacy View Post
    I need to develop a keltner channel which uses an ATR period in its calculation that can be adjusted. Initially I thought this would be as simple as substituting the emadiff variable in the code below with an adjustable ATR, but I can't seem to get that to work no matter how many different ways I try it. I have little to no coding experience, so perhaps that is the way to go about it, but I am making a simple error.

    Here is the keltner code...

    diff = new Series<double>(this);
    emaDiff = EMA(diff, Period); <<This needs to be changed, but how?
    emaTypical = EMA(Typical, Period);
    }
    }

    protected override void OnBarUpdate()
    {
    diff[0] = High[0] - Low[0];

    double middle = emaTypical[0];
    double offset = emaDiff[0] * OffsetMultiplier;

    double upper = middle + offset;
    double lower = middle - offset;

    Midline[0] = middle;
    Upper[0] = upper;
    Lower[0] = lower;

    BELOW IS THE PINESCRIPT CODE FOR THE KELTNER VARIANT I WANT....

    source = close
    length = input(125, minval=1, title = "EMA Length")
    atrlen = input(500, minval=1, title = "ATR Length")
    mult1 = input(3.2, minval=1, title = "Deviation multiplier 1")
    mult2 = input(6.4, minval=1, title = "Deviation multiplier 2")
    mult3 = input(9.5, minval=1, title = "Deviation multiplier 3")
    ma = ema(source, length)
    range = tr
    rangema = ema(range, atrlen)

    up1 = ma + rangema * mult1
    up2 = ma + rangema * mult2
    up3 = ma + rangema * mult3

    dn1 = ma - rangema * mult1
    dn2 = ma - rangema * mult2
    dn3 = ma - rangema * mult3

    plot(ma, color=white)


    I also want to add 3 multiples for the bands calculation instead of the 1, but I think I know how to do that part once I integrate the ATR.

    The final product should look like this....

    Click image for larger version  Name:	Yacine example.PNG Views:	3 Size:	14.9 KB ID:	1078897

    Thanks in advance for any help you can offer!
    Just change your calculation of diff to be the TrueRange instead of the Range.

    Code:
    diff = Math.Max(High[0], Close[1]) - Math.Min(Close[1], Low[0]);
    Remember to escape out of (CurrentBar == 0)
    Last edited by koganam; 11-25-2019, 11:50 AM.

    Comment


      #3
      Originally posted by koganam View Post

      Just change your calculation of diff to be the TrueRange instead of the Range.

      Code:
      diff = Math.Max(High[0], Close[1]) - Math.Min(Close[1], Low[0]);
      Remember to escape out of (CurrentBar == 0)
      Thank you for your response!

      I tried to do just that, however I might have implemented it incorrectly/put the code in the wrong place. Do you mean to replace the variable 'diff' that holds the series with true range? And when you say to escape current bar == 0, are you referring to the '[0]' that appears after some of the variables? If so, what would I change that to?

      Would it be too much to ask to show me where your code would go? Thank you again for responding.

      Comment


        #4
        Hello lunardiplomacy,

        Thank you for your posts.

        If youre wanting to swap the SMA for an ATR, you'd need to do something like this:

        Code:
                private Series<double>        diff;
                private    ATR                    atrDiff;
                private    ATR                    atrTypical;
        
                protected override void OnStateChange()
                {
                    if (State == State.SetDefaults)
                    {
                        Description                    = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionKeltnerChannel;
                        Name                        = "ATRKeltner";
                        Period                        = 10;
                        IsOverlay                    = false;
                        IsSuspendedWhileInactive    = true;
                        OffsetMultiplier            = 1.5;
        
                        AddPlot(Brushes.DarkGray,        NinjaTrader.Custom.Resource.KeltnerChannelMidline);
                        AddPlot(Brushes.DodgerBlue,        NinjaTrader.Custom.Resource.NinjaScriptIndicatorUpper);
                        AddPlot(Brushes.DodgerBlue,        NinjaTrader.Custom.Resource.NinjaScriptIndicatorLower);
                    }
                    else if (State == State.DataLoaded)
                    {
                        diff                = new Series<double>(this);
                        atrDiff                = ATR(diff, Period);
                        atrTypical            = ATR(Typical, Period);
                    }
                }
        
                protected override void OnBarUpdate()
                {
                    if (CurrentBar < 1)
                        return;
                    diff[0]            = Math.Max(High[0], Close[1]) - Math.Min(Close[1], Low[0]);
        
                    double middle    = atrTypical[0];
                    double offset    = atrDiff[0] * OffsetMultiplier;
        
                    double upper    = middle + offset;
                    double lower    = middle - offset;
        
                    Midline[0]        = middle;
                    Upper[0]        = upper;
                    Lower[0]        = lower;
                }
        All I've done here is replace the SMA with an ATR; though I factored in Kognam's changes as well, and you'd probably want to plot this in a separate panel or as an overlay - the values you get for the lines are a lot smaller than the current prices.

        Please let us know if we may be of further assistance to you.
        Last edited by NinjaTrader_Kate; 11-25-2019, 03:29 PM. Reason: Typoed ATR as ART
        Kate W.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by NinjaTrader_Kate View Post
          Hello lunardiplomacy,

          Thank you for your posts.

          If youre wanting to swap the SMA for an ATR, you'd need to do something like this:

          Code:
           private Series<double> diff;
          private ATR atrDiff;
          private ATR atrTypical;
          
          protected override void OnStateChange()
          {
          if (State == State.SetDefaults)
          {
          Description = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionKeltnerChannel;
          Name = "ATRKeltner";
          Period = 10;
          IsOverlay = false;
          IsSuspendedWhileInactive = true;
          OffsetMultiplier = 1.5;
          
          AddPlot(Brushes.DarkGray, NinjaTrader.Custom.Resource.KeltnerChannelMidline);
          AddPlot(Brushes.DodgerBlue, NinjaTrader.Custom.Resource.NinjaScriptIndicatorUpper);
          AddPlot(Brushes.DodgerBlue, NinjaTrader.Custom.Resource.NinjaScriptIndicatorLower);
          }
          else if (State == State.DataLoaded)
          {
          diff = new Series<double>(this);
          atrDiff = ATR(diff, Period);
          atrTypical = ATR(Typical, Period);
          }
          }
          
          protected override void OnBarUpdate()
          {
          if (CurrentBar < 1)
          return;
          diff[0] = Math.Max(High[0], Close[1]) - Math.Min(Close[1], Low[0]);
          
          double middle = atrTypical[0];
          double offset = atrDiff[0] * OffsetMultiplier;
          
          double upper = middle + offset;
          double lower = middle - offset;
          
          Midline[0] = middle;
          Upper[0] = upper;
          Lower[0] = lower;
          }
          All I've done here is replace the SMA with an ART; though I factored in Kognam's changes as well, and you'd probably want to plot this in a separate panel or as an overlay - the values you get for the lines are a lot smaller than the current prices.

          Please let us know if we may be of further assistance to you.
          Hi Kate,

          Thank you for your response. I apologize if my explanation was misleading, I still want the EMA, I just want to calculate the upper and lower bands as a multiple of the ATR.

          Let me try to be as specific as I can... currently the NT KeltnerChannel code base uses the previous bar high - close in it's calculation of the offset multiple, such that, for example, the upper band is calculated as:

          Code:
           emaTypical + emaDiff * OffsetMultiplier
          where emaDiff = high - low. What I want is for the calculation to look like this:

          Code:
           emaTypical + emaATR * OffsetlMultiplier
          where emaATR is an exponential moving average of the true range over a period of the last 500 bars. Something like ema(tr, 500), or at least that's how it looks in pinescript.

          In other words, instead of simply using the high - low I want to use the true range of the prior 500 bars, and THAT'S what I am having trouble substituting/implementing. I would also preferably like to be able to change the ATR period so that it doesn't HAVE to be 500 bars, but I can figure that out another time.

          Okay, thank you so much for helping me out, I am sorry if this was poorly explained the first time, I am only just starting to learn to code, so it's difficult for me to put it into English eloquently. I appreciate any help you can give me.

          Comment


            #6
            Hello LunarDiplomacy,

            Thank you for your reply.

            Ah, I understand much better now. You're wanting to use the ATR value in place of the current diff value, is that correct? Here's an example:

            Code:
            private Series<double>        diff;
                    private    SMA                    smaDiff;
                    private    SMA                    smaTypical;
            
                    protected override void OnStateChange()
                    {
                        if (State == State.SetDefaults)
                        {
                            Description                    = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionKeltnerChannel;
                            Name                        = "ATRKeltner";
                            Period                        = 10;
                            ATRPeriod                    = 10;
                            IsOverlay                    = true;
                            IsSuspendedWhileInactive    = true;
                            OffsetMultiplier            = 1.5;
            
                            AddPlot(Brushes.DarkGray,        NinjaTrader.Custom.Resource.KeltnerChannelMidline);
                            AddPlot(Brushes.DodgerBlue,        NinjaTrader.Custom.Resource.NinjaScriptIndicatorUpper);
                            AddPlot(Brushes.DodgerBlue,        NinjaTrader.Custom.Resource.NinjaScriptIndicatorLower);
                        }
                        else if (State == State.DataLoaded)
                        {
                            smaDiff                = SMA(ATR(ATRPeriod), Period);
                            smaTypical            = SMA(Typical, Period);
                        }
                    }
            
                    protected override void OnBarUpdate()
                    {
            
                        double middle    = smaTypical[0];
                        double offset    = smaDiff[0] * OffsetMultiplier;
            
                        double upper    = middle + offset;
                        double lower    = middle - offset;
            
                        Midline[0]        = middle;
                        Upper[0]        = upper;
                        Lower[0]        = lower;
                    }
            
                    #region Properties
                    [Browsable(false)]
                    [XmlIgnore()]
                    public Series<double> Lower
                    {
                        get { return Values[2]; }
                    }
            
                    [Browsable(false)]
                    [XmlIgnore()]
                    public Series<double> Midline
                    {
                        get { return Values[0]; }
                    }
            
                    [Range(0.01, int.MaxValue), NinjaScriptProperty]
                    [Display(ResourceType = typeof(Custom.Resource), Name = "OffsetMultiplier", GroupName = "NinjaScriptParameters", Order = 0)]
                    public double OffsetMultiplier
                    { get; set; }
            
                    [Range(1, int.MaxValue), NinjaScriptProperty]
                    [Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 1)]
                    public int Period
                    { get; set; }
            
                    [Range(1, int.MaxValue), NinjaScriptProperty]
                    [Display(ResourceType = typeof(Custom.Resource), Name = "ATRPeriod", GroupName = "NinjaScriptParameters", Order = 2)]
                    public int ATRPeriod
                    { get; set; }
            
                    [Browsable(false)]
                    [XmlIgnore()]
                    public Series<double> Upper
                    {
                        get { return Values[1]; }
                    }
                    #endregion
            Is that more in line for what you were looking for?

            Please let us know if we may be of further assistance to you.
            Kate W.NinjaTrader Customer Service

            Comment


              #7
              Yes, Kate!! You are a goddess, this is it. Thank you so much for your help.

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by benmarkal, Yesterday, 12:52 PM
              3 responses
              23 views
              0 likes
              Last Post NinjaTrader_Gaby  
              Started by helpwanted, Today, 03:06 AM
              1 response
              19 views
              0 likes
              Last Post sarafuenonly123  
              Started by Brevo, Today, 01:45 AM
              0 responses
              11 views
              0 likes
              Last Post Brevo
              by Brevo
               
              Started by pvincent, 06-23-2022, 12:53 PM
              14 responses
              244 views
              0 likes
              Last Post Nyman
              by Nyman
               
              Started by TraderG23, 12-08-2023, 07:56 AM
              9 responses
              388 views
              1 like
              Last Post Gavini
              by Gavini
               
              Working...
              X