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

Issue with Stop Loss

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

    Issue with Stop Loss

    Hey guys first of all reading the topics I'm grateful for your constant support and quick responses....
    I am fairly new to NinjaScript so I apologize if my question might sound naive

    I am building a strategy and during the execution part I have an issue with the stop loss

    inside protected override void OnBarUpdate()
    I am creating some calculations and once met I am using this block for execution:

    EnterLongLimit(1, entryPrice, "BullishEntry");
    SetStopLoss("BullishEntry", CalculationMode.Price, stopPrice, false);
    SetProfitTarget("BullishEntry", CalculationMode.Price, targetPrice);

    the issue that I encountered is that with this method sometimes when price reaches the stop loss and it tries to place the order, price already went below and I get an error "Orders cannot be placed above the market". One thing I noticed is that when manually placing an ATM strategy the stop loss is a solid red color (stop loss), however when using this strategy the stop loss is a pale pink color (Stop Market Order)....

    How can I change the StopLoss so that it places a stop loss at a defined price right away upon entry rather than placing a stop market order that gets triggered once price reaches my defined price?

    #2
    Hello alifarahani,

    as a side note the set methods should always come first to ensure the most recent calculated price is used.

    SetStopLoss("BullishEntry", CalculationMode.Price, stopPrice, false);
    SetProfitTarget("BullishEntry", CalculationMode.Price, targetPrice);
    EnterLongLimit(1, entryPrice, "BullishEntry");

    Using the set methods like this should allow you to place targets once the entry has filled. The orders wont be sent when the entry is submitted and working but once the entry fills the targets are submitted. Each time you call the Set methods it will update the prices. Is your entry condition becoming true for multiple bars in a row before it fills? if so the prices are likely being reset while the entry is working and once it fills the price has shifted from what it was for the original submission of the entry.

    To make a fixed offset you can use one of the other calculation modes like Ticks
    JesseNinjaTrader Customer Service

    Comment


      #3
      thanks for your reply, is there a way to change the stoploss so that it places a limit order, instead of a market order? the same way that it places stops on the ATM strategy?

      Comment


        #4
        Hello alifarahani,

        The Set methods specifically use stop market orders. To submit a stop limit order or other type of order you would need to either create a separate condition to wait for a long/short position or use OnExecutionUpdate to submit the targets when the entry has filled.

        You can see an example of submitting targets based on an entry fill here: https://ninjatrader.com/support/help...ub=onexecution
        JesseNinjaTrader Customer Service

        Comment


          #5
          Thank you Jesse, can you help me understand the difference (see attached) between a Stop Loss and a Stop Market Order?
          I know in the ATM strategy it places a Stop Loss, however in my code it places a Stop market order...
          What I'd like to achieve is a Stop Loss instead of a Stop Market Order
          Attached Files

          Comment


            #6
            Hello alifarahani,

            Those are for when an ATM is used, the orders named named stoploss and profittarget use those colors. ATM's also use stop market orders for their stoploss's unless a stop limit is selected instead.

            You can use the control center orders tab to compare the types of orders different actions or tools use in the platform if you are trying to recreate something in your own scripts using the order methods.
            JesseNinjaTrader Customer Service

            Comment


              #7
              Thanks a lot Jesse, please see attached . . . the issue that we're trying to solve is not getting this type of errors, which happen quite frequently and the system disabling the strategy.... Do you have any recommendation on how to solve this type of behavior?
              I appreciate you being patient with me answering these weird requests
              Attached Files

              Comment


                #8
                Hello alifarahani,

                In that series of errors the OCO error can be ignored, that happens when a stoploss is rejected but a target with the same OCO is submitted.

                The actual error that needs addressed is the stop being placed above the market. That will cause a rejection which will terminate the strategy. That can be caused depending on the strategies settings, bars type being used and price that you calculated while using CalculationMode.Price. At the time the order was submitted the price that was calculated was no longer valid. You would need to look at the price you are calculating and make sure that is below the current market price when the order is submitted. You may need to add additional offset to the stop to ensure it is placed below market.
                JesseNinjaTrader Customer Service

                Comment


                  #9
                  Thanks a lot Jesse, seems like I was able to fix it using:

                  // Ensure the stop price is below the current market price
                  if (stopPrice >= roundedCurrentPrice)
                  {
                  stopPrice = roundedCurrentPrice - tickSize; // Adjust the stop price to be slightly below the current market price
                  }

                  one other issue that I'm facing is, if I enter a trade and it hits the target or the stop loss on the same candle, it places again the same order, I tried using a bool:
                  private bool orderPlacedThisCandle = false;

                  and then set it to true once it the entry is submitted but no luck... any ideas?​

                  Comment


                    #10
                    Hello alifarahani,

                    You can use bars since entry to help control that:

                    JesseNinjaTrader Customer Service

                    Comment


                      #11
                      Hi Jesse

                      I have some code/logic like below, I have spared you the full details of the entry logic (ex. if price > EMA), but have left the ninjascript of concern.

                      You can see the first if statement (the onBarUpdate) is proper Ninjascript used to set the OktoTrade flag to true on every new bar, and in the conditional check for entry I set it to false if a trade is entered.

                      The goal here is to ensure I only enter one trade per bar if it hits the target, so it doesn't reenter the same trade. That seems to be working well.

                      However, for some reason the strategy is not entering more than one live trade at a time, meaning if one trade is open, it won't enter another (for example in another bar the setup occurs again). I've made the EntriesPerDirection quite large, but I cannot see any other reason why it wouldn't enter more than once.

                      Can you please advise?



                      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 B2B : Strategy
                      {
                      private bool OkToTrade;
                      protected override void OnStateChange()
                      {
                      if (State == State.SetDefaults)
                      {
                      Description = @"Order Block B2B Open Entry";
                      Name = "B2B";
                      Calculate = Calculate.OnPriceChange;
                      EntriesPerDirection = 50;
                      EntryHandling = EntryHandling.AllEntries;
                      IsExitOnSessionCloseStrategy = true;
                      ExitOnSessionCloseSeconds = 30;
                      IsFillLimitOnTouch = false;
                      MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
                      OrderFillResolution = OrderFillResolution.Standard;
                      Slippage = 0;
                      StartBehavior = StartBehavior.ImmediatelySubmit;
                      TimeInForce = TimeInForce.Gtc;
                      TraceOrders = true;
                      RealtimeErrorHandling = RealtimeErrorHandling.StopCancelCloseIgnoreRejects ;
                      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 OnBarUpdate()
                      {
                      if (IsFirstTickOfBar)
                      {
                      OkToTrade = true; //flag to ensure I only enter once per bar, but allows for multiple ongoing trades at once (so can enter only once per bar but can enter on many bars)
                      }

                      if <condition is met for long>
                      set entry
                      set target
                      set stop
                      EnterLongLimit(1, entryPrice, "BullishEntry");
                      OkToTrade = false; //setting to false ensures we do not enter mroe than once on the same bar, this will get reset to true on every new bar (onBarUpdate)
                      else if condition is met for short>
                      set entry
                      set target
                      set stop
                      EnterShortLimit(1, entryPrice, "BearishEntry");
                      OkToTrade = false; //setting to false ensures we do not enter mroe than once on the same bar, this will get reset to true on every new bar (onBarUpdate)​

                      Comment


                        #12
                        Hello alifarahani,

                        The full strategy was not included so I am unsure how it should work.


                        ​​​​​​​
                        JesseNinjaTrader Customer Service

                        Comment


                          #13
                          Hi, sure of course, here is the full code. Please have a look. I have searched the forums all over and just unable to determine why this is not entering multiple live trades.

                          I do believe the OkToTrade flag is being reset to True on every new bar, but perhaps I am doing that incorrectly. Thanks for your help.


                          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 Algo : Strategy
                          {
                          private bool OkToTrade;
                          protected override void OnStateChange()
                          {
                          if (State == State.SetDefaults)
                          {
                          Description = @"Algo Entry";
                          Name = "B2B";
                          Calculate = Calculate.OnPriceChange;
                          EntriesPerDirection = 50;
                          EntryHandling = EntryHandling.AllEntries;
                          IsExitOnSessionCloseStrategy = true;
                          ExitOnSessionCloseSeconds = 30;
                          IsFillLimitOnTouch = false;
                          MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
                          OrderFillResolution = OrderFillResolution.Standard;
                          Slippage = 0;
                          StartBehavior = StartBehavior.ImmediatelySubmit;
                          TimeInForce = TimeInForce.Gtc;
                          TraceOrders = true;
                          RealtimeErrorHandling = RealtimeErrorHandling.StopCancelCloseIgnoreRejects ;
                          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 OnBarUpdate()
                          {
                          if (IsFirstTickOfBar)
                          {
                          OkToTrade = true;
                          }

                          if (CurrentBars[0] < 3) return;

                          bool isBullish = Close[2] < Open[2];
                          bool isBearish = Close[2] > Open[2];

                          if ((isBullish || isBearish))
                          {
                          double entryPrice = Open[2]; // Entry at the opening price of C1
                          // Correctly setting the stop price for Bullish and Bearish OBs
                          double stopPrice = isBullish ? Math.Min(Low[2], Low[1]) : Math.Max(High[2], High[1]);
                          double targetPrice = isBullish ? entryPrice + ((entryPrice - stopPrice)*10) : entryPrice - ((stopPrice - entryPrice)*10); // 1R target

                          // Request account size
                          double accountSize = Account.Get(AccountItem.CashValue, Currency.UsDollar);
                          double RiskPercentage = 0.01;
                          double stopLossSizePoints = accountSize * RiskPercentage / Math.Abs(stopPrice - entryPrice) /50; // Example: 10 points stop loss

                          // Calculate the number of contracts to trade
                          int contractsToTrade = (int)(stopLossSizePoints);

                          // Ensure the calculated quantity is at least 1 contract or more
                          contractsToTrade = Math.Max(contractsToTrade, 1);

                          // Get the tick size of the instrument
                          double tickSize = Instrument.MasterInstrument.TickSize;

                          // Round the current price to the nearest tick size
                          double roundedCurrentPrice = Math.Round(Close[0] / tickSize) * tickSize;


                          if (isBullish && OkToTrade)
                          {
                          // Check if the stop price needs adjustment
                          if ((Math.Abs(entryPrice - stopPrice) / tickSize) >= 1)
                          {
                          // Ensure the stop price is below the current market price
                          if (stopPrice >= roundedCurrentPrice)
                          {
                          stopPrice = roundedCurrentPrice - tickSize; // Adjust the stop price to be slightly below the current market price
                          }

                          // Set stop loss and profit target
                          SetStopLoss("BullishEntry", CalculationMode.Price, stopPrice, false); // Set stop loss
                          SetProfitTarget("BullishEntry", CalculationMode.Price, targetPrice); // Set profit target

                          // Enter long at the entry price
                          //EnterLongLimit(contractsToTrade, entryPrice, "BullishEntry");
                          EnterLongLimit(1, entryPrice, "BullishEntry");
                          OkToTrade = false;
                          }
                          }
                          else if (isBearish && OkToTrade)
                          {
                          // Check if the stop price needs adjustment
                          if ((Math.Abs(entryPrice - stopPrice) / tickSize) >= 1)
                          {
                          // Ensure the stop price is above the current market price
                          if (stopPrice <= roundedCurrentPrice)
                          {
                          stopPrice = roundedCurrentPrice + tickSize; // Adjust the stop price to be slightly above the current market price
                          }

                          // Set stop loss and profit target
                          SetStopLoss("BearishEntry", CalculationMode.Price, stopPrice, false); // Set stop loss
                          SetProfitTarget("BearishEntry", CalculationMode.Price, targetPrice); // Set profit target

                          // Enter short at the entry price
                          //EnterShortLimit(contractsToTrade, entryPrice, "BearishEntry");
                          EnterShortLimit(1, entryPrice, "BearishEntry");
                          OkToTrade = false;
                          }
                          }
                          }
                          }
                          }
                          }​

                          Comment


                            #14
                            Hello alifarahani,

                            While I cannot test your code for you I can suggest that you test this code and also use Print statements.



                            using prints lets you see what the logic is doing, by looking at the logic you can better understand why it is or is not trading.

                            JesseNinjaTrader Customer Service

                            Comment


                              #15
                              Good morning Jesse,

                              I have an issue with my code, after enabling the strategy it places the stop loss and targets even before entering the position:

                              protected override void OnBarUpdate()
                              {
                              if (IsFirstTickOfBar)
                              {
                              OkToTrade = true;
                              }
                              if (CurrentBars[0] < 4) return;
                              bool isBullishFVG = High[3] < Low[1];
                              double entryPrice = Open[0];
                              double stopPrice = Low[2];
                              double targetPrice = entryPrice + ((entryPrice - stopPrice) * 5);
                              double riskValue = 100; // Amount you're willing to risk per trade in dollars
                              double pointValue = 5; // Value of each point in dollars
                              double stopLossPoints = Math.Abs(entryPrice - stopPrice); // Size of the stop loss in points
                              // Calculate the number of contracts to trade, rounded down to the nearest whole number
                              int contractsToTrade = (int)Math.Floor(riskValue / (stopLossPoints * pointValue));
                              // Ensure the calculated quantity is at least 1 contract or more
                              contractsToTrade = Math.Max(contractsToTrade, 1);
                              // Get the tick size of the instrument
                              double tickSize = Instrument.MasterInstrument.TickSize;
                              // Round the current price to the nearest tick size
                              double roundedCurrentPrice = Math.Round(Close[0] / tickSize) * tickSize;
                              if (isBullishFVG && OkToTrade)
                              {
                              // Check if the stop price needs adjustment
                              if ((Math.Abs(entryPrice - stopPrice) / tickSize) >= 1)
                              {
                              // Ensure the stop price is below the current market price
                              if (stopPrice >= roundedCurrentPrice)
                              {
                              stopPrice = roundedCurrentPrice - tickSize; // Adjust the stop price to be slightly below the current market price
                              }
                              // Generate a unique signal name for this trade
                              string signalName = "BullishEntry_" + tradeCounter;
                              tradeCounter++; // Increment the trade counter
                              // Set stop loss and profit target only after placing the entry order
                              SetStopLoss(signalName, CalculationMode.Price, stopPrice, false); // Set stop loss
                              SetProfitTarget(signalName, CalculationMode.Price, targetPrice); // Set profit target
                              // Enter long at the entry price
                              EnterLong(contractsToTrade, signalName);
                              OkToTrade = false;
                              }
                              }
                              }​


                              Can you please help me finding the issue?

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by NeoTraderBot, Yesterday, 10:55 PM
                              0 responses
                              6 views
                              0 likes
                              Last Post NeoTraderBot  
                              Started by OliverWaters, Yesterday, 10:35 PM
                              0 responses
                              6 views
                              0 likes
                              Last Post OliverWaters  
                              Started by Graci117, 07-06-2024, 09:32 AM
                              6 responses
                              37 views
                              0 likes
                              Last Post Graci117  
                              Started by AdamDJ8, 07-01-2024, 06:50 PM
                              2 responses
                              120 views
                              0 likes
                              Last Post AdamDJ8
                              by AdamDJ8
                               
                              Started by AdamDJ8, 07-01-2024, 05:55 PM
                              3 responses
                              32 views
                              0 likes
                              Last Post AdamDJ8
                              by AdamDJ8
                               
                              Working...
                              X