View Full Version : Strategy Analyzer basic question "An Enter() method .... has been ignored"
04-19-2010, 06:57 AM
This could easily be the stupid user not scripting his strategy properly.
I keep getting a single warning message in the Output window with each backtest:
"**NT** An Enter() method to submit an entry order at '22/01/2001 21:00:00' has been ignored. Please search on the term 'Internal Order Handling Rules' in the Help Guide for detailed explanation."
I'm using 60 mins bars and my strategy is simple:
goLong = false;
goShort = false;
if (SMA(longLen) > SMA(longLen))
goLong = true;
if (SMA(shortLen) < SMA(shortLen))
goShort = true;
if (Position.MarketPosition == MarketPosition.Flat)
if (goLong && !goShort)
EnterLongLimit(Close - longRange, "Go Long");
if (goShort && !goLong)
EnterShortLimit(Close + shortRange, "Go Short");
trailStop = 0;
I see from the Strategy Analyzer Orders tab that there are in fact no open orders at 21:00:00 on 2001-01-22.
Can you tell me what NT is complaining about?
04-19-2010, 08:22 AM
Thank you for your post.
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
A position is open and an order submitted by a set method (SetStopLoss() for example) is active
The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active
The entry signal name is not unique
I have also provided a link below to our Help Guide that goes over internal Order Handling Rules.
Please let me know if I may be of further assistance.
04-19-2010, 11:01 AM
I did actually read that before posting, but unfortunately the explanation is not obvious enough for me because I still don't understand which of those rules I have violated.
You can see from my code that I make position opening orders when the position is flat. So my problem cannot be item 1 or 2. It cannot be 4 either since I don't give names.
That means it must be item #3 but as I stated earlier, the Strategy Analyzer does not show any active entry orders. So how can it be?
04-19-2010, 01:53 PM
Strategy Analyzer will show you analysis after the fact. What you should try is turning on TraceOrders = true to see where exactly you had the active order. Print() methods in OnOrderUpdate() will also help you figure out your current active orders at the time of submission of the opposite direction entry order.
04-19-2010, 04:52 PM
by the way the dates are British format
05/01/2001 15:00:00 Entered internal PlaceOrder() method at 05/01/2001 15:00:00: Action=Buy OrderType=Limit Quantity=1 LimitPrice=0.9471 StopPrice=0 SignalName='Go Long' FromEntrySignal=''
05/01/2001 16:00:00 Entered internal PlaceOrder() method at 05/01/2001 16:00:00: Action=SellShort OrderType=Limit Quantity=1 LimitPrice=0.9557'5 StopPrice=0 SignalName='Go Short' FromEntrySignal=''
05/01/2001 16:00:00 Ignored PlaceOrder() method at 05/01/2001 16:00:00: Action=SellShort OrderType=Limit Quantity=1 LimitPrice=0.9557'5 StopPrice=0 SignalName=Go Short' FromEntrySignal='' Reason='An Enter() method to submit an entry order has been ignore. Please search on the term 'Internal Order Handling Rules' in the Help Guide for detailed explanation.'
**NT** An Enter() method to submit an entry order at '05/01/2001 16:00:00' has been ignored. Please search on the term 'Internal Order Handling Rules' in the Help Guide for detailed explanation.
05/01/2001 16:00:00 Cancelled expired order: BarsInProgress=0: Order='NT-00023/Backtest' Name='Go Long' State=Working Instrument='$EURUSD' Action=Buy Limit price=0.9471 Stop price=0 Quantity=1 Strategy='TrendFollower002' Type=Limit Tif=Gtc Oco='' Filled=0 Fill price=0 Token='2afb389313ec4257a107a676c1a46211' Gtd='01/12/2099 00:00:00'
I can't see anything this trace that is wrong - apart from the fact that NT is ignoring it. Or could it be because the order from 05/01/2001 15:00:00 is cancelled after the orders are submitted?
04-20-2010, 08:19 AM
The is due to the "Go Long" signal being active at 15:00:00 therefore ignoring the "Go Short" signal generated at 16:00:00.
04-20-2010, 09:11 AM
The exact rule in violation is #3.
"The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active"
The current active order is EnterLongLimit() from your "Go long". You then submit a EnterShortLimit() when the long one was already active so that is why you run into the ignored order. Should you want to go EnterShortLimit() at this point in time you would need to first cancel or wait for EnterLongLimit() to expire.
04-20-2010, 10:31 AM
I misunderstood the order handling mechanism. I thought that the orders would all expire at the end of the bar.
Is there a way to configure that with ATM?
I found the IOrder and OrderState objects - if I want to call CancelOrder, what OrderState is it best to check for? I could check for Filled but it might be only partially filled. I could check for OrderState.working or OrderState.accepted - or should I just call CancelOrder() anyway - will that have a disruptive effect if the order was filled?
04-20-2010, 10:41 AM
If you want to call ATM strategies from a NinjaScript strategy that would be a whole different discussion. You can see an example of this in the preinstalled SampleAtmStrategy.
For CancelOrder() you can call it whenever you want. There is no need to necessarily tie it to a specific OrderState. What should be done though is to ensure that the OrderState is .Cancelled before submitting your next order though. This ensures that the order is properly cancelled first so you won't run into the internal order handling rules. If you had partial fills it would be a state of PartFilled instead of Filled so you will be able to differentiate between the two.
04-21-2010, 03:36 AM
thanks for the run-down.
I'm afraid I still don't get it, not completely.
I'm getting this slightly different trace in the output window:
16/01/2009 15:00:00 Entered internal PlaceOrder() method at 16/01/2009 15:00:00: Action=SellShort OrderType=Limit Quantity=0.1M LimitPrice=1.3335 StopPrice=0 SignalName='Go Short' FromEntrySignal=''
16/01/2009 16:00:00 Entered internal PlaceOrder() method at 16/01/2009 16:00:00: Action=Buy OrderType=Limit Quantity=0.1M LimitPrice=1.3236 StopPrice=0 SignalName='Go Long' FromEntrySignal=''
16/01/2009 16:00:00 Ignored PlaceOrder() method at 16/01/2009 16:00:00: Action=Buy OrderType=Limit Quantity=0.1M LimitPrice=1.3236 StopPrice=0 SignalName=Go Long' FromEntrySignal='' Reason='An Enter() method to submit an entry order has been ignore. Please search on the term 'Internal Order Handling Rules' in the Help Guide for detailed explanation.'
**NT** An Enter() method to submit an entry order at '16/01/2009 16:00:00' has been ignored. Please search on the term 'Internal Order Handling Rules' in the Help Guide for detailed explanation.
This is the relevant part of my Strategy, which looks to me as if it's got the situation under control:
// cancel existing orders
if (longEntry != null) CancelOrder(longEntry);
if (shortEntry != null) CancelOrder(shortEntry);
if (stopOrder != null) CancelOrder(stopOrder);
// Set entry orders if flat
if (Position.MarketPosition == MarketPosition.Flat)
if (goLong && !goShort)
longEntry = EnterLongLimit(Close - longRange, "Go Long");
if (goShort && !goLong)
shortEntry = EnterShortLimit(Close + shortRange, "Go Short");
trailStop = 0;
As far as I can tell, I've cancelled the order that the trace is complaining about. This is the only place where I create orders, so it's got to be cancelled, hasn't it?
If I follow your suggestion and check to see whether the old orderStatus is cancelled before placing the order, what do I do then? Cancel it again? Wait? (is that possible?)
04-21-2010, 08:52 AM
Just because you send a CancelOrder() does not mean the order has been cancelled yet. You have to wait for the order to have an OrderState of Cancelled before it is truly cancelled and only then can you submit your next order. What you should probably do is go into OnOrderUpdate() and set a bool variable to true when the order finishes cancelling. In your trade condition only allow for trades to be placed when that bool is true. Of course you would also need to then set the bool to false again so you can reuse the bool.
04-21-2010, 10:19 AM
thanks for that. Is there documentation for all these events and when they fire?
I follow your suggestion only half - if I flag up a bool to show cancellation completion, I need to fire the event to place the orders again.
What this means is that I need to cancel all my orders at the end of the bar, so that the OnBarUpdate() code will place new orders. Which event would be best for that?
04-21-2010, 10:48 AM
Please see here for the events: http://www.ninjatrader-support.com/HelpGuideV6/helpguide.html?Overview51
What you can do is this.
1. Wait for your trade signal in OnBarUpdate()
2. When your trade signal is true, check if you currently have an active order.
3. If an active order exists, CancelOrder() it and also set a bool to place a trade to be true.
4. In OnOrderUpdate() the order you just called CancelOrder() on will push events here so you wait for the Cancelled OrderState. When the OrderState is given and the bool to trade is true, place in your Enter() with liveUntilCancelled = true overload method.
5. In OnOrderUpdate() when this new entry order goes into an accepted/working state go ahead and reset the bool to false.
If all of this is too complicated you can also just try to submit the order in OnBarUpdate(). Call your CancelOrder(). And then run checks in OnBarUpdate() for the IOrder to be in a Cancelled state. When such is true then you can submit your new Enter trade.
Untested code to give you some ideas. This would only work if your trade conditions persist to be true the whole time. Otherwise you will need to use some bools to track the state.
if (some trade conditions)
if (someIOrder != null && someIOrder.OrderState == OrderState.Cancelled)
04-21-2010, 12:14 PM
that gives me a bit of thinking to do!
I think I want to try to keep the calculations for limit and stop prices in one place, so I might have to put those in variables too.
Thanks for the advice.
04-22-2010, 06:29 AM
I think I've got a handle on it now, but I just wanted to verify the OrderStates with you to check I'm not inadvertantly making mistakes here. I need to know which OrderStates require cancelling, and which do not, when I come to enter the next order. So far I have worked it out like this:
Order shd be cancelled:
And these states mean the order can be overwritten:
And this means I just have to wait:
I also notice that OrderStatus.Initialize isn't in the docs for NT7 - is that an oversight or has it been obsoleted? It's on the object in the compiler.
Thanks in advance
04-22-2010, 08:44 AM
Only the states documented are relevant. Extraneous ones that may show up in the Intellisense should not be used.
You can cancel on any state that is not a terminal state. A terminal state would be Cancelled, Rejected, Filled. When in a terminal state there is no further action that can be taken. Any other state means the order is still doing something and you can send a cancel on it.
PendingCancel means it is in the process of cancelling so generally would not require you to send another cancel.
04-22-2010, 09:57 AM
Great. Looks like I have sorted the order handling now. I guess I'll need to check it carefully when I move from backtesting to the simulated trading, but it looks like I've nailed it down and have a robust strategy, which is good.
Thanks for your help.