This article reiterates the most important points we discussed in the chapter about generating MultiCharts alerts. Follow the links in this article for more information and additional code examples.

In this article:

Using MultiCharts alerts and configuring them

After the chapter’s introduction we discussed enabling alerts by hand. While MultiCharts can fire alerts when we open a workspace, replace a data series with another, or when the bar closes or there’s a new price update (MultiCharts Wiki, 2013a), those alerts only fire when the ‘Enable Alerts’ checkbox is turned on.

Enabling the alerts of a MultiCharts indicator or strategy by hand

When this checkbox is enabled, the alert can appear as an audio alert, notification window, and/or email alert (MultiCharts Wiki, 2013a). How an alert appears and how often it fires is something we configure in the script’s alert settings. Those manual options look like:

Configuring the manual MultiCharts alert settings

If we’re away from the computer when our script generates an alert, we can still find the alert in the log of alert messages in the Order and Position Tracker window. There we can also perform filtering to find specific alerts:

Log of alerts messages in the Order and Position Tracker window

While the chapter’s focus is on generating alerts programmatically, it’s also possible to trigger alerts with manual MultiCharts drawings. That way we can quickly and easily generate an alert without having to write a script. But this has a couple of disadvantages too. First, the information provided by those alerts is limited (see image below), and that makes them less useful and harder to separate from each other.

A MultiCharts alert triggered by trend line

Another drawback of alerts generated by manual drawings is that we have to configure the alert settings of each and every drawing. There’s also no log of alert messages, and we can only generate alerts with drawings on the chart (and not in the Scanner/Watchlist window or the Portfolio Trader). Luckily, all these limitations go away when we use code to generate alerts.

Generating MultiCharts alerts programmatically

When the script’s alerts are enabled, our indicator or signal can generate alerts programmatically with Alert(). This keyword can make the script fire an alert each time it executes (MultiCharts Wiki, 2012a).

However, Alert() can only fire an alert when the ‘Enable Alerts’ checkbox is enabled. Furthermore, how and when the alert appears also depends on the manual alert settings. Since those options cannot be set with code, there are always a couple of manual actions left to do – even when we use alerts programmatically.

There are two ways to generate an alert with Alert() (MultiCharts Wiki, 2012a):

  • Simply executing Alert() generates an alert with basic information: the script name, the instrument and its resolution, and the current price.
  • When we provide a string (that is, text) between the parentheses of the Alert() keyword (like Alert("New lowest low")), then the alert contains that message alongside the standard information. This way we can generate more meaningful alerts.

Other features of Alert() are:

  • Alert() only triggers alerts on the last bar of the data series (MultiCharts Wiki, 2012a). If we want to simulate how it performs on historical bars, we’ll have to use the ‘Data Playback’ mode.
  • Each time the script executes Alert(), another alert can be generated. We need to use the manual alert settings to limit the number of alerts, or otherwise use code to prevent too many alerts after each other.
  • Strictly speaking, Alert() only triggers the alert. If and how the alert generates (like a notification window or email) is configured in the script’s manual alert settings.
  • We can use Alert() in indicators, functions, and signals.

An example of Alert() is:


if (Close > Low[1]) then
    Alert(Text("Current close ", Close, 
        " is above the previous bar low (", Low[1], ")"));

Customising dynamic values in MultiCharts alert messages

While the alert message between the parentheses of Alert() can be a static string (like Alert("New high")), the message is often more meaningful when it includes dynamic values. But MultiCharts by default displays numerical values as a 2-decimal string, which may be the wrong amount of decimals for our purposes. Furthermore, the PowerLanguage format of dates and times isn’t easy to read. Luckily, we can customise dynamic values to our exact specification.

To format numerical values in alert messages we use NumToStr(). That keyword requires two parameters: the numerical value to convert to text and the amount of decimals the converted number should get (PowerLanguage Keyword Reference, 2016). For instance, NumToStr(Close, 5) converts the bar’s closing price to a string with a 5 decimals:


