Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Enter long stop limit

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

    Enter long stop limit

    Hi, I'm creating a strategy, and when I perform it manually I'm sending a "BuyStopLimit" or "SellStopLimit" order depending if I want to make a short or a long entry. How should I do it on ninjascript?

    I'm using the following code:

    HTML Code:
    string signalName = "Short entry zone " + i;
    
    // We enter the position
    
    Order myOrder = EnterShortStopLimit(1, entryPrice, stopPrice, signalName);                                        
    // Set take profit
    SetProfitTarget(signalName, CalculationMode.Price, takeProfitPrice);
    // Set stop loss
    //SetStopLoss(signalName, CalculationMode.Price, stopPrice, true);​
    But when I run a backtest with this strategy. No position is being opened

    Note: stopPrice, entryPrice and takeProfitPrice are variables previously calculated
    Last edited by speedytrade02; 09-06-2023, 03:37 AM.

    #2
    Hello speedytrade02,

    Thank you for your post.

    I see you are using SetProfitTarget() and SetStopLoss(). These methods should be called prior to entering a position. This would not be the reason you are not seeing a position being opened, but it is important to note and put into practice. For more information on SetProfitTarget() and SetStopLoss():I also see you are creating an order object called myOrder. Working with order objects is an advanced method of order handling; you have to be sure to transition historical order references, set orders to null when necessary, etc. For an overview, please see "The Order Class" on the following page:When your strategy is enabled, be sure to check the color of the strategy name on the Strategies tab of the Control Center. If the name is green, the strategy is in sync and ready to submit live orders. If it is orange/yellow, that means the strategy is waiting to become flat prior to submitting live orders. For more information about the strategy position vs. account position and syncing positions:Ultimately, TraceOrders can be a helpful debugging tool when developing a strategy and understanding its behavior. When set to true in State.SetDefaults, TraceOrders will send output to the NinjaScript Output window related to orders and whether they are submitted, ignored, changed, canceled, rejected, etc. I suggest enabling TraceOrders and reviewing the output as you test your strategy to gain helpful insights into the behavior of your strategy. This can help you to identify what you might need to change in order to get the desired behavior. For more info on TraceOrders:Please let us know if we may be of further assistance.

    Comment


      #3
      Hi Emily Thanks for your response.

      But I haven't fully understand how to solve this problem:

      I'm creating a strategy, and when I perform it manually I'm sending a "BuyStopLimit" or "SellStopLimit" order depending if I want to make a short or a long entry. How should I do it on ninjascript?
      Let's say that I have the variables:
      · entryPrice
      · stopPrice
      · takeProfitPrice

      How can I place a buyStopLimit or sellStopLimit order then?

      Maybe I should use EnterLongStopLimit()? and if so, How can I place the take profit? and How do i know when has this order hit the takeProfit or the stopLoss

      Thanks again!
      Last edited by speedytrade02; 09-06-2023, 08:10 AM.

      Comment


        #4
        Hello speedytrade02,

        Yes, for a stop limit order you can use EnterLongStopLimit() / EnterShortStopLimit() / ExitLongStopLimit() / ExitShortStopLimit() / or SubmitOrderUnmanaged (with the unmanaged approach).

        Below are links to the help guide.
        https://ninjatrader.com/support/help...gstoplimit.htm
        https://ninjatrader.com/support/help...runmanaged.htm

        For the profit target or 'take profit' limit order to exit the position, you can use ExitLongLimit() / ExitShortLimit() / or SubmitOrderUnmanaged.
        I recommend submitting this in OnExecutionUpdate() when the entry order fills.
        https://ninjatrader.com/support/help...tlonglimit.htm

        Below is a link to an example.
        https://ninjatrader.com/support/foru...269#post802269
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Thanks for the info Chelsea B.

          I've made some modifications on my code based on what you've said

          HTML Code:
          private Order lastOrder = null;
          private double TP = -1;
          protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time){
          
              if(marketPosition == MarketPosition.Long){
                  ExitLongLimit(TP);
              }
          
              else if(marketPosition == MarketPosition.Short){
                  ExitShortLimit(TP);
              }
          }
          protected override void OnBarUpdate(){
              // Rest strategy logic ...
              if(entrada == true){
          
                  Print("Hola Long 2");
                  if(lastOrder != null){
          
                      if(lastOrder.OrderState ==  OrderState.Submitted){
                          CancelOrder(lastOrder);
                      }
                      /*
                      else if (lastOrder.OrderState ==  OrderState.Filled){
                          return;
                      }
                      */
                  }
          
                  // generate a name for the signal with the number of the zone and the length of the position
                  string signalName = "Long entry zone " + i;
                  // We enter the position
                  TP = takeProfitPrice;
                  Order myOrder = EnterLongStopLimit(1, entryPrice, stopPrice, signalName);
          
                  Print("---------------------------------");
                  Print(Time[0]);
                  Print("Long2 ");
                  Print("Entry Price --> " + entryPrice);
                  Print("TP --> " + takeProfitPrice);
                  Print("SL --> " + stopPrice);
                  Print("---------------------------------");
                  using (StreamWriter writer = new StreamWriter(Fichero_Entradas, true)){
                      double Precio_Entrada = entryPrice;
                      double Take_Profit = takeProfitPrice;
                      double Stop_Loss = stopPrice;
          
                      // Format the data as a comma-separated string
                      string dataLine = string.Format("{0},{1},{2},{3},{4}", Time[0], "LONG", Precio_Entrada, Take_Profit, Stop_Loss);
                      // Write the data to the file
                      writer.WriteLine(dataLine);
                  }
                  // save last position to zonas[i]
                  lastOrder = myOrder;
              }
          }​
          But now, when I run the backtest. It's printing me on the output thi part
          HTML Code:
                  Print("---------------------------------");
                  Print(Time[0]);
                  Print("Long2 ");
                  Print("Entry Price --> " + entryPrice);
                  Print("TP --> " + takeProfitPrice);
                  Print("SL --> " + stopPrice);
                  Print("---------------------------------");​
          But no trade is being made at the end of the backtest

          What may be causing the problem?

          Comment


            #6
            Hello speedytrade02,

            Use the overload with isLiveUntilCancelled as true as demonstrated in the example I have provided a link to.

            Assign order objects to variables from OnOrderUpdate() only.


            Enable TraceOrders and print the order object in OnOrderUpdate() to understand the behavior of the strategy.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Hi Chelsea.

              I'm trying to print the EnterShortStopLimit order that I've saved on "myOrder" variable, but as you can see on th screenshot, nothing is being saved on the variable.

              Click image for larger version

