TriggerCustomEvent()

View as Markdown

Definition

Provides a way to use your own custom events (such as a Timer object) so that internal NinjaScript indexes and pointers are correctly set prior to processing user code triggered by your custom event. When calling this event, NinjaTrader will synchronize all internal pointers and then call your custom event handler where your user code is located.

The TriggerCustomEvent() method does NOT execute before State.DataLoaded or during or after State.Terminated. In effect, attempting to trigger custom events may be unavailable in some circumstances (e.g., while an indicator is terminating, or viewing the Strategy Analyzer chart display after backtest has completed, etc.)

Method Return Value

This method does not have a return value.

Syntax

TriggerCustomEvent(Action\<object\> customEvent, object state)

TriggerCustomEvent(Action\<object\> customEvent, int barsSeriesIndex, object state)

Parameters

ParameterDescription
barsIndexIndex of the bar series you want to synchronize to
customEventDelegate of your custom event method
stateAny object you want passed into your custom event method

Tips:

  • There may be scenarios in which you need to set a Series<T> value outside of one of the core data event methods. In these cases, you can use TriggerCustomEvent() to reliably synchronize the barAgo indexer to the recent. current bar being updated. Please see the example below.
  • Usually the correct approach is to use the WPF Dispatcher timer, however in cases where you need the timer to update a WinForms window it opened - please use the WinForms timer.

Examples

Using TriggerCustomEvent() in simple timer event

1protected override void OnBarUpdate()
2{
3 // OnBarUpdate() only runs as bars are processed, which is not guaranteed to occur at a specific interval
4 // e.g., even on a 5 second bar series, there may be time periods where there are no updates due to low trading activity
5 // or could be buffered due to running Calculate.OnBarClose. Instead of trying to obtain the Close[0] value
6 // at some interval here, we are going to do it in our custom TimerEventProcessor
7}
8
9// This is the method to run when the timer is raised.
10private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
11{
12 // Do not process your code here but instead call the TriggerCustomEvent() method
13 // and process your code in the custom handler method e.g., our custom PrintThePrice()
14 // Doing so ensures all internal indexers are up-to-date
15 if (CurrentBar > 0)
16 {
17 TriggerCustomEvent(PrintThePrice, Close[0]);
18 }
19}
20
21// Print the latest closing price with the current time
22private void PrintThePrice(object price)
23{
24 Print("The Last Bar's Closing Value as of " + NinjaTrader.Core.Globals.Now + " was " + price);
25}
26
27// Declare the WPF dispatcher timer
28private System.Timers.Timer myTimer;
29
30protected override void OnStateChange()
31{
32 if (State == State.SetDefaults)
33 {
34 Name = "SampleTriggerCustomEventTimer";
35 }
36 else if (State == State.DataLoaded)
37 {
38 // Instantiates the timer and sets the interval to 5 seconds.
39 myTimer = new System.Timers.Timer(5000);
40 // Adds the event handler for the method that will
41 // process the timer event to the timer.
42 myTimer.Elapsed += TimerEventProcessor;
43 // Starts the timer
44 myTimer.Enabled = true;
45 }
46 else if (State == State.Terminated)
47 {
48 // Stops the timer and removes the timer event handler
49 if (myTimer != null)
50 {
51 myTimer.Enabled = false;
52 myTimer.Elapsed -= TimerEventProcessor;
53 myTimer = null;
54 }
55 }
56}

Using TriggerCustomEvent to update a previously set custom Series<T> value

1// using the virtual on render method for demonstration
2// but concept could apply to any custom event that does not rely on bars data
3// e.g., from a custom mouse event or other 3rd party dependency
4protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
5{
6 // we want to reset a custom series values 20 barsAgo during some condition
7 if (conditionWhichRequiredUpdate)
8 {
9 // First, synchronize the index value used in via Series[barsAgo]
10 // to the NinjaScriptBase.CurrentBar being currently being processed in OnBarUpdate
11 TriggerCustomEvent(o =>
12 {
13 // For debugging, check the previous value
14 Print("Before value which was set in OnBarUpdate(): " + SomeVolumeData[20]);
15
16 SomeVolumeData[20] = 5; // set to our new custom value
17
18 // For debugging, check the updated value
19 Print("After value which was updated later in OnRender(): " + SomeVolumeData[20]);
20 }, null);
21
22 // reset our flag until we need to update a value again
23 conditionWhichRequiredUpdate = false;
24 }
25 //Output:
26 //Before value which was set in OnBarUpdate(): 1165
27 //After value which was updated later in OnRender(): 5
28}
29
30private Series<double> SomeVolumeData; // custom Series for tracking volume which will be modified through its lifetime
31private bool conditionWhichRequiredUpdate = true;
32
33protected override void OnStateChange()
34{
35 protected override void OnStateChange()
36 {
37 if (State == State.SetDefaults)
38 {
39 Name = "SampleUpdateCustomSeries";
40 }
41
42 else if (State == State.Historical)
43 {
44 SomeVolumeData = new Series<double>(this);
45 }
46 }
47}
48
49protected override void OnBarUpdate()
50{
51 SomeVolumeData[0] = Volume[0]; // set the custom series to the CurrentBar volume
52}