Alert("The bar's current closing price is: " + NumToStr(Close, 5));

Such an alert message looks like:

Example of an alert with formatted numbers in the alert message

To format times to a custom format in alert messages we use FormatTime(). That keyword needs two parameters: a format string that specifies how the time should appear and the time as a DateTime value (PowerLanguage Keyword Reference, 2016).

The first requirement of FormatTime() is the format string. That text consists out of a combination of letters that together exactly specify how the time should appear (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).

The second parameter of FormatTime() is a DateTime value, which is a number in a format that holds both the date and time of day in a single value. For that the integer portion represents the number of days passed since January 1, 1900, while the fractional part is the portion of the day elapsed since midnight (PowerLanguage Keyword Reference, 2016).

Now the typical PowerLanguage keywords for working with time don’t return a DateTime value. And so we need to convert the values of the Time and CurrentTime keywords to DateTime with the ELTimeToDateTime() keyword. And Time_s and CurrentTime_s need to be converted to DateTime with ELTimeToDateTime_s() (PowerLanguage Keyword Reference, 2016).

After that conversion, we can use FormatTime() to customise how the time appears. For example:


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

This Alert() statement generates an alert like:

MultiCharts alert message with time custom formatted

To format dates to a custom format in alert messages we use FormatDate(). This keyword requires two parameters: a format string and DateTime value (PowerLanguage Keyword Reference, 2016).

That format string exact specifies how the date should appear in the text. The different elements that we can use here are (PowerLanguage Keyword Reference, 2016):

Format element Value that the element is replaced with
d The day of the month as a digit without a leading zero for single-digits days.
dd The day of the month as a digit with a leading zero for single-digit days.
ddd The day of the week as a three-letter abbreviation, displayed with the computer’s regional settings.
dddd The day of the week as its full name, displayed in the format of the computer’s regional settings.
M The month of the date without a leading zero for single-digit months.
MM The month of the date with a leading zero for single-digit months.
MMM The month as a three letter abbreviation, in the region settings of the computer.
MMMM The month as its full name, displayed in the computer’s region and language settings.
y The year of the date as the last two digits without a leading zero for years less than 10.
yy The year of the date as the last two digits, with a leading zero for years that are less than 10.
yyyy The date’s year represented with four digits.

The second parameter of FormatDate() is a DateTime value, which differs from the default PowerLanguage format for dates. Because of that we have to convert the values of keywords like Date and CurrentDate to DateTime with DateToJulian() (PowerLanguage Keyword Reference, 2016).

After that conversion, we use FormatDate() to specify how that DateTime value should appear as a date. For instance:


Alert("This bar closes on " + FormatDate("dd-MM-yyyy", DateToJulian(Date)));

The alert message that this generates looks like:

Example alert message with the date customised

Working with alerts programmatically in PowerLanguage

Besides generating alerts and configuring alert messages, there are a couple of other ways to work with MultiCharts alerts programmatically.

We can, for instance, programmatically check if alerts are enabled. That allows us to see whether the ‘Enable Alerts’ checkbox of the indicator or strategy is enabled. This is useful because when that checkbox is disabled, our script cannot generate any alert.

Two PowerLanguage keywords return the state of the ‘Enable Alerts’ checkbox (MultiCharts Wiki, 2012b, 2012c):

  • AlertEnabled returns true when the ‘Enable Alerts’ checkbox is enabled and returns false when that option is turned off.
  • CheckAlert returns true when the ‘Enable Alerts’ checkbox is enabled and the bar currently processed by the script is the last of the data series. CheckAlert returns false when that checkbox is disabled or when the current bar isn’t the last.
Note: On historical bars, the AlertEnabled keyword checks if alerts are enabled. But the alerts themselves can only generate on the last bar (MultiCharts Wiki, 2012a). AlertEnabled is still useful, however, since we can use it to minimise script calculations when alerts are disabled.

