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

Constant order submissions.

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

    Constant order submissions.

    I'm testing a "simple" execution strategy on a 1 minute chart to see the difference between strategy analyzer execution and market replay/live execution. Unfortunately neither is submitting orders the way I expected.
    With strategy analyzer, the order won't be submitted until the open of the next bar, even with historical fill resolution set to tick.
    During live/market replay, the order will be triggered instantly as I would hope, but then it keeps closing position and then resubmitting until finally your sim account is drained to the point that you don't have enough margin. I tested this on ES, CL, etc.

    I don't want the script to keep submitting orders to go long if my market position is already long. Same applies for being short. Any help with the code logic will be greatly appreciated.

    #2
    Hello daghost_88,

    Thanks for your post.

    Historical processing (backtesting) is forced to calculate on bar close unless you are using Tick Replay. If you would like the strategy to submit orders OnEachTick or OnPriceChange, please enable Tick Replay.

    Please also note that Tick Replay is not compatible with High Order Fill Resolution and the bar OHLC values would be used to estimate the order fill. If you would like to have fills associated with intrabar price action, you will need to add a single tick data series to the script and submit orders to that single tick sata series.

    Developing For Tick Replay - https://ninjatrader.com/support/help...ick_replay.htm

    Discrepancies between realtime and backtest - https://ninjatrader.com/support/help...ime_vs_bac.htm

    Backtesting with intrabar granularity - https://ninjatrader.com/support/help...ipt_strate.htm

    As for the strategy submitting multiple orders per bar, it is because the strategy logic is allowing these order submission methods to be reached. I may suggest checking if the strategy is flat before submitting your entry orders so the strategy will not constantly reverse positions by calling EnterLong and then EnterShort. I have included a link to our Managed Approach documentation page for further insight on how calling EnterLong and then EnterShort will reverse positions.

    Managed Approach - https://ninjatrader.com/support/help...d_approach.htm

    Please let me know if I can be of further assistance.
    JimNinjaTrader Customer Service

    Comment


      #3
      NinjaTrader_Jim,

      Does this mean I will have to manually code this order management? I don't recall seeing anything in the script wizard that will give me the options in the links.

      Comment


        #4
        Hello daghost_88,

        You can enable Tick Replay from the Tools > Options > Market Data menu of the Control Center to have the strategy process logic with OnEachTick or OnPriceChange, but the order fills will still go against the OHLC values instead of any intrabar action. (High Order Fill Resolution cannot be used with Tick Replay.) If you are using tick replay and want intrabar granularity for order fills, the strategy must be unlocked.

        The Strategy Builder creates code following the Managed Approach so that article is also relevant to the Strategy Builder.

        The constant order fills are still going to be based on the logic: when the strategy is processing OnEachTick, one bar receives multiple iterations of the strategy logic. As the strategy logic processes, it is calling your EnterLong, and then your EnterShort repeatedly on the same bar. Resolving this would involve adding additional logic to control how these orders get submitted.

        Let me know if you have any additional questions.
        Last edited by NinjaTrader_Jim; 03-22-2022, 07:50 AM.
        JimNinjaTrader Customer Service

        Comment


          #5
          Dis this issue get resolved. If so, how?

          Thank you,

          Nick

          Comment


            #6
            Hello njmeyer713,

            The issue mentioned here involves order logic being processed with each tick when processing realtime data. In a backtest (historical processing) there is only the OHLC of the bar and bars a re processed on bar close even if Calculate is set to OnEachTick/OnPriceChange.

            I would suggest building a strategy that uses Calculate.OnBarClose because this would have similar behavior between backtesting and realtime testing.

            However, If you want to process Calculate.OnEachTick and prevent multiple submissions from taking place when your submission logic becomes true, I suggest expanding on the logic so the entry conditions would not become true multiple times.

            You could consider using a position check to make sure you are flat before an entry order is submitted and this can help

            Position checks - https://ninjatrader.com/support/help...ionComparisons

            You can also add Boolean variables to the strategy to control the logic.

            Code:
            if (CONDITONS TO ENTER && bAllowedToEnter == true)
            {
                EnterLong();
                bAllowedToEnter = false;
            }
            else if (Position.MarketPosition == MarketPosition.Flat)
            {
                bAllowedToEnter = true;
            }
            JimNinjaTrader Customer Service

            Comment


              #7
              Jim,

              Thank you for your response. I already have the Market.Flat condition in my code. What I believe is happening is that the strategy is buying then selling, then buying and selling, etc many times over. I don't want to add the Booelean logic to say it can't trade on the same candle because I want the code to take a retrigger if it occurs on that candle after being stopped out. However, what I don't understand is that when the code "glitches" it buys 2 contracts at a price say 4300 (MES) then hits my stop which is set at 16 ticks, then buys two contracts at the 4300 price level, then sells at the 16 tick stop over and over again. What doesn't seem possible is for the market to have that kind of price action instantaneously and repeatedly.

              Let me know you thoughts.

              Thank you,

              Nick

              Comment


                #8
                Hello Nick,

                Have you added debugging prints to see which of your order submission methods are firing when you see this occur? (This would be important to better understand the behavior you see.)

                Debugging Tips - https://ninjatrader.com/support/help...script_cod.htm

                What specific order methods are hit when you see this occur?

                Are some order methods firing when other resting orders (I.E. target/stop from Set methods) are getting filled?

                Are you able to simplify the code so it is easy to follow and also demonstrates the behavior you see?

                If you can provide a small example (we would not be able to debug and reduce a large strategy for you) we would have something common to look at where we may better assist.

                Exporting as source code - https://ninjatrader.com/support/help...tAsSourceFiles
                JimNinjaTrader Customer Service

                Comment


                  #9
                  Jim-

                  I am getting back to this issue. Please see the attached screenshot. I rewrote the code for my exits after studying ninjascript more and more but I am still having issues with the Strategy Analyzer. When I use the Playback feature, the code works perfectly, knock on wood. But when I go to the Strategy Analyzer, it bugs out.

                  Before I export the code, I want to ask a general question.

                  I have read and re-read all of the factors and considerations that someone needs to take into account when trying to get the most accurate back test or replays possible. But is there something I have missed that would cause the code to run how it should in the Replay and then glitch when running in the strategy analyzer? I have tick replay checked and the code runs on each tick with the 1 tick data series added.

                  Thank you in advance,

                  Nick

                  Comment


                    #10
                    Hello Nick,

                    If you enable Tick Replay, the strategy will be able to process OnBarUpdate following Calculate.OnPriceChange or Calculate.OnEachTick.

                    The above just accounts for intrabar logic. To have orders filled intrabar, the order methods need to be submitted a single tick data series that is added to the script.

                    Using Tick Replay and developing a Multi Time Frame strategy to have the orders filled by the single tick data adds a lot more work to a strategy that is built with the Strategy Builder.

                    Using Playback will be much easier if you are just transitioning from the Strategy Builder.

                    Having said this, if you do want to make more advanced modifications so the strategy can be backtested in the Strategy Analyzer with intrabar strategy logic and single tick order fill resolution, please see below.

                    The thread linked below further discusses using Exit methods in OnExecutionUpdate for the target/stop. It also gives an example where Exit methods can be used in place of Set methods to have intrabar granularity with the target/stop.

                    https://ninjatrader.com/support/foru...40#post1199540
                    Last edited by NinjaTrader_Jim; 05-02-2022, 12:40 PM.
                    JimNinjaTrader Customer Service

                    Comment


                      #11
                      Jim-

                      Thank you for your response. I am pretty familiar with the different exit methods and I the have the single tick data series added to the script.

                      I'd like to get your thoughts on my question from the mu previous post. Do you know of a reason that the same algo over the same period of time would trade without "glitches" during the Playback but would bug out when I run the Strategy Analyzer over that same period of time?

                      As it sits right now, the analyzer is pretty much worthless to me and I need to get that thing to work to optimize variables.

                      Thank you,

                      Nick

                      Comment


                        #12
                        Hello Nick,

                        "Bug out" and "Glitches" are a bit vague. The exact symptom should be described and then that specific behavior should be reproduced, and the related code should be debugged/analyzed. (We want to understand exactly what the problem is, what specific code is involved, and then we want to watch the logic evaluate to step through the behavior and see what is happening.)

                        To elaborate: Playback mimics real-time processing while the Strategy Analyzer processes historical data. These are different mechanisms, and there can be different corner cases and different behavior encountered. Having a deep understanding of the logic (following it with prints) will tell the tale why unexpected actions are being taken, or why some actions that you expect to be taken are not being taken.

                        Clearly describing the problem and using prints to see how the logic is allowing that to occur would be the first step to diagnose the issue. Otherwise, we would be making blind guesses as to what is happening.

                        As a tip, and especially if you are just moving from the Strategy Builder, I suggest getting familiar with the SampleOnOrderUpdate strategy, and how orders are submitted to a single tick data series.

                        Once you are comfortable there, set up a new strategy (similar to the one I shared in the linked thread) that provides a framework for submitting orders to the single tick data series that can also use Tick Replay /Calculate.OnEachTick/Calculate.OnPriceChange.

                        Getting something stable with these advanced concepts will be a good stepping stone before trying to implement in an existing strategy.
                        JimNinjaTrader Customer Service

                        Comment


                          #13
                          Jim-

                          Yes I was pretty vague with that, I apologize for that. In nutshell it is taking too many trades. In one scenario it buys at the correct price and sells at the correct price, 16 ticks profit, but it does it over and over and over again. Like I have said previously, I just don't think the price action moves like that repeatedly and instantaneously back and forth like that over a 16 tick distance.

                          Another situation I come across is outlines below.

                          Please see the attached screenshot and we can try to tackle this issue. Thank you in advance.

                          This is the entry code that submits correctly.

                          Code:
                          // 15 Long 1-2U
                          
                          
                          if ((High[1] <= High[2])
                          && (Low[1] >= Low[2])
                          && (GetCurrentBid(0) > High[1])
                          && (GetCurrentBid(0) > Opens[1][0])
                          && (GetCurrentBid(0) > Opens[2][0])
                          && (GetCurrentBid(0) > Opens[3][0])
                          && (GetCurrentBid(0) > Opens[4][0])
                          && (GetCurrentBid(0) > Highs[4][1])
                          // Condition group 1
                          && ((BarsSinceExitExecution(0, @"15RunnerBreakeven", 0) > 0)
                          || (BarsSinceExitExecution(0, @"15RunnerBreakeven", 0) == -1)))
                          // && (CurrentBars[0] > ExitBar)
                          
                          {
                          EnterLongLimit(Convert.ToInt32(Quantity), (High[1] + (LimitOrderSlippage * TickSize)) , @"15Long1-2U");
                          }
                          However on this one, the entries per direction shouldn't allow this to occur correct? Each order should buy 2 contracts.

                          Code:
                          Description = @"Using CurrentBar and ExitBar with new stops";
                          Name = "AAAVersion22";
                          Calculate = Calculate.OnEachTick;
                          EntriesPerDirection = 1;
                          EntryHandling = EntryHandling.UniqueEntries;
                          IsExitOnSessionCloseStrategy = true;
                          ExitOnSessionCloseSeconds = 30;
                          IsFillLimitOnTouch = false;
                          MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
                          OrderFillResolution = OrderFillResolution.Standard;
                          Slippage = 0;
                          StartBehavior = StartBehavior.WaitUntilFlat;
                          TimeInForce = TimeInForce.Gtc;
                          TraceOrders = true;
                          RealtimeErrorHandling = RealtimeErrorHandling.StopCancelCloseIgnoreRejects ;
                          StopTargetHandling = StopTargetHandling.PerEntryExecution;
                          BarsRequiredToTrade = 2;
                          I have tried and tried to wrap my head around with the prints but struggle with that. Could you help me with that please? Is it based on my entry conditions?

                          Thank you in advance,

                          Nick
                          Attached Files

                          Comment


                            #14
                            Hello Nick,

                            Simply put: Each time an order is submitted, it would mean the order submission method was reached.

                            The same can be said for any action that is taken programmatically.

                            The first step would be to confirm the symptom is from a specific part of code.

                            1. Add a print next to the order submission method(s)

                            Code:
                            if ((High[1] <= High[2])
                            && (Low[1] >= Low[2])
                            && (GetCurrentBid(0) > High[1])
                            && (GetCurrentBid(0) > Opens[1][0])
                            && (GetCurrentBid(0) > Opens[2][0])
                            && (GetCurrentBid(0) > Opens[3][0])
                            && (GetCurrentBid(0) > Opens[4][0])
                            && (GetCurrentBid(0) > Highs[4][1])
                            && ((BarsSinceExitExecution(0, @"15RunnerBreakeven", 0) > 0)
                            || (BarsSinceExitExecution(0, @"15RunnerBreakeven", 0) == -1)))
                            
                            {
                            [B]    Print("Order Submission method reached at Line 123!");[/B]
                                EnterLongLimit(Convert.ToInt32(Quantity), (High[1] + (LimitOrderSlippage * TickSize)), @"15Long1-2U");
                            }
                            2. Then open the Control Center's New > NinjaScript Output window.

                            3. Test to reproduce the issue, and check the Output window. How many times do you see this print?

                            The above would confirm that your order logic is allowing the method to be reached and submit the orders.

                            You can use prints to examine what you are using in your conditions to see how the logic is becoming true.

                            The example print below would be how to look at the first part of your condition. You would want to print out each part of your larger condition to see how it evaluates and why the order submission method is being reached. Knowing what specifically is not working for your entry logic will be key for making appropriate changes.

                            Code:
                            [B]Print(High[1] + " " + High[2]);[/B]
                            
                            [B]if ((High[1] <= High[2])[/B]
                            && (Low[1] >= Low[2])
                            && (GetCurrentBid(0) > High[1])
                            && (GetCurrentBid(0) > Opens[1][0])
                            && (GetCurrentBid(0) > Opens[2][0])
                            && (GetCurrentBid(0) > Opens[3][0])
                            && (GetCurrentBid(0) > Opens[4][0])
                            && (GetCurrentBid(0) > Highs[4][1])
                            && ((BarsSinceExitExecution(0, @"15RunnerBreakeven", 0) > 0)
                            || (BarsSinceExitExecution(0, @"15RunnerBreakeven", 0) == -1)))
                            
                            {
                                Print("Order Submission method reached at Line 123!");
                                EnterLongLimit(Convert.ToInt32(Quantity), (High[1] + (LimitOrderSlippage * TickSize)), @"15Long1-2U");
                            }
                            4. Examine the prints and look up each item used in the Help Guide if you need to look up specifics on how they work.

                            As a tip for debugging, narrow prints to specific bars. For example, you can check if (CurrentBars[0] == 12345) { } and place your prints inside that condition and those prints would only be seen on bar 12345. The Data Box can be used to display bar indexes and this can help to narrow prints to specific bars, and this makes the debugging prints less overwhelming.

                            GetCurrentBid - https://ninjatrader.com/support/help...currentbid.htm

                            BarsSinceExitExecution - https://ninjatrader.com/support/help...texecution.htm

                            Another item to note is that if you are using GetCurrentBid/GetCurrentAsk, you will be referencing the Close price of the given data series when you are processing historical data. GetCurrentBid/GetCurrentAsk give the current bid/ask from

                            You are also providing 0 as the BarsInProgress index to GetCurrentBid/GetCurrentAsk, so you would be getting the Close of the primary bar when you process historical data. If we use GetCurrentAsk(1), we would fetch from the first added data series. And If this is while we are processing historical data, it would be the Close of that added data series.

                            If you want to reference the bid/ask that is stamped from each Last tick (Last as in Last Qualified Tick) you can reference them from the single tick data series with: BarsArray[1].GetAsk(CurrentBars[1]);

                            Bars.GetAsk - https://ninjatrader.com/support/help...tml?getask.htm

                            Regarding your settings:

                            When I test the attached test script with your settings and Tick Replay, I do not get an issue of repeated submissions.

                            It also does not look like you are submitting orders to the single tick data series.

                            Entering/Exiting and Retrieving Position information - https://ninjatrader.com/support/help...ionInformation

                            See EnterLongLimit documentation for the syntax on using the right method overload for submitting to a specific data series (BarsInProgress Index)

                            EnterLongLimit(int barsInProgressIndex, bool isLiveUntilCancelled, int quantity, double limitPrice, string signalName)

                            EnterLongLimit - https://ninjatrader.com/support/help...rlonglimit.htm
                            Attached Files
                            Last edited by NinjaTrader_Jim; 05-03-2022, 01:12 PM.
                            JimNinjaTrader Customer Service

                            Comment


                              #15
                              Jim,

                              Thank you for your detailed response. I worked my way through points 1-3 and added the prints. As you suggested, my "glitch" is my logic evaulating as true and entering a trade.

                              Now what I am trying to figure out is how it could be taking more than one entry when I have entries per direction set at 1.

                              I also added this logic to try and fix the problem with no success.

                              Code:
                              Position.MarketPosition == MarketPosition.Flat

                              Thoughts on this?

                              Also I changed my entry logic to as follows to enter based on the 1

                              Code:
                              EnterLongLimit(0, false, Convert.ToInt32(Quantity), (High[1] + (LimitOrderSlippage * TickSize)) , @"15Long1-2U");
                              Is this what you were suggesting I do in the last part of you previous post?

                              Thank you again for the thorough reply.

                              Talk to you soon,

                              Nick

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by kevinenergy, 02-17-2023, 12:42 PM
                              115 responses
                              2,699 views
                              1 like
                              Last Post kevinenergy  
                              Started by prdecast, Today, 06:07 AM
                              1 response
                              4 views
                              0 likes
                              Last Post NinjaTrader_LuisH  
                              Started by Christopher_R, Today, 12:29 AM
                              1 response
                              14 views
                              0 likes
                              Last Post NinjaTrader_LuisH  
                              Started by chartchart, 05-19-2021, 04:14 PM
                              3 responses
                              577 views
                              1 like
                              Last Post NinjaTrader_Gaby  
                              Started by bsbisme, Yesterday, 02:08 PM
                              1 response
                              15 views
                              0 likes
                              Last Post NinjaTrader_Gaby  
                              Working...
                              X