Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

ATR Multiple Stops/Targets

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

    ATR Multiple Stops/Targets

    I have been struggling with this all week... I've looked at all the old posts and cannot get something to work as I want it to...

    Goal - To have a stop and target order created at order entry based on a multiple of the ATR of the trigger bar

    Code snippets of where I am now -

    private Series<double> ATR2;
    ...

    ATR1 = ATR(Close, 14);
    ATR2[0] = Convert.ToDouble(ATR1);

    SetStopLoss(@"PPOShort", CalculationMode.Price, (Convert.ToDouble(Close) + (ATR2[0] * 2)), true);
    SetProfitTarget(@"PPOShort", CalculationMode.Price, (Convert.ToDouble(Close) + (ATR2[0] * 3)));

    This compiles, but will not enter any orders. This appears in the Output window:
    "Error on calling 'OnStateChange' method: Unable to cast object of type 'NinjaTrader.NinjaScript.Indicators.ATR' to type 'System.IConvertible'."

    Is what I am trying to accomplish even possible in Ninjascript? I am coming from Pine script on Tradingview and it is so simple to perform calculations on indicator values there that I got spoiled.
    Any help/direction would be appreciated!

    Mickey
    Last edited by mickeyg819; 03-04-2022, 07:45 AM.

    #2
    Hello mickeyg819,

    Thank you for your post.

    First, the ATR indicator already returns a double value, so you don't need to use another series, you can just use ATR1[0]. You're getting that error because you're trying to convert the entire ATR1 to a double, but it holds a value for each bar and can't be converted like you're trying to do.

    Next, where within your code are you setting SetStopLoss() and SetProfitTarget()? If you're using the ATR value times a multiplier for the stop, these shouldn't be set in OnStateChange, but rather just before submitting the entry order in OnBarUpdate, as that would allow you to get the current ATR value.

    Could you supply the entire strategy so we may better understand what you're trying?

    Thanks in advance; I look forward to assisting you further.

    Comment


      #3
      Thanks for the reply Kate,

      I get the same error by simply moving the SetStopLoss() and SetProfitTarget() commands. Perhaps I need to do something different. Here is further code as it stands now.

      private EMA EMA1;
      private ADX ADX1;
      private PPO PPO1;
      private ATR ATR1;

      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enter the description for your new custom Strategy here.";
      Name = "TEST_ATR_Stop";
      Calculate = Calculate.OnBarClose;
      EntriesPerDirection = 1;
      EntryHandling = EntryHandling.AllEntries;
      IsExitOnSessionCloseStrategy = true;
      ExitOnSessionCloseSeconds = 120;
      IsFillLimitOnTouch = false;
      MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
      OrderFillResolution = OrderFillResolution.Standard;
      Slippage = 0;
      StartBehavior = StartBehavior.WaitUntilFlat;
      TimeInForce = TimeInForce.Gtc;
      TraceOrders = false;
      RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
      StopTargetHandling = StopTargetHandling.PerEntryExecution;
      BarsRequiredToTrade = 20;
      // Disable this property for performance gains in Strategy Analyzer optimizations
      // See the Help Guide for additional information
      IsInstantiatedOnEachOptimizationIteration = true;
      SL = 19;
      TP = 16;
      TrendMA = 235;
      ADX_Smooth = 20;
      ADX_Level = 22;
      PPO_Fast = 13;
      PPO_Slow = 23;
      PPO_Smooth = 9;

      }
      else if (State == State.Configure)
      {
      }
      else if (State == State.DataLoaded)
      {
      EMA1 = EMA(Close, Convert.ToInt32(TrendMA));
      ADX1 = ADX(Close, Convert.ToInt32(ADX_Smooth));
      PPO1 = PPO(Close, Convert.ToInt32(PPO_Fast), Convert.ToInt32(PPO_Slow), Convert.ToInt32(PPO_Smooth));
      ATR1 = ATR(Close, 14);
      EMA1.Plots[0].Brush = Brushes.Aqua;
      AddChartIndicator(EMA1);

      }
      }

      protected override void OnBarUpdate()
      {
      if (BarsInProgress != 0)
      return;

      if (CurrentBars[0] < 1)
      return;

      SetStopLoss(@"Short", CalculationMode.Price, (Convert.ToDouble(Close) + (ATR1[0] * 2)), true);
      SetProfitTarget(@"Short", CalculationMode.Price, (Convert.ToDouble(Close) + (ATR1[0] * 3)));

      if ((GetCurrentBid(0) <= EMA1[0])
      && (PPO1.Default[0] > 0)
      && (CrossBelow(PPO1.Default, PPO1.Smoothed, 1)));

      {
      EnterShort(2, @"Short");
      }

      I had it sort of working by setting a price and using an ExitShortLimit(), but when back testing at time it would blow by the order and not trigger (which can be costly). Here is that code:

      if ((Position.MarketPosition == MarketPosition.Flat)
      && (PPO1.Default[0] < 0)
      && (GetCurrentBid(0) >= EMA1[0])
      && (ADX1[0] >= 23)
      && (CrossAbove(PPO2.Default, PPO2.Smoothed, 1))
      && (ATR1[0] < 36))
      {
      EnterLong(Convert.ToInt32(DefaultQuantity), @"Short");
      StopPrice = (Close[0] - ((ATR2[0] * SL_Mult) )) ;
      Target = (Close[0] + ((ATR2[0] * TP_Mult) )) ;
      }

      if (Position.MarketPosition == MarketPosition.Long)
      {
      ExitShortLimit(Convert.ToInt32(DefaultQuantity), Target, @"Win", @"Short");
      ExitShortStopLimit(Convert.ToInt32(DefaultQuantity ) , StopPrice, StopPrice, @"Loss", @"Short");
      }

      }

      Thanks for your help!

      Comment


        #4
        Hello mickeyg819,

        Thank you for your reply.

        You've got a couple issues here. First, you're referring to the close prices incorrectly. You can get the current Close price using Close[0]. That's causing an error when you try to apply the strategy to the chart. Next, you should be calling SetStopLoss and SetProfitTarget directly before submitting the entry. Lastly, you're calculating the Profit target level as being above the current price when for a short order it would need to be below it. Try this:

        Code:
        protected override void OnBarUpdate()
        {
        if (BarsInProgress != 0)
        return;
        
        if (CurrentBars[0] < 1)
        return;
        
        if ((GetCurrentBid(0) <= EMA1[0])
        && (PPO1.Default[0] > 0)
        && (CrossBelow(PPO1.Default, PPO1.Smoothed, 1))) ;
        {
        SetStopLoss(@"Short", CalculationMode.Price, (Close[0] + (ATR1[0] * 2)), true);
        SetProfitTarget(@"Short", CalculationMode.Price, (Close[0] - (ATR1[0] * 3)));
        EnterShort(2, @"Short");
        }
        }
        I'm able to see the strategy take trades and submit the stop and target using the above.

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

        Comment


          #5
          Kate,
          Yes, getting the code in the right spot did the trick! I appreciate your quick and helpful assistance!

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by NullPointStrategies, Today, 05:17 AM
          0 responses
          50 views
          0 likes
          Last Post NullPointStrategies  
          Started by argusthome, 03-08-2026, 10:06 AM
          0 responses
          126 views
          0 likes
          Last Post argusthome  
          Started by NabilKhattabi, 03-06-2026, 11:18 AM
          0 responses
          69 views
          0 likes
          Last Post NabilKhattabi  
          Started by Deep42, 03-06-2026, 12:28 AM
          0 responses
          42 views
          0 likes
          Last Post Deep42
          by Deep42
           
          Started by TheRealMorford, 03-05-2026, 06:15 PM
          0 responses
          46 views
          0 likes
          Last Post TheRealMorford  
          Working...
          X