Situation
As a means of being notified of potential data feed issues, you want to trigger an alert when an instrument in MultiCharts .NET did not update for a certain number of seconds.

Programming example

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;

namespace PowerLanguage.Indicator
{
    [UpdateOnEveryTick(true), SameAsSymbol(true)]
    public class Example_DataFeedAlert : IndicatorObject
    {
        private DateTime prevAlertTime;

        public Example_DataFeedAlert(object _ctx) : base(_ctx) { }

        protected override void CalcBar()
        {
            // Only perform real-time calculations
            if (!Environment.IsRealTimeCalc)
                return;

            TimeSpan timeDifference = DateTime.Now - Bars.StatusLine.Time;

            // Generate alert if these are enabled and time difference is more than 25 seconds
            if ((Alerts.CheckAlertLastBar) && (timeDifference > TimeSpan.FromSeconds(25)))
            {
                // .. but have at least 5 seconds between consecutive alerts
                if (DateTime.Now > prevAlertTime.AddSeconds(5))
                {
                    Alerts.Alert("The last data feed update was {0} seconds ago!",
                        timeDifference.ToString(@"s\.f"));
                    
                    prevAlertTime = DateTime.Now;
                }
            }
            
            // Recalculate every second
            ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(1));
        }

        // This method is called every time RecalcLastBarAfter() executes
        protected override void OnRecalcLastBarAfterEvent()
        {
            this.CalcBar();
        }
    }
}

Output of the programming example

Applied to a chart like the following:

Example of data feed time out in MultiCharts .NET

The indicator generates the following type of alerts:

Example of data feed time out alerts in MultiCharts .NET

Monitoring data feed connectivity issues in MultiCharts .NET

When a data feed connection is lost in MultiCharts .NET, a C# event is not triggered (see Henry MultiCharts, 2014). This prevents a direct way of being notified about a data feed disconnection.

A partial workaround, however, is to monitor the amount of time elapsed since the last tick update (see Henry MultiCharts, 2013). Such a workaround has the following features:

  • An arbitrarily time period will need to be chosen or calculated such that false positives are kept to a minimum;
  • This can, especially for relatively illiquid instruments, introduce a significant lag between a data feed disconnection and the trader being notified;
  • Issues that are not accompanied with a data feed disconnection, such as trading halts or data problems while the connection remains alive, are still caught and brought to the attention of the trader.

Let's look at the programming example to see how this works in practice.

Programming example

The example begins with declaring two attributes (line 8): UpdateOnEveryTick, which causes the indicator to be also updated intra-bar, and SameAsSymbol, which will plot the indicator on the main price chart.

Next a DateTime value type is declared (line 11). This prevAlertTime variable will be used later on to prevent alerts from quickly being triggered after each other.

Monitoring the time of the last data feed update

The next part of the programming example is the CalcBar() override method. In this method the following code is implemented:

// Only perform real-time calculations
if (!Environment.IsRealTimeCalc)
    return;

TimeSpan timeDifference = DateTime.Now - Bars.StatusLine.Time;

// Generate alert if these are enabled and time difference is more than 25 seconds
if ((Alerts.CheckAlertLastBar) && (timeDifference > TimeSpan.FromSeconds(25)))
{
    // .. but have at least 5 seconds between consecutive alerts
    if (DateTime.Now > prevAlertTime.AddSeconds(5))
    {
        Alerts.Alert("The last data feed update was {0} seconds ago!",
            timeDifference.ToString(@"s\.f"));
        
        prevAlertTime = DateTime.Now;
    }
}

// Recalculate every second
ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(1));

We start here with verifying if there is a real-time calculation, in which case Environment.IsRealTimeCalc returns true. With the use of the logical not operator (!), the return statement is called when real-time calculation is absent. This, for example, prevents that alerts are triggered in the weekend.

By the way, Bars.StatusLine.Time returns the DateTime value of the last tick, bid, or ask update from the instrument, and is in the same time zone as the chart. If your chart is set to Exchange time, you will need to correct DateTime.Now, since this latter returns the local time.

Then a local TimeSpan variable named timeDifference is declared and assigned the difference between the current computer DateTime (DateTime.Now) and the time of the last data feed update (Bars.StatusLine.Time).

Triggering data feed time out alerts

Next the alerts are programmatically implemented:

// Generate alert if these are enabled and time difference is more than 25 seconds
if ((Alerts.CheckAlertLastBar) && (timeDifference > TimeSpan.FromSeconds(25)))
{
    // .. but have at least 5 seconds between consecutive alerts
    if (DateTime.Now > prevAlertTime.AddSeconds(5))
    {
        Alerts.Alert("The last data feed update was {0} seconds ago!",
            timeDifference.ToString(@"s\.f"));
        
        prevAlertTime = DateTime.Now;
    }
}

PS: To turn alerts on, right-click on the chart, choose ‘Format Indicators’, and select the indicator followed by clicking on ‘Format’. Next move to the ‘Alerts’ tab, check ‘Enable Alerts’ and set the alerts to be triggered on ‘Every Tick’. See the article generating alerts in MultiCharts .NET to learn more about working with alerts.

The if statement (line 24) verifies whether alerts are enabled (in which case the Alerts.CheckAlertLastBar property returns true) and the calculated time difference is larger than a TimeSpan value of 25 seconds.

After that, the nested if statement in line 27 evaluates if the current current time is greater than the time of the previous alert plus five seconds (prevAlertTime.AddSeconds(5)). This ensures that an alert is triggered, at most, every five seconds.

Should the conditional expressions in both if statements evaluate to true, the alert message is generated (lines 29-30) with string substitution parameters and custom TimeSpan format strings. After that the current computer DateTime is stored in the prevAlertTime variable for using it the next time the indicator calculates.

Forcing a time-based recalculation of the indicator

Because indicators and trading strategies are updated with incoming ticks in MultiCharts .NET (MultiCharts Wiki, 2012), we need to force a periodic recalculation of the indicator. Otherwise, a data feed problem will stop the indicator from recalculating and thus preventing the generating of alerts.

To recalculate on a specific time interval, the following is added in the CalcBar() method:

// Recalculate every second
ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(1));

Here a TimeSpan of 1 second is passed as a parameter into the RecalcLastBarAfter() method. This will cause the OnRecalcLastBarAfterEvent() method (lines 40-44) to be executed every second, which in turn calls the CalcBar() method for the actual recalculation. See the article forcing a time-based recalculation of an indicator or strategy to learn more.

Key points:

  • When a data feed disconnects in MultiCharts .NET, no C# event is triggered;
  • As a workaround, the time of the last data feed update (Bars.StatusLine.Time) can be compared to the current computer time (DateTime.Now);
  • This does require recalculating the script each time interval in case the data feed stops updating;
  • By adding a condition to only trigger an alert every x seconds, a flooding of alert messages can be prevented.
References

Henry MultiCharts (2013). Check for absence of real time data - forum discussion. Retrieved on April 11, 2014, from http://www.multicharts.com/discussion/viewtopic.php?f=19&t=16442#p65867

Henry MultiCharts (2014). Broker and datafeed connectivity status event - forum discussion. Retrieved on April 11, 2014, from http://www.multicharts.com/discussion/viewtopic.php?f=19&t=46271#p103339

MultiCharts Wiki (2012). How Scripts Work. Retrieved on April 13, 2014, from http://www.multicharts.com/trading-software/index.php/How_Scripts_Work