Name:	image.png
Views:	665
Size:	14.0 KB
ID:	1267875

              I have the following code

              HTML Code:
                                                   if(entrada == true){
              
                                                                              Print("Hola Short 2");
              
                                                                              if(lastOrder != null){
              
                                                                                  if(lastOrder.OrderState ==  OrderState.Submitted){
                                                                                      CancelOrder(lastOrder);
                                                                                  }
                                                                                  /*
                                                                                  else if (lastOrder.OrderState ==  OrderState.Filled){
                                                                                      return;
                                                                                  }
                                                                                  */
                                                                              }
              
                                                                              // generate a name for the signal with the number of the zone and the length of the position
                                                                              string signalName = "Short entry zone " + iAux;
                                                                              // We enter the position
                                                                              TP = takeProfitPrice;
                                                                              Order myOrder = EnterShortStopLimit(1, entryPrice, stopPrice, signalName);
                                                                              //Order myOrder = EnterShortLimit(1, entryPrice, signalName);                                        
                                                                              // Set take profit
                                                                              //SetProfitTarget(signalName, CalculationMode.Price, takeProfitPrice);
                                                                              // Set stop loss
                                                                              //SetStopLoss(signalName, CalculationMode.Price, stopPrice, true);
              
                                                                              Print("---------------------------------");
                                                                              Print(Time[0]);
                                                                              Print("Short2 ");
                                                                              Print("Entry Price --> " + entryPrice);
                                                                              Print("TP --> " + takeProfitPrice);
                                                                              Print("SL --> " + stopPrice);
                                                                              Print("---------------------------------");
              
                                                                              // we indicate that at least 1 trade has been made
                                                                              //aux[1] = 1;    
              
                                                                              using (StreamWriter writer = new StreamWriter(Fichero_Entradas, true)){
              
                                                                                  double Precio_Entrada = entryPrice;
                                                                                  double Take_Profit = takeProfitPrice;
                                                                                  double Stop_Loss = stopPrice;
              
                                                                                  // Format the data as a comma-separated string
                                                                                  string dataLine = string.Format("{0},{1},{2},{3},{4}", Time[0], "SHORT", Precio_Entrada, Take_Profit, Stop_Loss);
              
                                                                                  // Write the data to the file
                                                                                  writer.WriteLine(dataLine);
                                                                              }        
              
                                                                              // save last position to zonas[i]
                                                                              lastOrder = myOrder;
                                                                              Print ("Ultima orden --> " + lastOrder);
              
                                                                          }
                                                                      }​

              I've also created the "OnOrderUpdate" function but nothing is being printed

              HTML Code:
                      protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment){
                           Print("Tenemos cambio de orden status --> " + order);
                      }​

              Thanks again in advance

              Comment


                #8
                Hello speedytrade02,

                Thank you for your patience.

                Have you also enabled Trace Orders in your strategy? What is the Trace Orders output - does it show your entry order being filled? Are there any messages about orders being ignored, and if so what is the reason?

                The following reference sample shows how to work with separate Order objects (entryOrder, stopOrder, and targetOrder) and how to assign them and submit your entry, stop, and target orders. The entry order is handled in OnOrderUpdate() and then the stop and target orders are submitted within OnExecutionUpdate() when the entry is filled. This seems to be along the lines of what you are looking to achieve and you could still keep track of the entryPrice, takeProfitPrice, and stopPrice in different variables like you are already doing if you'd like. The sample may be found here:


                You should not combine Exit() methods, such as ExitLongStopLimit(), with the Set() methods, such as SetStopLoss() or SetProfitTarget(), for the same position. There are internal order handling rules to reduce unwanted positions (explained on this page) that will result in either the Exit() method or the Set() method being ignored when you try to use both at the same time.

                I appreciate your time and patience. Please let us know if we may be of further assistance.

                Comment


                  #9
                  Thanks Emily, Now I can see the log of the order.

                  I see that the order is being ignored everytime (as you can see on the following screenshot):

                  Click image for larger version