Another feature is programmatically cancelling an alert that’s already generated by Alert() during the current script calculation. We do that with the Cancel Alert keyword combination (MultiCharts Wiki, 2012d). This requires that the alert didn’t materialise yet. That means we’ll have to execute Cancel Alert somewhere between the Alert() keyword and the last line of the script. Since after that last line, any triggered alert by MultiCharts is cancelled and we’re too late to cancel it.

Tip: We cannot use Cancel Alert to specify which alert should be cancelled: whenever this keyword combination is executed, any alert is cancelled. Also keep in mind that, when executing Cancel Alert unconditionally (like, without an if statement to filter its use), all alerts are cancelled all the time.

It’s also possible to toggle the alert state with the SetAlertState() keyword, which either enables or disables alert generation for the current script calculation. That is, SetAlertState(false) turns off alerts while SetAlertState(true) (re-)enables an alert (for instance, one that we disabled with SetAlertState(false) or cancelled with Cancel Alert). When we turn an alert back on like that, we do lose the custom alert message specified when we generated the alert.

Tip: The Cancel Alert and SetAlertState() keywords make scripts more complicated than needed and increase the likelihood of programming errors. See don’t use Cancel Alert and SetAlertState() for more.

Other keywords for working with MultiCharts alerts are the #BeginAlert and #End compiler directives. We use these to surround code that should only execute when the script’s ‘Enable Alerts’ option is turned on. That way we can have two ‘different’ script versions depending on that manual option.

A basic example of #BeginAlert and #End is:


#BeginAlert

    // Our script only executes this code between
    // #BeginAlert and #End when 'Enable Alerts'
    // is enabled.

#End

In terms of script behaviour, this is identical to using CheckAlert to programmatically see whether alerts are enabled:


if (CheckAlert) then begin

    // The code inside this if statement
    // is also only executed when the
    // 'Enable Alerts' option is enabled.

end;

There are a couple of differences between these approaches too. For instance, we cannot access #BeginAlert to see if alerts are enabled – we have to use AlertEnabled or CheckAlert for that. Nor can #BeginAlert execute code when alerts are disabled, which we can do with those keywords (like if (AlertEnabled = false) then …).

Preventing a flood of MultiCharts alert messages

While alerts are helpful, too many alerts are not. And so in the chapter we also discussed ways to limit the number of alerts an indicator or signal generates.

One approach is generating alerts on bar close only. For that we use the BarStatus keyword, which returns the status of the most recent tick of the data series that the script calculates on (MultiCharts Wiki, 2014a). “Bar status” is, by the way, how the price update that’s currently processed by the script relates to the current price bar.

There are three possible bar statuses, and the BarStatus keyword returns a different value for each (MultiCharts Wiki, 2014a):

  • When our script processes a price update that’s the bar’s opening tick, BarStatus returns 0.
  • If the currently processed tick falls inside the bar, BarStatus returns 1.
  • And when the current price update marks the close of the price bar, BarStatus returns 2.
Note: In rare cases, BarStatus returns -1. That happens when the data series’ price bar has already closed, but the script still calculates, for instance due to price bars of an additional data series being processed, a broker event happening, or a periodic calculation with RecalcLastBarAfter() (e.g., Henry MultiCharts, 2015).

Now to only generate alerts when the bar closes, we use BarStatus like so:


if (BarStatus = 2) then begin

    if (High = Highest(High, 20)) then
        Alert("New 20-bar highest high");

end;

Another way to limit alerts is to trigger an alert at most once per bar. We can implement that with a variable that stores whether the alert already fired on the current bar. When we create that variable, we mark it as IntrabarPersist. That makes the variable remember any value stored in it (PowerLanguage Keyword Reference, 2016), as opposed to the default behaviour of only remembering the on-bar-close values.

