Managed Approach
<< Click to Display Table of Contents >> Managed Approach |
The Managed approach in NinjaScript is designed to offer the greatest ease of use for beginner to intermediate programmers. The order methods are wrapped in a 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 orders, exit orders, and positions to NinjaTrader. This approach is best suited for simple to moderate order complexity, and can be further broken down into a Basic/Common Managed approach and a more Advanced Managed approach. The following section will discuss the use of the Basic/Common approach.
A few key points to keep in mind:
•Orders are submitted as live and working when a strategy is running in real-time
•Profit target, stop loss and trail stop orders are submitted immediately when an entry order is filled, and are tied together via OCO (One Cancels Other)
•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
•Entry() methods will reverse the position automatically. For example if you are in a 1 contract long position and now call EnterShort() -> you will see 2 executions, one to close the prior long position and the other to get you into the desired 1 contract short position.
* Via the SetProfitTarget(), SetStopLoss(), SetTrailStop() and SetParabolicStop methods
Order 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 they are re-submitted on each call of the OnBarUpdate() method. If an order is not re-submitted, it is then canceled. Orders can be modified by re-submitting them with changed parameters (a new limit price, for example).
In the example below, a Buy Limit order 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 canceled.
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, which includes an option to keep orders alive until specifically canceled in code. |
Order Entry Methods
|
protected override void OnBarUpdate() |
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 signal names. The following properties can be set in the Strategies 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 - Determines if EntriesPerDirection applies across all entries or for entries with specified signal names
The example code below illustrates how the above properties control the processing of entry methods. The code contains two entry conditions and two EnterLong methods, each tagged with unique signal names.
protected override void OnStateChange() |
protected override void OnStateChange() |
More information on using BarsInProgress to filter instruments can be found in the Advanced Order Handling page.
You can set the entry order quantity and order type directly in code via the following properties: •QuantityType - Sets 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 |
Closing a Position using a Stop Loss, Trailing Stop and/or Profit TargetYou can predefine a stop loss, trailing stop and/or profit target in a strategy by calling the SetStopLoss(), SetTrailStop(), SetParabolicStop() or SetProfitTarget() methods from inside the OnStateChange() event handler. When these methods are called, they submit live working orders in real-time as executions are reported as a result of calling an entry method. These orders are also tied via OCO (One Cancels Other).
Stop losses and profit target can be generated for each fill or each position. This is determined by the "Stop & target submission" property which is set in the Strategies window. Possible values are listed below:
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 receive partial fills, the orders are re-inserted into the exchange order queue. The upside is that if you broker charges you commission per order (not per quantity), 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 that 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 MethodExit methods submit orders to close out a position in whole or in part. When closing a position with Exit orders, the order quantity will be reduced as the strategy position reduces - for example, if we use ExitLongStopMarket() and ExitLongStopLimit() to protect a position and one of those orders gets filled, the other order associated with exiting that position will reduce their quantity.
As with entry methods, more information about specific exit methods can be found in this Help Guide's table of contents, beneath this page.
Closing a Partial Position using an Exit MethodYou can close out a partial position by specifying the exit quantity. The following example first enters long for three contracts. Then, each subsequent bar update submits 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.
FromEntrySignal -- Using Signal Names in Exit MethodsIdentifying entries with a signal name allows you to place multiple unique entries within a single strategy and call exit methods with specified signal names, so that only a position created with the specified signal name is closed. In the example below, there are two entry conditions which create positions, and two exit conditions specifying which position to close based on the signal name.
|
Understanding core order objects
When using order methods such as EnterLong(), ExitShortLimit(), etc, a direct order object is returned for the NinjaTrader Core. These objects can be used throughout the lifetime of your strategy to provide additional metadata concerning your strategy, as well as apply advanced concepts such as CancelOrder() and ChangeOrder(). More information about this advanced concept which is discussed under the Advanced Order Handling section |
Internal Order Handling Rules that Reduce Unwanted Positions
To prevent situations in real-time in which you may have multiple orders working to accomplish the same task, there are some "under the hood" rules that a NinjaScript strategy follows when Managed order methods are called. For example, if your strategy had a limit order for 1 contract working as a Profit Target, but then your strategy was also programmed to reverse the position at the price very close to the target limit order, then submitting both orders can be risky, 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.
For the most part, you do not need to be intimately familiar with these rules as you develop your strategies. It is all taken care of for you internally within a strategy. If a rule is violated, you will be notified through an error log in the Control Center Log tab.
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 a non market order 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 •A position is open and two or more Entry methods to reverse the position are entered together. In this case the second Entry order will be ignored. •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 a non market order exit method (ExitLongLimit() for example) is active |
Through advanced order handling you can submit, change and cancel orders at your discretion through any event-driven method within a strategy. |
|
Cancels a specified order. |
|
Amends a specified Order. |
|
Generates a buy market order to enter a long position. |
|
Generates a buy limit order to enter a long position. |
|
Generates a buy MIT order to enter a long position. |
|
Generates a buy stop limit order to enter a long position. |
|
Generates a buy stop market order to enter a long position. |
|
Generates a sell short market order to enter a short position. |
|
Generates a sell short stop limit order to enter a short position. |
|
Generates a sell MIT order to enter a short position. |
|
Generates a sell short stop limit order to enter a short position. |
|
Generates a sell short stop order to enter a short position. |
|
Generates a sell market order to exit a long position. |
|
Generates a sell limit order to exit a long position. |
|
Generates a sell MIT order to exit a long position. |
|
Generates a sell stop limit order to exit a long position. |
|
Generates a sell stop market order to exit a long position. |
|
Generates a buy to cover market order to exit a short position. |
|
Generates a buy to cover limit order to exit a short position. |
|
Generates a buy to cover MIT order to exit a short position. |
|
Generates a buy to cover stop limit order to exit a short position. |
|
Generates a buy to cover stop market order to exit a short position. |
|
Returns a matching real-time order object based on a specified historical order object reference. |
|
Generates a parabolic type trail stop order with the signal name "Parabolic stop" to exit a position. |
|
Generates a profit target order with the signal name "Profit target" to exit a position. |
|
Generates a stop loss order with the signal name "Stop loss" used to exit a position. |
|
Generates a trail stop order with the signal name "Trail stop" to exit a position. |