• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

request for more user-friendly managed limit orders

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    request for more user-friendly managed limit orders

    Here are the current rules affecting EnterLongLimit or EnterShortLimit
    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
    I think the third rule highlighted is not quite correct. I think the part in bold below should be added.
    Suggested new version of rule:
    The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active and not due to expire, and the order is used to open a position in the opposite direction.
    Reason:
    The current rule has been implemented so that if there is
    Use of EnterLongLimit(...) on bar x (not filled), followed by use of EnterShortLimit(...) on bar x+1
    (or vice versa) then the second order is ignored (and should log an error).

    However assuming the entry order on bar x did not use the 'advanced' isLiveUntilCancelled=true signature, the limit placed on bar x (and not filled) will be due to expire at bar x+1.
    With the new version of the rule in place the implementation needs to change so that if the opposing direction limit order is due to expire now (bar x+1) then it should be cancelled before the new order is processed (currently the cancellation is being processed afterwards, so is still 'active' at point of request for new order, even though it is due for expiry, hence the rule violation).
    See this thread for an examples of the problems and misunderstandings caused by the current implementation of the existing rule.

    #2
    Hello DaveE,

    Thank you for your post.

    I will forward your suggestion to Development.

    To note, the reason the second entry order fails is that the first has yet to truly expire. The first order would only know to expire when the new tick of the next bar occurs in realtime or when that next bar closes in historical data (if you are backtesting for example).
    Patrick H.NinjaTrader Customer Service

    Comment


      #3
      I am using the word 'expire' in a logical sense, you seem to be using it as synonymous with 'cancelled'.
      I think its necessary to make a distinction:
      Assuming we are talking about a strategy using Calculate.OnBarClose then each OnBarUpdate is really the start of a new bar but given the Time of the end of the old bar. Its probably simpler just to talk about a sequence of OnBarUpdate.

      Currently (lets say we are realtime with a 60 minute TF):

      OnBarUpdate CurrentBar=0
      EnterLongLimit(...);//logically due to expire in 60 minutes
      //...but does not fill in the next 60 minutes

      OnBarUpdate CurrentBar=1

      //logically the long limit order is due to expire, but its actually active.
      if (Position.MarketPosition==MarketPosition.Flat) EnterShortLimit(...);/*this causes error because the current implementation does not realise that it would be logically valid to cancel the 'logically expired but still active' Long limit before processing the EnterShortLimit request.
      I assume that SubmitOrderManaged() looks to see if there is an active limit in the opposite direction (but does not check whether its due for expiry)
      I assume that milliseconds after NT has finished processing OnBarUpdate it calls some internal process called something like CancelExpiredLimits() where the 'logically expired but still active' Long limit does get cancelled, but milliseconds too late for the EnterShortLimit to be allowed by the current rule.*/


      How it would work with my revision:
      ...
      OnBarUpdate CurrentBar=1

      //logically the long limit order is due to expire, but its actually active.
      if (Position.MarketPosition==MarketPosition.Flat) EnterShortLimit(...);
      /
      *SubmitOrderManaged() will look to see if there is an active limit in the opposite direction.

      If active limit in opposite direction found then:
      if ('due for expiry')
      {
      then cancel it before processing EnterShortLimit.
      //this will result in the user's valid request for a limit in reverse direction to be processed
      }
      else
      {
      log the error "The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active and not due to expire, and the order is used to open a position in the opposite direction."
      Ignore the EnterShortLimit request.
      }*/
      after processing OnBarUpdate NT will call CancelExpiredLimits() but in this particular scenario it will not have anything left to do.


      Comment


        #4
        Originally posted by DaveE View Post
        I am using the word 'expire' in a logical sense, you seem to be using it as synonymous with 'cancelled'.
        I think its necessary to make a distinction:
        Assuming we are talking about a strategy using Calculate.OnBarClose then each OnBarUpdate is really the start of a new bar but given the Time of the end of the old bar. Its probably simpler just to talk about a sequence of OnBarUpdate.

        Currently (lets say we are realtime with a 60 minute TF):

        OnBarUpdate CurrentBar=0
        EnterLongLimit(...);//logically due to expire in 60 minutes
        //...but does not fill in the next 60 minutes

        OnBarUpdate CurrentBar=1

        //logically the long limit order is due to expire, but its actually active.
        if (Position.MarketPosition==MarketPosition.Flat) EnterShortLimit(...);/*this causes error because the current implementation does not realise that it would be logically valid to cancel the 'logically expired but still active' Long limit before processing the EnterShortLimit request.
        I assume that SubmitOrderManaged() looks to see if there is an active limit in the opposite direction (but does not check whether its due for expiry)
        I assume that milliseconds after NT has finished processing OnBarUpdate it calls some internal process called something like CancelExpiredLimits() where the 'logically expired but still active' Long limit does get cancelled, but milliseconds too late for the EnterShortLimit to be allowed by the current rule.*/


        How it would work with my revision:
        ...
        OnBarUpdate CurrentBar=1

        //logically the long limit order is due to expire, but its actually active.
        if (Position.MarketPosition==MarketPosition.Flat) EnterShortLimit(...);
        /
        *SubmitOrderManaged() will look to see if there is an active limit in the opposite direction.

        If active limit in opposite direction found then:
        if ('due for expiry')
        {
        then cancel it before processing EnterShortLimit.
        //this will result in the user's valid request for a limit in reverse direction to be processed
        }
        else
        {
        log the error "The strategy position is flat and an order submitted by an enter method (EnterLongLimit() for example) is active and not due to expire, and the order is used to open a position in the opposite direction."
        Ignore the EnterShortLimit request.
        }*/
        after processing OnBarUpdate NT will call CancelExpiredLimits() but in this particular scenario it will not have anything left to do.


        Very well explained, and very useful, but I am afraid that they are just going to tell you that for this kind of nitty-gritty logic, you will have to use the "Unmanaged" approach. That is pretty much the answer that is always given when any shortcomings of the "Managed" approach are breached.

        Comment


          #5
          I am afraid that they are just going to tell you that for this kind of nitty-gritty logic, you will have to use the "Unmanaged" approach.
          I know what you mean. I went through that loop in NT7 and was hoping that the managed approach would improve for 8.
          It would be good to be able to do rapid testing of new ideas with the managed approach, without having to add lots of fiddly special coding with OnOrderUpdate etc just to get round problems in the managed system.

          Comment


            #6
            DaveE,

            Your suggestion is being tracked under ID SFT-1655.
            Patrick H.NinjaTrader Customer Service

            Comment


              #7
              I attach a strategy demonstrating a work-around (needed until SFT-1655 is implemented).

              Whenever I want to use EnterLongLimit instead I call WantEnterLongLimit:

              Code:
              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')
              			}
              		}
              If the Long request is 'blocked' due to an active EnterShortLimit that is due for expiry this is dealt with in OnOrderUpdate as follows:
              Code:
              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;
              				}
              			}
              ...
              The strategy includes similar code for requirement to use EnterShortLimit.
              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.
              Attached Files

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by FMtrader, 03-15-2019, 02:30 AM
              6 responses
              32 views
              0 likes
              Last Post James108  
              Started by timko, Today, 08:18 AM
              0 responses
              2 views
              0 likes
              Last Post timko
              by timko
               
              Started by victorsmith, Today, 06:00 AM
              0 responses
              4 views
              0 likes
              Last Post victorsmith  
              Started by sohailashraf, Yesterday, 10:18 PM
              0 responses
              6 views
              0 likes
              Last Post sohailashraf  
              Started by jjnc2006, Yesterday, 07:36 PM
              0 responses
              16 views
              0 likes
              Last Post jjnc2006  
              Working...
              X