Then when we generate an alert, we switch the variable’s value to prevent more alerts from generating on this bar. As soon as the bar closes, we reset the variable. That way on the next bar, the script can generate its alert again. An example of limiting an alert to once per bar looks like:


Variables:
    IntrabarPersist alertFired(false);

// Only calculate and generate an alert when
// there wasn't an alert yet on this bar
if (alertFired = false) then begin

    if (High = Highest(High, 20)) then begin

        Alert("New 20-bar highest high");

        alertFired = true;

    end;

end;

// Reset the variable once per bar, when
// the bar closes
if (BarStatus = 2) then
    alertFired = false;

Yet another approach to limit alerts is to generate an alert at most a certain number of times per bar. For that we also create an IntrabarPersist variable, but now use it to count how many alerts trigger during the current bar. And when the bar closes, we reset the variable. Then on the next bar, the script can generate its maximum number of alerts again.

That approach basically looks like:


Variables:
    IntrabarPersist alertsGenerated(0);

if (alertsGenerated < 3 and 
    High = Highest(High, 20)) then begin

    Alert("New 20-bar highest high");

    alertsGenerated = alertsGenerated + 1;

end;

// Reset the variable once per bar, when
// the bar closes
if (BarStatus = 2) then
    alertsGenerated = 0;

Limiting alerts is also possible by generating an alert every number of times the alert condition happens. This still gives us the initial alert, but after that the alert only fires every number of times the alert condition happens (say, every 5th time). This limits the number of alerts but still gives us the occasional reminder alert.

For this approach we again create an IntrabarPersist variable, and this time use it to count how often the alert condition happens. (We reset that variable when the bar closes so that, on the next bar, counting starts anew.)

To programmatically check whether the alert condition happens for the nth time (like the 5th time), we use mod(). That keyword requires two parameters (the dividend and divisor), and returns the remainder of dividing the first parameter by the second (MultiCharts Wiki, 2012e). That returned value is called the arithmetic remainder or modulus (Sharp, 2013).

This way of limiting alerts looks like:


Variables:
    IntrabarPersist triggeredAlerts(0);

// Check for the alert condition
if (High = Highest(High, 20)) then begin

    // Only fire an alert when the alert
    // condition is an even multiple of 5
    if (mod(triggeredAlerts, 5) = 0) then
        Alert("New 20-bar highest high");
    
    // Keep track of how often the alert
    // condition happens
    triggeredAlerts = triggeredAlerts + 1;

end;

// Once per bar, when the bar closes,
// reset the counter variable
if (BarStatus = 2) then
    triggeredAlerts = 0;

A different way to limit alerts is not to use the price bar (whose duration depends on the time frame) but to keep a certain number of seconds between consecutive alerts. To implement that, we first create an IntrabarPersist variable in which we store the time of when the alert triggered last. We get that time with ComputerDateTime, a keyword that returns the computer’s current time and date in DateTime format (MultiCharts Wiki, 2013b).

To know how long ago an alert happened, we subtract the last alert time from the current time (ComputerDateTime). To convert that DateTime difference to a number of seconds, we divide it with ELTimeToDateTime_s(1). Then as soon as this number of seconds is bigger than some threshold value, we allow generating an alert.

A quick example of this approach is:


Variables:
    IntrabarPersist timeLastAlert(0),
    secondsSinceLastAlert(0);

// Calculate the seconds since the last alert
secondsSinceLastAlert = (ComputerDateTime - timeLastAlert) /
    ELTimeToDateTime_s(1);

// When the alert condition happens and the number of
// seconds is bigger than our threshold, generate an alert
if (High = Highest(High, 20) and 
    secondsSinceLastAlert > 30) then begin

    Alert("New 20-bar highest high");

    timeLastAlert = ComputerDateTime;

end;

Yet another way to limit alerts by using time is to only generate alerts during a certain time period. For this we need to use the current time, check whether the time window crosses midnight, and then see if the current time is in that window.

