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.
A few key points:
* Via the SetProfitTarget(), SetStopLoss() and SetTrailStop() methods
Order Submission for Entry and Exit Methods - Basic Operation
You can submit and manage orders in one of two ways:
The first and most common approach is the quickest and easiest approach and is suitable for programmers of all levels. The second approach, what we call live until cancelled, is reserved for experienced programmers only.
The Common Approach
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()
|
The Advanced Approach
The advanced approach providers a more granular approach to order submission and management which can be useful if you decide to distribute your strategy logic outside of the traditional OnBarUpdate() approach to other strategy event driven methods such as OnOrderUpdate() and OnMarketData() just to name a few. After reviewing this overview section on Order Methods please review the Advanced Order Handling section for further information on the advanced approach to order submission.
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:
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");
to the Strategies tab of the Control Center window.
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 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 2
|
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()
|
Quantity Type and TIF
You can also set the entry order quantity and order type which is generally set via the UI at run time.
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 canceled.
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. 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()
|
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 2
// Closes the position created by entry condition 1
// Closes the position created by entry condition 2
|
Interal 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 and then your strategy issued a market order to close the position. This is dangerous since it could result in both orders getting filled and instead of having a flat position you are now short! To prevent these types of situations, there are some "under the hood" rules that a NinjaScript strategy follows when order methods are called.
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 excluding market orders:
Methods that generate orders (excluding market orders) to enter a position will be ignored if:
Methods that generate orders to exit a position will be ignored if a strategy position is open and:
Set() methods that generate orders to exit a position will be ignored if a strategy position is open and: