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

interested in collaboration with other users to refine some code.

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

    #16
    Hello rtwave,

    An example of multiple entries and multiple exits is provided in post #10. Please review this. This simple working example's goal is to show proper usage of signal names and entries per direction to have multiple entries and multiple exits. The prices you would like to submit these, the times you would like to submit these, may be different in your final project.

    Debugging is an important part of programming. This should be something you learn before you start learning any complex logic for indicators or strategies. This is also in the NinjaScript Editor 401 training video. The training videos should also be watched to learn how to use NinjaTrader.

    Below is a link to a forum post that demonstrates how to use TraceOrders and prints to understand behavior. Please read the material, watch the videos (and try and follow along with them to learn how to debug), then begin debugging your code. The output will tell us what is going on.


    May I have the output from TraceOrders and prints? (Right-click the output window -> select save as.)


    Also, below is a link to a forum post with helpful information about getting started with C# and NinjaScript that includes links to the Strategy Builder 301 and NinjaScript Editor 401 training videos.


    I'm further linking the training video playlists.

    Reference quick tip videos designed to help you get up and running with the NinjaTrader platform.






    As a heads up, I am not able to debug your code, so I must guide with questions and answer any of your direct questions. Unfortunately, in the support department at NinjaTrader it is against our policy to create, debug, or modify, code or logic for our clients. Further, we do not provide C# programming education services or one on one educational support over the phone in our NinjaScript Support department. This is so that we can maintain a high level of service for all of our clients as well as our associates.

    We can provide demonstration example scripts for you to import and learn from. Links to educational material in the help guide and videos. We are also able to guide you through the debugging process to assist or building process of a specific script you are wanting to work out.

    You can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like our NinjaTrader Ecosystem team follow up with you with a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #17



      this entry works acceptably,

      if (Close[0] < EMA1[0])
      {
      Dtc = true;
      Utc = false;
      if (orshpoor == null)
      {
      EnterShort(Convert.ToInt32(Positionsize), @"orsp01");
      }
      }


      combined with this stop loss order.


      if (orshpoor != null && orshpoor == execution.Order)
      {
      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
      {
      // We sum the quantities of each execution making up the entry order
      sumFilled += execution.Quantity;

      // Submit exit orders for partial fills
      if (execution.Order.OrderState == OrderState.PartFilled && marketPosition == MarketPosition.Short)
      {
      orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Instlonuti * TickSize ), "orstorsp01", "orsp01");

      }
      // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
      else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled && marketPosition == MarketPosition.Short)
      {
      // Stop-Loss order for OrderState.Filled
      orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Instlonuti * TickSize ), "orstorsp01", "orsp01");

      }

      // Resets the orshpoor object and the sumFilled counter to null / 0 after the order has been filled
      if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
      {
      orshpoor = null;
      sumFilled = 0;
      }
      }
      }




      however, if this second entry is enabled, once it is triggered,


      if ( Dtc == true && High[0] > ( Position.AveragePrice + ( Punuti * TickSize ) ) )
      {
      EnterShort(Convert.ToInt32(Pullbackpositionsize), @"pusp01");
      }


      the combined - coordinated stop loss orders will not work anymore.


      if (pushpoor != null && pushpoor == execution.Order)
      {
      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
      {
      sumFilled += execution.Quantity;

      if (execution.Order.OrderState == OrderState.PartFilled && marketPosition == MarketPosition.Short)
      {
      pushpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustpusp01", "pusp01");
      orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustorsp01", "orsp01");
      }

      else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled && marketPosition == MarketPosition.Short)
      {
      pushpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustpusp01", "pusp01");
      orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustorsp01", "orsp01");
      }

      if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
      {
      pushpoor = null;
      sumFilled = 0;
      }
      }
      }


      it seems to me that the only things that could be causing these malfunctions would be conflicting values for execution.Order.Filled, execution.Order.AverageFillPrice and sumFilled between the first and second positions. if i want to create three variables to hold the values for execution.Order.Filled, execution.Order.AverageFillPrice and sumFilled for the ordinary position and three other variables to hold these values for the pullback position, żhow could i do this? and i think all these variables would need to be reset every time these positions are liquidated, żhow could i achieve this?


      Comment


        #18
        Hello rtwave,

        This is Jim responding on behalf of Chelsea who is out of the office at this time.

        the combined - coordinated stop loss orders will not work anymore.
        This would need to be investigated with prints and seeing how far the logic gets, and when some of the logic is not reached, print out the values used in each condition (above the condition) to see how they evaluate. This will point out why a piece of code is not being reached. If the code is reached but no order is submitted, test again with TraceOrders enabled to see why the order submission was ignored.

        You may have a better time testing this in Playback using Market Replay data and focusing on a specific time when the issue arises.

        it seems to me that the only things that could be causing these malfunctions would be conflicting values for execution.Order.Filled, execution.Order.AverageFillPrice and sumFilled between the first and second positions. if i want to create three variables to hold the values for execution.Order.Filled, execution.Order.AverageFillPrice and sumFilled for the ordinary position and three other variables to hold these values for the pullback position, żhow could i do this? and i think all these variables would need to be reset every time these positions are liquidated, żhow could i achieve this?
        execution.Order.Filled, execution.Order.AverageFillPrice, anything from the passed execution object in OnExecutionUpdate, will be local to the specific update of OnExecutionUpdate. sumFilled is a class level variable. You should make sure that each entry has its own class level sumFilled variable, and to treat each own as it is demonstrated in SampleOnOrderUpdate.

        Everything taking the SampleOnOrderUpdate approach is outlined in the example, for multiple entries you would just have to make sure that EntryHandling and EntriesPerDirection allow multiple entries, and the order handling logic (including stop/target submission logic) is unique for each entry. As you are developing, use debugging prints to see how far the code gets and why it is not reaching those sections to check your work.

        Let us know if there is anything else we can do to help.

        JimNinjaTrader Customer Service

        Comment


          #19



          NinjaTrader_Jim, people with nt,




          these onrderupdate and onexecutionupdate methods are really unpredictable.



          i have now created 4 sumfilled variables as i have 4 different orders (ordinary and pullback, both short and long). i have indeed noticed some improvement once i made this change.



          and i want to emphasize, it is not like i created some very extensive and complicated innovative code and i was asking nt to debug it. it is the complete opposite, all i have is the most elementary ema crossover strategy and i'm trying to work on the very samples nt makes available. everything compiles without issue, the entries work as expected, but the stop loss orders seem to be invalidated once the second entry is triggered.



          in the first thread i created about this development i asked nt for a working sample of a strategy with 2 positions and this is the strategy that was provided:


          if (entryOrder != null && entryOrder == execution.Order)
          {
          if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
          {
          // We sum the quantities of each execution making up the entry order
          sumFilled += execution.Quantity;
          Print("MyEntry1 Position and Quantity: " + marketPosition + " " + quantity);

          // Submit exit orders for partial fills
          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");
          }
          // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
          else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
          {
          // Stop-Loss order for OrderState.Filled
          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");
          Print("MyEntry exit orders submitted");
          }

          // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
          if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
          {
          entryOrder = null;
          sumFilled = 0;
          }
          }
          }
          if (entryOrder2 != null && entryOrder2 == execution.Order)
          {
          if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
          {
          //We sum the quantities of each execution making up the entry order
          sumFilled2 += execution.Quantity;
          Print("MyEntry2 Position and Quantity: " + marketPosition + " " + quantity);

          //Submit exit orders for partial fills
          if (execution.Order.OrderState == OrderState.PartFilled)
          {
          stopOrder2 = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 8 * TickSize, "MyStop2", "MyEntry2");
          targetOrder2 = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 16 * TickSize, "MyTarget2", "MyEntry2");
          //Print("MyEntry2 exit orders submitted");
          }
          //Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
          else if (execution.Order.OrderState == OrderState.Filled && sumFilled2 == execution.Order.Filled)
          {
          //Stop-Loss order for OrderState.Filled
          Print("MyEntry2 exit orders submitted");
          stopOrder2 = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 8 * TickSize, "MyStop2", "MyEntry2");
          targetOrder2 = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 16 * TickSize, "MyTarget2", "MyEntry2");
          }

          // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
          if (execution.Order.OrderState != OrderState.PartFilled && sumFilled2 == execution.Order.Filled)
          {
          entryOrder2 = null;
          sumFilled2 = 0;
          }
          }
          }




          i do notice that each one of those segments only references their own order, stop and target and they operate completely separately of one another. in contrast, in the strategy i have been trying to make work below, in the segment for the second order i try to reference its own stop and also the stop for the first position. it is possible that this is the cause of all the problems, żcan the nt platform do this and adjust a stop loss that had been defined previously in reference to a new value for average fill price? that's the exact objective of this entire development, a strategy that can add a secondary position on a pullback but always keeping the maximum possible loss capped for the larger combined position.




          if (pushpoor != null && pushpoor == execution.Order)
          {
          if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
          {
          pushpoorsufi += execution.Quantity;

          if (execution.Order.OrderState == OrderState.PartFilled && marketPosition == MarketPosition.Short)
          {
          pushpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustpusp01", "pusp01");
          orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustorsp01", "orsp01");
          }

          else if (execution.Order.OrderState == OrderState.Filled && pushpoorsufi == execution.Order.Filled && marketPosition == MarketPosition.Short)
          {
          pushpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustpusp01", "pusp01");
          orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustorsp01", "orsp01");
          }

          if (execution.Order.OrderState != OrderState.PartFilled && pushpoorsufi == execution.Order.Filled)
          {
          pushpoor = null;
          pushpoorsufi = 0;
          }
          }
          }




          from everything i have seen, i'm now not even sure that an external programmer could be of much help.


          żcan nt provide a working sample of their onorderupdate strategy such that it includes two positions, where the the second position is dependent on the profit - loss for the first and the stop loss orders are calculated and defined in relation to the average price for the aggregate position?
          Last edited by rtwave; 08-08-2021, 12:54 PM.

          Comment


            #20
            Hello rtwave,

            Where you have claimed 'these onrderupdate and onexecutionupdate methods are really unpredictable.' what exactly are you finding that is inconsistent and changes each time the script is run?


            A strategy cannot have two positions on the same instrument so an example of this cannot be provided because this is not possible.

            It is possible to scale into a single position with multiple contracts.

            If you want to scale and scale out, have each quantity be a separate entry with a unique signal name, then have a single exit order attached to the fromEntrySignal of that entry. As each exit fills, it will only exit the quantity of that entry from the position.


            Previously, I have provided a script showing that using SetStopLoss() with two entries is possible, in response to the message of your post #9.
            Attached, is an example script that scales in and out using exit methods instead of set methods.
            ​​​​​​​
            Attached Files
            Chelsea B.NinjaTrader Customer Service

            Comment


              #21





              people with nt,



              i still haven't been able to get the stop loss orders to work when using the onorderupdate and onexecutionupdate methods.



              i have now taken a look at the directory of 3rd party programmers that nt maintains. in order for it to be worth the trouble of hiring a programmer, i first want to make sure that the functionalities i have in mind are perfectly clear and also that the nt methods that i have been trying to make work are adequate for the intended objectives.




              i have now made changes to all my strategies to make sure that i use a similar terminology to to the one that the nt platform uses. where i previously used the word position, i now use the word entry. this is inconsequential but it means that my strategies now have an ordinary and a pullback entry.



              i'm interested in having the people with nt evaluate whether the onorderupdate and onexecutionupdate methods are really appropriate to achieve the following objectives. the structure i have in mind for my strategies is the following:






              if downtrend

              ordinary short entry at market ( 2 contracts )

              create stop loss order for ordinary short entry at +800 ticks from initial average entry price ( ordinary short entry )


              if time is between 9:30 and 16:00 and pullback

              pullback short entry at market ( 1 contract )

              create stop loss order for ordinary short entry at +600 ticks from combined average entry price ( average of ordinary and pullback short entries )

              create stop loss order for pullback short entry at +600 ticks from combined average entry price ( average of ordinary and pullback short entries )


              if downtrend ends


              liquidate all short entries

              cancel all stop orders



              i have been trying to use the onorderupdate and onexecutionupdate methods as nt support have stated that these are necessary to be able to create an initial stop loss order defined in ticks from the ordinary entry and then parallel stop loss orders defined in ticks from the new average price once the second entry has been executed for both the ordinary and pullback entries.



              żis this formulation clearer? żare the onorderupdate and onexecutionupdate methods the most appropriate to achieve these functionalities?



              oks, very well, regards.

              Comment


                #22
                Hello rtwave,

                We can take a look at the output from the TraceOrders and prints and help you along. The output will tell us what's going on so that we can direct you on what to change.

                There can be multiple entry orders that scale into a position and increase the positions quantity, and you can separate exit orders to scale of a position and reduce the position quantity.
                Below is a link to the help guide on Position.Quantity.


                OnExecutionUpdate() will be a method that runs when the execution of the entry fills and the position updates. This would be a good time to use exit order methods to submit a stop and target.

                You can choose to use SetStopLoss() instead of using exit orders, if SetStopLoss() suits your needs, but you cannot use both set methods and exit methods. You will have to choose one or the other. Set methods would be called before the entry is placed (and not in OnExecutionUpdate()).

                The pseudo logic you have suggested sounds possible, (though this is not very specific). When you say it is not working, what is the TraceOrders and prints specifically showing is not working?
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #23



                  people with nt,



                  i do not have any trace logs or prints for these strategies i'm working on. the data i have been working on goes from 202001 to 202106 and there are barely 30 pullback entries that have the characteristic i'm interested in over all that time. it would be impossible to evaluate whether these strategies are functioning as intended on simulator as it could take weeks to observe just one pullback like the ones i have in my strategies, what i do have are backtests and optimizations.


                  and from those optimizations i can conclude that set stops do work without problem but exit orders would be better because those could allow for more flexibility in the number of contracts for each entry and would make the calculations of the number of ticks for each stop much easier.


                  i have created another version of my experimental strategy and i have found that two sets of entry and exit orders do work without problem, provided that the two entries happen at the same time:



                  // Set 1
                  if (Close[0] < EMA1[0])
                  {
                  Dtc = true;
                  Utc = false;
                  if (shorenor == null)
                  {
                  EnterShort(Convert.ToInt32(Ordinaryentrysize), @"shoren01");
                  EnterShort(Convert.ToInt32(Pullbackentrysize), @"shpuen01");
                  }
                  }


                  // Set 2
                  if (Close[0] > EMA1[0])
                  {
                  Utc = true;
                  Dtc = false;
                  if (loorenor == null)
                  {
                  EnterLong(Convert.ToInt32(Ordinaryentrysize), @"looren01");
                  EnterLong(Convert.ToInt32(Pullbackentrysize), @"lopuen01");
                  }
                  }


                  Click image for larger version