We can use the CurrentTime or CurrentTime_s keywords to get the computer’s current time. The first returns that time in 24-hour HHmm format (hoursminutes, like 912 for 9:12), whereas the second uses the 24-hour HHmmss format (hoursminutesseconds, like 91234 for 9:12:34) (PowerLanguage Keyword Reference, 2016).

If we specify the time range with input options, then we don’t know beforehand whether the user sets a time range that’s on the same day (like 9:00 till 17:00) or crosses midnight (22:00 till 6:00). To check for a same-day time range, the start time has to be less than the end time (like starting at 17:00 and ending at 17:00). When the start time is greater than the end time (as is the case with beginning at 22:00 and ending at 6:00), then the time range does cross midnight.

When we know whether the time range falls on the same day or not, we can then determine if the current time falls inside that time window or not. When it does, we set a variable to true and later on use that variable as a requirement for generating an alert.

A basic example of only generating alerts during a certain time period is:


Inputs:
    StartTime(900),
    EndTime(1700);

Variables:
    inTimePeriod(false);

// Check if the current time falls inside the specified time
// range, depending on whether this crosses midnight or not
if (StartTime < EndTime) then
    inTimePeriod = (CurrentTime >= StartTime) and (CurrentTime <= EndTime)
else
    inTimePeriod = (CurrentTime > StartTime) or (CurrentTime < EndTime);

// If the current time is inside the time period and the
// alert condition happens, generate an alert
if (inTimePeriod and High = Highest(High, 20)) then begin

    Alert("New 20-bar highest high");

end;

While we discussed each approach to limiting alerts separately, we can of course combine them in our script so we can limit alerts in different ways. An example of that is combining an intra-bar alert with an on-bar-close alert. (Also see 5 ways to limit alerts for an overview of different approaches.)

Tips for working with MultiCharts alerts programmatically

Besides preventing a flood of alert messages, we discussed other alert suggestions too. The first tip is not to use Cancel Alert and SetAlertState(). Most importantly, these keywords make the code needlessly complicated. Luckily for us, we can replace their functionality with a simple if statement that filters when Alert() should generate an alert.

Another alert tip is to generate an error message when alerts are disabled. That prevents that we accidentally forget to enable the script’s alerts, which leaves the script incapable of generating alerts despite having programmed the alerts correctly.

The RaiseRunTimeError() keyword triggers those error messages, and with this keyword we can also specify an error message (PowerLanguage Keyword Reference, 2016). An example of RaiseRunTimeError() is:


if (AlertEnabled = false) then
    RaiseRunTimeError("This script's alerts are not enabled!");

Those error messages look like:

MultiCharts error message when alerts are disabled

These messages generate regardless of the script’s alert setting. And so they can generate a notification window even when the alerts are turned off. Those red error messages also won’t go away unless we click on them, which makes them a lot harder to miss.

A disadvantage is that executing RaiseRunTimeError() also turns off the indicator or signal. That makes creating a notifying text box when alerts are disabled a more user-friendly suggestion. We place such a text box on the chart with Text_New_DT(). That keyword puts a text message on a certain time and price coordinate, and returns a numerical identifier that we use to access the text box later on (PowerLanguage Keyword Reference, 2016).

An example that creates a text box in the chart’s lower left corner when alerts are disabled is:


[RecoverDrawings = false];

Variables:
    IntrabarPersist textBoxID(0);

if (LastBarOnChart_s and CheckAlert = false) then begin
    
    // Create the notifying text box
    if (textBoxID = 0) then begin
    
        textBoxID = Text_New_DT(GetAppInfo(aiLeftDispDateTime), 
            GetAppInfo(aiLowestDispValue), 
            "\n  The script's alerts are disabled  \n");
        
        // Change the text box's appearance
        Text_SetStyle(textBoxID, 0, 1);
        Text_SetBorder(textBoxID, true);
        Text_SetSize(textBoxID, 10);
        Text_SetColor(textBoxID, black);
        Text_SetBGColor(textBoxID, yellow);
    
    end 
    
    // If the text box is already made, we only 
    // need to update its location
    else if (textBoxID > 0) then begin
    
        Text_SetLocation_DT(textBoxID, 
            GetAppInfo(aiLeftDispDateTime),
            GetAppInfo(aiLowestDispValue));
    
    end;

