NinjaScript > Language Reference > Strategy > Order Methods >

Managed Approach

Print this Topic Previous pageReturn to chapter overviewNext page

The Managed approach in NinjaScript is the most commonly used approach because of the ease-of-use it has to offer. The order methods are wrapped with an invisible convenience layer that allows you to focus on your system's trading rules leaving the underlying mechanics of order management and the relationships between entry and exit orders and positions to NinjaTrader. This will become more evident as you review this section.

 

What makes this approach so universal for all levels of programmers is the flexibility in being able to scale its use for ease or for control. As such, this approach is best suited for simple to moderate order complexity strategies and can be further broken down into a Basic/Common approach and a more Advanced one. The following section will discuss the use of the Basic/Common approach.

 

 

A few key points:

 

Orders are submitted as live working orders when a strategy is running in real-time
*Profit targets, stop loss and trail stop orders are submitted immediately as entry orders are filled and are also OCO tied
Order changes and cancellations are queued in the event that the order is in a state where it can't be cancelled or modified
By default, orders submitted via Entry() and Exit() methods automatically cancel at the end of a bar if not re-submitted

 

* Via the SetProfitTarget(), SetStopLoss() and SetTrailStop() methods

 

tog_minusOrder Submission for Entry and Exit Methods - Basic Operation

Orders are primarily submitted from within the OnBarUpdate() method when a specific order method is called. By default, orders are kept alive provided that they are re-submitted on each call of the OnBarUpdate() method. If the order is not re-submitted, the order is then cancelled. If the order is re-submitted with changed parameters (new limit price for example) the order is modified.

 

In the example below, a buy limit order to enter a long position is working at the bid price provided that the close price of the current bar is greater than the current value of the 20 period simple moving average. If the entry condition is no longer true and the order is still active it will be immediately cancelled.

 

protected override void OnBarUpdate()
{
    // Entry condition
    if (Close[0] > SMA(20)[0])
         EnterLongLimit(GetCurrentBid());
}

 

This technique allows you the quickest and easiest order submission method suitable for programmers of all levels. Should you want to submit an order and not have to keep re-submitting it to keep it alive you can use an advanced approach reserved for experienced programmers called "live until cancelled".

tog_minusEntry Methods

Entry Methods
Entry methods are used to submit orders that create a market position if none exists or to reverse an existing position. An example of an entry method that submitted a buy market order would look like the following:

 

 EnterLong();

 

 

Signal Names on Entry Methods

You can optionally tag an entry order with a signal name. Signal names are used to identify executions resulting from the order on a chart and in performance reports. Market positions created from a tagged entry method are marked with the signal name which serves two purposes:

 

Used to tie an exit method to a specific position
Used to identify unique entries in a strategy

 

An example of an entry method that submitted a sell short market order with a tagged signal name would look like the following:

 

 EnterShort("My Signal Name");

 

 

Defining how Entry Methods are Processed in a Strategy

You can limit how many entry methods are processed by determining the maximum number of entries in a single direction across all entry methods, or across unique entry methods, defined by providing signal names. The following properties can be set in the Strategy Dialog window when adding a strategy to a chart or to the Strategies tab of the Control Center window.

 

EntriesPerDirection property - Sets the maximum number of entries in a single direction
EntryHandling property - Limits EntriesPerDirection property across all entries on per unique entries (tagged with a signal name)

 

To illustrate how the above properties control the processing of entry methods let's look at the example code below. The code contains two entry conditions and two EnterLong methods each tagged with unique signal names.

 

protected override void OnBarUpdate()
{
    // Entry condition 1
    if (CrossAbove(SMA(10), SMA(20), 1))
         EnterLong("Condition 1 Entry");

 

    // Entry condition 2
    if (CrossAbove(RSI(14, 3), 30, 1))
         EnterLong("Condition 2 Entry");
}

 

If you wanted your strategy to enter only once per direction on either condition 1 or condition 2, whichever condition evaluated to true first, you would set the EntriesPerDirection to a value of "1" and the EntryHandling to a value "AllEntries".

 

If you wanted your strategy to enter only once per direction for both conditions, you would set EntriesPerDirection to a value of "1" and the EntryHandling to the value "UniqueEntries". This is possible since the entry methods have been tagged with unique signal names.

 

 

Entry Methods on Multi-Instrument Strategies
When running strategies that submit orders to multiple instruments, entry methods will submit orders to the instrument referenced by the BarsInProgress. The following example assumes that the strategy is running on a 1 minute ES chart. It adds an ER2 data series and enters a position on both the ES and ER2.

 

protected override void Initialize()
{
    Add("ER2 12-06", PeriodType.Minute, 1);
}
 
protected override void OnBarUpdate()
{
    if (BarsInProgress == 0)
         EnterLong("ES Trade");
    else if (BarsInProgress == 1)
         EnterLong("ER2 Trade");
}

tog_minusQuantity Type and TIF

You can also set the entry order quantity and order type which is generally set via the UI at run time.

