Dark Theme
Light Theme
Trading Articles
Article Categories
Article Tools
Welcome to NexusFi: the best trading community on the planet, with over 150,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 -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
Updated June 23, 2024
trending_up
82 views
thumb_up
0 thanks given
group
2 followers
forum
1 posts
attach_file
0 attachments
June 17th, 2024, 10:03 PM
Greensboro, NC
Experience: Intermediate
Platform: MT4
Trading: Forex
Posts: 1 since Apr 2015
Thanks Given: 0
Thanks Received: 0
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!
Code
//
// 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
Can you help answer these questions from other members on NexusFi?
Best Threads (Most Thanked) in the last 7 days on NexusFi
June 23rd, 2024, 11:18 AM
Posts: 76 since Jan 2020
Thanks Given: 23
Thanks Received: 45
viperboy1012
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!
Code
//
// 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
One way of doing this is to alternate the PlotStyle for the relevant plot between .Line and .PriceBox
For example, on button engaged, use:
Code
Plots[0].PlotStyle = PlotStyle.Line;
And when button is disengaged, use:
Code
Plots[0].PlotStyle = PlotStyle.PriceBox;
The PriceBox style plots just a marker in the price axis. If you don't want that to show, you can apply a Brushes.Transparent color to it.
I hope this helps.
Last Updated on June 23, 2024