Whenever I want to use EnterLongLimit instead I call WantEnterLongLimit:
private void WantEnterLongLimit(double price) { Print(string.Format(" WantEnterLongLimit({0})", price)); if (ordEntShortLimit != null && Order.IsTerminalState(ordEntShortLimit.OrderState)) { ordEntShortLimit=null; Print(" Nulled terminal state ordEntShortLimit"); } if (ordEntShortLimit != null) {//there is an active EnterShortLimit order that needs dealing with first if (!ordEntShortLimit.IsLiveUntilCancelled) { Print(" active EnterShortLimit is due to expire, so cancelling it before placing contrary order"); ordReq = new OrderReq(true, price); CancelOrder(ordEntShortLimit); } else {//opposite direction order is not due to expire. Log violation of rule 3 string serr = "rule 3 violation: Attempt to EnterLongLimit ignored due to internal unfilled EnterShortlimit which is not due to expire (due to use of IsLiveUntilCancelled)"; Print(serr); Log(serr, LogLevel.Error); } } else {//no active EnterShortLimit order, assume that 'Managed Orders' can cope ordEntLongLimit=null; //ordEntLongLimit = EnterLongLimit(DefaultQuantity, price);//there is no point trying to get the ordEntLongLimit since NT does not seem to set the return value until after its OnOrderUpdate events have finished! EnterLongLimit(DefaultQuantity, price);//so we have to match on order Name (assume the default here is reliable as 'Buy') } }
protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string comment) { Print(" OnOrderUpdate()"); if (order.Name=="Sell short" && ordEntShortLimit==null) ordEntShortLimit=order;//Name matching required since NT does not reliably set the return value of EnterShortLimit(...) if (order == ordEntShortLimit) { if (orderState==OrderState.Cancelled) { Print(" EnterShortLimit order cancelled."); if (ordReq==null) return;//no opposite order requested if (ordReq.WantLong) { Print(string.Format(" allowing EnterLongLimit({0}) to be placed.",ordReq.Price)); ordEntLongLimit = EnterLongLimit(DefaultQuantity, ordReq.Price); ordReq=null; } ordEntShortLimit=null; if (ordEntShortLimit!=null) Print(" cant null ordEntShortLimit!"); return; } else {//not cancelled, perhaps 'Managed orders' has detected that the previous EnterShortLimit was not filled, and needs to have its price changed Print(string.Format(" ordEntShortLimit time={0}, limit price={1}, OrderState={2}", ordEntShortLimit.Time, ordEntShortLimit.LimitPrice, ordEntShortLimit.OrderState)); return; } } ...
Running the strategy (say on Forex instrument 1min TF) shows that reverse direction unfilled limit orders are being successfully placed on alternate bars, with no errors.
I would expect the SubmitOrderManaged() to be able to do this automatically.
Leave a comment: