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

Best way to handle dynamic stops?

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

    Best way to handle dynamic stops?

    I've done some searching on the forums, read a bunch of posts, and my takeaway on this topic is that there are two ways to go about it: one method (the easier one?) is to use SetStopLoss/managed approach. The other (harder?) is to use an unmanaged approach, with lOrder and lExecution.


    I'm trying to create a dynamic stop for my trading system that:
    1. Sets a stop loss initially when a trade is entered, with the stop distance based on the ATR indicator. My system allows up to 4 entries in the same direction (4 consecutive individual trades, either all long or all short).
    2. Moves the stop loss closer to breakeven once a certain open profit is achieved
    3. Moves the stop to breakeven plus a tick or two once a 2nd profit target is achieved.


    I've got step 1 working so far, using SetStopLoss under the OnOrderUpdate method. I'm about to start on steps 2 and 3 and I figure the best/easiest way to approach it is to continue using a SetStopLoss approach, combined with Position.AvgPrice and the current price to calculate the profit targets. Something like this:

    http://www.ninjatrader.com/support/forum/showthread.php?t=57666&highlight=dynamic+stops


    My question to the forum is:
    I allow my system to take up to 4 entries in each direction. I want the strategy to handle the dynamic stop for each entry individually. When I call on Position.AvgPrice in order to calculate the profit of each trade, will it give me the entry price for each entry or will it give the average price for the overall position?


    If Position.AvgPrice can't be used for individual entries but only for aggregate positions, then I would assume this is not the way to manage and modify stop orders for what I'm trying to accomplish?

    #2
    Hello PhillyD,

    Thanks for your post.

    Position.AvgPrice will return the price of the entire position with all orders.

    To find the entry price of a specific order use the IOrder handle of that order.

    For example if this is in OnOrderUpdate(IOrder order) use:

    order.AvgFillPrice
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hi Chelsea,


      Thanks for the help. Are there any examples, sample scripts, documents, or any other resources you could refer me to for this? I'm going to read up on lOrder but any other help would be appreciated.


      Would I be able to keep using SetStopLoss for my initial stop, in conjunction with order.AvgFillPrice, or do I have to switch my whole stop loss strategy over to ExitLong/ExitShort?

      Comment


        #4
        Hello,

        I am slightly confused about your inquiry. The Position.AvgPrice is the entry price of the position. The order.AvgFillPrice is the entry price of a specific order.

        Are you looking for the performance?

        If so, you will need to use the trade collection to find the last orders PnL.

        Print(Performance.AllTrades[Performance.AllTrades.Count-1].ProfitCurrency);


        Also, you will be able to continue using SetStopLoss/SetProfitTarget.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Hi Chelsea,

          Basically what I'm asking is whether I will have to build my stop-loss strategy using the unmanaged approach if I want to use order.AvgFillPrice. My understanding is that managed and unmanaged can't be mixed.

          I'm looking to be able to manage/change individual stop loss orders (up to 4 of them) that are associated with up to four individual entries, all initiated by the same entry signal.

          It would seem like this is probably something that is fairly commonly used in automated strategies, so I was wondering if there are any code snippets or examples that I can refer to.

          Would something like this work, under OnBarUpdate? At the close of every bar it's supposed to check if price in the previous bar reached the first target, if yes, move the stop loss order up and set at newstopdistance, then if the second target is reached, move stop to breakeven plus 2 ticks.

          Code:
           
          if (Position.MarketPosition == MarketPosition.Flat)
          {
               SetStopLoss(CalculationMode.Ticks,stop);
          }
          //stop is the original stop value, some very low number for long entry stop losses. This code resets the stop when I have no position.
           
           
          if (FinalStopMarker == false) //FinalStopMarker is a bool variable that is initialized as 'false' and turns off the stop movement after the price hits the second target
          {
               if (High[0] >= order.AvgFillPrice + Target2*TickSize)
               {
               SetStopLoss("LongEntry",CalculationMode.Ticks,Position.AvgPrice+2*TickSize,false);
          FinalStopMarker == true;
               }
           
          else if (High[0] >= order.AvgFillPrice + Target1*TickSize)
               { 
                    SetStopLoss("LongEntry", CalculationMode.Ticks,newstopdistance,false);
               }
          }

          Comment


            #6
            Hello PhillyD,

            You can use the managed approach for this. IOrders also work with the managed approach.

            (SetStopLoss can't be set to an IOrder object from the call, but the object can be captured in OnOrderUpdate and set to an IOrder object)

            In OnOrderUpdate the order variable is created as the IOrder object of the OnOrderUpdate method.

            private override void OnOrderUpdate(IOrder order)

            This is where the order fill amount is coming from (order.AvgFillPrice).

            (You could also check an IOrder handle where the entry order is saved, but you will also need to check if the order is filled first.
            For example:

            in #region Variables:
            private IOrder myEntryOrder = null;

            Where your entry order is submitted (probably OnBarUpdate()):
            myEntryOrder = EnterLong();

            Where you are checking the fill price of the order and setting the exit price:
            if (myEntryOrder.OrderState == OrderState.Filled
            {
            double orderFillPrice = myEntryOrder.AvgFillPrice;
            }


            Where you place the code depends on what behavior you want the script to have.

            Also, here is a link to a sample that uses IOrders:
            http://www.ninjatrader.com/support/f...ead.php?t=7499

            And a link to all the reference samples.
            http://www.ninjatrader.com/support/f...ead.php?t=3220
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Originally posted by PhillyD View Post
              Hi Chelsea,

              Basically what I'm asking is whether I will have to build my stop-loss strategy using the unmanaged approach if I want to use order.AvgFillPrice. My understanding is that managed and unmanaged can't be mixed.

              I'm looking to be able to manage/change individual stop loss orders (up to 4 of them) that are associated with up to four individual entries, all initiated by the same entry signal.

              It would seem like this is probably something that is fairly commonly used in automated strategies, so I was wondering if there are any code snippets or examples that I can refer to.

              Would something like this work, under OnBarUpdate? At the close of every bar it's supposed to check if price in the previous bar reached the first target, if yes, move the stop loss order up and set at newstopdistance, then if the second target is reached, move stop to breakeven plus 2 ticks.

              Code:
               
              if (Position.MarketPosition == MarketPosition.Flat)
              {
                   SetStopLoss(CalculationMode.Ticks,stop);
              }
              //stop is the original stop value, some very low number for long entry stop losses. This code resets the stop when I have no position.
               
               
              if (FinalStopMarker == false) //FinalStopMarker is a bool variable that is initialized as 'false' and turns off the stop movement after the price hits the second target
              {
                   if (High[0] >= order.AvgFillPrice + Target2*TickSize)
                   {
                   SetStopLoss("LongEntry",CalculationMode.Ticks,Position.AvgPrice+2*TickSize,false);
              FinalStopMarker == true;
                   }
               
              else if (High[0] >= order.AvgFillPrice + Target1*TickSize)
                   { 
                        SetStopLoss("LongEntry", CalculationMode.Ticks,newstopdistance,false);
                   }
              }
              You can use the Managed approach, and you can use SetStopLoss().

              You must use separate signal-names for your entry orders, then tie the SetStopLoss() orders to each individual entry signal-name.

              Comment


                #8
                Thank you.

                If I have four separate signals, how would I identify/tag/tie the entry fill price of the signal to its associated SetStopLoss()? I would need to be able to grab the fill price of each of the four individual signals so that I can compare to the market price and see whether or not my profit targets have been hit for that specific signal. I assume I should use the method outlined by Chelsea above,for each of the four entry signals, for both long and short (eight times in total)?

                You could also check an IOrder handle where the entry order is saved, but you will also need to check if the order is filled first.
                For example:

                in #region Variables:
                private IOrder myEntryOrder = null;

                Where your entry order is submitted (probably OnBarUpdate()):
                myEntryOrder = EnterLong();

                Where you are checking the fill price of the order and setting the exit price:
                if (myEntryOrder.OrderState == OrderState.Filled
                {
                double orderFillPrice = myEntryOrder.AvgFillPrice;
                }

                Comment


                  #9
                  Hi PhillyD,

                  This information can be found in OnOrderUpdate().

                  You can capture the stop loss as it fills and find the signal name of the stop loss and the fromSignalName of the associated entry.

                  For example:

                  private override void OnOrderUpdate(IOrder order)
                  {
                  if (order.Name == "Stop loss")
                  {
                  Print(order.FromEntrySignal);
                  }
                  }
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #10
                    Chelsea, thanks, but I'm not looking for the names of the entry and stop loss orders (I already know those) - I'm looking to capture the fill price of the entry order and store it. I think the code snippet of yours that I posted in my previous post should do the job?

                    Comment


                      #11
                      Hello PhillyD,

                      That is correct, the IOrder object will have the AvgFillPrice which is the entry fill price for that order.

                      This can also be detected in OnOrderUpdate with the IOrder order object.
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #12
                        Hi Chelsea,

                        I'm trying this, but it's not working. It compiles OK but then doesn't do anything:

                        Code:
                        private IOrder myEntryOrder = null;
                        private double orderFillPrice = 0;
                        
                        protected override void OnBarUpdate()
                        
                        // Condition set for short trades
                                    if (some entry conditons are met && myEntryOrder == null)
                        
                                    {
                                        myEntryOrder = EnterShortLimit(DefaultQuantity, Close[0], "ShortEntry1");
                                        Variable0 = StopMultiplier*4*ATR(BarsArray[2],ATRperiod)[0];
                                        SetStopLoss("ShortEntry1", CalculationMode.Ticks, Variable0, false);
                                    }
                                                    
                                    if (Low[0] <= orderFillPrice - Target2*4*ATR(BarsArray[2],ATRperiod)[0])
                                        {
                                            SetStopLoss("ShortEntry1", CalculationMode.Ticks,orderFillPrice-stopLimitOffset*TickSize,false);
                                        }
                        
                        protected override void OnOrderUpdate(IOrder order)
                                {
                                    if (myEntryOrder != null && myEntryOrder.OrderState == OrderState.Filled)    
                                                    {    
                                                        orderFillPrice = myEntryOrder.AvgFillPrice;
                                                    }
                                }
                        It's supposed to move the stop loss order down on a short trade when a certain price target is met. Like I said, it compiles but doesn't do anything. I checked the output window and it shows no reference of any sort to any of the order modification code.

                        One thing of note though is that when I remove the "myEntryOrder != null" condition from the IF statement under OnOrderUpdate, the code compiles but the backtest doesn't run and when I check the output window I see the following message:

                        **NT** Error on calling 'OnOrderUpdate' method for strategy 'TrendTrader/b48b1bf2d2e64ae69d1c427e54cd8450': Object reference not set to an instance of an object.

                        I don't fully understand what the issue is and why the stop modification isn't working properly.

                        Comment


                          #13
                          Hello PhillyD,

                          Thank you for your response.

                          Please try adding a Print() when the condition is true, then check the Output window (Tools > Output) for this print. For example:
                          Code:
                                      if (Low[0] <= orderFillPrice - Target2*4*ATR(BarsArray[2],ATRperiod)[0])
                                          {
                                              Print("Stop Loss adjusted to " + orderFillPrice-stopLimitOffset*TickSize " at " + Times[0][0]);
                                              SetStopLoss("ShortEntry1", CalculationMode.Ticks,orderFillPrice-stopLimitOffset*TickSize,false);
                                          }
                          If this print does not occur, then the calculation is wrong. Try printing the values of the calculation as well in that case.
                          If the print does occur, then something is wrong with the SetStopLoss(), check your log tab of the Control Center for error in that case.

                          Comment


                            #14
                            Hi Patrick,

                            Thanks for your help. I used a Print statement to troubleshoot and work my way through my code and I got the dynamic stop working for one entry signal/setstoploss combination. For my 1st short entry signal, the NinjaScript can now track the entry order fill price after it fills, and can track the associated stop loss order and move it when price reaches a certain target.

                            I now need to make this work for 7 more entry signals, and I believe the way I have the code written right now won't work. The reason is that orderFillPrice, which comes from OnOrderUpdate(IOrder order), doesn't refer to the specific fill price for a specific entry signal, but just to the fill price of whatever order filled last. I need to be able to track the name of the entry signal for which the order filled, tie it to its SetStopLoss order, and manage all the stop loss orders separately.

                            It looks like Chelsea provided some info in post #9 above, but I'm still unsure how I'd use that to store orderFillPrice for each individual entry signal in the Ninja Strategy. Can you expand on this a bit please?

                            Comment


                              #15
                              Hi PhillyD,

                              You can use 8 variables to track the avgFillPrice for each order.

                              Or you can use a list of doubles to track these using a number to correspond with a specific order.
                              http://www.dotnetperls.com/list

                              In post #9, I was showing how to find the fromSignalName of a stop.

                              So if the entry order is 'shortEntry1', and the stop loss associated with shortEntry1 fills, the fromSignalName will be 'shortEntry1', and you can use this to identify this stop as being associated with that particular entry.

                              For example:
                              private List<double> fillPrices = new List<double>();
                              if (order.Name == "Stop loss")
                              {
                              if (order.fromEntrySignal == "shortEntry1")
                              {
                              fillPrices[1] = order.avgFillPrice;
                              }
                              }

                              Then fillPrices[1] will hold the exit price of the stop loss that is associated with shortEntry1.

                              There are actually a few ways you could accomplish this. You could also use a key value pair and use the signal name of the order as the key.
                              http://www.dotnetperls.com/sort-keyvaluepair
                              Chelsea B.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by bmartz, 03-12-2024, 06:12 AM
                              5 responses
                              33 views
                              0 likes
                              Last Post NinjaTrader_Zachary  
                              Started by Aviram Y, Today, 05:29 AM
                              4 responses
                              13 views
                              0 likes
                              Last Post Aviram Y  
                              Started by algospoke, 04-17-2024, 06:40 PM
                              3 responses
                              28 views
                              0 likes
                              Last Post NinjaTrader_Jesse  
                              Started by gentlebenthebear, Today, 01:30 AM
                              1 response
                              8 views
                              0 likes
                              Last Post NinjaTrader_Jesse  
                              Started by cls71, Today, 04:45 AM
                              1 response
                              8 views
                              0 likes
                              Last Post NinjaTrader_ChelseaB  
                              Working...
                              X