MultiCharts trading strategies calculate, by default, on the close of each price bar (MultiCharts Wiki, 2015b). But sometimes a lot happens before the bar closes. So how can a strategy calculate more often than that?

In this article:

Generating intra-bar orders with the IntrabarOrderGeneration attribute

An attribute is a PowerLanguage keyword that affects how the script operates by enabling or disabling a certain feature. They’re applied when the script’s source code compiles and cannot be changed during script run-time (MultiCharts Wiki, 2012a). That means that once we’ve programmatically added an attribute to our script, we cannot manually change the feature it affects. Instead, we then need to set the attribute to true or false to enable or disable its feature.

Some attributes (like IntrabarOrderGeneration) have an equivalent manual setting, however. But most attributes affect features that we can only set programmatically (like ProcessMouseEvents does). Attributes can be placed anywhere in the script, but their typical and advised location is in the top of the script. For instance, here we started the script with the IntrabarOrderGeneration and RecoverDrawings attributes:

Example location of MultiCharts attributes in a script

So what does IntrabarOrderGeneration do? This attribute, when set to true, allows a trading strategy to calculate and generate orders intra-bar (MultiCharts Wiki, 2012a). This means that when we enable this attribute (which is commonly abbreviated to IOG; MultiCharts Wiki, 2015b), a strategy can react to price changes that happen inside a price bar. To see why that’s beneficial, let’s look at the differences between IOG turned on and off.

Intra-bar order generation enabled versus disabled

MultiCharts trading strategies have IOG disabled by default, and this affects a strategy as follows (MultiCharts Wiki, 2015b):

  • On historical data the script is calculated on bar close. A generated order is then submitted on the close of this bar or on the open of the next. These orders can be filled at a bar’s open, high, low, or close price.
  • On real-time data the script also calculates on bar close, with orders being placed for the open of the next bar. Pending orders can be filled at any real-time tick that satisfies the order execution conditions.

When we enable IOG, the strategy behaves as follows (MultiCharts Wiki, 2015b):

  • On historical data with the Bar Magnifier (discussed below) disabled, our strategy calculates four times per bar (on the bar’s open, high, low, and close prices). An order can be generated on any of these four calculations, and can be filled on any price that’s inside the bar’s range and that satisfies the order’s execution conditions.
  • On historical data with the Bar Magnifier feature enabled, an IOG-enabled strategy calculates on the open of the main data series, then on the open, high, low, and close of each bar set by the Bar Magnifier’s resolution, and then on the close of the main data series. An order can be generated on any of these calculations, and that order can be filled on the first price that meets the order execution logic. Only the exact prices of the main bar and Bar Magnifier bars are used for filling the order.
  • On real-time data, the strategy calculates on every tick, which allows the script to react to every price update. An order can be filled on any tick that satisfies the conditions for order execution.

In other words, when IOG is disabled anything that a strategy does (from submitting an order and drawing a trend line to generating an alert) is done once per bar. When IOG is enabled, the script calculates several times per bar and can also perform its actions while a bar hasn’t closed yet.

That also makes an IOG strategy less dependent on the chart’s time frame since it calculates more often than a strategy without IOG that has to ‘wait’ till the bar closes.

Tip: IOG has two important consequences. First, since open orders need to be resubmitted to keep them alive (see, for example, MultiCharts Wiki, 2012c), we now need to submit any unfilled order each time the script calculates. The other effect of IOG is that orders that are marked next bar will now be submitted on the next tick and will not necessarily execute on the open of the next bar.
Note: A trading strategy script is called a signal in MultiCharts (MultiCharts Wiki, 2015a). A signal can be a complete trading strategy, but we can also add multiple signals (acting as strategy ‘building blocks’) to the chart or Portfolio Trader and they will then be combined by MultiCharts into one trading strategy (see MultiCharts Wiki, 2012b). But we can configure the intra-bar order generation setting for each signal individually, even though several signals are treated as one strategy in MultiCharts.

