When generating alerts in MultiCharts programmatically, we often include an alert message with additional information. But how do we include times in alert messages?

In this article:

Generating dynamic MultiCharts alerts with time data

We programmatically generate alerts with the Alert() keyword (PowerLanguage Keyword Reference, 2016). Before that keyword can generate alerts, we need to enable the alert settings and probably also want to configure the MultiCharts alerts so that they generate in the way we want.

While Alert() can generate an alert without a message, it’s more common to generate an alert message with this keyword. Those messages consists out of strings (that is, text) and can either be static (like "New daily low.") or dynamic by including the values that change while the script runs (PowerLanguage Keyword Reference, 2016). Combining static with dynamic text is possible too, and we can combine those different parts of an alert message with the + operator or the Text() keyword.

Including a time in an alert message is, however, less straightforward. That’s because times in PowerLanguage are in numerical values that are not easily readable when printed in an alert message. For instance, let’s look at some of the PowerLanguage keywords that return time data (PowerLanguage Keyword Reference, 2016):

Keyword Description
Time Returns the bar’s closing time as a numerical value in 24-hour HHmm format, whereby a time of 14:20:40 is returned as 1420.
Time_s Returns the bar’s closing time as a numerical value in 24-hour HHmmss format, whereby a time of 14:20:40 is returned as the value of 142040.
CurrentTime Returns a numerical value with the computer’s current time in 24-hour HHmm format, whereby the 19:29:47 time is returned as 1929.
CurrentTime_s Returns a numerical value with the computer’s current time in 24-hour HHmmss format, which makes the time of 19:29:47 return as 192947.

Especially in alert messages that are intended to be read quickly, a time as a numerical value is not easily readable. For example, let’s say that we include the computer’s current time in an alert message like so:


Alert(Text("Current time is ", CurrentTime_s));

The alert that’s generated with this code snippet looks like:

Example of a MultiCharts alert with a hard-to-read time value

As we see, the time is in an uncommon format, which makes it harder to read. So how can we format times into a readable text when including them in an alert message?

Converting MultiCharts times into a readable text

We can format times in MultiCharts to a readable string with FormatTime(), but this keyword does require a DateTime value to work with (PowerLanguage Keyword Reference, 2016).

The DateTime format is an alternative way to represent both time and date into one numerical value. To accomplish that, a DateTime value consists out of an integer and decimal part. The integer portion represents the number of days that have passed since January 1, 1900, while the fractional part represents the portion of the day that has elapsed since midnight (PowerLanguage Keyword Reference, 2016). Combined, a single DateTime value represents both a date and time of day.

To convert the 24-hour HHmm and HHmmss time format (which we saw in the previous table) to DateTime values, we can use the following two keywords (PowerLanguage Keyword Reference, 2016):

Keyword Description
ELTimeToDateTime() Returns the DateTime value of the value between this keyword’s parentheses, which needs to be in 24-hour HHmm format (the same format that’s used by Time and CurrentTime). For example, ELTimeToDateTime(1015) translates to the DateTime value of 0.42708333.
ELTimeToDateTime_s() Returns the DateTime value of the value between this keyword’s parentheses, which needs to be in 24-hour HHmmss format (the same format that’s used by Time_s and CurrentTime_s). So a time of 15:55:20 is converted to DateTime value with ELTimeToDateTime_s(155520), and that returns a value of 0.66342593.

Now back to how we can format times to a readable text with FormatTime(). That keyword requires two parameters. The first is a format string that specifies exactly how we want to display the time, and the second parameter is the DateTime value that needs to be converted to a string (PowerLanguage Keyword Reference, 2016).

That format string tells FormatTime() how to convert the DateTime value into a string, and we can set this format string to practically anything. Two common formats are "HH:mm" to display the time in 24-hour HH:mm format (like 11:30), and "HH:mm:ss" has FormatTime() generate a string in 24-hour HH:mm:ss format (like 11:30:21).

We can use the following elements in the format string of the FormatTime() keyword (PowerLanguage Keyword Reference, 2016):

Format element Value that the element is replaced with
h Hours in 12-hour AM/PM format without a leading zero for single-digit hours.
hh Hours in 12-hour AM/PM format with a leading zero for single-digit hours.
H Hours in 24-hour format without a leading zero for single-digit hours.
HH Hours in 24-hour format with a leading zero for single-digit hours.
m Minutes without a leading zero for single-digit minutes.
mm Minutes with a leading zero for single-digit minutes.
s Seconds without a leading zero for single-digit seconds.
ss Seconds with a leading zero for single-digit seconds.
t A one character AM/PM designator (that is, ‘A’ for AM and ‘P’ for PM).
tt AM/PM designator with two characters (so ‘AM’ for AM times and ‘PM’ for PM times).