Name:	image.png
Views:	640
Size:	103.1 KB
ID:	1267928
                  I'm calculating the stoploss this way (i want to place it 1 tick above the low of the current candle)

                  HTML Code:
                  // set prices
                  double stopPrice = Low[0] - TickSize;
                  double entryPrice = High[0] + TickSize;
                  double percentage = 1 - (stopPrice / entryPrice);
                  double takeProfitPrice = entryPrice + (entryPrice * percentage);
                  bool entrada = true;
                  ​

                  Comment


                    #10
                    Originally posted by speedytrade02 View Post
                    Thanks Emily, Now I can see the log of the order.

                    I see that the order is being ignored everytime (as you can see on the following screenshot):​
                    I'm calculating the stoploss this way (i want to place it 1 tick above the low of the current candle)

                    HTML Code:
                    // set prices
                    double stopPrice = Low[0] - TickSize;
                    double entryPrice = High[0] + TickSize;
                    double percentage = 1 - (stopPrice / entryPrice);
                    double takeProfitPrice = entryPrice + (entryPrice * percentage);
                    bool entrada = true;
                    ​
                    Thank you for that information.

                    I see you are getting an error message ' An order has been ignored since the stop price ‘____’ near the bar stamped ‘____’ is invalid based on the price range of the bar.' This message has to do with how historical orders are processed; when you enable your strategy, a backtest is run to determine if the strategy would have an open position at the time it was enabled if it had been running for the existing data in the series. For more details on historical fill processing:
                    The standard fill resolution uses OHLC values for each bar to determine fill prices. The way the bars developed historically with their OHLC values, the historical fill algorithm is seeing the stop market order on the wrong side of the market. This can be prevented by changing your strategy settings to use the High order fill resolution with a more granular data series added (such as 1-tick for the most granular option) or you can develop your strategy to submit orders to a more granular data series. This error message has been discussed in the following forum threads as well:Alternatively, if you want to stop your strategy from processing on historical data altogether, you can add a return statement if the state is historical in the beginning of OnBarUpdate():
                    Code:
                    if (State == State.Historical)
                    return;
                    Please let us know if we may be of further assistance.

                    Comment


                      #11
                      Hi Emily and thanks for the info.

                      I'm actually trying the strategy with "strategy analizer", so I need to do something at "State.Historical".

                      As you said, I've changes "OrderFillResolution" from "Standard" to "High" as you can see on the code:

                      Code:
                                  if (State == State.SetDefaults)
                                  {
                                      Description                                    = @"Joan strategy";
                                      Name                                        = "test4";
                                      Calculate                                    = Calculate.OnBarClose;
                                      EntriesPerDirection                            = 1;
                                      EntryHandling                                = EntryHandling.AllEntries;
                                      IsExitOnSessionCloseStrategy                = false;
                                      ExitOnSessionCloseSeconds                    = 0;
                                      IsFillLimitOnTouch                            = true;
                                      MaximumBarsLookBack                            = MaximumBarsLookBack.Infinite;
                                      OrderFillResolution                            = OrderFillResolution.High;
                                      Slippage                                    = 0;
                                      StartBehavior                                = StartBehavior.WaitUntilFlat;
                                      TimeInForce                                    = TimeInForce.Day;
                                      TraceOrders                                    = true;
                                      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)
                                  {
                                      Calculate = Calculate.OnBarClose;
                      
                                      AddDataSeries("YM SEP23", Data.BarsPeriodType.Minute, 1, Data.MarketDataType.Last);
                                      AddDataSeries("YM SEP23", Data.BarsPeriodType.Second, 15, Data.MarketDataType.Last);
                                      AddDataSeries("YM SEP23", Data.BarsPeriodType.Tick, 1, Data.MarketDataType.Last);
                                      AddDataSeries("YM SEP23", Data.BarsPeriodType.Volume, 1, Data.MarketDataType.Last);
                                  }
                                  else if (State == State.DataLoaded)
                                  {                
                                      CumDelta1m = OrderFlowCumulativeDelta(BarsArray[1], CumulativeDeltaType.BidAsk, CumulativeDeltaPeriod.Bar, 0);
                                      CumDelta15s = OrderFlowCumulativeDelta(BarsArray[2], CumulativeDeltaType.BidAsk, CumulativeDeltaPeriod.Bar, 0);
                                  }​
                      I keep getting the same error
                      Click image for larger version

