When we have a MultiCharts strategy that scales out of positions, a lot of code is needed to manage each exit. Is there a way in which we can reuse exit orders?

In this article:

Using a strategy’s same order to exit a position multiple times

A PowerLanguage attribute is a keyword that enables or disables a certain script feature. These attributes are applied when the script compiles and cannot be changed during run-time (e.g., MultiCharts Wiki, 2014a). This means the feature that’s affected by an attribute can’t be adjusted unless we change the attribute’s setting in the code and recompile the script.

Furthermore, most attributes – including the SameExitFromOneEntryOnce attribute – have no manual setting in the MultiCharts program. And so we’ll often use an attribute to change a script’s behaviour. Those attributes can be placed anywhere, but their typical location is at the beginning of the script’s code like these IntrabarOrderGeneration and RecoverDrawings attributes:

Example location of MultiCharts attributes in a script

Another attribute is SameExitFromOneEntryOnce. This attribute affects how a signal can reuse exit orders as follows (Henry MultiCharts, 2012; MultiCharts Wiki, 2013):

  • When SameExitFromOneEntryOnce is set to true, an exit order cannot be used to exit again from the same position. This means we need to create individual orders for each exit – so scaling out of a long position in 4 steps requires 4 separate sell orders. This has the potential disadvantage of requiring a lot of extra code.
  • When SameExitFromOneEntryOnce is set to false, a filled exit order can be generated again and applied to the same position. Since an exit order can then be used an unlimited number of times, scaling out of a long position in 4 steps only requires one sell order.

And so the SameExitFromOneEntryOnce attribute only affects a signal’s behaviour when that script uses partial exits.

Programmatically enabling or disabling the reuse of exit orders

To allow a signal to apply filled exit orders again to the same position, we set the SameExitFromOneEntryOnce attribute to false (as in: ‘do not fill the same exit order with the same position just once’):


[SameExitFromOneEntryOnce = false];

When this attribute isn’t added to the code or when set to true, then the signal cannot reuse an exit order to close part of the same position (MultiCharts Wiki, 2013).


[SameExitFromOneEntryOnce = true];

MultiCharts, by default, does not allow the reuse of an exit order (MultiCharts Wiki, 2013). Also, the SameExitFromOneEntryOnce attribute doesn’t have a manual equivalent option in the MultiCharts program and so using the attribute is the only way to change how MultiCharts deals with reusing exit orders.

Example: scaling out of position with multiple exit orders

In the remainder of this article we’ll look at two examples. Both have the same buy and sell conditions and both enter a long position of 10 contracts and scale out in 5 steps. The difference between these scripts is that the first has the SameExitFromOneEntryOnce attribute set to true (and so needs separate sell orders for each exit), while the second has this attribute set to false in which case we only need to code one sell order.

Let’s start with the version that requires a different sell order for each exit. After discussing the code, we’ll look at how this signal script behaves on the chart.


[SameExitFromOneEntryOnce = true];

Variables:
    quickMA(0), slowMA(0);

// Calculate the moving averages  
quickMA = AverageFC(close, 10);
slowMA  = AverageFC(close, 25);

// Go long when the quick MA crosses above the slow one
if (MarketPosition(0) = 0 and quickMA crosses over slowMA) then
    Buy ("EL") 10 contracts next bar at market;
    
// Scale out when the bar closes below the quick MA
if (Close crosses under quickMA) then begin

    if (CurrentContracts = 10) then
        Sell ("XL 1") 2 contracts next bar at market
    else if (CurrentContracts = 8) then
        Sell ("XL 2") 2 contracts next bar at market
    else if (CurrentContracts = 6) then
        Sell ("XL 3") 2 contracts next bar at market
    else if (CurrentContracts = 4) then
        Sell ("XL 4") 2 contracts next bar at market
    else if (CurrentContracts = 2) then
        Sell ("XL 5") 2 contracts next bar at market;

end;

We start by setting the SameExitFromOneEntryOnce attribute to true. This makes the default behaviour explicit, meaning we need to create a sell order for each exit (MultiCharts Wiki, 2013).

But first we declare two variables and compute moving averages:


Variables:
    quickMA(0), slowMA(0);

quickMA = AverageFC(close, 10);
slowMA  = AverageFC(close, 25);

Both variables (quickMA and slowMA) are set to a default value of 0. Then we store in them the value that’s returned by AverageFC(), a standard function that calculates a moving average with two parameters: a series of data and the length of the moving average.

We set quickMA to the value returned by that function when it computes on closing prices (close) with a length of 10 bars. The slowMA variable is assigned the value that’s returned by AverageFC() when this function calculates on close data of the recent 25 bars. Both variables are used later on with the buy and sell conditions.

Then we evaluate an if statement before submitting a buy order:


if (MarketPosition(0) = 0 and quickMA crosses over slowMA) then
    Buy ("EL") 10 contracts next bar at market;

The condition of this if statement evaluates two expressions. The first is whether the MarketPosition(0) keyword returns a value that’s equal to (=) 0. This keyword, with a value of 0 between its parentheses, returns a number that indicates the strategy’s current position: 1 is returned when the strategy is long, -1 when short, and 0 when flat (MultiCharts Wiki, 2015). Since we evaluate whether this keyword returns 0, we’re checking to see if the strategy is flat. This way we only submit our buy order when there isn’t a position already, and that prevents accidental scale-in orders and ending up with a much bigger long position than intended.

The if statement’s second expression is the buy condition, which evaluates whether the 10-bar moving average (stored in the quickMA variable) crossed above (crosses over) the 25-bar moving average (slowMA). This expression returns true whenever the value of quickMA is greater than the value of slowMA on the current bar while quickMA was below or equal to slowMA on the previous bar (MultiCharts Wiki, 2012a).

So whenever the strategy is flat and the fast moving average crossed above the slow one, we open a long position. We do that with the buy keyword to generate a market order that’s named “EL” (Enter Long) and that has a size of 10 contracts (MultiCharts Wiki, 2012b). That order name appears on the chart but also in the ‘Strategy Performance Report’.

The last part of the signal’s code scales out of that long position:


if (Close crosses under quickMA) then begin

    if (CurrentContracts = 10) then
        Sell ("XL 1") 2 contracts next bar at market
    else if (CurrentContracts = 8) then
        Sell ("XL 2") 2 contracts next bar at market
    else if (CurrentContracts = 6) then
        Sell ("XL 3") 2 contracts next bar at market
    else if (CurrentContracts = 4) then
        Sell ("XL 4") 2 contracts next bar at market
    else if (CurrentContracts = 2) then
        Sell ("XL 5") 2 contracts next bar at market;

end;

We start here with an if statement that evaluates whether the close of the current bar (Close) dropped below (crosses under) the 10-bar moving average. This condition is true whenever the close is below that moving average on the current bar, while it was above or equal to that moving average on the previous bar (MultiCharts Wiki, 2012a). Whenever this is the case, the if statement’s code executes.

That code contains an if/else statement whose 5 different conditions all evaluate the value of CurrentContracts. That keyword returns the position size of the strategy’s open position (MultiCharts Wiki, 2012c), and we use it here with the different if statements to determine which exit order to submit for scaling out of the long position.

The first if statement checks whether CurrentContracts equals (=) 10, which it does when we still have the full long position open. In that case, we use the Sell keyword to shave off 2 contracts from the long position with a market order that’s named “XL 1” (MultiCharts Wiki, 2012d).

When the open position is not 10 contracts big, the next if statement is processed. This one checks whether CurrentContracts returns a value that’s equal to 8. When this is true, we submit another sell market order for again 2 contracts and name it “XL 2”.

Now when the current position size isn’t 10 or 8, the next if statement is evaluated. The condition is this time CurrentContracts = 6. When that’s true, we submit yet another sell order (“XL 3”) for 2 contracts.

The fourth if statement executes when the current position size isn’t 10, 8, or 6, and checks whether CurrentContracts equals 4. In that case we generate another sell market order with 2 contract and name it “XL 4”.

The very last if statement checks whether the position size if 2 contracts, and this is the case when all of the previous sell orders have been executed and we’re left with just 2 contracts out of the original 10 long contracts. We then exit these two remaining contracts with the last sell order at market that we name “XL 5”.

Once that final order executes, we’ve closed the entire original long position of 10 contracts. Note that, since our signal can only enter a long position when the strategy is flat, executing this last sell order also means that a new long position can be opened whenever the 10-bar moving average crosses above the 25-bar moving average.

Example: scaling out of a position with multiple exit orders

Now when we add this example strategy to a NASDAQ-100 CFD chart, it looks like:

Example of scaling out with SameExitFromOneEntryOnce set to true

Here we see that our enter long order bought 10 contracts and that the position is closed with 5 different exit orders, named “XL 1” through “XL 5”.

When we open the ‘Strategy Performance Report’ (through the ‘View’ menu item) and select the ‘Total Trade Analysis’ segment, the strategy behaved like:

Performance report of our MultiCharts example strategy

Our strategy example generated 66 trades, and 27 of these were profitable. Now let’s revisit our code example, this time setting SameExitFromOneEntryOnce to false.

Scaling out of a MultiCharts position with a single exit order

The previous example used 5 sell market orders to close a long position. Even without adding stops and take profit orders, those individual orders already required several lines of code and thereby increased the potential for programming errors.

However, exit orders can be reused when we set the SameExitFromOneEntryOnce attribute to false (MultiCharts Wiki, 2013). This means we can achieve the same strategy behaviour but with less code, and so we change the example to the following:


[SameExitFromOneEntryOnce = false];

Variables:
    quickMA(0), slowMA(0);

// Calculate the moving averages
quickMA = AverageFC(close, 10);
slowMA  = AverageFC(close, 25);

// Go long when the quick MA crosses above the slow one
if (MarketPosition(0) = 0 and quickMA crosses over slowMA) then
    Buy ("EL") 10 contracts next bar at market;
    
// Scale out when the bar closes below the quick MA
if (MarketPosition(0) > 0 and Close crosses under quickMA) then
    Sell ("XL") 2 contracts next bar at market;

Since a lot of statements haven’t changed, let’s focus on the ones that did. The first adjustment is setting the SameExitFromOneEntryOnce attribute to false:


[SameExitFromOneEntryOnce = false];

Because this makes reusing exit orders possible, we can now scale out of a long position with just one exit order instead of 5 different sell orders:


if (MarketPosition(0) > 0 and Close crosses under quickMA) then
    Sell ("XL") 2 contracts next bar at market;

But before we submit the sell order here, we use an if statement to evaluate two expressions. First, the strategy needs to be long – that way we only send a sell order when there’s something to sell.

For that we check whether MarketPosition(0) returns a value that’s greater than zero. That keyword, with a value of 0 between its parentheses, returns a number that indicates the strategy’s current position: 1 for long, 0 for flat, and -1 for short (MultiCharts Wiki, 2015).

The second requirement before we submit the sell order is that the bar’s closing price (Close) dropped below (crosses under) the 10-bar moving average (quickMA). Now when both of these expressions are true, we submit a sell order named “XL” for 2 contracts and set this market order to execute on the open of the next bar (MultiCharts Wiki, 2012d).

Since we can reuse this exit order repeatedly now with SameExitFromOneEntryOnce set to false, we don’t need to code additional sell orders in the script.

Note: When SameExitFromOneEntryOnce is set to false, a filled exit order cannot be submitted until the script calculates again. That means our sell order only executes once for each time that the if statement’s condition is true. In addition, we haven’t added the IntrabarOrderGeneration attribute to the code. Because of that the strategy defaults to a calculation once per bar, and so our sell order can also be triggered at most once per bar.

Example: using the same exit order to scale out a position

When we add this new example to the same NASDAQ-100 CFD chart, the strategy looks like:

Example of scaling out of a MultiCharts strategy with SameExitFromOneEntryOnce

Here we can see that the strategy behaves in the same way as it did with multiple exit orders. The only difference is that each exit order is named “XL” instead of “XL 1” through “XL 5”.

The ‘Total Trades Analysis’ segment of the ‘Strategy Performance Report’ confirms that the strategy’s behaviour hasn’t changed:

Example of our MultiCharts example strategy's performance

So while our example strategy works the same as before, we can do with a lot less code when the SameExitFromOneEntry attribute is set to false.

To learn about other PowerLanguage attributes that can be used in signal scripts, see IntrabarOrderGeneration to generate orders intra-bar and AllowSendOrdersAlways to always send orders regardless of the script’s calculation reason.

Summary

The default behaviour of MultiCharts requires that every exit order that’s applied to the same position is unique. That means we need to code all of those different exits separately. But when the SameExitFromOneEntryOnce attribute is set to false, then a filled exit order can be reapplied to the same position once the script recalculates again. That means the same order can be used to exit repeatedly from the same position. While that doesn’t affect the signal’s behaviour, it does reduce the amount of code that’s needed and that makes the programming more efficient and less error-prone.


References

Henry MultiCharts (2012, October 11). multiple partial exits from same order line ignored – forum discussion. Retrieved on February 16, 2016, from https://www.multicharts.com/discussion/viewtopic.php?f=1&t=11110#p54914

MultiCharts Wiki (2012a, February 19). Cross. Retrieved on February 17, 2016, from https://www.multicharts.com/trading-software/index.php/Cross

MultiCharts Wiki (2012b, February 19). Buy. Retrieved on February 17, 2016, from https://www.multicharts.com/trading-software/index.php/Buy

MultiCharts Wiki (2012c, February 13). CurrentContracts. Retrieved on February 17, 2016, from https://www.multicharts.com/trading-software/index.php/CurrentContracts

MultiCharts Wiki (2012d, February 19). Sell. Retrieved on February 17, 2016, from https://www.multicharts.com/trading-software/index.php/Sell

MultiCharts Wiki (2013, June 7). SameExitFromOneEntryOnce. Retrieved on February 10, 2016, from https://www.multicharts.com/trading-software/index.php/SameExitFromOneEntryOnce

MultiCharts Wiki (2014a, January 23). RecoverDrawings. Retrieved on February 8, 2016, from http://www.multicharts.com/trading-software/index.php/RecoverDrawings

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