Before exploring how FormatTime() can format times in alert messages, let’s recap the different steps discussed above. Going from the bar’s closing time to a nicely formatted, easily-readable time involves the following:

  • We get the bar’s closing time with minute precision with Time while the Time_s keyword returns the bar’s closing price with second precision.
  • To format those values to a readable string, we first need to take the intermediate step of converting them to DateTime values. We do that with ELTimeToDateTime() for Time values and use ELTimeToDateTime_s() for Time_s values.
  • That DateTime value can then be used with the FormatTime() keyword, but this keyword also requires a string that specifies how to format the time. Common format strings include "HH:mm" (for times like 9:56 and 14:45) and "HH:mm:ss" to print times of 9:56:21 and 14:45:42.

Let’s examine a few examples. When we want to display the current bar’s closing time in HH:mm format, we use FormatTime() in the Alert() keyword like this:


Alert(Text("Bar closes at ", FormatTime("HH:mm", ELTimeToDateTime(Time))));

This code snippet generates an alert that looks like:

Example of a MultiCharts alert message with a customised time

If we want to include the computer’s current time in HH:mm:ss format, we use Alert() and FormatTime() like:


Alert(Text("Current computer time is ", 
    FormatTime("HH:mm:ss", ELTimeToDateTime_s(CurrentTime_s))));

That Alert() statement generates an alert message like:

Example of a MultiCharts alert with a time value in a custom format

These two quick examples show how we can use the FormatTime() keyword to generate alerts that include the time formatted into a readable format. Now let’s see how we can use this FormatTime() approach in a full programming example.

Generating MultiCharts alerts with times in a custom format

In the example indicator below we generate alerts by comparing the current bar’s volume to the average volume that’s increased or decreased by 10%. Now whenever the current bar’s volume is more than 10% above the average volume, or whenever the bar’s volume is more than 10% below the average volume, we generate an alert. This way the script notifies us of bars whose volume readings are off compared to the average.

The image below shows how the generated alerts look like. After discussing the code we’ll take a closer look at the indicator’s appearance and the alerts it generates.

Example of the alerts generated by the MultiCharts indicator

Variables:
    avgVolume(0);

// Compute values
avgVolume = AverageFC(Ticks, 30);

// Plot
Plot1(Ticks, "Volume", blue);
Plot2(avgVolume, "Average Volume", red);

// Generate alerts
if (Ticks > avgVolume * 1.10) then
    
    Alert("The " + FormatTime("HH:mm:ss", ELTimeToDateTime_s(Time_s)) +
        " price bar has a volume that's above the treshold level.")

else if (Ticks < avgVolume * 0.90) then

    Alert("The volume of the " + 
        FormatTime("HH:mm", ELTimeToDateTime(Time)) + 
        " price bar is below the alert level.");

We begin our indicator with creating one variable:


Variables:
    avgVolume(0);

The avgVolume variable starts with a value of 0, and that variable is then used with computing the average volume:


avgVolume = AverageFC(Ticks, 30);

We set avgVolume here to the 30-bar average volume that we calculate with the AverageFC() function. This function computes a moving average with two parameters: a series of values to process and a numerical value that sets the number of bars to calculate on. Here we use the bar’s volume (Ticks) and 30 to get the 30-bar average volume.

Note:

On tick, volume, and time-based charts (with a resolution less than 24 hours) the Volume keyword only returns the bar’s up volume (MultiCharts Wiki, 2012), oddly enough. The Ticks keyword does return the bar’s total volume (up volume plus down volume) (MultiCharts Wiki, 2015). This is why we use the Ticks keyword here instead of the more intuitive Volume keyword.

Now to have the Ticks keyword return the bar’s volume (and not tick count), the chart’s ‘Build Volume On’ setting needs to be set to ‘Trade Volume’ (MultiCharts Wiki, 2015). To change or verify that setting, right-click on a price bar of the instrument and select ‘Format [symbol name]‘. This opens the ‘Format Instrument’ window, and there in the ‘Settings’ tab we find the ‘Build Volume On’ setting:

Configuring the Trade Volume setting in MultiCharts

Next we plot the indicator’s values on the chart:


Plot1(Ticks, "Volume", blue);
Plot2(avgVolume, "Average Volume", red);

We do the plotting with Plot1() and Plot2(). Both keywords accept a range of parameters to configure the plot, of which we use three here: the value to plot, the plot’s name, and its colour (PowerLanguage Keyword Reference, 2016). To plot the bar’s volume, we use the Ticks value as the first parameter and set this plot’s name to “Volume”, while its colour is going to be the blue basic MultiCharts colour.

