Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

StopLoss vs AveragePrice + Offset

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

    StopLoss vs AveragePrice + Offset

    I'm clearly missing something simple and just hoping for some clarification.

    I'm writing a strategy that involves a normal stop loss input and also an input to offset a stop loss via average position price.

    I would think they would have the same results when implemented separately, but I get different results with equal values.

    For example with a long strategy:

    when setting StopLoss to 16, and StopTickOffset to -(unreachable number) I get 'x' results
    But
    when setting StopLoss to (unreachable number) and StopTickOffset to -16 I get 'y' results.


    Code for the StopTickOffset stop loss:

    (Close[0] < (Position.AveragePrice + (StopTickOffset * TickSize)) ))

    ..

    StopLoss is the default StopLoss input within DataLoaded and the StopTickOffset is within OnBarUpdate

    .

    I am certain this is just me misunderstanding very basic logic, I am very much a novice, so bare with me.

    Thanks.

    #2
    Hello setardiff,

    It is a little hard to follow what you mean, the example you provided has unreachable number which I don't understand what that means. I also cant tell what the values would be in that sample because of that.

    The code you provided looks correct for how you would get an offset price from the average price. The amount of ticks can be multiplied by TickSize and then that value can be added to the price to offset it. That condition will be true as long as the close is less than the offset price. It would help to see more of the code like the stoploss along with the code for your example.

    I would likely suggest also to use prints for the math or logic in the example that you described, that would be the easiest way to get a better idea of what's happening. For example you could print any calculated values from your inputs or also how if conditions evaluate so you can see if it logically works the same in both cases.
    Last edited by NinjaTrader_Jesse; 06-25-2024, 02:08 PM.

    Comment


      #3
      Thanks for the quick response. I'll try to be more clear, but no promises.

      For unreachable number, I just mean when I'm testing the strategy, I'm entering a number in that the strategy would never hit, assumingly rendering that parameter useless.

      The conditions work properly but I would think that having a closing condition offset by -16 ticks from average price would be the same as a normal stop loss of 16 ticks.
      But when testing the strategy, a StopLoss of 16 renders different results than the StopTickOffset -16.



      Here is the full code.

      namespace NinjaTrader.NinjaScript.Strategies
      {
      public class Last10minLong : Strategy
      {
      private VWAP VWAP1;

      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enters Long trades at 3:51pm when conditions are met";
      Name = "Last10minLong";
      Calculate = Calculate.OnBarClose;
      EntriesPerDirection = 1;
      EntryHandling = EntryHandling.AllEntries;
      IsExitOnSessionCloseStrategy = true;
      ExitOnSessionCloseSeconds = 30;
      IsFillLimitOnTouch = false;
      MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
      OrderFillResolution = OrderFillResolution.Standard;
      Slippage = 0;
      StartBehavior = StartBehavior.WaitUntilFlat;
      TimeInForce = TimeInForce.Gtc;
      TraceOrders = false;
      RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
      StopTargetHandling = StopTargetHandling.PerEntryExecution;
      BarsRequiredToTrade = 20;
      // Disable this property for performance gains in Strategy Analyzer optimizations
      // See the Help Guide for additional information
      IsInstantiatedOnEachOptimizationIteration = true;
      StopOffset = 0;
      ProfitTarget = 1;
      StopLoss = 1;
      }
      else if (State == State.Configure)
      {
      }
      else if (State == State.DataLoaded)
      {
      VWAP1 = VWAP(Close);
      SetProfitTarget("", CalculationMode.Ticks, ProfitTarget);
      SetStopLoss("", CalculationMode.Ticks, StopLoss, false);
      }
      }

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

      if (CurrentBars[0] < 1)
      return;

      // Set 1
      if ((Close[0] > VWAP1.PlotVWAP[0])
      && (Times[0][0].TimeOfDay == new TimeSpan(15, 50, 0)))
      {
      EnterLong(Convert.ToInt32(DefaultQuantity), "");
      }

      // Set 2
      if ((Close[0] < (Position.AveragePrice + (StopOffset * TickSize)) )
      || (Times[0][0].TimeOfDay == new TimeSpan(16, 40, 0)))
      {
      ExitLong(Convert.ToInt32(DefaultQuantity), "", "");
      }

      }

      region Properties
      [NinjaScriptProperty]
      [Range(-16, int.MaxValue)]
      [Display(Name="StopOffset", Order=1, GroupName="Parameters")]
      public int StopOffset
      { get; set; }

      [NinjaScriptProperty]
      [Range(1, int.MaxValue)]
      [Display(Name="ProfitTarget", Order=2, GroupName="Parameters")]
      public int ProfitTarget
      { get; set; }

      [NinjaScriptProperty]
      [Range(1, int.MaxValue)]
      [Display(Name="StopLoss", Order=3, GroupName="Parameters")]
      public int StopLoss
      { get; set; }
      #endregion

      }
      }


      Comment


        #4
        Hello setardiff,

        Thanks for the clarification that makes more sense.

        Regarding the difference that you are seeing what specifically happens different, is the fill price different for the exit or on different bars? There are a couple of considerations here, the first is that a stop loss order is a stop market order and an exit is just a market order so that could affect the fill price. The second is the stoploss will be a working realtime order, the condition you have for the exit will rely on the bar close events because you are using OnBarClose. That means it could have filled the stoploss intrabar if it was active and instead waited till the bar close to exit.

        Comment


          #5
          I admittingly have not looked at the specific fill prices, only viewing the results in the analyzer.
          But that makes sense.

          To drive the point home, the StopLoss is a stop market order that potentially fills intrabar and the StopTickOffset is a condition that is only filled when the price closes below the offset price?

          Which means if I have the StopTickOffset within DataLoaded (or whatever I need to do to make it a stop market order intrabar), then it would then act exactly as the StopLoss does?

          I really appreciate the help.

          Comment


            #6
            Hello setardiff,

            Yes,This is what would happen in realtime. The stoploss is submitted based on the entry order filling so it will be working immediately and as soon as the market permits it will fill.Your exit logic, lets assume you use 5 minute bars, will check once every 5 minutes. If the stop could have filled during the last 5 minute bar it would have where the exit will wait for the next bar close to get executed.

            In historical this still presents a difference, the stoploss is again a working order after the entry fill however the fill is checked once per bar. The exit again comes in as a bar update based order so the price has to be in the range of your condition before that order is activated at all. Depending on when your exit condition becomes true that may not be on the same bar where the target would have filled based on the available OHLC data.

            To have the market order act similar to the stoploss would require using realtime and OnEachTick calculation mode. That would also take some programming considerations to make the backtest similar. The main issue with this comparison would be when the market order exit condition is being checked and the frequency its checked. The live stop order has no reason to not fill immediately once the market moves to its fill price. The market order has to wait to fill based on the OnBarUpdate events which are dictated by the series you applied the strategy to.

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by NullPointStrategies, Today, 05:17 AM
            0 responses
            49 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
            67 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