Name:	20210824 duplicate exit stops 0001.JPG
Views:	356
Size:	245.8 KB
ID:	1169003



                  for all these trades, there is only one execution.Order.AverageFillPrice as entries happen at the same time. exit orders work without issue.




                  however, when i first have ordinary short and long entries:



                  // Set 1
                  if (Close[0] < EMA1[0])
                  {
                  Dtc = true;
                  Utc = false;
                  if (shorenor == null)
                  {
                  EnterShort(Convert.ToInt32(Ordinaryentrysize), @"shoren01");
                  }
                  }


                  // Set 2
                  if (Close[0] > EMA1[0])
                  {
                  Utc = true;
                  Dtc = false;
                  if (loorenor == null)
                  {
                  EnterLong(Convert.ToInt32(Ordinaryentrysize), @"looren01");
                  }
                  }


                  these result in some initial values for execution.Order.AverageFillPrice which are used to define exit orders for these ordinary entries.


                  and then the pullback entries are added when these conditions are observed:



                  if ( Dtc == true && High[0] > ( Position.AveragePrice + ( Punuti * TickSize ) ) )
                  {
                  EnterShort(Convert.ToInt32(Pullbackentrysize), @"shpuen01");
                  }


                  if ( Utc == true && Low[0] > ( Position.AveragePrice - ( Punuti * TickSize ) ) )
                  {
                  EnterLong(Convert.ToInt32(Pullbackentrysize), @"lopuen01");
                  }



                  these second entries will mean that there will be a new value for execution.Order.AverageFillPrice and it seems to me like the platform will then have problems with the stop orders as the averagefillprice has changed and the ordinary entry stops were defined for the initial value but the pullback entry stops will be referenced to the new value.


                  if (shorenor != null && shorenor == execution.Order)

                  shorenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Instlonuti * TickSize ), "orstshoren01", "shoren01");

                  shorenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Instlonuti * TickSize ), "orstshoren01", "shoren01");


                  if (shpuenor != null && shpuenor == execution.Order)

                  shpuenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustshpuen01", "shpuen01");

                  shpuenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustshpuen01", "shpuen01");



                  i think this must be the issue here. shorenstor is correctly defined with the initial value for average price. however, when the second entry is added, there is now a new value for average price. after a pullback entry is added, what i want is for both exit orders to be set at the exact same level = execution.Order.AverageFillPrice + ( Costlonuti * TickSize ). żhow could the shorenstor order be updated to the new level after the pullback entry has been added? żand how can the shpuenstor be correctly defined being that it is here that the stop orders seem to not work properly anymore? and eventually, if these entries are made to be nicely in profit, i would like to then move these stops to break even in parallel, i suppose it should also be possible to update shorenstor and shpuenstor once again to a new price level when the conditions are appropriate.



                  as always, i have attached the latest version of this experimental strategy. i have tried everything i could think of, if i can now hire a proficient programmer perhaps this could be easy for them. i will definitely ask for quotes for this code i have not been able to make work.

                  Comment


                    #24
                    Hello rtwave,

                    Debugging and gaining understanding with Print() and TraceOrders is really the only way to move forward. Trying different things doesn't give you an understanding of what is going wrong with the existing code.

                    If you are not wanting to debug the script using TraceOrders and Print() yourself with our guidance and resolve the issue, you can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like our NinjaTrader Ecosystem team follow up with you with a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.

                    That said, we can get to the bottom of this with TraceOrders and prints.

                    May I have you start by enabling TraceOrders and providing the output from this?

                    As a suggestion, when debugging it is important to reduce variables, and reduce the amount of data being tested over, to focus on a smaller amount of output from TraceOrders and Print() and only focus on one issue at a time. Try testing over a much smaller data set and focus on a specific order that is not being submitted when expected.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #25


                      people with nt,



                      i haven't been able to hire a programmer to help with the functionality i have been working on. i wrote to 8 - 10 programmers but only received 2 replies and 1 single quote. i work directly on nt's samples and it typically takes me 10 minutes or so to create or modify strategies, surprisingly the programmers i wrote to said my strategy would take several hours to create.


                      now, once i saw that i wasn't making much progress on that front, i have been studying the resources that nt makes available and there are some videos which are magnificent. i have watched 3 videos that are among the results when one searches for nt + print or nt + traceorders. these videos are great, i really wish i had started by watching them when i first started trying to code on nt as i have learned most of the information covered there by trial and error.


                      if nt has any videos for how to debug code and how to use traceorders, onorderupdate and onexecutionupdate i will be very interested in studying them.


                      in the case of the code that i can't make work, i understand that it is the exit - stop loss orders that stop working after the second entry is executed. żam i supposed to print everything that is inside the order and execution methods? żcan nt provide examples of how to do this? same with traceorders, if i enable this functionality in my strategies, żhow can access this data when running optimization processes in strategy analyzer windows?



                      very well, regards.

                      Comment


                        #26
                        Hello rtwave,

                        Thanks for your note.

                        This is Brandon responding on behalf of Chelsea who is out of the office at this time.

                        if nt has any videos for how to debug code and how to use traceorders, onorderupdate and onexecutionupdate

                        Please see this debugging video created by my colleague Jim which demonstrates debugging using prints and TraceOrders: https://drive.google.com/file/d/1rOz...w?usp=drivesdk

                        Prints are used to understand why the script is behaving as it is, such as placing orders or not placing orders when expected. Prints would be added to a script to print the values used for the logic of the script to understand how the script is evaluating. In the strategy, add prints (outside of any conditions) that print the values of every variable used in every condition that places an order along with the time of that bar. A simple example could be seen below. This print will tell you what the Close and Open values are and can tell you why the condition below has/has not become true.

                        Code:
                        Print("Close: " + Close[0] + " Open: " + Open[0]);
                        if (Close[0] > Open[0])
                        {
                            ...
                        }
                        Debugging Tips: https://ninjatrader.com/support/help...script_cod.htm

                        TraceOrders could be used to check for messages saying that orders are being ignored and not being submitted when the condition to place the orders is evaluating as true. This may happen when there is an issue where the strategy is hitting an internal rule that is not allowing you to re-enter. TraceOrders could be enabled in the strategy (set in State.SetDefaults) so it prints its order feedback, and you may also observe the log tab of the Control Center for additional hints.

                        TraceOrders: https://ninjatrader.com/support/help...aceorders2.htm

                        Please see the example script, SampleOnOrderUpdate, linked here which demonstrates using the OnOrderUpdate() and OnExecutionUpdate() methods: https://ninjatrader.com/support/help...and_onexec.htm

                        The way this script work is an entry market order is submitted if we currently don't have an entry order open.

                        In OnOrderUpdate() we check to see if the name of the order matches the signal name of the order and we assign the order to our order object. Then we check if the OrderState is canceled without any fill and reset the order object. This is done for both entry orders, MyEntry and MyEntry2

                        In OnExecutionUpdate() we check if our order object is not null and if the order object matches the executed order. A condition is made to check if the OrderState is filled, part-filled, canceled, or filled and we sum up the quantities of each execution making up the entry order and assign it to sumFilled. Next, we check if there are partial fills and submit exit orders for those partial fills or if the orders are filled and the execution quantities match order quantities then we update our exit order quantities. We then reset the order object and the sumFilled counter to null after each order has been filled. This is done for both entry orders, My Entry and MyEntry2. At the end of OnExecutionUpdate() we reset our stop orders and target orders' order objects after the position is closed.

                        OnOrderUpdate(): https://ninjatrader.com/support/help...rderupdate.htm
                        OnExecutionUpdate(): https://ninjatrader.com/support/help...tionupdate.htm

                        Let us know if we may assist further.
                        Brandon H.NinjaTrader Customer Service

                        Comment


                          #27



                          people with nt,



                          i just discovered nt ninjascript output windows. there's very interesting information there. when i run an optimization the window will be saturated with thousands of lines of traceorders information, żhow can i share this with nt support?



                          and i need an example of how to print the code inside onorderupdate. nt support has suggested multiple times in this thread that i:

                          "Enable TraceOrders, print the order object in OnOrderUpdate(), and print the price supplied to the order along with the time of the bar."

                          but it is obvious that anyone who is not an experienced ninjascript programmer would never have any idea of how to do this. żcan nt provide an example of how to print all the objects inside onorderupdate and onexecutionupdate (specially the exit-stopmarket orders)? the only samples that exist all deal with printing the entry conditions for the same old and tired nt sample sma crossover strategy but that has nothing to do with more advanced methods that are not covered or discussed anywhere.


                          very well, regards.

                          Comment


                            #28
                            Hello rtwave,

                            It is recommended that when testing for a specific issue, reduce the amount of data. Reduce the iterations in an optimization to as few as possible that can still reproduce the behavior, or just run a single backtest. Reduce the amount of days in the backtest as much as possible while still being able to reproduce the behavior.

                            If this is still too much output, see if the prints can be more focused in the code, such as printing within a datetime condition to filter out other days and focus on a specific event in question.


                            Or write the information to a text file with StreamWriter.
                            Citizens of the NinjaTrader Community, A common question we hear from clients is 'why are results from backtest different from real-time or from market replay?'. Live orders are filled on an exchange with a trading partner on an agreed upon price based on market dynamics. Backtest orders are not using these market dynamics.


                            Below are links to the help guide that have code examples of overriding OnOrderUpdate() and OnExecutionUpdate().



                            To print the order object:
                            Code:
                            protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, Cbi.OrderState orderState, DateTime time,  bi.ErrorCode error, string comment)
                            {
                            [B]Print(order.ToString());[/B]
                            }
                            To print the execution object:
                            Code:
                            protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
                            {
                            [B]Print(execution.ToString());[/B]
                            }
                            Chelsea B.NinjaTrader Customer Service

                            Comment


                              #29



                              people with nt,



                              i have made some changes to my experimental onorderexecutionupdate strategies.


                              i have managed to add prints to the sections that are the most problematic.


                              i have uploaded the nt output for two backtests. the seven trades below which lost more than $204 usd are the cases where the stop loss orders failed to work for the strategy with two entry orders. i used two contracts for the ordinary initial entry and only one contract for the pullback entry, this to make it easier to identify each of the entries in the strategy analyzer and output logs.




                              Click image for larger version

