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

ForceRefresh Not working

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

    ForceRefresh Not working

    Hi,

    I am trying to use a button in my chart to change settings, I am not having much luck, I wrote a simple test project to show the issue..

    If you press the button the forcerefresh should cause the script to move the line to the right 200 bars each time.. But it doesnt.

    Any help would be appreciated.

    Code:
    #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;
    
    //Added
    using System.Windows.Controls;
    using System.Windows.Automation;
    using System.Windows.Automation.Provider;
    #endregion
    
    //This namespace holds Indicators in this folder and is required. Do not change it. 
    namespace NinjaTrader.NinjaScript.Indicators.KhaosCounts
    {
    	public class button  : Indicator
    	{
    		private Chart 			 chartWindow;
    		private DependencyObject searchObject;
    		private bool 			 isToolBarButtonAdded;
    		private Button			 exampleButton;
    		
    		private int oBarNumber =100;
    		
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{				
    				Name						= "SampleAddChartButton";
    				Calculate					= Calculate.OnEachTick;
    				IsOverlay					= true;
    				DisplayInDataBox			= true;
    				DrawOnPricePanel			= true;
    				DrawHorizontalGridLines		= true;
    				DrawVerticalGridLines		= true;
    				PaintPriceMarkers			= true;
    				ScaleJustification			= NinjaTrader.Gui.Chart.ScaleJustification.Right;
    				//Disable this property if your indicator requires custom values that cumulate with each new market data event. 
    				//See Help Guide for additional information.
    				IsSuspendedWhileInactive	= true;
    			}			
    			else if (State == State.Historical)
    			{
    				if (!isToolBarButtonAdded) 
    					Dispatcher.Invoke((Action)(() => {  
    						
    						chartWindow = Window.GetWindow(ChartControl.Parent) as Chart;
    						if (chartWindow == null) return;
    						
    						chartWindow.MainTabControl.SelectionChanged += MySelectionChangedHandler;
    						foreach (DependencyObject item in chartWindow.MainMenu)
    						{
    							if (AutomationProperties.GetAutomationId(item) == "exampleButton")
    							{
    								isToolBarButtonAdded = true;
    							}
    						}
    
    						if (!isToolBarButtonAdded)
    						{
    							exampleButton = new Button { Content = "Example Button", };
    							chartWindow.MainMenu.Add(exampleButton);
    							chartWindow.MainTabControl.SelectionChanged += MySelectionChangedHandler;
    							exampleButton.Click += ExampleButtonClick;
    							AutomationProperties.SetAutomationId(exampleButton, "exampleButton");
    						}
    					}));
    			}
    			
    			else if (State == State.Terminated)
    			{
    				if(chartWindow != null)
    				{					
    					if (exampleButton != null)
    					{
    						Dispatcher.Invoke((Action)(() =>
    						{
    							chartWindow.MainMenu.Remove(exampleButton);						
    							exampleButton.Click -= ExampleButtonClick;
    							exampleButton = null;
    						}));
    					}
    					chartWindow.MainTabControl.SelectionChanged -= MySelectionChangedHandler;
    					chartWindow = null;
    				}
    			}
    		}
    		
    		private void ExampleButtonClick(object sender, RoutedEventArgs e)
    		{
    			Print("Button is working"); 
    			oBarNumber +=200;
    			ForceRefresh();
    			Print (oBarNumber);
    			
    		}	
    		
    		private void MySelectionChangedHandler(object sender, SelectionChangedEventArgs e)
    		{
    			if (e.AddedItems.Count <= 0)
    				return;
    			TabItem tabItem = e.AddedItems[0] as TabItem;
    			if (tabItem == null) return;
    			ChartTab temp = tabItem.Content as ChartTab; 
    			if (temp != null)
    			{
    				if (exampleButton != null)
    					exampleButton.Visibility = temp.ChartControl == ChartControl ? Visibility.Visible : Visibility.Collapsed;
    			}
    		}	
    
    		protected override void OnBarUpdate()
    		{
    			if (IsFirstTickOfBar)
    			{
    				if (CurrentBar <33) {return;}
    				if (CurrentBar == oBarNumber)
    				Draw.VerticalLine(this, "VerticalLine_Bullish"+CurrentBar, 2, Brushes.DarkGreen, DashStyleHelper.Dash, 1, true);
    			}
    		}
    	}
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
    	public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
    	{
    		private KhaosCounts.button[] cachebutton;
    		public KhaosCounts.button button()
    		{
    			return button(Input);
    		}
    
    		public KhaosCounts.button button(ISeries<double> input)
    		{
    			if (cachebutton != null)
    				for (int idx = 0; idx < cachebutton.Length; idx++)
    					if (cachebutton[idx] != null &&  cachebutton[idx].EqualsInput(input))
    						return cachebutton[idx];
    			return CacheIndicator<KhaosCounts.button>(new KhaosCounts.button(), input, ref cachebutton);
    		}
    	}
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    	public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
    	{
    		public Indicators.KhaosCounts.button button()
    		{
    			return indicator.button(Input);
    		}
    
    		public Indicators.KhaosCounts.button button(ISeries<double> input )
    		{
    			return indicator.button(input);
    		}
    	}
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
    	public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
    	{
    		public Indicators.KhaosCounts.button button()
    		{
    			return indicator.button(Input);
    		}
    
    		public Indicators.KhaosCounts.button button(ISeries<double> input )
    		{
    			return indicator.button(input);
    		}
    	}
    }
    
    #endregion

    #2
    Hello KhaosTrader,

    To export a NinjaTrader 8 NinjaScript for easy sharing do the following:
    1. Click Tools -> Export -> NinjaScript...
    2. Click the 'add' link -> check the box(es) for the script(s) you want to include
    3. Click the 'Export' button
    4. Enter a unique name for the file in the value for 'File name:'
    5. Choose a save location -> click Save
    6. Click OK to clear the export location message

    By default your exported file will be in the following location:
    • (My) Documents/NinjaTrader 8/bin/Custom/ExportNinjaScript/<export_file_name.zip>


    Below is a link to the help guide on Exporting NinjaScripts.


    What is the exact code you are expecting to move the line when the button is clicked?

    From what I can see, the line is drawn in OnBarUpdate. This means the button would need to be clicked before 233 bars are processed. After bar 33 the object is drawn once, and then if the button is clicked before bar 233 is processed then when bar 233 is processed the drawing object would be drawn again. After bar 233 the object would not be drawn again.

    How many historical bars are being processed before the button is clicked?
    Are you clicking the button before bar 233 and then allowing bar 233 to be processed as a real-time bar?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hi,

      Thank you for the reply.

      Ok I uploaded it below....
      Its called button but its held in a folder called "KhaosCounts"
      I loaded it on a daily chart with 1000+ bars on it, i expect the line to move forward every time i click the button..

      The code that i expect to move the line is in 2 places, the button click will increment the variable OBarNumber... Then, on the OnBarUpdate() will place the vertical line on the chart based on the value of OBarNumber. I also display the OBarnumber variable value in the debug window... via a print statement, so it verifies that its incremented.

      I believe the ForceRefresh should refresh the ninjascript thereby repainting the line.

      Thank you for your continued help on this matter.
      Attached Files

      Comment


        #4
        Hello KhaosTrader,

        Your logic does not allow for the button press to be effective after the 300 bars are processed.

        (I had to re-look at your logic and correct some of my response)

        The oBarNumber is initialized with 100.

        The line is first drawn on bar 99 when bar 100 is processing (likely when the historical data is processing if you have more than 100 bars of historical data loading on the chart) as the condition requires CurrentBar (the currently processing bar) to be equal to oBarNumber to draw the line.

        The button does not change the position of the line, but instead the button sets this variable oBarNumber to a new value.

        This variable is checked in OnBarUpdate as each bar is processed. Each bar is only processed once.

        The button is pressed and sets the variable to a value of 100 plus 200 which is 300.

        If bar 300 has already processed, and its bar 1000, bar 300 will never be processed again.

        The condition in OnBarUpdate requires that the CurrentBar processing be the same value as oBarNumber. This condition would never be true if the button is clicked after bar 300 has processed since CurrentBar will be the value of the currently processing bar which is greater and not equal to 300

        Is this not the behavior you were intending?

        Are you expecting bar 300 to be processed multiple times?

        Are you expecting the condition to be true when CurrentBar is on bar 1000 (or any bar greater than 300)?


        I recommend that you add prints to your code and find why the condition is not evaluating as true.

        Below I am providing a link to videos that demonstrate adding prints to a script to get further information about the behavior of the script.
        Describes the elements of a string.Format() call. Used to debug a script to understand behavior.
        Last edited by NinjaTrader_ChelseaB; 05-17-2017, 09:34 AM.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          i expect forcerefresh to reload the chart, and thus old line is removed and new one painted at 200 bars further distance..

          The goal of all this, is i want a button to be able to change a property value and reload the chart with the new property value, rather than me having to load the property sheet and select which property and change it and close it. I want it done all in 1 click, a true/false property value. I wrote this demo project to see if forcerefresh would refresh the chart logic, but it doesnt seem to.


          I basically would like to know how i can use a button to

          1) Show / Hide an Indicator
          2) Show / Hide a plot
          3) i have logic that writes drawings on the chart, so i figure a disabling of that and refresh the indicator would be good for that.
          Last edited by KhaosTrader; 05-17-2017, 06:18 PM.

          Comment


            #6
            Hello KhaosTrader,

            No, ForceRefresh() will trigger OnRender() to render the chart.

            ForceRefresh() will not reload a NinjaScript.

            Below is a link to the help guide where you can read about the ForceRefresh() method and what this does.


            There are no documented/supported ways of reloading NinjaScripts programmatically.

            Would you like to submit a feature request for the NinjaTrader Development to consider adding a NinjaScript method that would allow a NinjaScript to be reloaded?


            If you might consider not reloading a NinjaScript, you could hide a plot by setting its color to Brushes.Transparent. And for any objects drawn, you could hide these by not drawing / removing anything that may be drawn in the logic.
            Last edited by NinjaTrader_ChelseaB; 05-18-2017, 07:15 AM.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              I think there is a way using ChartControl.ChartPanel.Refresh();

              take a look here on this page, post number 30
              Now you're just teasing!! On a serious note - I shall persist in this but it does look like it's beyond my capabilities and of course NT doesn't support it so if anyone else would like to pick up the baton please feel free. If you change a parameter, NT will recalc the indicator. So, just opting not to plot (or calling Value.Reset() on every bar) when your hide/show parameter is set to false will do the trick. This is what Big Mike and others had suggested. I've attached an example indicator, &#8230;


              unfortunately its written in ninja7, so I dont know how to use it for ninja 8.

              its an indicator called MAtoggle.

              Comment


                #8
                Hello KhaosTrader,

                If there is a method 'ChartControl.ChartPanel.Refresh();' this would not be supported by NinjaTrader to use and I would not be able to assist with this.

                There are no supported methods of refreshing an indicator or a chart programmatically.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Originally posted by KhaosTrader View Post
                  I think there is a way using ChartControl.ChartPanel.Refresh();

                  take a look here on this page, post number 30
                  Now you're just teasing!! On a serious note - I shall persist in this but it does look like it's beyond my capabilities and of course NT doesn't support it so if anyone else would like to pick up the baton please feel free. If you change a parameter, NT will recalc the indicator. So, just opting not to plot (or calling Value.Reset() on every bar) when your hide/show parameter is set to false will do the trick. This is what Big Mike and others had suggested. I've attached an example indicator, &#8230;


                  unfortunately its written in ninja7, so I dont know how to use it for ninja 8.

                  its an indicator called MAtoggle.


                  Hi Khaos,

                  See code below for a quick fix using the "SendKeys" which simulates an F5 press.. See line 119 of the code below for this.

                  In order for oBarNumber to remeber the new value assigned in your buttonclick void it now needs to be a [NinjaScriptProperty] see line 146 for this update.

                  This solution acheives the result you are looking for... but untimately the best method for this would be a simple work back after all bars are loaded to draw the vert line, this way avoiding a labor intensive F5. You could then put your vert line drawing code in the button click void and then use ChartControl.InvalidateVisual(); instead of ForceRefresh as ForceRefresh doesnt really do as it says it does (long story). Amending the location of the vert line and then calling the ChartControl.InvalidateVisual(); would give you the refresh without the need for the sendkeys f5....

                  //caveat - ChartControl.InvalidateVisual(); is unsupported by the NT folk, although i have had no unexpected behaviour using it.








                  Code:
                  #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;
                  
                  //Added
                  using System.Windows.Controls;
                  using System.Windows.Automation;
                  using System.Windows.Automation.Provider;
                  
                  
                  using System.Windows.Forms;
                  using System.IO;
                  using System.Collections;
                  
                  using SharpDX.DirectWrite;
                  #endregion
                  
                  //This namespace holds Indicators in this folder and is required. Do not change it. 
                  namespace NinjaTrader.NinjaScript.Indicators.KhaosCounts
                  {
                  	public class button  : Indicator
                  	{
                  		private Chart 			 chartWindow;
                  		private DependencyObject searchObject;
                  		private bool 			 isToolBarButtonAdded;
                  		private System.Windows.Controls.Button			 exampleButton;
                  		
                  		//private int oBarNumber =100;
                  		
                  		protected override void OnStateChange()
                  		{
                  			if (State == State.SetDefaults)
                  			{				
                  				Name						= "SampleAddChartButton";
                  				Calculate					= Calculate.OnEachTick;
                  				IsOverlay					= true;
                  				DisplayInDataBox			= true;
                  				DrawOnPricePanel			= true;
                  				DrawHorizontalGridLines		= true;
                  				DrawVerticalGridLines		= true;
                  				PaintPriceMarkers			= true;
                  				ScaleJustification			= NinjaTrader.Gui.Chart.ScaleJustification.Right;
                  				//Disable this property if your indicator requires custom values that cumulate with each new market data event. 
                  				//See Help Guide for additional information.
                  				IsSuspendedWhileInactive	= true;
                  				
                  				 oBarNumber =100;
                  			}			
                  			else if (State == State.Historical)
                  			{
                  				if (!isToolBarButtonAdded) 
                  					Dispatcher.Invoke((Action)(() => {  
                  						
                  						chartWindow = Window.GetWindow(ChartControl.Parent) as Chart;
                  						if (chartWindow == null) return;
                  						
                  						chartWindow.MainTabControl.SelectionChanged += MySelectionChangedHandler;
                  						foreach (DependencyObject item in chartWindow.MainMenu)
                  						{
                  							if (AutomationProperties.GetAutomationId(item) == "exampleButton")
                  							{
                  								isToolBarButtonAdded = true;
                  							}
                  						}
                  
                  						if (!isToolBarButtonAdded)
                  						{
                  							exampleButton = new System.Windows.Controls.Button { Content = "Example Button", };
                  							chartWindow.MainMenu.Add(exampleButton);
                  							chartWindow.MainTabControl.SelectionChanged += MySelectionChangedHandler;
                  							exampleButton.Click += ExampleButtonClick;
                  							AutomationProperties.SetAutomationId(exampleButton, "exampleButton");
                  						}
                  					}));
                  			}
                  			
                  			else if (State == State.Terminated)
                  			{
                  				if(chartWindow != null)
                  				{					
                  					if (exampleButton != null)
                  					{
                  						Dispatcher.Invoke((Action)(() =>
                  						{
                  							chartWindow.MainMenu.Remove(exampleButton);						
                  							exampleButton.Click -= ExampleButtonClick;
                  							exampleButton = null;
                  						}));
                  					}
                  					chartWindow.MainTabControl.SelectionChanged -= MySelectionChangedHandler;
                  					chartWindow = null;
                  				}
                  			}
                  		}
                  		
                  		private void ExampleButtonClick(object sender, RoutedEventArgs e)
                  		{
                  			Print("Button is working"); 
                  			oBarNumber +=200;
                  			ForceRefresh();
                  			Print (oBarNumber);
                  			SendKeys.SendWait("{F5}");
                  
                  		}	
                  		
                  		private void MySelectionChangedHandler(object sender, SelectionChangedEventArgs e)
                  		{
                  			if (e.AddedItems.Count <= 0)
                  				return;
                  			TabItem tabItem = e.AddedItems[0] as TabItem;
                  			if (tabItem == null) return;
                  			ChartTab temp = tabItem.Content as ChartTab; 
                  			if (temp != null)
                  			{
                  				if (exampleButton != null)
                  					exampleButton.Visibility = temp.ChartControl == ChartControl ? Visibility.Visible : Visibility.Collapsed;
                  			}
                  		}	
                  
                  		protected override void OnBarUpdate()
                  		{
                  			if (IsFirstTickOfBar)
                  			{
                  				if (CurrentBar <33) {return;}
                  				if (CurrentBar == oBarNumber)
                  				Draw.VerticalLine(this, "VerticalLine_Bullish"+CurrentBar, 2, Brushes.DarkGreen, DashStyleHelper.Dash, 1, true);
                  			}
                  		}
                  		[NinjaScriptProperty]
                  		[Display(ResourceType = typeof(Custom.Resource), Name = "OBar", GroupName = "Parameters", Order = 9)]
                  		public int oBarNumber
                  		{ get; set; }
                  	}
                  }
                  
                  #region NinjaScript generated code. Neither change nor remove.
                  
                  namespace NinjaTrader.NinjaScript.Indicators
                  {
                  	public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
                  	{
                  		private KhaosCounts.button[] cachebutton;
                  		public KhaosCounts.button button(int oBarNumber)
                  		{
                  			return button(Input, oBarNumber);
                  		}
                  
                  		public KhaosCounts.button button(ISeries<double> input, int oBarNumber)
                  		{
                  			if (cachebutton != null)
                  				for (int idx = 0; idx < cachebutton.Length; idx++)
                  					if (cachebutton[idx] != null && cachebutton[idx].oBarNumber == oBarNumber && cachebutton[idx].EqualsInput(input))
                  						return cachebutton[idx];
                  			return CacheIndicator<KhaosCounts.button>(new KhaosCounts.button(){ oBarNumber = oBarNumber }, input, ref cachebutton);
                  		}
                  	}
                  }
                  
                  namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
                  {
                  	public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
                  	{
                  		public Indicators.KhaosCounts.button button(int oBarNumber)
                  		{
                  			return indicator.button(Input, oBarNumber);
                  		}
                  
                  		public Indicators.KhaosCounts.button button(ISeries<double> input , int oBarNumber)
                  		{
                  			return indicator.button(input, oBarNumber);
                  		}
                  	}
                  }
                  
                  namespace NinjaTrader.NinjaScript.Strategies
                  {
                  	public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                  	{
                  		public Indicators.KhaosCounts.button button(int oBarNumber)
                  		{
                  			return indicator.button(Input, oBarNumber);
                  		}
                  
                  		public Indicators.KhaosCounts.button button(ISeries<double> input , int oBarNumber)
                  		{
                  			return indicator.button(input, oBarNumber);
                  		}
                  	}
                  }
                  
                  #endregion
                  Last edited by marty087; 05-20-2017, 07:17 AM.

                  Comment


                    #10
                    Thanks marty087, I really appreciate your help and solution!

                    All the best

                    - KhaosTrader

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by RubenCazorla, Today, 09:07 AM
                    2 responses
                    13 views
                    0 likes
                    Last Post NinjaTrader_ChelseaB  
                    Started by i019945nj, 12-14-2023, 06:41 AM
                    7 responses
                    82 views
                    0 likes
                    Last Post NinjaTrader_ChelseaB  
                    Started by timmbbo, 07-05-2023, 10:21 PM
                    4 responses
                    158 views
                    0 likes
                    Last Post NinjaTrader_Gaby  
                    Started by tkaboris, Today, 08:01 AM
                    1 response
                    7 views
                    0 likes
                    Last Post NinjaTrader_Gaby  
                    Started by Lumbeezl, 01-11-2022, 06:50 PM
                    31 responses
                    820 views
                    1 like
                    Last Post NinjaTrader_Adrian  
                    Working...
                    X