Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Partial Fill + multiple "Exit" methods problem

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

    Partial Fill + multiple "Exit" methods problem

    Hello,

    I have faced the following problem when using multiple profit targets set via "Exit" methods ("ExitShortMIT" in particular) for a short trade that was filled in two stages:

    1. A short trade on ES futures with 20 lot size was opened in two parts - first part is 4 lots, the second part - 16 lots
    2. Once the entry order is filled (has state "Filled" in OnExecution method) - the strategy has set a stop loss and several profit targets (using ExitShortStop and ExitShortMIT methods): 1st = 10 lots, 2nd = 2 lots, 3rd = 2 lots and so on till 6th = 2 lots
    3. Once 1st profit target with 10 lots was filled, the strategy has cancelled the stop loss and all other profit targets leaving 10 lots from the original position without a stop loss and profit target

    Can you please advise me on how I can set multiple profit targets so that they are not cancelled in case of the initial position is filled in several stages?

    Attached is the screenshot of the problem.

    And below is the related log data:

    Opening the short position:

    Order (orderId='87156e96e62d40ad9c0b5a08ec3c6760' account='Playback101' name='Short' orderState=PartFilled instrument='ES 09-19' orderAction=SellShort orderType='Market' limitPrice=0 stopPrice=0 quantity=20 tif=Gtc oco='' filled=4 averageFillPrice=2917.5 onBehalfOf='' id=1375 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: PartFilled

    Order (orderId='87156e96e62d40ad9c0b5a08ec3c6760' account='Playback101' name='Short' orderState=Filled instrument='ES 09-19' orderAction=SellShort orderType='Market' limitPrice=0 stopPrice=0 quantity=20 tif=Gtc oco='' filled=20 averageFillPrice=2917.3 onBehalfOf='' id=1375 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Filled

    Setting Exit orders (1 SL and 6 TP):

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=StopMarket Quantity=20 LimitPrice=0 StopPrice=2919.25 SignalName='Short#SL' FromEntrySignal='Short'

    Order (orderId='2a145b237cfb419fa9f5fa62877394cb' account='Playback101' name='Short#SL' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='Stop Market' limitPrice=0 stopPrice=2919.25 quantity=20 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1376 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=MIT Quantity=10 LimitPrice=0 StopPrice=2916.00 SignalName='Short#TP1' FromEntrySignal='Short'

    Order (orderId='b1821b253a3d46148ea2bd69c4c530f2' account='Playback101' name='Short#TP1' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2916 quantity=10 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1377 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=2915.25 SignalName='Short#TP2' FromEntrySignal='Short'

    Order (orderId='4b47137d7c5841b9b70381b26665006f' account='Playback101' name='Short#TP2' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2915.25 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1378 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=2914.75 SignalName='Short#TP3' FromEntrySignal='Short'

    Order (orderId='520b395597c34ea8a529c3705e8650d3' account='Playback101' name='Short#TP3' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2914.75 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1379 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=2914.00 SignalName='Short#TP4' FromEntrySignal='Short'

    Order (orderId='a598533675e44bb2bf00e835344405b2' account='Playback101' name='Short#TP4' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2914 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1380 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=2913.25 SignalName='Short#TP5' FromEntrySignal='Short'

    Order (orderId='7d81350207db4cd295fb818c5c38ff5d' account='Playback101' name='Short#TP5' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2913.25 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1381 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    Entered internal SubmitOrderManaged() method at 02.09.2019 15:30:01: BarsInProgress=0 Action=BuyToCover OrderType=MIT Quantity=2 LimitPrice=0 StopPrice=2912.75 SignalName='Short#TP6' FromEntrySignal='Short'

    Order (orderId='db289dfb7c714723bb2746b2c3d4176f' account='Playback101' name='Short#TP6' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2912.75 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1382 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02') update: Accepted

    TP1 is filled:

    Order (orderId='b1821b253a3d46148ea2bd69c4c530f2' account='Playback101' name='Short#TP1' orderState=Filled instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2916 quantity=10 tif=Gtc oco='' filled=10 averageFillPrice=2916.25 onBehalfOf='' id=1377 time='2019-09-02 16:17:49' gtd='2099-12-01' statementDate='2019-09-02') update: Filled

    Stop loss and other profit targets are cancelled:

    Cancelled pending exit order, since associated position is closed, orderId='db289dfb7c714723bb2746b2c3d4176f' account='Playback101' name='Short#TP6' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2912.75 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1382 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02'

    Cancelled pending exit order, since associated position is closed, orderId='7d81350207db4cd295fb818c5c38ff5d' account='Playback101' name='Short#TP5' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2913.25 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1381 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02'

    Cancelled pending exit order, since associated position is closed, orderId='a598533675e44bb2bf00e835344405b2' account='Playback101' name='Short#TP4' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2914 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1380 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02'

    Cancelled pending exit order, since associated position is closed, orderId='520b395597c34ea8a529c3705e8650d3' account='Playback101' name='Short#TP3' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2914.75 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1379 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02'

    Cancelled pending exit order, since associated position is closed, orderId='4b47137d7c5841b9b70381b26665006f' account='Playback101' name='Short#TP2' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='MIT' limitPrice=0 stopPrice=2915.25 quantity=2 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1378 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02'

    Cancelled pending exit order, since associated position is closed, orderId='2a145b237cfb419fa9f5fa62877394cb' account='Playback101' name='Short#SL' orderState=Accepted instrument='ES 09-19' orderAction=BuyToCover orderType='Stop Market' limitPrice=0 stopPrice=2919.25 quantity=20 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=1376 time='2019-09-02 15:30:01' gtd='2099-12-01' statementDate='2019-09-02'



    Best regards,
    Alexei

    #2
    Hi Alexei, thanks for your note.

    This will depend on how you are setting your stop loss orders. If you are using SetStopLoss, make sure you give unique signal names to each entry so they can be referenced in SetStopLoss using the fromEntrySignal string. There is also a more advanced way of setting OCO protective orders, see this reference sample:



    Please let me know if I can assist any further.
    Chris L.NinjaTrader Customer Service

    Comment


      #3
      Hi Chris,

      I use "Exit" methods to place stop loss and profit targets in OnExecution(): "ExitShortStopMarket" and "ExitShortMIT" in particular.

      Comment


        #4
        Hello akuntysh,

        Thanks for your post.

        We would suggest splitting up the entry order as well so your separate Exit methods are associated with a specific Enter method.

        For example, create an entry for "Entry1" and entries for "Entry2" and "Entry3." These can all be the same order type residing on the same price level. When "Entry1" fills, set the targets and stops you would like associated with that specific entry. (Use "Entry1" as the fromSignalName in the Exit method.) When "Entry2" fills set targets and stops for that specific entry.

        The SampleOnOrderUpdate strategy Chris had linked can provide further direction for handling partial fills in a strategy using the OnExecutionUpdate method. You may use it for the basis of your works with modifications to have separate stop/target levels set by using separate Entry orders and separate Exit methods associated with each entry. I.E.You will have 3 sets of target/stop orders for each of your 3 entries in this case.

        Please let us know if you have any additional questions.
        JimNinjaTrader Customer Service

        Comment


          #5
          Hello Jim,

          I also had the same idea, but then I have faced the fact that the entry order has the same signal name in all its partial executions. If the order is executed in parts, there is no way to name the 1st part as "Entry1" and the 2nd part as "Entry2", since the name for the signal is provided once the order is sent via "EnterShort" method. So in all "Exit" methods (for all execution parts) I have to pass the same signal name, that was specified in "EnterShort" method and that all execution parts have.

          Or do you mean to split the original entry order from the beginning in order to reduce the probability of it being filled in several parts? In this case, the only way to get 100% of confidence is to enter using 1 lot for each "EnterShort" method call, as even an order with 2 lots may be filled partially in theory, am I right?

          Best regards,
          Alexei

          Comment


            #6
            Hi akuntysh, thanks for your reply.

            I'm not sure exactly what your strategy is doing without a code sample, but through my test, the SampleOnOrderUpdate strategy handles partial fills perfectly, see attached screen shot. Even if the order is partially filled it will have the same entry signal name, the Order object state contains a Partfilled state where you can still apply a stop to it. Please let me know if I can assist further after reviewing the SampleOnOrderUpdate strategy.

            Best regards.
            Attached Files
            Chris L.NinjaTrader Customer Service

            Comment


              #7
              Hi Chris,

              1. I have composed a short code sample as an example of what I mean:

              Code:
              protected override void OnBarUpdate()
              {
                  if (CurrentBar < 0 || State == State.Historical) return;
              
                  if (Position.MarketPosition == MarketPosition.Flat){
                      EnterLong(20,"Long");
                  }
              }
              
              protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment){
                  Print("Order ("+order.ToString()+") update: "+order.OrderState.ToString());    
              }
              
              protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time){
                  Print("Execution of order: "+execution.Order.ToString());
                  if (execution.Order.Name == "Long" && execution.Order.OrderState == OrderState.Filled){
                      ExitLongStopMarket(0,true,20,price - 20 * TickSize,"SL","Long");
                      ExitLongMIT(0,true,1,price + 5 * TickSize,"TP1","Long");
                      ExitLongMIT(0,true,19,price + 30 * TickSize,"TP2","Long");
                  }
              }
              2. Attached are two screenshots (how the trade has started and what has happened after the 1st target was hit) and the related log file. As you can see, the trade was executed in two parts; the strategy has set Stop Loss and two profit targets (TP1 and TP2) upon trade execution and once TP1 was hit - TP2 and SL were cancelled, even though the position had still a part of it left.

              Best regards,
              Alexei
              Attached Files

              Comment


                #8
                Hello Alexei,

                If you would like separate exit levels, I would recommend splitting your entry so each exit is tied to a specific entry. You would submit separate entry orders for "Entry1" and 'Entry2" that would then be associated with the exits for that "group." I.E. "Entry1" for 1 contract, and "Entry2" for 19 contracts. The entry orders can be at the same level. You would then submit additional exits so "Entry1" has a target/stop for 1 contract and "Entry2" has a target/stop for 19 contracts.

                Please let me know if you have any questions.
                JimNinjaTrader Customer Service

                Comment


                  #9
                  Hello Jim,

                  I got your idea, and this would definitely work if I know in advance the exact amount of parts in which my entry order will be filled. But how do I know in advance that my entry order will be filled in exactly two parts with exactly this amount of lots (1 and 19) in order to split it correctly in trade entry code block?

                  The only idea that I have in relation to this is to execute each entry with 1 lot only, as even an entry with 2 lots may be filled in parts in theory. In other words, do you mean that if I want to enter a trade with 20 lots, I should do this? If I understand correctly, this is the only way to ensure that each trade will be executed in full (not in parts):

                  Code:
                  for (int i = 1;i <= 20;i++){
                      EnterLong(1,"Long"+i.ToString());
                  }
                  Best regards,
                  Alexei

                  Comment


                    #10
                    Hi Alexei, thanks for your reply.

                    I wouldn't recommend doing a loop to fill orders. In OnExecutionUpdate, you can check how much of an order has filled. The SampleOnOrderUpdate does this exactly:

                    Code:
                    if (execution.Order.OrderState == OrderState.PartFilled)
                                        {
                                            stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
                                            targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
                                        }
                    The execution.Order.Filled property is how much of the order has filled in that instance.

                    Please let me know if you have any questions.
                    Chris L.NinjaTrader Customer Service

                    Comment


                      #11
                      Hello Chris,

                      Jim's suggestion was to split the entry into parts with different names ("Enrty1", "Entry2", etc) to ensure that each part has its own related "Exit" orders that are related to this particular entry name specified in "fromEntrySignal" parameter of the "Exit" method.

                      If I do not make the loop with "Entry" method, then can you please advise me how I can predict in how many parts my entry order would be filled in order to correctly split it on separate unique entries in the trade entry block?

                      Best regards,
                      Alexei

                      Comment


                        #12
                        Hi Alexei, thanks for your reply.

                        To split an order such that they can have different stops you would need to have different signal names for each group of orders. If you have one set of contracts that need stop loss value 'x' and another set of contracts that need stop loss value 'y', then you need to submit your orders separately with two different entry signals. In OnExecutionUpdate you can look at the signal name and apply the correct stops to each signal name using the execution.Order.Name property.
                        Chris L.NinjaTrader Customer Service

                        Comment


                          #13
                          Hello Chris,

                          I think now I got it! Thank you for your patience!

                          Best regards,
                          Alexei

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by pmachiraju, 11-01-2023, 04:46 AM
                          8 responses
                          149 views
                          0 likes
                          Last Post rehmans
                          by rehmans
                           
                          Started by mattbsea, Today, 05:44 PM
                          0 responses
                          5 views
                          0 likes
                          Last Post mattbsea  
                          Started by RideMe, 04-07-2024, 04:54 PM
                          6 responses
                          33 views
                          0 likes
                          Last Post RideMe
                          by RideMe
                           
                          Started by tkaboris, Today, 05:13 PM
                          0 responses
                          5 views
                          0 likes
                          Last Post tkaboris  
                          Started by GussJ, 03-04-2020, 03:11 PM
                          16 responses
                          3,283 views
                          0 likes
                          Last Post Leafcutter  
                          Working...
                          X