With the Plot2() statement we display the 30-bar average volume (avgVolume) on the chart. This plot’s name is “Average Volume” and its colour is red.

We end the example with an if/else statement that generates alerts programmatically:


if (Ticks > avgVolume * 1.10) then
    
    Alert("The " + FormatTime("HH:mm:ss", ELTimeToDateTime_s(Time_s)) +
        " price bar has a volume that's above the treshold level.")

else if (Ticks < avgVolume * 0.90) then

    Alert("The volume of the " + 
        FormatTime("HH:mm", ELTimeToDateTime(Time)) + 
        " price bar is below the alert level.");

The first if statement evaluates whether the current bar’s volume (Ticks) is greater than (>) the 30-bar average volume increased with 10% (avgVolume * 1.10). When that expression evaluates to true, we execute the Alert() keyword to generate an alert (PowerLanguage Keyword Reference, 2016).

Inside that keyword’s parentheses, we specify an alert message that contains static strings alongside the bar’s closing time in a readable format. For that latter we use FormatTime(), and set this keyword’s first parameter to the "HH:mm:ss" format string with the second parameter set to the bar’s closing time with seconds notation (Time_s) converted to a DateTime value with ELTimeToDateTime_s() (PowerLanguage Keyword Reference, 2016).

The else if portion of our if/else statement checks whether the bar’s volume is less than (<) the average volume decreased by 10% (avgVolume * 0.90). When that’s the case, we again execute Alert() to generate an alert. Inside the keyword’s parentheses we specify the alert message, and again use a static string alongside a dynamic text combined together with the + operator.

The time that we include in this second Alert() statement is the bar’s time without seconds. For that we use the FormatTime() keyword with the "HH:mm" format string. To get the required DateTime value, we convert the bar’s closing time (Time) to DateTime with the ELTimeToDateTime() keyword.

This ends the discussion of the programming example. But before adding the script to a chart, we need to change a manual setting so that the volume values (which we plotted with Plot1()) appear as a histogram and not as a line. Because we cannot set this programmatically, we need to right-click somewhere in the text window of the PowerLanguage Editor and then choose ‘Properties’. This opens a window with the different script settings, and here in the ‘Chart Style’ tab we need to set the ‘Type’ of the “Volume” plot to ‘Histogram’. If we don’t do that, the volume values show up as a consecutive line by default.

Manually setting a plot to a Histogram in MultiCharts

After configuring that option we compile the script and it’s ready to be added to the chart.

Examples: using formatted time in MultiCharts alerts

When we add the script to the chart, we need to configure the manual alert settings before the script can generate alerts. The options that we at least need to configure are ‘Enable Alerts’ and ‘On Bar Close’:

Configuring the alert settings of the MultiCharts script

On a price chart, the example indicator looks like:

Example chart of the MultiCharts indicator

When the bar’s volume is below the average with a 10% margin, the script generates the following kind of alerts:

Example of a formatted alert message generated by MultiCharts

And when the volume is 10% higher than the average volume, the alerts look like:

Another example of a MultiCharts alert message with custom time

See the articles about formatting numerical values in alerts and including dates in MultiCharts alerts for other ways to format the alert message to your liking.

Summary

We programmatically generate alerts with Alert(), but we do need to manually enable the script’s alert settings before that keyword can trigger alerts. With Alert() it’s also possible to specify an alert message, and we can include the bar’s or computer’s time in those messages. We retrieve those times with the Time, Time_s, CurrentTime, and CurrentTime_s keywords. These keywords return time in a 24-hour numerical format (like 134338 for 13:43:38), and we likely want to format those values to something that’s easier to read. That’s possible with the FormatTime() keyword, which requires two parameters: a format string specifying how the time should be formatted (like "HH:mm:ss" or "HH:mm") and the time in DateTime format. To get those DateTime values, we need to convert the values returned by Time and CurrentTime with ELTimeToDateTime(), whereas Time_s and CurrentTime_s are converted to DateTime with ELTimeToDateTime_s().

Learn more:


References

MultiCharts Wiki (2012, February 28). Volume. Retrieved on September 8, 2016, from http://www.multicharts.com/trading-software/index.php/Volume

MultiCharts Wiki (2015, November 20). Ticks. Retrieved on September 8, 2016, from http://www.multicharts.com/trading-software/index.php/Ticks

PowerLanguage Keyword Reference (2016). Retrieved on May 25, 2016, from http://www.multicharts.com/trading-software/images/c/c6/PowerLanguage_Keyword_Reference.pdf