The IOGMode and CalcAtOpenNextBar attributes influence when a strategy’s orders are send. But can we also influence how many orders are needed for exiting a position?

Reusing an exit order when scaling out with ExitFromOneEntryOnce

C#’s optional class attributes refine a class’ definition and are specialised to address issues of specific programming tasks (Stephens, 2014). In MultiCharts .NET class attributes are used to set certain options.

One such attribute is ExitFromOneEntryOnce that allows for repeatedly using the same order to exit multiple times from one entry (MultiCharts, 2014). This attribute has two options (Henry MultiCharts, 2014a):

  • With StandardCalculation a filled exit order can be generated again and applied to a different entry order, but the exit order cannot be executed again for that same entry. This means an individual exit order is needed for each exit — so with scaling out in five steps we’ll need to code five different exit orders.
  • With FillAndKillExitOrder a filled exit order can be generated again by the script to be executed against the same entry order. This means the same exit order can be applied an unlimited number of times to one entry, and so scaling out in five steps requires just a single, reusable exit order.

There isn’t a manual setting for ExitFromOneEntryOnce and so this attribute can only be defined programmatically.

Setting the ExitFromOneEntryOnce attribute in MultiCharts .NET

To reuse an already executed exit order again for the same entry, set ExitFromOneEntryOnce to FillAndKillExitOrder:

[ExitFromOneEntryOnce(ExitFromOneEntryOnce.FillAndKillExitOrder)]
public class Example_ExitFromOneEntryOnce : SignalObject
{
    // Strategy code
}

And set the attribute to StandardCalculation for exit orders that cannot be reapplied:

[ExitFromOneEntryOnce(ExitFromOneEntryOnce.StandardCalculation)]
public class Example_ExitFromOneEntryOnce : SignalObject
{
    // Strategy code
}

When the attribute isn’t defined, the StandardCalculation behaviour applies. This approach originated from EasyLanguage (see Henry MultiCharts, 2012), the language that formed the basis of MultiCharts PowerLanguage.

MultiCharts .NET trading strategy that scales out of positions

The two examples discussed below (one for each ExitFromOneEntryOnce setting) both generate the exact same orders, like this:

MultiCharts .NET ExitFromOneEntryOnce - example

What makes the examples different is the number of orders needed to scale out of a position.

Example: repeatedly using the same exit order in MultiCharts .NET

The first scaling out example looks as follows:

[ExitFromOneEntryOnce(ExitFromOneEntryOnce.FillAndKillExitOrder)]
public class Example_ExitFromOneEntryOnce : SignalObject
{
    public Example_ExitFromOneEntryOnce(object _ctx) : base(_ctx) { }

    private IOrderMarket buyOrder, sellOrder;

    protected override void Create()
    {
        buyOrder = OrderCreator.MarketNextBar(new
            SOrderParameters(Contracts.UserSpecified, EOrderAction.Buy));

        sellOrder = OrderCreator.MarketNextBar(new
            SOrderParameters(Contracts.UserSpecified, EOrderAction.Sell));
    }

    int counter = 0;

    protected override void CalcBar()
    {
        if (StrategyInfo.MarketPosition == 0)
        {
            buyOrder.Send(6);

            counter = 0;
        }
        else if (counter == 2 || counter == 4 || counter == 6)
        {
            sellOrder.Send(2);
        }

        counter++;
    }
}

We start with setting ExitFromOneEntryOnce to FillAndKillExitOrder so that an exit order can be used repeatedly to close an entry (MultiCharts, 2014). Since that order can be reused, we only need to declare two IOrderMarket orders here: an entry (buyOrder) and exit order (sellOrder).

These orders are subsequently created in the Create() method with OrderCreator.MarketNextBar() and set to buy (EOrderAction.Buy) and sell (EOrderAction.Sell). Their position size is set to Contracts.UserSpecified so that the order size can be specified with the order’s Send() method.

Enter a position and scaling out in MultiCharts .NET

Next an integer variable (counter) is declared and initialised to zero. This variable is used to close parts of the position after a certain amount of bars.

An if/else statement in the CalcBar() method implements the strategy’s logic. Its if part checks if StrategyInfo.MarketPosition equals 0, which it does when the strategy is flat (see MultiCharts, 2014). In that case the buy order’s Send() method is executed with 6 passed in as an argument so that a long position for six contracts (or shares) is opened. The counter variable is then set to 0 so we can begin counting the bars before scaling out.

