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

Getting Individual Entry Prices from OnExecutionUpdate

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

    Getting Individual Entry Prices from OnExecutionUpdate

    So, I'm a complete newbie where it comes to coding. I have unfortunately found myself at a hard stop where my research has identified I can no longer use the strategy builder to accomplish something I would like to.

    Here's the situation: I have a strategy with 3 sets of conditions producing long orders, and 2 sets of conditions producing short orders. They are all assigned names and associated exits through the condition builder.

    When the second entry occurs, adding to my position, the Unrealized PnL data are now calculated from the average position price. I understand the only way to handle the entry prices independently is through the Order object.

    My goal is to block exiting the second entry (and later, the third entry) unless the Unrealized PnL relative to the individual entry price, not the average entry price, is greater than zero (in other words, price is greater than entry price). I imagine the current conditions in the OnBarUpdate section may have to be edited to reference the correct objects because they currently reference Unrealized PnL according to the Average Position Price. But I have no clue how to put this into code.

    Any help the community can offer is greatly appreciated.
    Last edited by liquid150; 12-20-2017, 04:21 PM.

    #2
    This is the progress I have so far:

    I created the following variables to deal with the things I need to do at the beginning of the strategy:

    Code:
    private double EntryPrice1
    private double EntryPrice2
    private double EntryPrice3
    private double EntryPrice4
    private double EntryPrice5
    Code:
    private order entryOrder
    private order order1
    private order order2
    private order order3
    private order order4
    private order order5
    And coded the default where needed:
    Code:
    EntryPrice1 = 0.00
    EntryPrice2 = 0.00
    EntryPrice3 = 0.00
    EntryPrice4 = 0.00
    EntryPrice5 = 0.00
    And I put the following to access the data, and manage the variables:

    Code:
    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
    		{
    			
    			if (execution.Order.Name == @"LongEntry1")
          		entryOrder = order1;
    			
    			if (execution.Order.Name == @"LongEntry2")
          		entryOrder = order2;
    		
    			if (execution.Order.Name == @"LongEntry3")
          		entryOrder = order3;
     
    			if (execution.Order.Name == @"ShortEntry1")
          		entryOrder = order4;
    			
    			if (execution.Order.Name == @"ShortEntry2")
          		entryOrder = order5;
    			
    			if (entryOrder != null && entryOrder == order1)
    				execution.Price = EntryPrice1;
    				entryOrder = null;
    			
    			if (entryOrder != null && entryOrder == order2)
    				execution.Price = EntryPrice2;
    				entryOrder = null;
    			
    			if (entryOrder != null && entryOrder == order3)
    				execution.Price = EntryPrice3;
    				entryOrder = null;
    			
    			if (entryOrder != null && entryOrder == order4)
    				execution.Price = EntryPrice4;
    				entryOrder = null;
    			
    			if (entryOrder != null && entryOrder == order5)
    				execution.Price = EntryPrice5;
    				entryOrder = null;
    			
    		}
    And for each closing order, within OnBarUpdate, I changed the Unrealized PnL reference to:
    Code:
    if Close[0] > EntryPrice1
    and so on, for each exit order I have. For short orders it instead reads
    Code:
    if Close[0] < EntryPrice4
    However, this is not working. I'm not sure why. It also seems to have completely broken my exit orders on the short side in the strategy.

    Any ideas?
    Last edited by liquid150; 12-20-2017, 09:38 PM.

    Comment


      #3
      If it helps to mention, the above changes do compile. But when the strategy is backtested the exit orders, especially on the short side, refuse to work at all.

      When I get time I will create a new copy of my base strategy from the Strategy Builder and unlock the code, and copy this stuff over. I am wondering if it is possible I deleted something else on accident. I don't think there is, though, because I checked.

      Comment


        #4
        Hello,

        Thank you for the note.

        An error that could occur that I see from your snippet is that the check for Close[0] > Entry1 is becoming true at the beginning of the script when all of your entry variables are still set to 0, but that is just an external observation.

        You can use Print() statements to debug your code. You may check the value of your variables before you use them in IF statements to check why statements evaluate to true or false.

        Also, you are setting the Executions entry price to the EntryPrice1 variable. The Execution's price is read-only, maybe you meant to do EntryPrice1 = execution.Price;

        Example:

        Code:
        Print("About to check Entry1");
        if(Close[0] > Entry1)
        {
                Print("Entry1 condition true.");
                Print("Close Price[0]" + Close[0]);
                Print("Entry1 Value" + Entry1);
        }
        You can also set up boolean flags to ensure that the Entry1 variable has been set before you check it.

        Example:

        Code:
        public class MyStrategy : Strategy
        {
        
            private bool myFlag = false;
        
        ...
         
           protected void OnExecutionUpdate()
           {
               if (execution.Order.Name == @"LongEntry1")
               {
                        myFlag = true;
              		entryOrder = order1;
               }
        ...
           }
        
           protected void OnBarUpdate()
           {
                if(Close[0] > Entry1 && myFlag == true)
                {
                      //Do something 
                }
           }
        Here is the help guide page on the Print statement:


        Prints can be viewed from the output window. (Control Center> New > Output window)

        I look forward to hearing of your results.
        Last edited by NinjaTrader_ChrisL; 12-21-2017, 09:19 AM.
        Chris L.NinjaTrader Customer Service

        Comment


          #5
          Good morning Chris,

          In reviewing my code, I have found something I might want to ask you about. When my strategy executes an order in OnBarUpdate, double clicking EnterLong and looking at the expected fields therein shows me that some string called signalName is assigned.

          Any hints on accessing the signalName object? I'm assuming I can read it and use it here.
          Last edited by liquid150; 12-22-2017, 12:34 PM.

          Comment


            #6
            Hello,

            Thank you for the reply.

            Once you have assigned your Order object, you can access the name of an order object like so:

            Order myOrder;

            Code:
            OnBarUpdate()
            {
            
                    if(myOrder != null && myOrder.FromEntrySignal == "MyEntrySignalName")
                    {
                       
                             Print("The signal name is " + myOrder.FromEntrySignal);
            
                    }
            
            OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
            {
            			
            			if (execution.Order.FromEntrySignal == @"LongEntry1")
                  		                   myOrder = execution.Order;
            
            }
            https://ninjatrader.com/support/help...-us/?order.htm - Order object

            If we may be of any further assistance, please let us know.
            Chris L.NinjaTrader Customer Service

            Comment


              #7
              Merry Christmas, Chris!

              Of course, I am working. I have determined using the above Print command suggestion that my current issue is the execution.Order.FromEntrySignal string does not appear to be created when my orders are placed. Here is the text for my entry signals:

              Code:
              EnterLong(Convert.ToInt32(LongOrderQuantity), "CrossAboveEntry");
              ...
              EnterLong(Convert.ToInt32(LongOrderQuantity), "BoughtDip");
              ...
              EnterLong(Convert.ToInt32(LongOrderQuantity), "FollowOnLong");
              ...
              EnterShort(Convert.ToInt32(ShortOrderQuantity), "CrossBelowShort");
              ...
              EnterShort(Convert.ToInt32(ShortOrderQuantity), "FollowOnShort");
              I have called out the following for variables:
              Code:
              private double EntryPrice1;
              private double EntryPrice2;
              private double EntryPrice3;
              private double EntryPrice4;
              private double EntryPrice5;
              
              private Order order1;
              private Order order2;
              private Order order3;
              private Order order4;
              private Order order5;
              And set the default for EntryPrice variables:
              Code:
              EntryPrice1 					= 0.00;
              EntryPrice2 					= 0.00;
              EntryPrice3 					= 0.00;
              EntryPrice4 					= 0.00;
              EntryPrice5 					= 0.00;
              Here is OnOrderUpdate and OnExecutionUpdate. I added an empty OnOrderUpdate because I thought maybe that was an issue:

              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)
              		{
              			
              		}
              		
              		protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
              		{
              			
              			if (execution.Order.FromEntrySignal == "CrossAboveEntry")
                    		order1 = execution.Order;
              			Print("The order name is " + execution.Order.FromEntrySignal);
              			
              			if (execution.Order.FromEntrySignal == "BoughtDip")
                    		order2 = execution.Order;
              			Print("The order name is " + execution.Order.FromEntrySignal);
              		
              			if (execution.Order.FromEntrySignal == "FollowOnLong")
                    		order3 = execution.Order;
               			Print("The order name is " + execution.Order.FromEntrySignal);
              			
              			if (execution.Order.FromEntrySignal == "CrossBelowShort")
                    		order4 = execution.Order;
              			Print("The order name is " + execution.Order.FromEntrySignal);
              			
              			if (execution.Order.FromEntrySignal == "FollowOnShort")
                    		order5 = execution.Order;
              			Print("The order name is " + execution.Order.FromEntrySignal);
              			
              			if (execution.Order == order1)
              				EntryPrice1 = execution.Order.AverageFillPrice;
              				Print("The price is " + execution.Order.AverageFillPrice);
              			
              			if (execution.Order == order2)
              				EntryPrice2 = execution.Order.AverageFillPrice;
              				Print("The price is " + execution.Order.AverageFillPrice);
              			
              			if (execution.Order == order3)
              				EntryPrice3 = execution.Order.AverageFillPrice;
              				Print("The price is " + execution.Order.AverageFillPrice);
              			
              			if (execution.Order == order4)
              				EntryPrice4 = execution.Order.AverageFillPrice;
              				Print("The price is " + execution.Order.AverageFillPrice);
              			
              			if (execution.Order == order5)
              				EntryPrice5 = execution.Order.AverageFillPrice;
              				Print("The price is " + execution.Order.AverageFillPrice);
              			
              		}
              The following is from my Output screen, showing the FromEntrySignal field not being populated upon an execution. This is apparent because no "FromEntrySignal" is shown where one would be expected:

              Code:
              CrossAboveEntry = Now
              The order name is 
              The order name is 
              The order name is 
              The order name is 
              The order name is 
              The price is 64.32
              The price is 64.32
              The price is 64.32
              The price is 64.32
              The price is 64.32
              Is there some way to force FromEntrySignal to populate correctly? It is apparent the script is changing ALL of the order and price variables because the string is blank.

              Comment


                #8
                Hello liquid150,

                The FromEntrySignal is only used for exit orders.

                This needs to match the Name (SignalName) of the entry order.

                Are these exit orders that you are printing?

                The prints that you have will all print every update because none of these are within the if statements that preceed them.

                By not using curly braces, the only action that is triggered by the if is the setting of the order objects if the FromEntrySignal is what you are expecting. The prints will always print even if no order is being assigned.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Thanks Chelsea, that would explain some of this behavior if I am looking for something only used on exit orders. That was not clear from the help documentation, however. If that were noted it would be helpful.

                  Originally posted by NinjaTrader_ChelseaB View Post
                  By not using curly braces, the only action that is triggered by the if is the setting of the order objects if the FromEntrySignal is what you are expecting. The prints will always print even if no order is being assigned.
                  Can you help me understand where the curly braces should be expected?

                  The issue is the prints are printing nothing at all except the "The order name is". I will change these to order name references later today and see if that fixes it.

                  Comment


                    #10
                    Hello,

                    Thank you for the reply.

                    The EnterLong method uses signalName (or just Name)

                    Code:
                    EnterLong(int quantity, string signalName)
                    And the ExitLong method uses fromEntrySignal

                    Code:
                    ExitLong(int quantity, string signalName, string fromEntrySignal)



                    If you are wanting to print the name of an order use execution.Order.Name.

                    If you are trying to find out which entry and exit order is attached to when detecting an exit order use execution.Order.FromEntrySignal

                    Curly braces are used for scope and grouping. If you do not put curly braces on the IF statement, the compiler will assume that the next line is the only line relevant to that IF statement. So anything within the IF statement's curly braces will be executed only if the IF statement evaluates to true.

                    Code:
                    if(condition)
                    {
                    
                        Print("condition is true");
                        Print("condition is still true");
                    
                    }
                    Here is a publicly available link to the if statement:
                    Encode branching logic with if, else-if and else. Evaluate conditions to true or false.

                    Search for the "brackets" heading on this page.

                    Please let us know if we may be of any further assistance.
                    Chris L.NinjaTrader Customer Service

                    Comment


                      #11
                      I would like to thank Chris and Chelsea for their awesome help, over the holiday even! Amazing service.

                      I was able to cobble together functional code to generate the expected results. I would like to post it here for the community to reference since this is, from my perspective, a very useful and necessary part of any strategy. I am sure there is a better way to do this, and this is not going to be my final product, since I have thought of some things that need adjustment in my exit signals. But if you have directly tied all entries to a specific exit, this will work for you.

                      First, establish order variables and double variables for the orders and entry prices in the declarations area:
                      Code:
                                      private double EntryPrice1;
                      		private double EntryPrice2;
                      		private double EntryPrice3;
                      		private double EntryPrice4;
                      		private double EntryPrice5;
                      
                      		private Order order1;
                      		private Order order2;
                      		private Order order3;
                      		private Order order4;
                      		private Order order5;
                      Next, set the default entry price in the Set Defaults section:
                      Code:
                       
                                                      EntryPrice1 					= 0.00;
                      				EntryPrice2 					= 0.00;
                      				EntryPrice3 					= 0.00;
                      				EntryPrice4 					= 0.00;
                      				EntryPrice5 					= 0.00;
                      Third step is to create the OnExecutionUpdate logic. I inserted this before the OnBarUpdate section. I don't know if that matters.

                      Code:
                      protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
                      		{
                      			
                      			if (execution.Order.Name == "CrossAboveEntry")
                            		{
                      			order1 = execution.Order;
                      			Print("The order name is " + execution.Order.Name);
                      			}
                      				
                      			if (execution.Order.Name == "BoughtDip")
                            		{
                      			order2 = execution.Order;
                      			Print("The order name is " + execution.Order.Name);
                      			}
                      				
                      			if (execution.Order.Name == "FollowOnLong")
                            		{
                      			order3 = execution.Order;
                       			Print("The order name is " + execution.Order.Name);
                      			}
                      				
                      			if (execution.Order.Name == "CrossBelowShort")
                            		{
                      			order4 = execution.Order;
                      			Print("The order name is " + execution.Order.Name);
                      			}
                      			
                      			if (execution.Order.Name == "FollowOnShort")
                            		{
                      			order5 = execution.Order;
                      			Print("The order name is " + execution.Order.Name);
                      			}
                      				
                      			if (execution.Order == order1)
                      			{
                      				EntryPrice1 = execution.Order.AverageFillPrice;
                      				Print("The price is " + execution.Order.AverageFillPrice);
                      			}
                      				
                      			if (execution.Order == order2)
                      			{
                      				EntryPrice2 = execution.Order.AverageFillPrice;
                      				Print("The price is " + execution.Order.AverageFillPrice);
                      			}
                      				
                      			if (execution.Order == order3)
                      			{
                      				EntryPrice3 = execution.Order.AverageFillPrice;
                      				Print("The price is " + execution.Order.AverageFillPrice);
                      			}
                      				
                      			if (execution.Order == order4)
                      			{
                      				EntryPrice4 = execution.Order.AverageFillPrice;
                      				Print("The price is " + execution.Order.AverageFillPrice);
                      			}
                      				
                      			if (execution.Order == order5)
                      			{
                      				EntryPrice5 = execution.Order.AverageFillPrice;
                      				Print("The price is " + execution.Order.AverageFillPrice);
                      			}
                      		}
                      The last step is to make being greater than/less than your entry price according to market position a condition in your exit orders in OnBarUpdate:

                      Code:
                      if ((Close Condition = True)
                      				 && (Close[0] > EntryPrice1))
                      Thanks for this great forum and customer service. I am greatly thankful not only for all the help given by Ninjatrader CS, but also for all the members who ask questions and continue to publicly push for solutions to their problems.
                      Last edited by liquid150; 12-29-2017, 09:00 AM.

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by ftsc2022, 10-25-2022, 12:03 PM
                      5 responses
                      255 views
                      0 likes
                      Last Post KeyonMatthews  
                      Started by ScottW, Today, 06:09 PM
                      0 responses
                      3 views
                      0 likes
                      Last Post ScottW
                      by ScottW
                       
                      Started by Board game geek, 10-29-2023, 12:00 PM
                      14 responses
                      244 views
                      0 likes
                      Last Post DJ888
                      by DJ888
                       
                      Started by Waxavi, 04-19-2024, 02:10 AM
                      4 responses
                      56 views
                      0 likes
                      Last Post sonia0101  
                      Started by cmtjoancolmenero, Today, 03:58 PM
                      0 responses
                      9 views
                      0 likes
                      Last Post cmtjoancolmenero  
                      Working...
                      X