More precise backtesting with the Bar Magnifier

The Bar Magnifier is an option that emulates the price movement within a bar more precisely (MultiCharts Wiki, 2013), which makes the backtest results of IOG-enabled strategies more accurate (MultiCharts Wiki, 2015b).

An example of the benefit of the Bar Magnifier is when a profit target and stop-loss order execute on the same bar. With the Bar Magnifier, MultiCharts can then see how the price bar was formed and which of these orders was executed first. As such, we can think of the Bar Magnifier as a replay of how the price bar was formed, and that ‘replay frequency’ can be set to a number of ticks, seconds, or minutes in its settings.

The Bar Magnifier isn’t available for the Portfolio Trader and cannot be enabled programmatically. To configure it, we right-click on the chart and select ‘Format Signals’:

The 'Format Signals' menu item on a MultiCharts chart

Then we click on ‘Properties’ to configure the settings of all signals applied to the chart:

Selecting the properties of a MultiCharts strategy

This opens the ‘Strategy Properties’ window in which we move to the ‘Backtesting’ tab to enable the Bar Magnifier with its preferred precision:

Enabling the Bar Magnifier in MultiCharts
Note: The Bar Magnifier’s precision is a trade-off: the lower its resolution setting, the more accurate the backtested results but also the more data needs to be loaded, processed, and kept in the computer’s memory (MultiCharts Wiki, 2013).

Toggling intra-bar order generation programmatically in MultiCharts

Now back to the IntrabarOrderGeneration attribute. We use this attribute to enable IOG programmatically as follows:


[IntrabarOrderGeneration = true];

And when we set this attribute to false, intra-bar order generation is disabled:


[IntrabarOrderGeneration = false];

By default, MultiCharts strategies have intra-bar order generation turned off (MultiCharts Wiki, 2015b).

Setting MultiCharts’ intra-bar order generation settings by hand

A signal’s intra-bar order generation settings can also be set manually, and that allows us to configure the same signal differently on multiple charts. However, that setting can only be changed when the IntrabarOrderGeneration attribute isn’t added to the script’s code (MultiCharts Wiki, 2012a).

To set a signal’s IOG settings, we first right-click on the chart and select ‘Format Signals’:

The 'Format Signals' option on a MultiCharts chart

This opens the ‘Format Objects’ window. Here we select the strategy whose IOG settings we want to change and then click ‘Format…’:

Formatting a MultiCharts trading signal

We’re now presented with the ‘Format Signal’ window that’s used to configure a signal’s options. Here we select the ‘Properties’ tab that lists several intra-bar order generation settings:

A MultiCharts strategy's intra-bar order generation settings

To have the script calculate and submit its orders intra-bar, we select the ‘Enable Intra-Bar Order Generation’ checkbox. Now we can also set the two additional options listed under ‘Entries’ and ‘Exits’:

Enabling intra-bar order generation in MultiCharts

These options help to prevent a flood of orders when intra-bar order generation is enabled. The three ‘Entries’ choices affect how many positions may be opened: one entry per bar for the current signal, one entry per bar for all signals added to the chart, or a certain amount of entries per bar for all the chart’s signals.

Exit orders are configured with three options below ‘Exits’: the current signal may exit once per bar, all signals on this chart may exit once per bar, or any exit from any signal may happen several times per bar.

Tip: The ‘Entries’ and ‘Exits’ settings cannot be set programmatically. So when the IntrabarOrderGeneration attribute is enabled, we still need to configure them manually if they should act differently than their default settings (one entry for all signals and one exit for all signals per bar; see previous image).

By the way, the ‘Entries’ and ‘Exits’ settings are closely related to the ‘Position limits’ setting. That’s because, before a signal can generate multiple orders per bar in the same direction, the ‘Position limits’ setting needs to allow pyramiding. We change that setting in the ‘Strategy Properties’ window, which is opened by right-clicking on the chart, selecting ‘Format Signals’ followed by pressing ‘Properties’.

