Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Bollinger Alert indicator - help please

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

    Bollinger Alert indicator - help please

    region Using declarations
    using System;
    using System.ComponentModel;
    using System.Xml.Serialization;
    using System.ComponentModel.DataAnnotations;
    using System.Windows.Media;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    namespace NinjaTrader.NinjaScript.Indicators
    {
    public class BollyAlerts : Indicator
    {
    private SMA sma;
    private StdDev stdDev;
    private bool upperAlertTriggered;
    private bool lowerAlertTriggered;

    // Custom properties for alert
    private string soundFilePath = @"C:\\Sounds\\customAlert.wav"; // Set this to your desired sound file path

    [XmlElement("SoundFilePath")]
    public string SoundFilePath
    {
    get { return soundFilePath; }
    set { soundFilePath = value; }
    }

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = "Bollinger Bands with custom alerts and arrows";
    Name = "BollyAlerts";
    IsOverlay = true;
    IsSuspendedWhileInactive = true;
    NumStdDev = 2;
    Period = 14;
    Calculate = Calculate.OnEachTick; // To check conditions on every tick, not just at bar close

    AddPlot(Brushes.Goldenrod, "UpperBand");
    AddPlot(Brushes.Goldenrod, "MiddleBand");
    AddPlot(Brushes.Goldenrod, "LowerBand");
    }
    else if (State == State.DataLoaded)
    {
    sma = SMA(Period);
    stdDev = StdDev(Period);
    }
    }

    protected override void OnBarUpdate()
    {
    // Ensure there are enough bars to calculate the SMA and Bollinger Bands
    if (CurrentBar < Period || CurrentBar < BarsRequiredToPlot)
    return; // Exit if not enough bars are available

    double sma0 = sma[0];
    double stdDev0 = stdDev[0];

    Upper[0] = sma0 + NumStdDev * stdDev0;
    Middle[0] = sma0;
    Lower[0] = sma0 - NumStdDev * stdDev0;

    // Reset flags on a new bar
    if (IsFirstTickOfBar)
    {
    upperAlertTriggered = false;
    lowerAlertTriggered = false;
    }

    // Create unique arrow tags for each condition
    string downArrowTag = "downArrow" + CurrentBar + "_" + DateTime.Now.Ticks;
    string upArrowTag = "upArrow" + CurrentBar + "_" + DateTime.Now.Ticks;

    // Check if price touched or crossed the upper band (at any point, not just close)
    if (High[0] >= Upper[0] && !upperAlertTriggered)
    {
    // Draw a red arrow above the candle
    Draw.ArrowDown(this, downArrowTag, false, 0, High[0] + TickSize, Brushes.Red);
    // Trigger alert for Upper Band touch
    Alert("UpperBandTouch" + CurrentBar, Priority.High, "Price touched the Upper Bollinger Band", SoundFilePath, 10, Brushes.Red, Brushes.Transparent);
    upperAlertTriggered = true; // Mark that the upper alert has been triggered
    }
    // Check if price touched or crossed the lower band (at any point, not just close)
    else if (Low[0] <= Lower[0] && !lowerAlertTriggered)
    {
    // Draw a green arrow below the candle
    Draw.ArrowUp(this, upArrowTag, false, 0, Low[0] - TickSize, Brushes.Green);
    // Trigger alert for Lower Band touch
    Alert("LowerBandTouch" + CurrentBar, Priority.High, "Price touched the Lower Bollinger Band", SoundFilePath, 10, Brushes.Green, Brushes.Transparent);
    lowerAlertTriggered = true; // Mark that the lower alert has been triggered
    }
    }

    region Properties
    [Browsable(false)]
    [XmlIgnore()]
    public Series<double> Upper
    {
    get { return Values[0]; }
    }

    [Browsable(false)]
    [XmlIgnore()]
    public Series<double> Middle
    {
    get { return Values[1]; }
    }

    [Browsable(false)]
    [XmlIgnore()]
    public Series<double> Lower
    {
    get { return Values[2]; }
    }

    [Range(0, int.MaxValue), NinjaScriptProperty]
    [Display(Name = "NumStdDev", GroupName = "Parameters", Order = 0)]
    public double NumStdDev { get; set; }

    [Range(1, int.MaxValue), NinjaScriptProperty]
    [Display(Name = "Period", GroupName = "Parameters", Order = 1)]
    public int Period { get; set; }
    #endregion
    }
    }

    region NinjaScript generated code. Neither change nor remove.

    namespace NinjaTrader.NinjaScript.Indicators
    {
    public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
    {
    private BollyAlerts[] cacheBollyAlerts;
    public BollyAlerts BollyAlerts(double numStdDev, int period)
    {
    return BollyAlerts(Input, numStdDev, period);
    }

    public BollyAlerts BollyAlerts(ISeries<double> input, double numStdDev, int period)
    {
    if (cacheBollyAlerts != null)
    for (int idx = 0; idx < cacheBollyAlerts.Length; idx++)
    if (cacheBollyAlerts[idx] != null && cacheBollyAlerts[idx].NumStdDev == numStdDev && cacheBollyAlerts[idx].Period == period && cacheBollyAlerts[idx].EqualsInput(input))
    return cacheBollyAlerts[idx];
    return CacheIndicator<BollyAlerts>(new BollyAlerts(){ NumStdDev = numStdDev, Period = period }, input, ref cacheBollyAlerts);
    }
    }
    }

    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
    {
    public Indicators.BollyAlerts BollyAlerts(double numStdDev, int period)
    {
    return indicator.BollyAlerts(Input, numStdDev, period);
    }

    public Indicators.BollyAlerts BollyAlerts(ISeries<double> input , double numStdDev, int period)
    {
    return indicator.BollyAlerts(input, numStdDev, period);
    }
    }
    }

    namespace NinjaTrader.NinjaScript.Strategies
    {
    public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
    {
    public Indicators.BollyAlerts BollyAlerts(double numStdDev, int period)
    {
    return indicator.BollyAlerts(Input, numStdDev, period);
    }

    public Indicators.BollyAlerts BollyAlerts(ISeries<double> input , double numStdDev, int period)
    {
    return indicator.BollyAlerts(input, numStdDev, period);
    }
    }
    }

    #endregion

    Click image for larger version