end;

When the script’s ‘Enable Alerts’ checkbox is disabled, the above example script creates the following text box:

Drawing a text box on the chart when alerts are disabled

Another tip for working with alerts is to periodically recalculate the script. With those time-based calculations, the script keeps up to date and can generate alerts independent of price updates. That means even when the instrument is closed or receives only a couple of ticks, the alerts still generate at the right time with no lag.

We implement that with RecalcLastBarAfter(). Inside this keyword’s parentheses we specify a certain number of seconds, and the keyword then ensures that the script calculates at least once in that amount of seconds (PowerLanguage Keyword Reference, 2016).

A basic example of the RecalcLastBarAfter() keyword to keep the script up to date when generating alerts is:


// Generate an alert when the alert condition happens
if (High = Highest(High, 20)) then begin

    Alert("New 20-bar highest high");

end;

// Make the script calculate at least once
// every second
RecalcLastBarAfter(1);

In the last part of the chapter we explored examples of generating alerts programmatically.

Examples of using alerts in MultiCharts PowerLanguage

A couple of ways in which we can use MultiCharts alerts are:

  • One approach to trigger MultiCharts alerts is to generate alerts with moving averages. In that article, we fired alert based on an Exponential Moving Average crossing a Simple Moving Average.
  • One way to use alerts for risk management is by generating an alert for possible real-time data issues. For that we used the Q_Time_DT keyword to retrieve the DateTime value of the chart’s Status Line (PowerLanguage Keyword Reference, 2016), which is the time of when the last trade, bid, or ask update happened. Then when that time was more than a certain number of seconds ago, we assumed a possible data feed or internet problem and triggered an alert programmatically.
  • While turning a script’s alerts on or off typically involves several manual steps, we can also use code to enable or disable alerts with a single click. To implement that, we processed mouse events so that a single click on the chart switched the value of a true/false variable. That variable was then used as a filter prior to generating alerts.
  • We explored another approach in generating alerts with programmatically-drawn trend lines. In that article, we used the TL_New_s() keyword to draw a trend line and then retrieved that line’s price for a certain date and time with TL_GetValue_s() (PowerLanguage Keyword Reference, 2016). By comparing that trend line price value with the current bar’s closing price, we can check if the bar crossed the trend line. If it did, we generate an alert programmatically.
  • In generating a semi-automatic alert we explored how an example indicator can monitor mouse clicks on the price chart, and based on those clicks generate an alert at the clicked-on price level. This gives us a quick way to attach alerts to price levels without having to meddle with a script’s input options. We generate those alerts with MouseClickPrice, a keyword that returns the price coordinate of where the click happened (PowerLanguage Keyword Reference, 2016) whenever the ProcessMouseEvents attribute is enabled.