Specifying the position limits of a MultiCharts strategy

Why are the intra-bar order generation settings greyed out?

Since PowerLanguage attributes are applied during compilation and cannot be changed when the script is in use (MultiCharts Wiki, 2012a), we cannot alter the main intra-bar order generation setting when its attribute is present in the script’s code. And so when IntrabarOrderGeneration is set to false, the ‘Enable Intra-Bar Order Generation’ setting is greyed out:

Intra-bar order generation settings greyed out in MultiCharts

Likewise, when the IntrabarOrderGeneration attribute is enabled, we cannot turn off that ‘Enable Intra-Bar Order Generation’ setting:

Disabling intra-bar order generation in MultiCharts turned off

So if we want to change that intra-bar order generation setting by hand, we’ll need to remove the IntrabarOrderGeneration attribute from our code first.

Creating an intra-bar order generation strategy in MultiCharts

Now let’s turn to a programming example that uses the IntrabarOrderGeneration attribute. The example strategy opens a position at the first bar of the day and goes flat in the five minutes before the end of trading. Before we look at how this example script behaves with intra-bar order generation enabled, let’s first create a version that does not generate orders intra-bar:


[IntrabarOrderGeneration = false];

// Enter at the first bar of the day
if (MarketPosition(0) = 0) and (Date <> Date[1]) then
    Buy ("Enter Long") 1 contracts next bar at market;
    
// Exit before the close
if (Time_s >= 215500) and (Time_s <= 220000) then
    Sell ("Time Exit") all contracts next bar at market;

We begin with the IntrabarOrderGeneration attribute set to false to only have the strategy calculate on bar close. Note that we place this attribute between square brackets ([ and ]); otherwise, PowerLanguage generates the ‘assignment is only for variables or array elements’ error message.

An if statement then evaluates two conditions:


if (MarketPosition(0) = 0) and (Date <> Date[1]) then
    Buy ("Enter Long") 1 contracts next bar at market;

The first condition checks if the value returned by MarketPosition(0) equals 0. That keyword returns, with a zero between its parentheses, a number indicating the strategy’s current market position: 0 for flat, -1 for short, and 1 for long (MultiCharts Wiki, 2015c). And so whenever MarketPosition(0) equals 0, the strategy currently is flat. With this condition we prevent pyramiding: the buy order that’s below the if statement is now only submitted when the strategy is flat.

The second condition in our if statement is whether the current bar’s date (Date) is unequal to (<>) the date of the previous bar (Date[1]), which happens on the first bar of a trading day. Since both conditions are combined with the and keyword, both need to be true the if statement’s entire condition is true.

When the strategy is flat and the current bar is the first of the trading day, we submit an enter long order with the Buy keyword (MultiCharts Wiki, 2012c). The order name is specified as “Enter long” with a position size of 1 and submitted as a market order on the next bar (next bar at market).

The next if statement in our example is used to exit the long position:


if (Time_s >= 215500) and (Time_s <= 220000) then
    Sell ("Time Exit") all contracts next bar at market;

Here we also evaluate two conditions that we also combine with and. The first checks whether Time_s returns a value that’s greater than or equal to (>=) 215500. That Time_s keyword returns the bar’s closing price in 24-hour HHmmss format (MultiCharts Wiki, 2012d), so a time like 21:57:30 is returned as the 215730 number. The value that we check Time_s against is 215500 (so 21:55:00 or 9:55 p.m.).

The second condition, in turn, evaluates if the current bar’s time (Time_s) is less than or equal to (<=) 220000 (22:00:00 hour or 10 p.m.). By combining both conditions, we’re in effect looking for a 5-minute time period: the bar’s time needs to be between 21:55 and 22:00 before the if statement’s code is executed. That time period is just before the close of trading of the instrument that we add our script to (see below).

When both of those conditions are true, we submit an exit long order with the Sell keyword (MultiCharts Wiki, 2012e). The order is named “Time Exit” and we have it close the entire long position (all contracts) with a market order (next bar at market).

