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

Printing Entry & Exit Information

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

    Printing Entry & Exit Information

    Hi NinjaTrader support,

    Hope you can help please. I'm having some difficulties running a backtest of a strategy and trying to print order information to help me debug (once I get the print correct, I'll switch to using StreamWriter). I've read the documentation but I'm a little lost by some of the options and hoping you could advise please. Some context:

    1. My backtests have exit at end of day/session enabled

    2. When I create an order I set both a stoploss and profit target:

    Code:
    EnterLong(barsInProgressIndex:1, quantity:varOrderQty, signalName:"BuyLong");
    SetStopLoss(CalculationMode.Price, varStopLoss);
    SetProfitTarget(CalculationMode.Price, varTarget);
    3. I have additional logic (beyond the stoploss & profit target) to exit a position if certain conditions are met

    Code:
    if ([some logic here)
    {
    ExitLong(convertedBaseOrderQty, @"ExitBuyLong", @"BuyLong");
    }
    When the strategy enters a position, I'd like to print the fill price, qty, timestamp of fill and perhaps an ID if there is one, and when the strategy exits that position I'd like to print the same information (fill price, qty, timestamp of fill, ID). I'm not sure how to go about this...

    https://ninjatrader.com/support/help...?execution.htm has a note saying that end of day exits (context point 1) may not be captured.
    https://ninjatrader.com/support/help...rderupdate.htm looks like it may need to be the path I take when order.OrderState == OrderState.Filled, but I'm not sure how to retrieve the qty & fill price info from it (sorry most guides I can see relate to overriding, not just pulling info).
    I've also seen posts relating to account positions, so unsure if I'm even looking in the right direction with these methods.

    Please could you kindly advise or point to an example strategy that does this?

    Many thanks

    ChainsawDR

    #2
    Hi Chainsaw, thanks for posting.

    OnExecutionUpdate will be called whenever an execution occurs on the account along with a Position update with the marketPosition parameter



    The orders being filled/executed can be identified through the execution.Name parameter.

    Also note this caveat if using Rithmic or Interactive brokers:
    Rithmic and Interactive Brokers Users: Due to provider API design these adapters do not guarantee the sequence of events of OnOrderUpdate, OnExecution, and OnPositionUpdate. Therefore when working on a strategy that will run on these connections it is best practice to only work with passed by value data from that callback to eliminate the dependency on the sequence of events.

    Kind regards,
    -ChrisL

    Chris L.NinjaTrader Customer Service

    Comment


      #3
      Thanks for this Chris. Context point #1 still looks to be a problem with this approach. I've added this code:

      Code:
       protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
      {
      Print(execution.ToString());
      }
      Which produces the following output for stock JAGX, however my strategy is set to exit at the end of session so the OnExecutionUpdate does not print this.

      Code:
      Disabling NinjaScript strategy 'ASDFGH/238460732'
      JAGX is being used as the input series
      execution='NT-00000-8819' instrument='JAGX' account='Sim101' exchange=Default price=3.54 quantity=1,400 marketPosition=Long orderId='NT-00000-8819' time='2021-01-25 10:08:06' sod=False statementDate='0001-01-01'
      execution='NT-00001-8819' instrument='JAGX' account='Sim101' exchange=Default price=3.53 quantity=1,400 marketPosition=Short orderId='NT-00003-8819' time='2021-01-25 10:08:25' sod=False statementDate='0001-01-01'
      execution='NT-00002-8819' instrument='JAGX' account='Sim101' exchange=Default price=2.86 quantity=1,700 marketPosition=Long orderId='NT-00004-8819' time='2021-01-27 10:05:20' sod=False statementDate='0001-01-01'
      execution='NT-00003-8819' instrument='JAGX' account='Sim101' exchange=Default price=2.83 quantity=1,700 marketPosition=Short orderId='NT-00005-8819' time='2021-01-27 10:09:15' sod=False statementDate='0001-01-01'
      execution='NT-00004-8819' instrument='JAGX' account='Sim101' exchange=Default price=2.86 quantity=1,700 marketPosition=Long orderId='NT-00007-8819' time='2021-01-27 10:28:45' sod=False statementDate='0001-01-01'
      execution='NT-00005-8819' instrument='JAGX' account='Sim101' exchange=Default price=2.95 quantity=1,700 marketPosition=Short orderId='NT-00009-8819' time='2021-01-27 10:32:25' sod=False statementDate='0001-01-01'
      execution='NT-00006-8819' instrument='JAGX' account='Sim101' exchange=Default price=2.85 quantity=1,800 marketPosition=Long orderId='NT-00010-8819' time='2021-02-03 15:59:06' sod=False statementDate='0001-01-01'
      Enabling NinjaScript strategy 'ASDFGH/238460732' : On starting a real-time strategy - StartBehavior=WaitUntilFlat Position=JAGX 1800L, JAGX 1800L, JAGX 1800L EntryHandling=All entries EntriesPerDirection=1 StopTargetHandling=Per entry execution ErrorHandling=Stop strategy, cancel orders, close positions ExitOnSessionClose=True / triggering 30 seconds before close SetOrderQuantityBy=Strategy ConnectionLossHandling=Recalculate DisconnectDelaySeconds=10 CancelEntriesOnStrategyDisable=False CancelExitsOnStrategyDisable=False Calculate=On bar close IsUnmanaged=False MaxRestarts=4 in 5 minutes
      Do you have any other ideas please on how to print the executed trades? I note that the end position is 'JAGX 1800L' so it knows the long position is open for 1800 shares, but OnExecutionUpdate didn't trigger.

      Thanks again

      ChainsawDR

      Comment


        #4
        Hello ChainsawDR,

        When I read the Help Guide note, I understand the information being missing specifically for the Order object of the passing execution. When I test, this information is available in Playback and backtesting so I am checking further into that.

        Regardless, the help guide documentation states only the Order object information may specifically be missing. Other parameters may be available to identify exits. For example, checking the time of the execution and the market position of that execution can be used to identify if the execution was from an exit on session close.

        Attached is my test script and an example of the output I see if you want to have a look on your end. (I see similar results with Playback and in the Strategy Analyzer.) If there is something that you would like me to have a look at, please modify the example and share it back here so I may test the same.

        Attached Files
        JimNinjaTrader Customer Service

        Comment


          #5
          Thank you Jim this is super helpful. You are correct - running the backtest from Strategy Analyzer does show the end of session exit. I had run my debugging from a chart and the behavior is different (from a chart, OnExecutionUpdate doesn't trigger the print for the end of session exit, but from strategy analyzer it does trigger OnExecutionUpdate). This will work for me, thanks!

          Comment


            #6
            Hello ChainsawDR,

            Do you see the same testing my test script on a chart? I am thinking the Help Guide note needs to be updated. I see the [historical] Exit On Session Close prints from OnExecutionUpdate on a chart, also applying to a sim account and a paper trading account. My screenshot from post #4 shows realtime OnExecutionUpdate prints for Exit On Session Close.
            JimNinjaTrader Customer Service

            Comment


              #7
              Hi Jim,

              Yes I just tested your code with historical data on both a chart and via strategy analyzer. Strategy Analyzer printed all of the entries and exits.

              Code:
              orderId='NT-00020-9040' account='Backtest' name='Buy' orderState=Filled instrument='JAGX' orderAction=Buy orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.83 onBehalfOf='' id=-1 time='2021-02-02 09:30:05' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00020-9040' instrument='JAGX' account='Backtest' exchange=Default price=2.83 quantity=100 marketPosition=Long orderId='NT-00020-9040' time='2021-02-02 09:30:10' sod=False statementDate='0001-01-01'
              executionId: NT-00020-9040, price: 2.83, quantity: 100, marketPosition: Long, orderId: NT-00020-9040, time: 2/2/2021 9:30:10 AM
              
              orderId='NT-00021-9040' account='Backtest' name='Exit on session close' orderState=Filled instrument='JAGX' orderAction=Sell orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.73 onBehalfOf='' id=-1 time='2021-02-02 16:00:00' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00021-9040' instrument='JAGX' account='Backtest' exchange=Default price=2.73 quantity=100 marketPosition=Short orderId='NT-00021-9040' time='2021-02-02 16:00:00' sod=False statementDate='0001-01-01'
              executionId: NT-00021-9040, price: 2.73, quantity: 100, marketPosition: Short, orderId: NT-00021-9040, time: 2/2/2021 4:00:00 PM
              
              orderId='NT-00022-9040' account='Backtest' name='Buy' orderState=Filled instrument='JAGX' orderAction=Buy orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.79 onBehalfOf='' id=-1 time='2021-02-03 09:30:05' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00022-9040' instrument='JAGX' account='Backtest' exchange=Default price=2.79 quantity=100 marketPosition=Long orderId='NT-00022-9040' time='2021-02-03 09:30:10' sod=False statementDate='0001-01-01'
              executionId: NT-00022-9040, price: 2.79, quantity: 100, marketPosition: Long, orderId: NT-00022-9040, time: 2/3/2021 9:30:10 AM
              
              orderId='NT-00023-9040' account='Backtest' name='Exit on session close' orderState=Filled instrument='JAGX' orderAction=Sell orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.85 onBehalfOf='' id=-1 time='2021-02-03 16:00:00' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00023-9040' instrument='JAGX' account='Backtest' exchange=Default price=2.85 quantity=100 marketPosition=Short orderId='NT-00023-9040' time='2021-02-03 16:00:00' sod=False statementDate='0001-01-01'
              executionId: NT-00023-9040, price: 2.85, quantity: 100, marketPosition: Short, orderId: NT-00023-9040, time: 2/3/2021 4:00:00 PM
              The Chart approach printed all entries and exits EXCLUDING the final exit.

              Code:
              orderId='NT-00020-9039' account='Sim101' name='Buy' orderState=Filled instrument='JAGX' orderAction=Buy orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.83 onBehalfOf='' id=-1 time='2021-02-02 09:30:05' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00020-9039' instrument='JAGX' account='Sim101' exchange=Default price=2.83 quantity=100 marketPosition=Long orderId='NT-00020-9039' time='2021-02-02 09:30:10' sod=False statementDate='0001-01-01'
              executionId: NT-00020-9039, price: 2.83, quantity: 100, marketPosition: Long, orderId: NT-00020-9039, time: 2/2/2021 9:30:10 AM
              
              orderId='NT-00021-9039' account='Sim101' name='Exit on session close' orderState=Filled instrument='JAGX' orderAction=Sell orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.73 onBehalfOf='' id=-1 time='2021-02-02 16:00:00' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00021-9039' instrument='JAGX' account='Sim101' exchange=Default price=2.73 quantity=100 marketPosition=Short orderId='NT-00021-9039' time='2021-02-02 16:00:00' sod=False statementDate='0001-01-01'
              executionId: NT-00021-9039, price: 2.73, quantity: 100, marketPosition: Short, orderId: NT-00021-9039, time: 2/2/2021 4:00:00 PM
              
              orderId='NT-00022-9039' account='Sim101' name='Buy' orderState=Filled instrument='JAGX' orderAction=Buy orderType='Market' limitPrice=0 stopPrice=0 quantity=100 tif=Gtc oco='' filled=100 averageFillPrice=2.79 onBehalfOf='' id=-1 time='2021-02-03 09:30:05' gtd='2099-12-01' statementDate='2021-07-28'
              execution='NT-00022-9039' instrument='JAGX' account='Sim101' exchange=Default price=2.79 quantity=100 marketPosition=Long orderId='NT-00022-9039' time='2021-02-03 09:30:10' sod=False statementDate='0001-01-01'
              executionId: NT-00022-9039, price: 2.79, quantity: 100, marketPosition: Long, orderId: NT-00022-9039, time: 2/3/2021 9:30:10 AM
              Enabling NinjaScript strategy 'ExitOnCloseTest/238460733' : On starting a real-time strategy - StartBehavior=WaitUntilFlat Position=JAGX 100L EntryHandling=All entries EntriesPerDirection=1 StopTargetHandling=Per entry execution ErrorHandling=Stop strategy, cancel orders, close positions ExitOnSessionClose=True / triggering 30 seconds before close SetOrderQuantityBy=Strategy ConnectionLossHandling=Recalculate DisconnectDelaySeconds=10 CancelEntriesOnStrategyDisable=False CancelExitsOnStrategyDisable=False Calculate=On bar close IsUnmanaged=False MaxRestarts=4 in 5 minutes
              Yes I think updating the help section to help users understand this difference would be helpful.

              Thanks again for your help

              ChainsawDR

              Comment


                #8
                FYI I wasn't sure where to copy in your file so I recreated/copy-pasted in, this was the code used:

                Code:
                #region Using declarations
                using System;
                using System.Collections.Generic;
                using System.ComponentModel;
                using System.ComponentModel.DataAnnotations;
                using System.Linq;
                using System.Text;
                using System.Threading.Tasks;
                using System.Windows;
                using System.Windows.Input;
                using System.Windows.Media;
                using System.Xml.Serialization;
                using NinjaTrader.Cbi;
                using NinjaTrader.Gui;
                using NinjaTrader.Gui.Chart;
                using NinjaTrader.Gui.SuperDom;
                using NinjaTrader.Gui.Tools;
                using NinjaTrader.Data;
                using NinjaTrader.NinjaScript;
                using NinjaTrader.Core.FloatingPoint;
                using NinjaTrader.NinjaScript.Indicators;
                using NinjaTrader.NinjaScript.DrawingTools;
                #endregion
                
                //This namespace holds Strategies in this folder and is required. Do not change it.
                namespace NinjaTrader.NinjaScript.Strategies
                {
                public class ExitOnCloseTest : Strategy
                {
                protected override void OnStateChange()
                {
                if (State == State.SetDefaults)
                {
                Description = @"Enter the description for your new custom Strategy here.";
                Name = "ExitOnCloseTest";
                Calculate = Calculate.OnBarClose;
                EntriesPerDirection = 1;
                EntryHandling = EntryHandling.AllEntries;
                IsExitOnSessionCloseStrategy = true;
                ExitOnSessionCloseSeconds = 30;
                IsFillLimitOnTouch = false;
                MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
                OrderFillResolution = OrderFillResolution.Standard;
                Slippage = 0;
                StartBehavior = StartBehavior.WaitUntilFlat;
                TimeInForce = TimeInForce.Gtc;
                TraceOrders = false;
                RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
                StopTargetHandling = StopTargetHandling.PerEntryExecution;
                BarsRequiredToTrade = 20;
                // Disable this property for performance gains in Strategy Analyzer optimizations
                // See the Help Guide for additional information
                IsInstantiatedOnEachOptimizationIteration = true;
                }
                else if (State == State.Configure)
                {
                }
                }
                
                
                protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
                Cbi.MarketPosition marketPosition, string orderId, DateTime time)
                {
                Print("");
                Print(execution.Order.ToString());
                Print(execution.ToString());
                Print(String.Format("executionId: {0}, price: {1}, quantity: {2}, marketPosition: {3}, orderId: {4}, time: {5}", executionId, price, quantity, marketPosition.ToString(), orderId, time));
                }
                
                protected override void OnBarUpdate()
                {
                EnterLong();
                }
                }
                }
                I've attached the settings used.
                Attached Files

                Comment


                  #9
                  also attaching the output from the chart straetgy run of those settings (apologies if oversharing, I couldn't tell from your last post if you were or were not seeing different results to myself, so sharing everything I have). Thanks
                  Attached Files

                  Comment


                    #10
                    Hi Chainsaw,

                    The exit on session close strategy will report the exit on session close execution. I attached my test script if you would like to test it on a chart for yourself.

                    Kind regards.
                    Attached Files
                    Chris L.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by bsbisme, Yesterday, 02:08 PM
                    1 response
                    15 views
                    0 likes
                    Last Post NinjaTrader_Gaby  
                    Started by prdecast, Today, 06:07 AM
                    0 responses
                    3 views
                    0 likes
                    Last Post prdecast  
                    Started by i019945nj, 12-14-2023, 06:41 AM
                    3 responses
                    60 views
                    0 likes
                    Last Post i019945nj  
                    Started by TraderBCL, Today, 04:38 AM
                    2 responses
                    18 views
                    0 likes
                    Last Post TraderBCL  
                    Started by martin70, 03-24-2023, 04:58 AM
                    14 responses
                    106 views
                    0 likes
                    Last Post martin70  
                    Working...
                    X