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

Managed Stop Loss Per Unique Entry

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

    Managed Stop Loss Per Unique Entry

    I would like to implement into my strategy a way to have individual stop losses per unique order entry. When backtesting or using live replay, setting entries per direction >1 fires the same logic with the same entry "LONG" or "SHORT" and enters into OnOrderUpdate() and OnExecutionUpdate(). From there initial targets and stops are placed and OnBarUpdate() manages trailing based on ATR once conditions are met. This works great for one contract, but n>1 causes only one stop/target bracket while the rest of the orders are on their own.

    I have attached sample code.
    Attached Files

    #2
    Hello rdavido,

    Thank you for your note.

    So I can best answer your question, the issue is that new entries are not having a stop and profit target associated with them? If so, have you tried updating the quantity of the PT and SL upon a new fill?

    I have attached a strategy which enters a long position with 3 entry calls, then submits a separate profit target and stop loss for each entry, without using order objects. You could use this as a template as well.

    I look forward to your reply.
    Attached Files
    Alan P.NinjaTrader Customer Service

    Comment


      #3
      Yes, this is essentially what I'm looking for, however, am I able to make it more dynamic; i.e. based on the market conditions a new order will be placed on each bar, each having its own stop and profit target handled by OnExecutionUpdate versus specifically entering 3 trades at a time?

      How could I adjust my stop and profit quantity upon each order entry? In the code I have attached, OnBarUpdate utilizes a trailing stop method, but as it is, only processes one contract, when additional contracts are added, it still utilizes P/S orders for one contract and as soon as that order is fulfilled, I am left with remaining open orders with no stop/profit targets.. probably due to the reset coded within OnExecution; is there a way to make each S/P limit independent of eachother?

      Perhaps adding unique identifiers to each "LONG" or "SHORT" order such as + Time[0] and then processing it so it will have the same target and stop, but I'm not sure how to code this.
      Last edited by rdavido; 01-21-2018, 03:07 PM.

      Comment


        #4
        Hello rdavido,

        I put together a script which I suggest you connect to the simulated data feed, and apply the strategy to a 2 second chart, with the orders tab open.

        When applied the strategy will EnterLong, 3 bars later a SL will be submitted, 7 bars later a bool will be reset to allow a new entry to be made on the next bar, which will have a SL submitted 7 bars after that, etc. You will see in the orders tab a new SL is submitted covering this entry.

        To tie a stop loss to a particular entry, you must pass the stop the entries entry name. In this sample I amended the entry name with the current bar ("entry1"), as well as named the stops signal name with the CB ("stopentry1").

        Please let us know if you need further assistance.
        Attached Files
        Alan P.NinjaTrader Customer Service

        Comment


          #5
          Thanks for the samples, however, I am trying to tie in stop losses within my own strategy and not sure if your latest sample is what I'm looking for.

          I do not want to have a predefined set of Long orders (such as three in your example), I'd like to stick with just one Long condition that is dynamically scalable and processed through OnOrderUpdate with initial bracket handled with OnExecutionUpdate with final trailing handled OnBarUpdate; see my sample code

          Comment


            #6
            Hello rdavido,

            The script I provided demonstrates how you could have multiple entries using the same entry logic, with unique PT and SL tied to each entry. You could use the logic as a framework for building what you're looking to do, however in the support department at NinjaTrader we do not create, debug, or modify code for our clients. This is so that we can maintain a high level of service for all of our clients.

            You can also contact a professional NinjaScript Consultants who would be eager to create or modify this script at your request or assist you with your script. Please let me know if you would like our business development follow up with you with a list of professional NinjaScript Consultants who would be happy to create this script or any others at your request.

            Please let us know if you need further assistance.
            Alan P.NinjaTrader Customer Service

            Comment


              #7
              Thanks for the sample, with your method, am I able to tie it to use within OnExecution and OnOrder update? It seems that your example only has OnBarUpdate. Also, I don't want to wait three bars to have stop losses kick in. Please refer to my original sample.

              As it is:

              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 nativeError)
              				{
              					// Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order.
              					// Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
              		            // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting
              					
              					if (order.Name == "LONG")
              		    		{	
              		        		entryOrder = order;
              
              		                // Reset the entryOrder object to null if order was cancelled without any fill
              		                if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
              							entryOrder = null;
              					}
              					
              					if (order.Name == "SHORT")
              					{
              						entryOrder = order;
              					
              					if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
              							entryOrder = null;
              					}
              										
              				}
              
              		protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity, Cbi.MarketPosition marketPosition, string orderId, DateTime time)
              		{
              //			/* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate()
              //			which ensures your strategy has received the execution which is used for internal signal tracking. */
              			if (entryOrder != null && entryOrder == execution.Order)
              			{
              				Print(execution.Order.Name.ToString());
              				if (execution.Order.Name == "LONG" && (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0)))
              				{
              	
              						targetOrder = ExitLongLimit(1, true,entryOrder.Quantity, execution.Order.AverageFillPrice + (profitTargetTicks * TickSize), "T1", "LONG");		
              						stopOrder = ExitLongStopMarket(1, true, entryOrder.Quantity, execution.Order.AverageFillPrice - (stopLossTicks * TickSize), "S1", "LONG");
              						
              				}
              					
              				if (execution.Order.Name == "SHORT" && (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0)))
              					{
              						targetOrder = ExitShortLimit(1, true, entryOrder.Quantity, execution.Order.AverageFillPrice - (profitTargetTicks * TickSize), "T1", "SHORT");	
              						stopOrder = ExitShortStopMarket(1, true, entryOrder.Quantity, execution.Order.AverageFillPrice +  (stopLossTicks * TickSize), "S1", "SHORT");	
              						
              					}
              					
              					if (execution.Order.OrderState != OrderState.PartFilled)
              						entryOrder = null;
              				}
              
              			// Reset our stop order and target orders' Order objects after our position is closed.
              			if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
              			{
              				if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
              				{
              					stopOrder = null;
              					targetOrder = null;
              				}
              			}
              		}
              Code when entering Long/Short. This is good for one order. I am hoping to use your entry string from above to create unique entries such that I can have unique stop and losses based on the OnExecutionUpdate, or is this not possible? For example, replacing execution.Order.Name = "LONG" with the unique entry from the string "entry"? Your example commits me to three entries with defined limits. I want to be able to dynamically adjust this based on the strategy panel "Entries per direction".
              Last edited by rdavido; 01-24-2018, 05:35 PM.

              Comment


                #8
                Hello rdavido,

                The code sample I provided demonstrates how you could uniquely define your entry signal name,

                Code:
                Entry1=”Entry”+CurrentBar.ToString()
                As well as the stop signal name,

                Code:
                Stopentry1=”stop”+CurrentBar.ToString(),
                The +CurrentBar.ToString is going to make the entry name unique, for example “Entry589”. Under this approach, you could control the amount of entries with entries per direction. Obviously you would replace the doOnce==false if condition in my sample with your own conditions, which everytime they become true, would allow a new entry order to be placed assuming your strategy position has not exceeded entries per direction.

                Within OnExecutionUpdate, you could filter fills for the entry with,

                Code:
                if (execution.Order.Name == Entry1 && execution.Order.OrderState == OrderState.Filled)
                Please let us know if you need further assistance.
                Alan P.NinjaTrader Customer Service

                Comment


                  #9
                  This makes more sense. However, when running the following in MarketReplay, orders are not filling

                  Code:
                  protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
                  				{
                  					// Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order.
                  					// Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
                  		            // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting
                  					if (order.Name == entryLong || order.Name == entryShort || order.Name == profitTarget || order.Name == stopLoss)
                  		    		{	
                  		        		entryOrder = order;
                  
                  		                // Reset the entryOrder object to null if order was cancelled without any fill
                  		                if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                  							entryOrder = null;
                  					}
                  					
                  				}
                  
                  		protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
                  		{
                  //			/* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate()
                  //			which ensures your strategy has received the execution which is used for internal signal tracking. */
                  			if (execution.Order.OrderState == OrderState.Filled && entryOrder != null)
                  			{	
                  				if (Position.MarketPosition == MarketPosition.Long)
                  				{
                  					targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + (profitTargetTicks * TickSize), "T1", entryLong);		
                  					stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - (stopLossTicks * TickSize), "S1", entryLong);
                  					
                  					if (execution.Order.OrderState != OrderState.PartFilled)
                  					entryOrder = null;
                  				}
                  				if (Position.MarketPosition == MarketPosition.Short)
                  				{
                  					targetOrder = ExitShortLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - (profitTargetTicks * TickSize), "T1", entryShort);		
                  					stopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + (stopLossTicks * TickSize), "S1", entryShort);
                  					
                  					if (execution.Order.OrderState != OrderState.PartFilled)
                  					entryOrder = null;
                  				}
                  			}
                  
                  			// Reset our stop order and target orders' Order objects after our position is closed.
                  			if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
                  			{
                  				if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
                  				{
                  					stopOrder = null;
                  					targetOrder = null;
                  					stopLoss = string.Empty;
                  					profitTarget = string.Empty;
                  				}
                  			}
                  		}
                  Here is the output log:

                  Code:
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Cancelled' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Cancel submitted' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Working' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Accepted' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Change submitted' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Working' Instrument='ES 03-18' Action='Buy' Limit price=2808.5 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Accepted' Instrument='ES 03-18' Action='Buy' Limit price=2808.5 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Submitted' Instrument='ES 03-18' Action='Buy' Limit price=2808.5 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error=''
                  NinjaScript strategy 'ThreeLine/128380886' submitting order
                  So it seems orders are submitted and cancelled right away.

                  Comment


                    #10
                    Hello rdavido,

                    It does not look like you have logic to prevent the resubmission of the orders. I would suggest using a bool,

                    Code:
                    private doOnce=false;
                    
                    if(doOnce==false)
                    <do something>
                    Then set the bool to true after the first submission.

                    Please let us know if you need further assistance.
                    Alan P.NinjaTrader Customer Service

                    Comment


                      #11
                      I think I'm getting there. Please take a look. I am still unable to get my stop/target conditions per unique order using your ascribed methods.

                      Refer to the region #StopLoss
                      Last edited by rdavido; 01-31-2018, 06:40 PM.

                      Comment


                        #12
                        Hello rdavido,

                        In the support department at NinjaTrader we do not create, debug, or modify code for our clients. This is so that we can maintain a high level of service for all of our clients.

                        If you wanted to upload a copy of the script, stripped down to the bare minimum to reproduce, I could take a look and see if anything jumps out.

                        You can also contact a professional NinjaScript Consultants who would be eager to create or modify this script at your request or assist you with your script. Please let me know if you would like our business development follow up with you with a list of professional NinjaScript Consultants who would be happy to create this script or any others at your request.

                        Please let us know if you need further assistance.
                        Alan P.NinjaTrader Customer Service

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by frankthearm, Today, 09:08 AM
                        7 responses
                        29 views
                        0 likes
                        Last Post NinjaTrader_Clayton  
                        Started by NRITV, Today, 01:15 PM
                        1 response
                        5 views
                        0 likes
                        Last Post NinjaTrader_Jesse  
                        Started by maybeimnotrader, Yesterday, 05:46 PM
                        5 responses
                        25 views
                        0 likes
                        Last Post NinjaTrader_ChelseaB  
                        Started by quantismo, Yesterday, 05:13 PM
                        2 responses
                        17 views
                        0 likes
                        Last Post quantismo  
                        Started by adeelshahzad, Today, 03:54 AM
                        5 responses
                        33 views
                        0 likes
                        Last Post NinjaTrader_BrandonH  
                        Working...
                        X