Name:	image.png
Views:	648
Size:	103.1 KB
ID:	1268221

                      Should I change something else in order to execute the orders correctly?

                      Thanks again.

                      Comment


                        #12
                        Hello speedytrade02,

                        Thank you for your reply.

                        Although you have set the order fill resolution to High (which may be done in the code or in the Strategy Analyzer settings), what do you have selected for the "Type" and "Value" of the series for high order fill resolution? You will likely need to select a more granular series than what you have, with 1-tick being the most granular option. That said, when using a 1-tick series for high order fill resolution, it is expected that the backtest to take longer to complete. You also need to have tick data stored in your historical data already or be connected to a provider who offers historical tick data for the instrument you are testing on. The data offered by each provider is listed in the help guide here:Thank you for your patience.

                        Comment


                          #13
                          Hi Emily,

                          I have the following series:

                          Code:
                          AddDataSeries("YM SEP23", Data.BarsPeriodType.Minute, 1, Data.MarketDataType.Last);
                          AddDataSeries("YM SEP23", Data.BarsPeriodType.Second, 15, Data.MarketDataType.Last);​
                          How can I use 1-tick series then?

                          Note: I'm using "Simulation" connection. Does this has something to do with the error?

                          Thanks againfor your time!

                          Comment


                            #14
                            Originally posted by speedytrade02 View Post
                            Hi Emily,

                            I have the following series:

                            Code:
                            AddDataSeries("YM SEP23", Data.BarsPeriodType.Minute, 1, Data.MarketDataType.Last);
                            AddDataSeries("YM SEP23", Data.BarsPeriodType.Second, 15, Data.MarketDataType.Last);​
                            How can I use 1-tick series then?

                            Note: I'm using "Simulation" connection. Does this has something to do with the error?

                            Thanks againfor your time!
                            The following is mentioned in the help guide:
                            "Order fill resolution cannot be used with Multi Time Frame/Multi Instrument strategies, or when Tick Replay is used. For those cases, a strategy should be written to submit orders to a single tick data series.​"

                            We have a reference sample that demonstrates how to submit orders to a more granular series here:


                            You can call AddDataSeries() to add a 1-tick series and then submit orders to that specific BarsInProgress index when that is the BarsInProgress called by OnBarUpdate() or by using the method overloads that allow you to designate the barsInProgressIndex as described under "Working with a multi-instrument strategy" here:


                            Please let us know if we may be of further assistance.

                            Comment


                              #15
                              Hi Emily, and sorry for the late response since the last qüestion.

                              But I've read the booth links you've provided to me and I don't understand at all how the submit orders to a more granular series. Could you tell me more or less what should I change on the code?

                              here's my configuration:

                              Code:
                                      protected override void OnStateChange()
                                      {
                                          if (State == State.SetDefaults)
                                          {
                                              Description                                    = @"Joan strategy";
                                              Name                                        = "test4";
                                              Calculate                                    = Calculate.OnBarClose;
                                              EntriesPerDirection                            = 1;
                                              EntryHandling                                = EntryHandling.AllEntries;
                                              IsExitOnSessionCloseStrategy                = false;
                                              ExitOnSessionCloseSeconds                    = 0;
                                              IsFillLimitOnTouch                            = true;
                                              MaximumBarsLookBack                            = MaximumBarsLookBack.Infinite;
                                              OrderFillResolution                            = OrderFillResolution.High;
                                              Slippage                                    = 0;
                                              StartBehavior                                = StartBehavior.WaitUntilFlat;
                                              TimeInForce                                    = TimeInForce.Day;
                                              TraceOrders                                    = true;
                                              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)
                                          {
                                              Calculate = Calculate.OnBarClose;
                              
                                              AddDataSeries("YM SEP23", Data.BarsPeriodType.Minute, 1, Data.MarketDataType.Last);
                                              AddDataSeries("YM SEP23", Data.BarsPeriodType.Second, 15, Data.MarketDataType.Last);
                                              AddDataSeries("YM SEP23", Data.BarsPeriodType.Tick, 1, Data.MarketDataType.Last);
                                              AddDataSeries("YM SEP23", Data.BarsPeriodType.Volume, 1, Data.MarketDataType.Last);
                                          }
                                          else if (State == State.DataLoaded)
                                          {                
                                              CumDelta1m = OrderFlowCumulativeDelta(BarsArray[1], CumulativeDeltaType.BidAsk, CumulativeDeltaPeriod.Bar, 0);
                                              CumDelta15s = OrderFlowCumulativeDelta(BarsArray[2], CumulativeDeltaType.BidAsk, CumulativeDeltaPeriod.Bar, 0);
                                          }
                                      }​
                              Another thing. You thing that If I try my actual code on live trading, the orders should work nice?

                              Thanks again in advance

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                              0 responses
                              646 views
                              0 likes
                              Last Post Geovanny Suaza  
                              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                              0 responses
                              367 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by Mindset, 02-09-2026, 11:44 AM
                              0 responses
                              107 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                              0 responses
                              569 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by RFrosty, 01-28-2026, 06:49 PM
                              0 responses
                              573 views
                              1 like
                              Last Post RFrosty
                              by RFrosty
                               
                              Working...
                              X