The effect of intra-bar order generation in MultiCharts PowerLanguage

The above example, when added to a an EuroStoxx 50 future chart, looks like:

Example of the MultiCharts trading strategy MultiCharts strategy behaving differently than intended

As we can see here, our strategy doesn’t behave as intended: positions aren’t opened on the first bar of the day and, even worse, positions are kept overnight and not exited before the close of trading.

However, let’s change the first line of the example to the following:


[IntrabarOrderGeneration = true];

We keep the rest of the script unchanged and recompile it. Now as the same time period as the previous charts, the strategy behaves as follows:

MultiCharts strategy closing a position before the close Exiting orders in MultiCharts before the close of trading

Now the strategy performs as it should: positions are opened at the start of the trading day and exited at the close of trading. Why is that?

When intra-bar order generation is turned off, the strategy calculates on bar close and submits next bar orders for the next price bar (MultiCharts Wiki, 2015b). In our case, that means the long order is generated on the day’s first bar (but submitted for the next bar) while the exit long order generates at the end of trading, but executes on the next bar (which is the first bar of the next day).

With intra-bar order generation turned on, however, the strategy calculates four times per bar (at the bar’s open, high, low, and close price) on historical data. During any of those calculations, an order can be generated and subsequently be filled on the next calculation (MultiCharts Wiki, 2015b). For our example, this means that the long order generates at the open of the first bar of that day (and fills during the three remaining calculations on that bar). Likewise, when our exit long order generates on the last bar of trading, there still several calculations left on that same bar to fill the exit long market order.

To learn about other PowerLanguage attributes that affect trading strategies, see AllowSendOrdersAlways to submit orders regardless the script’s calculation reason and SameExitFromOneEntryOnce to reuse exit orders.

Summary

The IntrabarOrderGeneration attribute enables (when set to true) or disables (false) a signal’s intra-bar order generation (IOG). A strategy can calculate multiple times per bar when that feature is enabled, instead of just once per bar (which is the default behaviour). The advantage of intra-bar order generation is that a strategy can react to price changes happening inside a bar, which allows a strategy to perform its actions (like submitting an order or generating an alert) when the price bar still develops. When intra-bar order generation is enabled, orders that are marked as next bar can be executed the next time a strategy calculates; that doesn’t necessarily has to be the next bar but can also be the same bar.


References

MultiCharts Wiki (2012a, August 31). IntrabarOrderGeneration. Retrieved on November 28, 2015, from http://www.multicharts.com/trading-software/index.php/IntraBarOrderGeneration

MultiCharts Wiki (2012b, February 23). Signal Settings. Retrieved on November 30, 2015, from https://www.multicharts.com/trading-software/index.php/Signal_Settings

MultiCharts Wiki (2012c, February 19). Buy. Retrieved on December 11, 2015, from http://www.multicharts.com/trading-software/index.php/Buy

MultiCharts Wiki (2012d, February 28). Time_s. Retrieved on December 12, 2015, from https://www.multicharts.com/trading-software/index.php/Time_s

MultiCharts Wiki (2012e, February 19). Sell. Retrieved on December 12, 2015, from https://www.multicharts.com/trading-software/index.php/Sell

MultiCharts Wiki (2013, May 21). Bar Magnifier. Retrieved on December 11, 2015, from https://www.multicharts.com/trading-software/index.php/Bar_Magnifier

MultiCharts Wiki (2015a, May 4). How Scripts Work. Retrieved on November 30, 2015, from http://www.multicharts.com/trading-software/index.php/How_Scripts_Work

MultiCharts Wiki (2015b, May 15). How Signals are Calculated. Retrieved on December 11, 2015, from https://www.multicharts.com/trading-software/index.php/How_Signals_are_Calculated

MultiCharts Wiki (2015c, July 22). MarketPosition. Retrieved on December 12, 2015, from https://www.multicharts.com/trading-software/index.php/MarketPosition