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

strategies with one market and one stop market entry orders.

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

    strategies with one market and one stop market entry orders.




    people with nt,



    i have several trend following strategies that are very simple.



    in the case of a downtrend, the strategy will sell 1 contract short (of having it) and attach stop loss and breakeven stop orders to the position. this works well, the position will be held until it is stopped or until the downtrend condition is made to end.


    my strategies typically open positions at extremes and there is almost always a temporary pullback against the direction i have opened my position in. because of this i am interested in adding code to my strategies so that every position will sell one contract short at market and a second entry will be placed some points above the current price. i would use the inverse of this methodology for long positions.


    so, i want to understand whether the following position management would be possible in nt, specially if a strategy like i describe below could be backtested - optimized.


    if a downtrend starts:


    enter short = open short position sell 1 contract short at close market ; ordinary position
    and place stop order sell short position for 1 contract at close + 16 points; pullback position



    and the position management i have in mind would be as follows:

    ordinary position would have stop loss and breakeven stop orders attached to it. if price is mostly made to move in my favor, then i would have only 1 contract at risk. when this position is closed all stops should be cancelled and the second entry order that was never opened should also be cancelled.

    if price is made to move against my initial ordinary position, and the pullback position is indeed executed - filled, then i would want stop loss and breakeven stop orders to be attached to and calculated for the entire 2 contract position. this larger position will then either be held until the downtrend condition is made to end or will be stopped out.



    this would be one single condition and one single entry with two separate orders, so i don't think it should be understood as pyramiding. i think i would only need a very simple working sample.


    very well, thanks, regards.

    #2
    Originally posted by rtwave View Post
    enter short = open short position sell 1 contract short at close market ; ordinary position
    and place stop order sell short position for 1 contract at close + 16 points; pullback position

    this would be one single condition and one single entry with two separate orders, so i don't think it should be understood as pyramiding. i think i would only need a very simple working sample.
    It's called "scaling in", not "pyramiding".

    [EDIT: The opposite is called "scaling out" -- where multiple exit orders (aka, profit targets)
    are used to exit the position.]

    I understand it's one single condition, that's entirely dependent on your code, but by definition,
    scale in requires two separate entry orders, because it is, by definition, two separate entries.

    Managed or Unmanaged, doesn't matter, it's still two separate entry orders. The concepts
    of "scale-in" and "scale-out" are standard trading terms, not beholden to NinjaTrader.

    Seriously, the idea that you're doing "one single entry" with "two separate orders" is simply
    incorrect. Don't say it that way, you're just gonna confuse yourself later.

    You are opening one position with a sell order, and then adding to that same position
    with a second sell stop order. These are two separate entry orders, with the second
    entry order adding contracts to the same position created by the first entry order.

    Two separate entry orders mean two separate entries -- why you think otherwise
    is unknown -- but to continue that thinking will cause chaos as you gain experience.

    [EDIT: Also when looking at Trade Performance, each entry order is its own row,
    so two entry orders results in (at least) two rows of data.]

    Also, "ordinary" position vs "pullback" position is unholy.
    Don't think that way -- it is one single position and you are scaling in to create it.

    The single position will have an Average Entry Price, but this is obviously just the
    Fill prices from the two entry orders averaged together.

    And, yes, it can be done.
    Works great.

    Comment


      #3
      Hello rtwave,

      Thank you for your post.

      bltdavid is correct. This would be considered scaling into a position and it would require two separate entry orders to be placed.

      Scaling into a position is controlled with the signal names of your strategy, and properties EntryHandling and EntriesPerDirection. This reference sample can help with scaling in and out of a strategy.
      https://ninjatrader.com/support/helpGuides/nt8/en-us/scaling_out_of_a_position.htm

      This sample can assist further with managing multiple exit/entry signals:
      https://ninjatrader.com/support/helpGuides/nt8/en-us/using_multiple_entry_exit_sign.htm

      Please let us know if we may be of further assistance.
      Brandon H.NinjaTrader Customer Service

      Comment


        #4





        thanks.


        nt does not include a native breakeven stop order, however it is possible to use a ordinary stop loss order and then move it to the entry price once a position has reached a defined profit amount. i have learned how to do this and i think that it should also be possible to achieve what i have in mind with profit - loss and boolean conditionals.


        i will take a look at the nt links that have been posted.



        anyway, i will point out that the nt platform is overwhelmed when one tries to optimize a strategy which includes the conditional breakeven stop code i mentioned above. the same strategy without this code will take something like 60 minutes to optimize but when one includes the breakeven this can take more than 5 times that amount of time. i think that in all likelihood, including even more complicated conditionals for position management should be much more problematic for the platform.


        i will have to see how this works out.

        Comment


          #5
          Hello rtwave,

          Thank you for your note.

          When it comes to running Optimizations, computer memory is important for long resource-intensive tests that generate a large number of trades without your machine stalling. Computer processor speed is important to get optimization iterations done quickly and the number of CPU cores allows for more iterations to run simultaneously.

          My colleague Jim has created a video demonstrating how the SampleMACrossover strategy, a simple strategy that utilizes IsInStantiatedOnEachOptimizationIteration=false for efficiency, can still quickly utilize memory resources.

          Demo — https://drive.google.com/file/d/15pz...w?usp=drivesdk

          As we can see there are a number of factors that are involved and memory utilization can climb very quickly depending on a few of these factors. Once memory gets maxed out, we can experience short freezes where memory is decommitted, stored to disk, and then new resources are committed before the backtest is resumed.

          We can easily control the number of iterations involved and we can also consider writing our strategies to use IsInstantiatedOnEachOptimizationIteration = false; (Which requires that we reset class level variables in State.DataLoaded.)

          See the help guide documentation below for more information about running optimizations.
          IsInstantiatedOnEachOptimizationIteration — https://ninjatrader.com/support/help...niteration.htm
          Optimization Tips — https://ninjatrader.com/support/help...ionPerformance
          Walk Forward Optimization — https://ninjatrader.com/support/help...ss_metrics.htm
          Genetic Optimization — https://ninjatrader.com/support/help..._algorithm.htm

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

          Comment


            #6
            Originally posted by rtwave View Post
            nt does not include a native breakeven stop order, however it is possible to use a ordinary stop loss order and then move it to the entry price once a position has reached a defined profit amount. i have learned how to do this ...
            Awesome!

            Yep, that's exactly correct -- to effect the "move to breakeven" you had to
            move an existing Stop order by updating its Stop price.

            You're doing well, but I'd like to continue to correct your thinking.
            (Please don't think I'm picking on you -- these concepts are universal
            and I enjoy teaching -- so stay with me and scoop up this knowledge.)

            Knowing the different order types is important.
            There are only a few, mainly Market, Limit, and Stop orders.
            Almost every order type in existence uses one of these three as its basic operation.

            But, there is no such order type as a "Breakeven Stop" or "Ordinary Stop", much
            less "native" versions of these.

            "Breakeven" is a procedure applied to move an existing Stop order.
            It is not an order type.

            Similarly, "Auto Trail" is a procedure applied to move an existing Stop order.
            It is not an order type.

            The name "Stop Loss" is sometimes used as a synonym for a Stop order,
            but saying "Stop Loss" implies several additional things:
            If you're Long, a sell Stop order is entered below your entry price.
            If you're Short, a buy Stop order is entered above your entry price.
            We conveniently call both of these Stop orders a "Stop Loss" order.

            Why?
            In both cases the order type is simple -- it is a Stop order -- but the vocabulary
            is such that "Stop Loss" conveys the intention of the order, which is to exit the
            position and attempt to limit your losses to a certain amount. I say "attempt"
            because the underlying Stop order is subject to slippage.

            Thus, we have,
            "Stop Loss" is a procedure applied in how a Stop order is created.

            See the distinctions?

            -=o=-

            Another hard thing to grasp for a lot of folks is that a Stop order can also be
            used as an entry order -- for ex, a buy Stop order is a Stop order entered above
            market price -- it waits there, and when price rises to the Stop price, the buy
            Stop order becomes a buy Market order, and you are Long.

            There are other variations and combinations, but almost all of them utilize
            these basic order types (sometimes together, such as a Stop Limit order).

            My point is:
            The three basic order types are the primary foundation for all orders.

            In speech, a person's trading vocabulary is usually kinda loose, many things
            are inferred from context. But when it gets written, it helps to be more precise.

            Updating your vocabulary will be helpful to you, especially as you learn from
            other educational sources and tutorials, both here and elsewhere on the web.

            Happy Trading!


            Comment


              #7



              people with nt,



              i need some help.


              i have been working on these additional conditional orders i'm interested in.


              i have the code below to transform stop loss orders into breakeven stops:



              Code:
              
              else if(BarsInProgress == 1)
              {
              
              
              
              if (Position.MarketPosition != MarketPosition.Short)
              {
              SetStopLoss(@"shortposition", CalculationMode.Ticks, Numberticks, false);
              Setbreakeven = true;
              }
              else if (Position.MarketPosition == MarketPosition.Short)
              {
              if ( Setbreakeven == true && Close[0] < ( Position.AveragePrice - ( Profit * TickSize ) ) )
              {
              SetStopLoss(@"shortposition", CalculationMode.Price, ( Position.AveragePrice - ( Numberticks * TickSize ) ) , false);
              Setbreakeven= false;
              }
              }
              
              if (Position.MarketPosition != MarketPosition.Long)
              {
              SetStopLoss(@"longposition", CalculationMode.Ticks, Stlonuti, false);
              Setbreakeven= true;
              }
              else if (Position.MarketPosition == MarketPosition.Long)
              {
              if ( Setbreakeven== true && Close[0] > ( Position.AveragePrice + ( Profit * TickSize ) ) )
              {
              SetStopLoss(@"longposition", CalculationMode.Price, ( Position.AveragePrice + ( Numberticks * TickSize ) ), false);
              Setbreakeven= false;
              }
              }

              i have worked the segment below to the following:

              else if (Position.MarketPosition == MarketPosition.Short)
              {
              if ( Pullbackposition == true && High[0] > ( Position.AveragePrice + ( Pullbackticks * TickSize ) ) )
              {
              EnterShort(Convert.ToInt32(Pullbacksize), @"shortpositionpullback");
              SetStopLoss(@"shortpositionpullback", CalculationMode.Price, ( Position.AveragePrice + ( Toslnuti * TickSize ) ) , false);
              SetStopLoss(@"shortposition", CalculationMode.Price, ( Position.AveragePrice + ( Numberticks * TickSize ) ) , false);
              Pullbackposition = false;
              }
              }


              from what i have observed, the fact that the second entry "shortpositionpullback" and the stop loss orders are all sent simultaneously is problematic. i want the second group of stop loss orders to use the Position.AveragePrice for all the positions and all the contracts in my account for the relevant symbol and thus the second stop loss should work globally and be set at one same price level. it seems to me that as i have structured this code so far, the platform cannot have the updated and correct Position.AveragePrice as it is being calculated at the same time a second entry order is being sent.


              if this observation is correct, ¿is there any way to delay the second group of stop loss orders so that they will operate in tandem and manage the strategy's cumulative position as one? or ¿could it be necessary to reformulate these secondary orders significantly to achieve that same objective?



              very well, regards.
              Last edited by rtwave; 03-24-2021, 10:10 AM.

              Comment


                #8
                Hello rtwave,

                The Strategy Position object is based on Executions. Set methods will prep NinjaTrader to submit Target/Stop when the associated Enter order fills. If you would like to update and place your stop losses relative to Position.AveragePrice when that entry order fills/executes, I would suggest then to use OnExecutionUpdate to place/move the stop loss orders because the Position object will be updated with the current position at that point.

                Also to note, because Set methods prep NinjaTrader to submit target/stop orders, they should be submitted before the associated Entrer method, otherwise a previous level may be used. It would not be recommended to use Set methods in OnExecutionUpdate, so you may wish to use Exit methods for your target/stops and use OnExecutionUpdate to submit initial stop losses, and when the second entry fills and is seen in OnExecutionUpdate, to submit the new stop and existing stop to your desired level.

                SampleOnOrderUpdate provides a good demonstration for using OnExecutionUpdate to submit Exit orders for target/stop.

                SampleOnOrderUpdate - https://ninjatrader.com/support/help...and_onexec.htm

                We look forward to assisting.
                JimNinjaTrader Customer Service

                Comment


                  #9



                  people with nt, NinjaTrader_Jim,


                  thanks.


                  i have read your comment very carefully.


                  these advanced onorder and onexecution update override methods seem fantastic for anyone who wants to manage positions with absolute precision.



                  however, i took a look at the one sample i found here:





                  and this fragment below makes me think that these advanced methods will not work if one wants to backtest - optimize strategies:


                  else if (State == State.Realtime)
                  {
                  // one time only, as we transition from historical
                  // convert any old historical order object references
                  // to the new live order submitted to the real-time account
                  if (entryOrder != null)
                  entryOrder = GetRealtimeOrder(entryOrder);
                  if (stopOrder != null)
                  stopOrder = GetRealtimeOrder(stopOrder);
                  if (targetOrder != null)
                  targetOrder = GetRealtimeOrder(targetOrder);
                  }



                  so, assuming my interpretation of this code above is acceptable and that the advanced methods won't work to backtest - optimize strategies, ¿is there any more rudimentary way to make sure that the nt platform will be able to manage a position that has been created by two different orders as one, and manage their stop loss price levels also as one? from the backtests i have ran it seems that the second entry does work as intended when a defined profit - loss amount is hit, but in the charts there are trades where i see two different exits and two different price levels and this is what i want to avoid. ¿could it be possible to delay 1, 2, 3 seconds after the second entry, the code that would set the second set of stop loss orders so that Position.AveragePrice can be updated and correct? ¿or maybe use a different second profit - loss amount to generate this second set? i'm interested in backtesting whether these additional conditional entries would be profitable and solid position management, so i'm interested in a structure that can be backtested - optimized and there must be ingenious coding solutions to enable the platform to manage positions as i have in mind.



                  very well, thanks, regards.

                  Comment


                    #10
                    Hello rtwave,

                    Thank you for your note.

                    ...and this fragment below makes me think that these advanced methods will not work if one wants to backtest - optimize strategies:

                    The SampleOnOrderUpdate example script would be able to be backtested in the Strategy Analyzer. That section of code would only update Historical order references if the State transitions from Historical to Realtime. Since backtests use historical processing, this section of code would not process since the State never transitions from Historical to Realtime. This means the Historical order references would be used in the script.

                    ¿is there any more rudimentary way to make sure that the nt platform will be able to manage a position that has been created by two different orders as one, and manage their stop loss price levels also as one?

                    Are you referring to scaling into a position and managing the stop loss order with one order as opposed to two? Scaling into a position is controlled with the signal names of your strategy, and the properties EntryHandling and EntriesPerDirection. This reference sample can help with scaling in and out of a strategy.
                    https://ninjatrader.com/support/helpGuides/nt8/en-us/scaling_out_of_a_position.htm

                    ¿could it be possible to delay 1, 2, 3 seconds after the second entry, the code that would set the second set of stop loss orders so that Position.AveragePrice can be updated and correct?

                    This would not be possible in a backtest since backtests are run all at once. If you want to get the Position for the scaled-in position, you should follow my colleague Jim's suggestion in post #8 and look for the second order to execute in OnExecutionUpdate.

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

                    Comment


                      #11



                      people with nt,



                      i have been looking at these onorderupdate and onexecutionupdate functionalities. it seems that these are potent tools but it will be quite a challenge for a non-programmer like me to learn to use them.




                      now, i have read these entries on the support guide and at the very bottom both promise additional resources that i haven't been able to find anywhere:



                      Additional Reference Samples
                      Additional reference code samples are available the NinjaScript Educational Resources section of our support forum.







                      ¿are there really any other resources to learn how to use these functionalities?






                      and i have taken a look at the sample strategy that nt makes available:


                      Code:
                      //
                      // Copyright (C) 2019, NinjaTrader LLC <www.ninjatrader.com>.
                      // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
                      //
                      #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.Data;
                      using NinjaTrader.NinjaScript;
                      using NinjaTrader.Core.FloatingPoint;
                      using NinjaTrader.NinjaScript.Indicators;
                      using NinjaTrader.NinjaScript.DrawingTools;
                      #endregion
                      
                      // This namespace holds all strategies and is required. Do not change it.
                      namespace NinjaTrader.NinjaScript.Strategies
                      {
                      public class SampleOnOrderUpdate : Strategy
                      {
                      private Order entryOrder = null; // This variable holds an object representing our entry order
                      private Order stopOrder = null; // This variable holds an object representing our stop loss order
                      private Order targetOrder = null; // This variable holds an object representing our profit target order
                      private int sumFilled = 0; // This variable tracks the quantities of each execution making up the entry order
                      
                      protected override void OnStateChange()
                      {
                      if (State == State.SetDefaults)
                      {
                      Description = @"Sample Using OnOrderUpdate() and OnExecution() methods to submit protective orders";
                      Name = "SampleOnOrderUpdate";
                      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.ByStrategyPosition;
                      BarsRequiredToTrade = 20;
                      }
                      else if (State == State.Realtime)
                      {
                      // one time only, as we transition from historical
                      // convert any old historical order object references
                      // to the new live order submitted to the real-time account
                      if (entryOrder != null)
                      entryOrder = GetRealtimeOrder(entryOrder);
                      if (stopOrder != null)
                      stopOrder = GetRealtimeOrder(stopOrder);
                      if (targetOrder != null)
                      targetOrder = GetRealtimeOrder(targetOrder);
                      }
                      }
                      
                      protected override void OnBarUpdate()
                      {
                      // Submit an entry market order if we currently don't have an entry order open and are past the BarsRequiredToTrade bars amount
                      if (entryOrder == null && Position.MarketPosition == MarketPosition.Flat && CurrentBar > BarsRequiredToTrade)
                      {
                      /* Enter Long. We will assign the resulting Order object to entryOrder1 in OnOrderUpdate() */
                      EnterLong(1, "MyEntry");
                      }
                      
                      /* If we have a long position and the current price is 4 ticks in profit, raise the stop-loss order to breakeven.
                      We use (7 * (TickSize / 2)) to denote 4 ticks because of potential precision issues with doubles. Under certain
                      conditions (4 * TickSize) could end up being 3.9999 instead of 4 if the TickSize was 1. Using our method of determining
                      4 ticks helps cope with the precision issue if it does arise. */
                      if (Position.MarketPosition == MarketPosition.Long && Close[0] >= Position.AveragePrice + (7 * (TickSize / 2)))
                      {
                      // Checks to see if our Stop Order has been submitted already
                      if (stopOrder != null && stopOrder.StopPrice < Position.AveragePrice)
                      {
                      // Modifies stop-loss to breakeven
                      stopOrder = ExitLongStopMarket(0, true, stopOrder.Quantity, Position.AveragePrice, "MyStop", "MyEntry");
                      }
                      }
                      }
                      
                      protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
                      {
                      // Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order.
                      // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
                      // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting
                      if (order.Name == "MyEntry")
                      {
                      entryOrder = order;
                      
                      // Reset the entryOrder object to null if order was cancelled without any fill
                      if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                      {
                      entryOrder = null;
                      sumFilled = 0;
                      }
                      }
                      }
                      
                      protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
                      {
                      /* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate()
                      which ensures your strategy has received the execution which is used for internal signal tracking. */
                      if (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;
                      
                      // 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");
                      }
                      
                      // 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;
                      }
                      }
                      }
                      
                      // Reset our stop order and target orders' Order objects after our position is closed. (1st Entry)
                      if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
                      {
                      if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
                      {
                      stopOrder = null;
                      targetOrder = null;
                      }
                      }
                      }
                      }
                      }



                      that sample could not be any more minimal. and it leaves me with a lot of questions about how many override voids, objects and how many units of every different element would be necessary to use these update functionalities if one has multiple different types of entries. so, if nt could provide a working sample of any strategy (preferably the price - ema crossover i will include in the next post) with both short and long positions where all positions are managed with stop loss and profit target orders by making use of these update overrides that would be fantastic.


                      (as an aside, i have enabled the sample strategy above in several charts and it will only place 1 or 2 trades and then stop definitely. this makes no sense to me because from what i can see in the code, it should keep making the same entry every single bar if there is no position open.)



                      very well, regards.

                      Comment


                        #12



                        these fora would not accept this strategy in the post above as then the site complained that there were too many characters.


                        this is a very simple strategy that could nicely serve to exemplify how to use the onbarupdate and onexecutionupdate tools to manage the positions of a long and short strategy.



                        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 sampleemacrossover : Strategy
                        {
                        private EMA EMA1;
                        
                        
                        protected override void OnStateChange()
                        {
                        if (State == State.SetDefaults)
                        {
                        Description = @"sampleemacrossover";
                        Name = "sampleemacrossover";
                        Calculate = Calculate.OnBarClose;
                        EntriesPerDirection = 1;
                        EntryHandling = EntryHandling.UniqueEntries;
                        IsExitOnSessionCloseStrategy = false;
                        ExitOnSessionCloseSeconds = 10;
                        IsFillLimitOnTouch = false;
                        MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
                        OrderFillResolution = OrderFillResolution.Standard;
                        Slippage = 8;
                        StartBehavior = StartBehavior.ImmediatelySubmitSynchronizeAccount;
                        TimeInForce = TimeInForce.Gtc;
                        TraceOrders = true;
                        RealtimeErrorHandling = RealtimeErrorHandling.StopCancelCloseIgnoreRejects ;
                        StopTargetHandling = StopTargetHandling.PerEntryExecution;
                        BarsRequiredToTrade = 10;
                        // Disable this property for performance gains in Strategy Analyzer optimizations
                        // See the Help Guide for additional information
                        IsInstantiatedOnEachOptimizationIteration = true;
                        Positionsize = 1;
                        Emap = 10;
                        
                        }
                        else if (State == State.Configure)
                        {
                        }
                        else if (State == State.DataLoaded)
                        {
                        EMA1 = EMA(Close, Convert.ToInt32(Emap));
                        }
                        }
                        
                        protected override void OnBarUpdate()
                        {
                        if (CurrentBars[0] < 1)
                        return;
                        
                        // Set 1
                        if (Close[0] < EMA1[0])
                        {
                        EnterShort(Convert.ToInt32(Positionsize), @"shortposition01");
                        }
                        
                        
                        // Set 2
                        if (Close[0] > EMA1[0])
                        {
                        EnterLong(Convert.ToInt32(Positionsize), @"longposition01");
                        }
                        
                        
                        }
                        
                        #region Properties
                        [NinjaScriptProperty]
                        [Range(1, int.MaxValue)]
                        [Display(ResourceType = typeof(Custom.Resource), Name="Emap", Description="ema", Order=1, GroupName="NinjaScriptStrategyParameters")]
                        public int Emap
                        { get; set; }
                        
                        [NinjaScriptProperty]
                        [Range(1, int.MaxValue)]
                        [Display(ResourceType = typeof(Custom.Resource), Name="Positionsize", Description="position size", Order=2, GroupName="NinjaScriptStrategyParameters")]
                        public int Positionsize
                        { get; set; }
                        #endregion
                        
                        }
                        }

                        Comment


                          #13
                          Hello rtwave,

                          Thank you for your note.

                          The SampleOnOrderUpdate script is the additional resources referred to in the OnOrderUpdate() and OnExecutionUpdate() help guide documentations. OnOrderUpdate() and OnExecutionUpdate() would only need to be called once within your strategy. Then, any OnOrderUpdate() logic in your script would be placed in the OnOrderUpdate() method.The same goes for the OnExecutionUpdate() method. OnExecutionUpdate() would only be called once in the script and any OnExecutionUpdate() logic would be placed in that methon.

                          I have modified and attached the SampleOnOrderUpdate script to demonstrate using Long and Short orders and managing positions with OnOrderUpdate() and OnExecutionUpdate(). The example script enters Long or Short depending on if the current Close price is greater than or less than an EMA indicator. Then, positions are managed within OnOrderUpdate() and OnExecutionUpdate().

                          See the help guide documentation below for more information.
                          OnOrderUpdate() - https://ninjatrader.com/support/help...rderupdate.htm
                          OnExecutionUpdate() - https://ninjatrader.com/support/help...tionupdate.htm
                          SampleOnOrderUpdate - https://ninjatrader.com/support/help...and_onexec.htm

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

                          Comment


                            #14





                            people with nt, NinjaTrader_BrandonH,



                            thanks.



                            i think i'm doing some progress.


                            i have two different short and two long entries. i will concentrate on one side for now, the other side would only need to be inverted.


                            i'm thinking i would just have to create this fragment of code in the onorderupdate method for every single different entry in my code:


                            else if (order.Name == "ordinaryshortposition/pullbackshortposition and the same for every long position")
                            {
                            entryOrder = order;

                            // Reset the entryOrder object to null if order was cancelled without any fill
                            if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                            {
                            entryOrder = null;
                            sumFilled = 0;
                            }
                            }



                            however, i have been taking a look at the onexecutionupdate method and it only deals with a single order for one single position. i would appreciate if the people with nt could help me to code one stop order for ordinaryshortposition and another consolidated or coordinated stop if and when pullbackshortposition is executed.


                            for ordinaryshortposition, i think this would achieve what i have in mind:

                            stopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( 100 * TickSize ), "ordinaryshortstop", "ordinaryshortposition");


                            and then, if pullbackshortposition happens to be executed i think i would need two stop orders:


                            stopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( 70 * TickSize ), "pullbackshortstop1", "ordinaryshortposition");

                            stopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( 70 * TickSize ), "pullbackshortstop2", "pullbackshortposition");


                            (i'm not sure about this, the price level is definitely correct and what i have in mind, but i don't know whether it would be possible to use one single order for the consolidated position or two separate orders and where i should place and condition them. also, the sample that nt provides includes a lot of code that would deal with partial fills, i don't think this would be necessary for my strategy (i use market entries for 1 contract each) but i don't think that leaving that code in the strategy would cause any harm and it could eventually be helpful if i work with larger position sizes later.)




                            and finally, assuming that both ordinaryshortposition and pullbackshortposition have been executed and that the consolidated position has now been made to move at least 180 ticks in my favor i would want to move the stoporder(s) to breakeven. i understand that would be done on the onbarupdate method i just want to make sure that an structure of this kind would be appropriate.



                            if (Position.MarketPosition == MarketPosition.Short && Close[0] <= ( Position.AveragePrice - ( 180 * TickSize ) )
                            {
                            // Checks to see if our Stop Order has been submitted already
                            if (stopOrder != null && stopOrder.StopPrice > Position.AveragePrice)
                            {
                            // Modifies stop-loss to breakeven
                            stopOrder = ExitShortStopMarket(0, true, stopOrder.Quantity ¿?, Position.AveragePrice, "breakevenstop", " ¿1 or 2 orders? ");
                            }
                            }





                            very well, those are the parts that have held me back when trying to use these advanced methods, regards.

                            Comment


                              #15
                              Hello rtwave,

                              Thank you for your note.

                              OnExecutionUpdate() and OnOrderUpdate() can be used to track any number of Order objects.

                              You would need to create an order object for each order that you would like to manage in your script. For example, if you have more than one entry order, stop order, and profit target order then you would need to create different variables for these orders. For example:

                              Code:
                              [I]private Order stopOrder2 = null; // This variable holds an object representing our stop loss order of the second trade
                              private Order targetOrder2 = null; // This variable holds an object representing our profit target order of the second trade
                              private Order entryOrder2 = null; // This variable holds an object representing our entry of the second trade[/I]
                              In OnOrderUpdate() you would then check if the entry order.Name is the name of the second entry order, followed by assigning that order to your second entry order variable.

                              Code:
                              [I]if(order.Name == "pullbackshortposition")
                              {
                                  entryOrder2 = order;
                                  if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                                      {entryOrder2 = null;}
                              }
                              }[/I]
                              In OnExecutionUpdate() you would check if the second entry order variable is not null and set your second stop loss order. For example:

                              Code:
                              [I]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))
                                  {
                                      stopOrder2 = ExitLongStopMarket(0, true, [/I] execution.Order.Filled, execution.Order.AverageFillPrice + ( 70 * TickSize ), "pullbackshortstop1", "pullbackshortposition");
                              [I]    }
                              }[/I]
                              In regards to moving a stop loss to breakeven, that would be the correct syntax for modifying the stop loss to breakeven.

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

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by quantismo, 04-17-2024, 05:13 PM
                              5 responses
                              32 views
                              0 likes
                              Last Post NinjaTrader_Gaby  
                              Started by proptrade13, Today, 11:06 AM
                              1 response
                              5 views
                              0 likes
                              Last Post NinjaTrader_Clayton  
                              Started by love2code2trade, 04-17-2024, 01:45 PM
                              4 responses
                              34 views
                              0 likes
                              Last Post love2code2trade  
                              Started by cls71, Today, 04:45 AM
                              2 responses
                              10 views
                              0 likes
                              Last Post eDanny
                              by eDanny
                               
                              Started by kulwinder73, Today, 10:31 AM
                              1 response
                              10 views
                              0 likes
                              Last Post NinjaTrader_Erick  
                              Working...
                              X