Closing part of the open position is done in the else if portion where the counter variable is evaluated to see if it equals 2, 4, or 6. When the variable has any of these values, sellOrder is submitted by calling its Send() method with an argument of 2. That way each time this statement executes two contracts of the open position are closed.

To count the bars since opening the position, the final line in CalcBar() increments counter with 1 by using the postfix increment operator (++).

Example: applying multiple exit orders to the same entry in MultiCharts .NET

In the above example we only needed one exit order to scale out when ExitFromOneEntryOnce was set to FillAndKillExitOrder. That’s not the case when this attribute is set to the default StandardCalculation, as the next example shows:

[ExitFromOneEntryOnce(ExitFromOneEntryOnce.StandardCalculation)]
public class Example_ExitFromOneEntryOnce : SignalObject
{
    public Example_ExitFromOneEntryOnce(object _ctx) : base(_ctx) { }

    private IOrderMarket buyOrder, sellOrder1, sellOrder2, sellOrder3;

    protected override void Create()
    {
        buyOrder = OrderCreator.MarketNextBar(new 
            SOrderParameters(Contracts.UserSpecified, EOrderAction.Buy));

        sellOrder1 = OrderCreator.MarketNextBar(new 
            SOrderParameters(Contracts.UserSpecified, EOrderAction.Sell));

        sellOrder2 = OrderCreator.MarketNextBar(new
            SOrderParameters(Contracts.UserSpecified, EOrderAction.Sell));

        sellOrder3 = OrderCreator.MarketNextBar(new
            SOrderParameters(Contracts.UserSpecified, EOrderAction.Sell));
    }

    int counter = 0;

    protected override void CalcBar()
    {
        if (StrategyInfo.MarketPosition == 0)
        {
            buyOrder.Send(6);

            counter = 0;
        }
        else
        {
            if (counter == 2)
                sellOrder1.Send(2);
            else if (counter == 4)
                sellOrder2.Send(2);
            else if (counter == 6)
                sellOrder3.Send(2);
        }

        counter++;
    }
}

While this example is similar to the previous, there are some differences because with StandardCalculation we cannot reuse an exit order if that order has already been executed for that position (Henry MultiCharts, 2014a). That’s why we create multiple IOrderMarket sell orders here (sellOrder1, sellOrder2, and sellOrder3).

Another difference is in the CalcBar() method’s if/else statement, where all three different exit orders are submitted only once to exit a part of the open position. For this we use a cascaded if/else statement that evaluates the counter variable and calls an order’s Send() method when this variable either equals 2, 4, or 6.

Tip: When you change code, like an attribute, with the script already applied to a chart, the effect of the modified code won’t be visible. Instead, the script first needs to be removed and re-added (see Henry MultiCharts, 2014b).

Another way to work with exits is to have an exit apply to a specific entry order by using OrderExit.FromEntry() when creating the order in the Create() method (MultiCharts, 2014). Other attributes that influence a trading strategy’s orders are CalcAtOpenNextBar for submitting orders a bar earlier, IOGMode for generating orders intra-bar, and AllowSendOrdersAlways to generate orders regardless of a script’s bar status.

Summary

The ExitFromOneEntryOnce attribute can be set to two values. With StandardCalculation an exit order can be applied to an entry only once, meaning that multiple exit orders are needed for scaling out of a position. Alternatively, with FillAndKillExitOrder an exit order can be executed an unlimited number of times against the same entry order, which removes the need to create a bunch of exit orders.


References

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

Henry MultiCharts (2014a, December 24). Close partial postions – forum discussion. Retrieved on February 3, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=19&t=47785&view=unread#p111812

Henry MultiCharts (2014b, December 11). MultiCharts .NET FAQ – forum discussion. Retrieved on January 25, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=19&t=45848#p111375

MultiCharts (2014). MultiCharts .NET Programming Guide (version 1.1). Retrieved from http://www.multicharts.com/downloads/MultiCharts.NET-ProgrammingGuide-v1.1.pdf

Stephens, R. (2014). C# 5.0 Programmer Reference. Indianapolis, IN: John Wiley & Sons.