Welcome to NexusFi: the best trading community on the planet, with over 200,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- discounts are available after registering.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
I'm trying to get the indicator plots to disappear/reappear when clicking the "AVG" and "BANDS" buttons on the toolbar. It works when I manually press F5 or do "Reload NinjaScript"; however, I'd like this to be done automatically. The "ForceRefresh()" in my code does not work. I've also tried "Update()" and even "SendKeys.SendWait({F5})". How is this done? I know it's possible because indicators offered in NexusFi have done this!
Can you help answer these questions from other members on NexusFi?
I'm trying to get the indicator plots to disappear/reappear when clicking the "AVG" and "BANDS" buttons on the toolbar. It works when I manually press F5 or do "Reload NinjaScript"; however, I'd like this to be done automatically. The "ForceRefresh()" in my code does not work. I've also tried "Update()" and even "SendKeys.SendWait({F5})". How is this done? I know it's possible because indicators offered in NexusFi have done this!
//
// Copyright (C) 2024, NinjaTrader LLC <www.ninjatrader.com>.
// NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
//
#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.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
// This namespace holds indicators in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Indicators
{
/// <summary>
/// Bollinger Bands are plotted at standard deviation levels above and below a moving average.
/// Since standard deviation is a measure of volatility, the bands are self-adjusting:
/// widening during volatile markets and contracting during calmer periods.
/// </summary>
public class BollingerPlus : Indicator
{
private SMA sma;
private StdDev stdDev;
private Chart chartWindow;
private bool isToolBarButtonAdded;
private System.Windows.Controls.Button averageButton;
private System.Windows.Controls.Button bandsButton;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionBollinger;
Name = "Bollinger Plus";
IsOverlay = true;
IsSuspendedWhileInactive = true;
NumStdDev = 2;
Period = 20;
averageClicked = false;
bandsClicked = false;
AddPlot(Brushes.Goldenrod, NinjaTrader.Custom.Resource.BollingerUpperBand);
AddPlot(Brushes.Goldenrod, NinjaTrader.Custom.Resource.BollingerMiddleBand);
AddPlot(Brushes.Goldenrod, NinjaTrader.Custom.Resource.BollingerLowerBand);
}
else if (State == State.Historical)
{
if ((ChartControl!=null) && (!isToolBarButtonAdded))
{
ChartControl.Dispatcher.InvokeAsync((Action)(() =>
{
AddButtonToToolbar();
}));
}
}
else if (State == State.Terminated)
{
if (chartWindow != null)
{
ChartControl.Dispatcher.InvokeAsync((Action)(() =>
{
DisposeToolBar();
}));
}
}
else if (State == State.DataLoaded)
{
sma = SMA(Period);
stdDev = StdDev(Period);
}
}
private void refreshChart()
{
try
{
ForceRefresh();
}
catch(Exception e)
{
Print(e.ToString());
}
}
protected override void OnBarUpdate()
{
double sma0 = sma[0];
double stdDev0 = stdDev[0];
if(!bandsClicked) { Upper[0] = sma0 + NumStdDev * stdDev0; }
if(!averageClicked) { Middle[0] = sma0; }
if(!bandsClicked) { Lower[0] = sma0 - NumStdDev * stdDev0; }
}
private void OnButtonClick(object sender, RoutedEventArgs rea)
{
System.Windows.Controls.Button button = sender as System.Windows.Controls.Button;
if ((button==averageButton) && (button.Name=="HideAverage") && (button.Foreground==Brushes.Black) && (button.Background==Brushes.PeachPuff))
{
button.Foreground = Brushes.White;
button.Background = Brushes.DarkOrange;
button.Name = "ShowAverage";
averageClicked = true;
Print("averageClicked = "+averageClicked);
refreshChart();
return;
}
if ((button==averageButton) && (button.Name=="ShowAverage") && (button.Foreground==Brushes.White) && (button.Background==Brushes.DarkOrange))
{
button.Foreground = Brushes.Black;
button.Background = Brushes.PeachPuff;
button.Name = "HideAverage";
averageClicked = false;
Print("averageClicked = "+averageClicked);
refreshChart();
return;
}
if ((button==bandsButton) && (button.Name=="HideBands") && (button.Foreground==Brushes.Black) && (button.Background==Brushes.Thistle))
{
button.Foreground = Brushes.White;
button.Background = Brushes.Violet;
button.Name = "ShowBands";
bandsClicked = true;
Print("bandsClicked = "+bandsClicked);
refreshChart();
return;
}
if ((button==bandsButton) && (button.Name=="ShowBands") && (button.Foreground==Brushes.White) && (button.Background==Brushes.Violet))
{
button.Foreground = Brushes.Black;
button.Background = Brushes.Thistle;
button.Name = "HideBands";
bandsClicked = false;
Print("bandsClicked = "+bandsClicked);
refreshChart();
return;
}
}
private void AddButtonToToolbar()
{
string aName;
string bName;
Brush aFore;
Brush bFore;
Brush aBack;
Brush bBack;
if(averageClicked)
{
aName = "ShowAverage";
aFore = Brushes.White;
aBack = Brushes.DarkOrange;
}
else
{
aName = "HideAverage";
aFore = Brushes.Black;
aBack = Brushes.PeachPuff;
}
if(bandsClicked)
{
bName = "ShowBands";
bFore = Brushes.White;
bBack = Brushes.Violet;
}
else
{
bName = "HideBands";
bFore = Brushes.Black;
bBack = Brushes.Thistle;
}
chartWindow = Window.GetWindow(this.ChartControl.Parent) as Chart;
if (chartWindow==null)
{
Print("chartWindow == null");
return;
}
averageButton = new System.Windows.Controls.Button
{
Name = aName, Content = "AVG", Foreground = aFore, Background = aBack
};
averageButton.Click += OnButtonClick;
chartWindow.MainMenu.Add(averageButton);
bandsButton = new System.Windows.Controls.Button
{
Name = bName, Content = "BANDS", Foreground = bFore, Background = bBack
};
bandsButton.Click += OnButtonClick;
chartWindow.MainMenu.Add(bandsButton);
/*
averageButton = new System.Windows.Controls.Button
{
if(averageClicked) { Name = "ShowAverage", Content = "AVG", Foreground = Brushes.White, Background = Brushes.DarkOrange }
else { Name = "HideAverage", Content = "AVG", Foreground = Brushes.Black, Background = Brushes.PeachPuff }
};
averageButton.Click += OnButtonClick;
chartWindow.MainMenu.Add(averageButton);
bandsButton = new System.Windows.Controls.Button
{
if(bandsClicked) { Name = "ShowBands", Content = "BANDS", Foreground = Brushes.White, Background = Brushes.Violet }
else { Name = "HideBands", Content = "BANDS", Foreground = Brushes.Black, Background = Brushes.Thistle }
};
bandsButton.Click += OnButtonClick;
chartWindow.MainMenu.Add(bandsButton);
*/
/*
averageButton = new System.Windows.Controls.Button
{
Name = "HideAverage", Content = "AVG", Foreground = Brushes.Black, Background = Brushes.PeachPuff
};
averageButton.Click += OnButtonClick;
chartWindow.MainMenu.Add(averageButton);
bandsButton = new System.Windows.Controls.Button
{
Name = "HideBands", Content = "BANDS", Foreground = Brushes.Black, Background = Brushes.Thistle
};
bandsButton.Click += OnButtonClick;
chartWindow.MainMenu.Add(bandsButton);
*/
isToolBarButtonAdded = true;
}
private void DisposeToolBar()
{
if (averageButton!=null)
{
averageButton.Click -= OnButtonClick;
chartWindow.MainMenu.Remove(averageButton);
averageButton = null;
}
if (bandsButton!=null)
{
bandsButton.Click -= OnButtonClick;
chartWindow.MainMenu.Remove(bandsButton);
bandsButton = null;
}
}
#region Properties
[Browsable(false)]
[XmlIgnore()]
public Series<double> Lower
{
get { return Values[2]; }
}
[Browsable(false)]
[XmlIgnore()]
public Series<double> Middle
{
get { return Values[1]; }
}
[Range(0, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "NumStdDev", GroupName = "NinjaScriptParameters", Order = 0)]
public double NumStdDev
{ get; set; }
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 1)]
public int Period
{ get; set; }
[Display(ResourceType = typeof(Custom.Resource), Name = "Hide Average", GroupName = "NinjaScriptParameters", Order = 2)]
public bool averageClicked
{ get; set; }
[Display(ResourceType = typeof(Custom.Resource), Name = "Hide Bands", GroupName = "NinjaScriptParameters", Order = 3)]
public bool bandsClicked
{ get; set; }
[Browsable(false)]
[XmlIgnore()]
public Series<double> Upper
{
get { return Values[0]; }
}
#endregion
}
}
#region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private BollingerPlus[] cacheBollingerPlus;
public BollingerPlus BollingerPlus(double numStdDev, int period)
{
return BollingerPlus(Input, numStdDev, period);
}
public BollingerPlus BollingerPlus(ISeries<double> input, double numStdDev, int period)
{
if (cacheBollingerPlus != null)
for (int idx = 0; idx < cacheBollingerPlus.Length; idx++)
if (cacheBollingerPlus[idx] != null && cacheBollingerPlus[idx].NumStdDev == numStdDev && cacheBollingerPlus[idx].Period == period && cacheBollingerPlus[idx].EqualsInput(input))
return cacheBollingerPlus[idx];
return CacheIndicator<BollingerPlus>(new BollingerPlus(){ NumStdDev = numStdDev, Period = period }, input, ref cacheBollingerPlus);
}
}
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.BollingerPlus BollingerPlus(double numStdDev, int period)
{
return indicator.BollingerPlus(Input, numStdDev, period);
}
public Indicators.BollingerPlus BollingerPlus(ISeries<double> input , double numStdDev, int period)
{
return indicator.BollingerPlus(input, numStdDev, period);
}
}
}
namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.BollingerPlus BollingerPlus(double numStdDev, int period)
{
return indicator.BollingerPlus(Input, numStdDev, period);
}
public Indicators.BollingerPlus BollingerPlus(ISeries<double> input , double numStdDev, int period)
{
return indicator.BollingerPlus(input, numStdDev, period);
}
}
}
#endregion