QuantityType property - Sets if the order quantity is taken from the entry method quantity property or the default strategy quantity size
TimeInForce propery - Sets the time in force of the order
tog_minusHow to close a position

Closing a Position using a Stop Loss, Trailing Stop and/or Profit Target

You can predefine a stop loss, trailing stop and/or profit target in a strategy by calling the SetStopLoss(), SetTrailStop() or SetProfitTarget() methods from inside the Initialize() method. When these methods are called, they submit live working orders in real-time operation as executions are reported as a result of calling an entry method. Stop and target orders are submitted to the market as soon as fills come in from an entry order. Trailing stop orders are modified in real-time and NOT on the close of a bar. A stop and target order are also tied via OCO (one cancels the other) so if one is filled, the other is automatically cancelled.

 

Stops and targets are generated either per fill or per position. This is determined by the "Stop & target submission" property which is set running a strategy live via the UI. For backtesting, this is irrelevant since there are no partial fills in a backtest. Property values are:

 

ByStrategyPosition - When this is selected, only one stop loss, trail stop and/or profit target order is submitted. As entry executions come in, the order size is amended. The downside of this approach is that if you have partial fills, the orders are re-inserted into the exchange order queue. The upside is that if you broker charges you a per order commission (not per lot), you will not incur additional commission expenses.

 

PerEntryExecution - When this is selected, a stop loss, trail stop and/or profit target order is submitted for each partial fill received. The downside is if your broker charges commission per order, you can incur very expensive commission costs if you receive partial fills. The upside is that orders are submitted as soon as possible giving you the advantage of getting into the order queue immediately.

 

 

Closing a Position using an Exit Method

Exit methods submit orders to close out a position in whole or in part. An example of an exit method that submitted a sell market order to close the entire strategy position would look like the following:

 

 ExitLong();

 

 

Closing a Partial Position using an Exit Method

You can close out a partial position by specifying the exit quantity. The following example goes long 3 contracts. Each subsequent bar update will submit a market order to exit one contract until the position is completely closed. ExitLong(1) will be ignored if a long market position does not exist.

 

protected override void OnBarUpdate()
{
    if (CrossAbove(SMA(10), SMA(20), 1))
         EnterLong(3);
 
    ExitLong(1);
}

 

 

Tying an Exit to an Entry: How to Close a Position Tagged with a Signal Name

Identifying entries with a signal name allows you to have multiple unique entries within a single strategy and call exit methods with specified signal names so that only a position created with the tagged signal name is closed. In the example below, there are two entry conditions which create positions. There are two exit conditions that specify which position to close based on the signal name.

 

protected override void OnBarUpdate()
{
    // Entry condition 1
    if (CrossAbove(SMA(10), SMA(20), 1))
         EnterLong("Condition 1 Entry");

 

    // Entry condition 2
    if (CrossAbove(RSI(14, 3), 30, 1))
         EnterLong("Condition 2 Entry");

 

    // Closes the position created by entry condition 1
    if (CrossBelow(SMA(10), SMA(20), 1)
         ExitLong("Condition 1 Entry");

 

    // Closes the position created by entry condition 2
    if (CrossBelow(RSI(14, 3), 70, 1))
         ExitLong("Condition 2 Entry");
}

tog_minusInternal Order Handling Rules that Reduce Unwanted Positions

NinjaTrader is a real-time live trading platform and thus we need to ensure that we prevent situations in real-time where you may have multiple orders working accomplishing the same task. An example of this would be if your strategy had a target limit order for 1 contract working, but then your strategy was also programmed to reverse the position at the price very close to the target limit order. Submitting both orders is dangerous since it could lead to a larger position than the strategy is designed to enter if both orders got filled in quick succession by the exchange! To prevent these types of situations, there are some "under the hood" rules that a NinjaScript strategy follows when order methods are called.

 

Note: These rules do not apply to market orders like ExitLong() or ExitShort(). 

 

For the most part, you do not need to be intimately familiar with these rules as you develop your strategies, its all taken care of for you internal within a strategy. If a rule is violated, you will be notified through an error log in the Control Center log tab when running a strategy in real-time or in a backtest.

 

The following rules are true per unique signal name:

 

 

Methods that generate orders to enter a position will be ignored if:

A position is open and an order submitted by an exit method (ExitLongLimit() for example) is active and the order is used to open a position in the opposite direction
A position is open and an order submitted by a set method (SetStopLoss() for example) is active and the order is used to open a position in the opposite direction
The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active and the order is used to open a position in the opposite direction
The entry signal name is not unique

 

Methods that generate orders to exit a position will be ignored if:

A position is open and an order submitted by an enter method (EnterLongLimit() for example) is active and the order is used to open a position in the opposite direction
A position is open and an order submitted by a set method (SetStopLoss() for example) is active

 

Set() methods that generate orders to exit a position will be ignored if:

A position is open and an order submitted by an enter method (EnterLongLimit() for example) is active and the order is used to open a position in the opposite direction
A position is open and an order submitted by an exit method (ExitLongLimit() for example) is active