Name:	20210912 stops not working 0001.JPG
Views:	180
Size:	361.0 KB
ID:	1171089


                              i also include the same output for the same strategy with the same parameters but with the second entry disabled. in that case, the stop loss orders never failed. this is something i had observed and documented in the two threads i have created dealing with this issue.


                              this is a malfunction of the nt platform as far as i can tell, hopefully nt support can finally take a look at this information and propose a solution to these failures.


                              very well, regards.

                              Comment


                                #30
                                Hello rtwave,

                                I am happy to take a look at the output text files. Please attach these with your next post.

                                What is the date and time of the first order we will focus on?
                                Chelsea B.NinjaTrader Customer Service

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by yertle, Today, 08:38 AM
                                5 responses
                                14 views
                                0 likes
                                Last Post NinjaTrader_BrandonH  
                                Started by frankthearm, Today, 09:08 AM
                                2 responses
                                5 views
                                0 likes
                                Last Post frankthearm  
                                Started by adeelshahzad, Today, 03:54 AM
                                3 responses
                                16 views
                                0 likes
                                Last Post NinjaTrader_BrandonH  
                                Started by bill2023, Yesterday, 08:51 AM
                                6 responses
                                27 views
                                0 likes
                                Last Post NinjaTrader_Erick  
                                Started by NinjaTrader_ChelseaB, 01-08-2017, 06:59 PM
                                80 responses
                                19,667 views
                                5 likes
                                Last Post NinjaTrader_ChelseaB  
                                Working...
                                X