Then we explored how we can use alerts with trading strategies:

  • We first created a signal that generates an alert when we don’t enable the strategy’s automated trading. By triggering alerts when that happens, we (hopefully) prevent that we overlook enabling automated trading on one of the charts before the trading session begins. To see whether automated trading is enabled or not, we use the GetAppInfo() keyword with the aiStrategyAuto parameter. That combination returns 1 when the signal has automated trade execution enabled and 0 when auto trading is off (PowerLanguage Keyword Reference, 2016).
  • We can also attempt to reduce risks by generating an alert when automated trading gets disabled. That happens when we change the symbol or chart that the strategy runs on, adjust the strategy’s settings, alter one of the signals, recompile a signal, or when there’s a connection loss between MultiCharts and the broker for a prolong period of time (MultiCharts Wiki, 2016). To keep track of the strategy’s automated trading state, we created an IntrabarPersist variable that held the value of GetAppInfo(aiStrategyAuto). That makes it possible to compare the current status of automated trading (that is, GetAppInfo(aiStrategyAuto)) with the previous status (the variable’s value), and then generate an alert when automated trading is off while being on previously.
  • Another way to monitor a trading strategy is by generating an alert when the strategy’s position changes. For that we tracked the MarketPosition and CurrentContracts keywords. The first returns the strategy’s direction (1 for long, -1 for short, and 0 for flat) while the other returns the number of open contracts, shares, units, or lots as an absolute value (PowerLanguage Keyword Reference, 2016). By comparing the current value of these with the previous, we can determine whether the strategy opened, closed, increased, or decreased a position and then generate an accompanying alert message.
  • Another automated trading risk is a position mismatch, which we examined in generating an alert when the broker’s position doesn’t match the MultiCharts position. The causes of that situation are: automated trading in asynchronous mode, combining manual with auto trading, trading the same instrument from multiple charts, and when MultiCharts doesn’t receive an order’s final status (MultiCharts Wiki, 2014b). To generate an alert when that happens, we used the MarketPosition_at_Broker keyword to fetch the currently open position at the broker (PowerLanguage Keyword Reference, 2016). We then compared that value with the product of MarketPosition and CurrentContracts, two keywords that tell us what the position according to MultiCharts is. When there’s a difference between these two, there’s a position mismatch and we generated an alert programmatically.

This ends the overview of the chapter on working with MultiCharts alerts. To learn more about other topics, see all MultiCharts programming tutorials.


References

Henry MultiCharts (2015, January 30). closing status of a bar sometimes takes too long – forum discussion. Retrieved on May 4, 2016, from http://www.multicharts.com/discussion/viewtopic.php?f=1&t=10642#p113092

MultiCharts Wiki (2012a, February 7). Alert. Retrieved on January 30, 2017, from http://www.multicharts.com/trading-software/index.php/Alert

MultiCharts Wiki (2012b, February 7). CheckAlert. Retrieved on March 11, 2016, from http://www.multicharts.com/trading-software/index.php/CheckAlert

MultiCharts Wiki (2012c, February 26). AlertEnabled. Retrieved on March 11, 2016, from http://www.multicharts.com/trading-software/index.php/AlertEnabled

MultiCharts Wiki (2012d, February 7). Cancel Alert. Retrieved on March 15, 2016, from http://www.multicharts.com/trading-software/index.php/Cancel_Alert

MultiCharts Wiki (2012e, February 13). Mod. Retrieved on May 10, 2016, from https://www.multicharts.com/trading-software/index.php/Mod

MultiCharts Wiki (2013a, May 10). Using Alerts. Retrieved on January 28, 2017, from https://www.multicharts.com/trading-software/index.php/Using_Alerts

MultiCharts Wiki (2013b, June 5). ComputerDateTime. Retrieved on May 11, 2016, from https://www.multicharts.com/trading-software/index.php/ComputerDateTime

MultiCharts Wiki (2014a, August 12). BarStatus. Retrieved on May 3, 2016, from https://www.multicharts.com/trading-software/index.php/BarStatus

MultiCharts Wiki (2014b, June 11). Why There Is Mismatch On Strategy Positions Tab. Retrieved on September 1, 2016, from http://www.multicharts.com/trading-software/index.php/Why_There_Is_Mismatch_On_Strategy_Positions_Tab

MultiCharts Wiki (2016, June 14). Auto Trading. Retrieved on July 29, 2016, from http://www.multicharts.com/trading-software/index.php/Auto_Trading

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

Sharp, J. (2013). Microsoft Visual C# 2013 Step by Step. Microsoft Press.