Name:	image.png
Views:	227
Size:	47.6 KB
ID:	1320065
    I'm trying to code an indicator that alerts audibly and draws an arrow over candles that touched the upper and lower bands of the standard bollinger. It's done and works correctly, problem is it seems when I try to extend the range or change dates it crashes or doesn't load. Something about indexes and accessing data or something. This was all done with chatgpt, I don't know how to code, so I can't find the problem and solve it. If someone knows a more efficient way to code it, or has a bollinger indicator with alerts that'd be amazing. Above is a picture that shows my goal with the bollinger.

    #2
    Hello imjustkaze,

    This thread will remain open for any community members that would like to debug and correct your script as a convenience to you.

    You can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.


    If you would like to work through the debugging process yourself, I can provide guidance.

    If you are hitting a run time error, please provide the full error message.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hi imjustkaze,

      ninZa.co has an indicator called "Superior Bollinger" that can do this.



      For more details, don't hesitate to get in touch with the support team: https://ninza.co/contact

      Regards,
      William
      ninZa
      NinjaTrader Ecosystem Vendor - ninZa.co

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by Geovanny Suaza, 02-11-2026, 06:32 PM
      0 responses
      557 views
      0 likes
      Last Post Geovanny Suaza  
      Started by Geovanny Suaza, 02-11-2026, 05:51 PM
      0 responses
      324 views
      1 like
      Last Post Geovanny Suaza  
      Started by Mindset, 02-09-2026, 11:44 AM
      0 responses
      101 views
      0 likes
      Last Post Mindset
      by Mindset
       
      Started by Geovanny Suaza, 02-02-2026, 12:30 PM
      0 responses
      545 views
      1 like
      Last Post Geovanny Suaza  
      Started by RFrosty, 01-28-2026, 06:49 PM
      0 responses
      547 views
      1 like
      Last Post RFrosty
      by RFrosty
       
      Working...
      X