I've got two buttons on the toolbar to show/hide either one. However, I've not been able to get the indicator to redraw or erase the plots when the buttons are clicked. When I reload the script (e.g. F5) it works, but not automatically.
I've tried Update() and ForceRefresh() and it won't work. I know part of the answer has to be resetting the number of bars that need to be updated in OnBarUpdate(). I know what I want is possible because I've seen other indicators replot based on a show/hide concept but cannot duplicate.
What am I doing wrong or missing?
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
{
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.NinjaScriptIndicatorDe scriptionBollinger;
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();
//ReloadAllHistoricalData();
}
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;
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;
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;
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;
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

Comment