Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

How to submit a stop using ExitLongStop() in proper sequence in historical testing?

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

    How to submit a stop using ExitLongStop() in proper sequence in historical testing?

    I am running into issues submitting a stop loss in my strategy. It seems like the order of the OnOrderUpdate and OnExecution functions are all screwy. For example, here is the output from the print screen when I submit an order to enter CHK:

    From the chart:
    5/17/2000 > Open = 4.19 / High = 5.12 / Low = 4.19 / Close = 5.12
    5/18/2000 > Open = 5.06 / High = 5.38 / Low = 4.94 / Close = 5.12
    5/19/2000 > Open = 5.06 / High = 5.25 / Low = 4.87 / Close = 5.19

    From the print window:
    5/19/2000 4:00:00 AM -> Submitting EnterLong order for CHK (entrySignal = LONG-CHK-96) - Last Close = 5.12
    5/18/2000 2:00:00 PM Entered internal PlaceOrder() method at 5/18/2000 2:00:00 PM: BarsInProgress=70 Action=Buy OrderType=Market Quantity=19,531 LimitPrice=0 StopPrice=0 SignalName='LONG-CHK-96' FromEntrySignal=''
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-96 // Order State = PendingSubmit
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-96 // Order State = Accepted
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-96 // Order State = Working
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-96 // Order State = Filled
    5/18/2000 2:00:00 PM In OnExecution() Function // Order = LONG-CHK-96 // Order State = Filled // Order Fill Price = 5.06
    5/18/2000 2:00:00 PM In OnExecution() Function - Updating initial stop - Current Ask Price = $5.12 // Current Bid Price = $5.12 // Last Open = 5.06 // Last Close = 5.12
    5/18/2000 2:00:00 PM CALCULATING INITIAL STOP (Instrument = CHK) - Last Close = 5.12 - Stop Price = $4.97
    5/18/2000 2:00:00 PM Entered internal PlaceOrder() method at 5/18/2000 2:00:00 PM: BarsInProgress=70 Action=Sell OrderType=Stop Quantity=19,531 LimitPrice=0 StopPrice=4.97 SignalName='InSTOP_L-CHK-95' FromEntrySignal='LONG-CHK-96'
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = InSTOP_L-CHK-95 // Order State = PendingSubmit
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = InSTOP_L-CHK-95 // Order State = Accepted
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = InSTOP_L-CHK-95 // Order State = Working
    5/18/2000 2:00:00 PM In OnOrderUpdate() Function // Order = InSTOP_L-CHK-95 // Order State = Filled
    5/18/2000 2:00:00 PM In OnExecution() Function // Order = InSTOP_L-CHK-95 // Order State = Filled // Order Fill Price = 4.97
    5/18/2000 2:00:00 PM In OnExecution() Function - STOP TRIGGERED! - Fill Price = 4.97


    What I want to do:
    1) Submit an order using EnterLong
    2) As soon as possible after the buy order has been filled, submit a stop loss order using ExitLongStop(), calculated based on the current price

    I understand that a buy order won't be filled until the next bar - that's no problem. However, my understanding was that the OnExecution function would only be called after the order was filled (i.e, at the open of the day after the order was submitted in the backtest). If that were the case, then wouldn't I be able to submit a stop order in that function, and have it be based off of the fill price of the order?

    Hopefully I've explained this properly - I'm really scratching my head over here

    Thanks

    #2
    As an update, I have tried entering a trailing stop of 100 ticks, and have run into the same issue. For example:

    7/5/2000 4:00:00 AM -> Submitting EnterLong order for CHK (entrySignal = LONG-CHK-127) - Last Close = 8.12
    7/3/2000 2:00:00 PM Entered internal PlaceOrder() method at 7/3/2000 2:00:00 PM: BarsInProgress=70 Action=Buy OrderType=Market Quantity=12,315 LimitPrice=0 StopPrice=0 SignalName='LONG-CHK-127' FromEntrySignal=''
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = PendingSubmit
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = Accepted
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = Working
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = Filled
    7/3/2000 2:00:00 PM In OnExecution() Function // Order = LONG-CHK-127 // Order State = Filled // Order Fill Price = 8.12
    7/3/2000 2:00:00 PM In OnExecution() Function - Updating initial stop - Current Ask Price = $8.12 // Current Bid Price = $8.12 // Last Open = 7.88 // Last Close = 8.12
    7/3/2000 2:00:00 PM Entered internal SetStopTarget() method: Type=TrailStop FromEntrySignal='LONG-CHK-127' Mode=Ticks Value=100 Currency=0 Simulated=False
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = PendingSubmit
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = Accepted
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = Working
    7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = Filled
    7/3/2000 2:00:00 PM In OnExecution() Function // Order = Trail stop // Order State = Filled // Order Fill Price = 7.19
    7/3/2000 2:00:00 PM In OnExecution() Function - STOP TRIGGERED! - Fill Price = 7.19



    ... How can I enter a stop order as quickly as possible after receiving confirmation that my entry has been filled? I obviously don't want to wait until the next bar (EOD Data) to submit the stop

    Thanks

    Comment


      #3
      Originally posted by kbeary33 View Post
      As an update, I have tried entering a trailing stop of 100 ticks, and have run into the same issue. For example:

      7/5/2000 4:00:00 AM -> Submitting EnterLong order for CHK (entrySignal = LONG-CHK-127) - Last Close = 8.12
      7/3/2000 2:00:00 PM Entered internal PlaceOrder() method at 7/3/2000 2:00:00 PM: BarsInProgress=70 Action=Buy OrderType=Market Quantity=12,315 LimitPrice=0 StopPrice=0 SignalName='LONG-CHK-127' FromEntrySignal=''
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = PendingSubmit
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = Accepted
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = Working
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = LONG-CHK-127 // Order State = Filled
      7/3/2000 2:00:00 PM In OnExecution() Function // Order = LONG-CHK-127 // Order State = Filled // Order Fill Price = 8.12
      7/3/2000 2:00:00 PM In OnExecution() Function - Updating initial stop - Current Ask Price = $8.12 // Current Bid Price = $8.12 // Last Open = 7.88 // Last Close = 8.12
      7/3/2000 2:00:00 PM Entered internal SetStopTarget() method: Type=TrailStop FromEntrySignal='LONG-CHK-127' Mode=Ticks Value=100 Currency=0 Simulated=False
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = PendingSubmit
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = Accepted
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = Working
      7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = Filled
      7/3/2000 2:00:00 PM In OnExecution() Function // Order = Trail stop // Order State = Filled // Order Fill Price = 7.19
      7/3/2000 2:00:00 PM In OnExecution() Function - STOP TRIGGERED! - Fill Price = 7.19


      ... How can I enter a stop order as quickly as possible after receiving confirmation that my entry has been filled? I obviously don't want to wait until the next bar (EOD Data) to submit the stop

      Thanks
      Your log shows that you are using the Set() methods.

      It would appear that the philosophy and intent of the Set() methods may have been misunderstood. The Set() methods are created to have orders at the ready to be submitted immediately after a position is activated. Therefore, you preset those orders so that they can be activated. They essentially perform the function of an entry order with of "Order triggers Next", where "the next" is another order, usually OCO, or just an exit. IOW, you are to determine where NT will place your stop and/or target, so that NT automatically places them once the order is filled: it is not for you to place the Set() order after NT fills the entry order. You are trying to do manually that which has already been automatically set up for you. I suggest that you use what has been already designed for you.

      If you want the kind of control that you describe, then you will have to use the Exit() methods, and do it as you are trying to do, in OnExecution().
      Last edited by koganam; 06-24-2013, 01:53 PM. Reason: Corrected spelling.

      Comment


        #4
        Hi Koganam

        thanks for the response - I actually wasn't aware of any of that regarding the set() methods - I had thought that since I was using the SetTrailStop(from entrySignal...) method, it had to be used after the entry that generated that signal. This is good information to know for the future.

        To clarify - for the first log that I posted, I actually did use the ExitLongStop() function. I'm away from my computer right now, but the order that I used was:
        1) In InBarUpdate, submit a long order using EnterLong()
        2) In OnOrderUpdate(), track all of the order state changes, just to confirm when things were being executed
        3) Once OnOrderUpdate() was complete, in the OnExecution() function, calculate the desired stop loss price, based on the last closing price (here, I set it to 0.5 times ATR, but I don't think that's significant)
        4) Still in the InExecution() function, enter the calculated stop loss using ExitLongStop()


        So, based on what I understand, it seems like the execution order actually is:
        - I submit a long order on Day 1
        - The long order is executed at the open on Day 2 (This is all good, acting how it should)
        - Even though I calculate my stop in OnExecution (which should only be called, by definition, after the order has been filled on Day 2), the stop is still calculated based on the close of Day 1
        - This means that if the fill price is lower than expected (lower then the close on Day 1) then the stop will be much closer than intended. If it is a tight stop, it could easily be above the opening price on Day 2 (although lower than the close on Day 1)


        Is that all correct? Sorry for belabor ring the point, I just want to make sure that I'm interpreting this all correctly.

        If you wouldn't mind spelling it out for a (nearly total) novice - what is the correct way to submit a stop order in my strategy, such that in a backtest the stop will be submitted ASAP after the open/fill price of the order?

        Also, one last question regarding the set() methods:
        - In the OnBarUpdate, right before I submit my EnterLong() order (and once I know what my entrySignal will be), can I just submit the SetTrailingStop()? (In which case I wouldn't have to bother with the OnExecution() stuff?)
        - I want to convert this to a real time strategy, so I want this to be robust for real time trading. What would be the best (maybe not easiest) way to program this?

        Thanks very much for your help!

        Comment


          #5
          Originally posted by kbeary33 View Post
          Hi Koganam

          thanks for the response - I actually wasn't aware of any of that regarding the set() methods - I had thought that since I was using the SetTrailStop(from entrySignal...) method, it had to be used after the entry that generated that signal. This is good information to know for the future.

          To clarify - for the first log that I posted, I actually did use the ExitLongStop() function. I'm away from my computer right now, but the order that I used was:
          1) In InBarUpdate, submit a long order using EnterLong()
          2) In OnOrderUpdate(), track all of the order state changes, just to confirm when things were being executed
          3) Once OnOrderUpdate() was complete, in the OnExecution() function, calculate the desired stop loss price, based on the last closing price (here, I set it to 0.5 times ATR, but I don't think that's significant)
          4) Still in the InExecution() function, enter the calculated stop loss using ExitLongStop()


          So, based on what I understand, it seems like the execution order actually is:
          - I submit a long order on Day 1
          - The long order is executed at the open on Day 2 (This is all good, acting how it should)
          - Even though I calculate my stop in OnExecution (which should only be called, by definition, after the order has been filled on Day 2), the stop is still calculated based on the close of Day 1
          - This means that if the fill price is lower than expected (lower then the close on Day 1) then the stop will be much closer than intended. If it is a tight stop, it could easily be above the opening price on Day 2 (although lower than the close on Day 1)


          Is that all correct? Sorry for belabor ring the point, I just want to make sure that I'm interpreting this all correctly.

          If you wouldn't mind spelling it out for a (nearly total) novice - what is the correct way to submit a stop order in my strategy, such that in a backtest the stop will be submitted ASAP after the open/fill price of the order?

          Also, one last question regarding the set() methods:
          - In the OnBarUpdate, right before I submit my EnterLong() order (and once I know what my entrySignal will be), can I just submit the SetTrailingStop()? (In which case I wouldn't have to bother with the OnExecution() stuff?)
          - I want to convert this to a real time strategy, so I want this to be robust for real time trading. What would be the best (maybe not easiest) way to program this?

          Thanks very much for your help!
          My mistake.
          7/3/2000 2:00:00 PM Entered internal SetStopTarget() method: Type=TrailStop FromEntrySignal='LONG-CHK-127' Mode=Ticks Value=100 Currency=0 Simulated=False
          7/3/2000 2:00:00 PM In OnOrderUpdate() Function // Order = Trail stop // Order State = PendingSubmit
          I should have read it more carefully, and I would have seen the error of my ways.

          Your issue arises. in any case, because you are actually making an assumption about the order fill price instead of just using the actual fill price. You have it all in place except for the "fill price" issue.

          Calculate your stop in OnExecution(), based on Position.AvgFillPrice, of the IOrder; not the entry price at which you placed the order.

          Comment


            #6
            Sounds great thanks,

            just to confirm - I should also leave COBC set to true? (I had just been playing with that when I was trying to make things line up)

            Also, Ideally, I would like to set this up as a trailing stop, and was calculating the ExitLongStop on every bar to mimic that. Would there be a benefit to letting NT handle this through the SetTrailStop method? Or does this ExitLongStop method approximate it close enough? (I'm thinking that in realtime, the OnBarUpdate would fire quickly enough for my needs, but in this EOD case, if the stock makes a new high, and then closes below the stop, I don't think that this would execute in the same way as in real life)

            Comment


              #7
              Originally posted by kbeary33 View Post
              Sounds great thanks,

              just to confirm - I should also leave COBC set to true? (I had just been playing with that when I was trying to make things line up)

              Hard to say. There are no absolutes. It depends on the sensitivity of your entry conditions to a whipsaw on a tick basis. If they are susceptible, then that is another condition for which you must code if you use COBC = false.

              Also, Ideally, I would like to set this up as a trailing stop, and was calculating the ExitLongStop on every bar to mimic that. Would there be a benefit to letting NT handle this through the SetTrailStop method? Or does this ExitLongStop method approximate it close enough? (I'm thinking that in realtime, the OnBarUpdate would fire quickly enough for my needs, but in this EOD case, if the stock makes a new high, and then closes below the stop, I don't think that this would execute in the same way as in real life)

              That works. It is my preferred method, as I find that it keeps me in trends longer, at the expense of sometimes not getting me out quickly enough when the market character changes to a ranging one, and ocassionally forcing me to bail leaving more on the table than I would like to have.

              The advantage of using the Set() methods, is that they are truly "set it and forget it", provided you get it right. The disadvantage, if you will, of using the Set() methods is a consequence of that very same simplicity. Set() methods mean that the preset order is always available, and can never be turned off, so you cannot use another method for trade management, even if you want to. Once you call a Set() method, it is the only method that you can use to manage trades. That Set() thingy is a hard task master.
              Answers in your quoted original text.

              Comment


                #8
                Beautiful, thanks very much for taking the time to walk through this!

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by MacDad, 02-25-2024, 11:48 PM
                7 responses
                158 views
                0 likes
                Last Post loganjarosz123  
                Started by Belfortbucks, Today, 09:29 PM
                0 responses
                6 views
                0 likes
                Last Post Belfortbucks  
                Started by zstheorist, Today, 07:52 PM
                0 responses
                7 views
                0 likes
                Last Post zstheorist  
                Started by pmachiraju, 11-01-2023, 04:46 AM
                8 responses
                151 views
                0 likes
                Last Post rehmans
                by rehmans
                 
                Started by mattbsea, Today, 05:44 PM
                0 responses
                6 views
                0 likes
                Last Post mattbsea  
                Working...
                X