Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Expanded background on how StopTargetHandling.ByStrategyPosition works?

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

    Expanded background on how StopTargetHandling.ByStrategyPosition works?

    Hi,

    I'm interested in any additional information you have available on how StopTargetHandling.ByStrategyPosition functions. There is not a lot in the NinjaTrader manual about this option.
    Specifically, is there a way to force the .ByStrategyPostion logic to sync the number of open Stop loss and Profit target orders to the number of contracts open in the strategy and/or the remaining contracts in an EntrySignal?

    There are some issues I've noticed with .ByStrategyPostion when taking a partial exit order on a previous entry. The strategy takes one bar to update the quantity of stop loss and profit target orders Accepted/Working. This risks a mismatch of open contracts to open orders during that bar.

    For example if your market position is 4 contracts Long with 4 stop loss and 4 target orders and you sell 1 contract in bar [0], the ByStrategyPosition logic lets you have 3 contracts Long with 4 stop loss and 4 profit target orders until the subsequent bar (bar [-1]). In that subsequent bar, the strategy will update to 3 contracts Long with 3 stop loss and 3 profit target orders. However, a lot can happen in that "processing" bar. I've seen all stop losses execute, resulting in a short position when you want to be flat. Also, the one bar delay can compound errors if there are 2 partial exits on subsequent bars etc.

    It would be amazing if there was a way to force or call the .ByStrategyPosition logic in the OnExecutionUpdate or some other way to instantly get the stop loss and profit target orders synced with the strategy position and/or remaining contracts from a specific EntrySignal .

    I know there is a .PerEntryExecution option where you can attach an EntrySignal to each stop/target, but I'm trying to understand how .ByStrategyPosition functions.

    I have the NinjaScript I used below if that helps. I've also got the trade output showing the delays and errors, but that made the post too long

    Thanks in advance for the help!



    NINJASCRIPT:

    public class ExpDevTradeOutputV2 : Strategy
    {




    private MIN MIN1;

    public double StopLossTicks
    { get; set; }

    public double TargetTicks
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Contracts", Description = "Number of contracts per entry", Order = 1, GroupName = "Parameters")]
    public int Contracts
    { get; set; }




    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Track order generation execution and errors in Output2 window";
    Name = "ExpDevTradeOutputV2";
    Calculate = Calculate.OnBarClose;
    //OnPriceChange vs OnBarClose doesn't seem to affect errors in updating quantities of stop loss/tgt orders
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.UniqueEntries;
    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;
    //this makes it better but the stop/targets are still off by 1 contract
    BarsRequiredToTrade = 5;

    IsInstantiatedOnEachOptimizationIteration = true;

    //Use this variable to modify trade size
    Contracts = 4;

    TargetTicks = 60;
    StopLossTicks = 12;



    }
    else if (State == State.Configure)
    {

    // Define list variables for stops and targets
    PrintTo = PrintTo.OutputTab2;
    ClearOutputWindow();
    }
    else if (State == State.DataLoaded)
    {

    //Min to set Stop Loss
    MIN1 = MIN(Low, 55);


    }
    }

    protected override void OnBarUpdate()
    {

    // Aviod out of bounds errors
    if (BarsInProgress != 0)
    return;

    if (CurrentBars[0] < 1)
    return;




    //Initial Entry logic
    if (Close[0] > Close[1] && Position.MarketPosition == MarketPosition.Flat) // figure something out so it doesn't place orders after it has partialed out (doesn't add orders)
    {
    //Need to set stop loss / profit target orders this way
    //to ensure stop is submitted simultaneously with entry order

    //Always handle stops and targets prior to order entry

    //CalcMode.Ticks for convinience for tradeoutput script. Other strategies will use something different
    SetProfitTarget(@"LongEntry1", CalculationMode.Ticks, TargetTicks);

    //.Price mode can set any double as the price...call Min1[0] as that double
    SetStopLoss(@"LongEntry1", CalculationMode.Price, MIN1[0], false);


    EnterLong(Convert.ToInt32(Contracts), @"LongEntry1");

    //Due to this entry method each open contract will not have a unique name and will not be uniquely tracable


    }




    //Partial out
    if (Position.MarketPosition == MarketPosition.Long && Close[0] >= Position.AveragePrice + 2)
    {

    //Always handle stops & targets before entries and exits
    //Move stop to breakeven
    SetStopLoss(@"LongEntry1", CalculationMode.Price, Position.AveragePrice + 0.5, false);

    ExitLong(1, @"Partial1", @"LongEntry1");

    //this now moves the stops appropriately to breakeven but in the execution bar there is
    //a mismatch between the Position.MarketPosition and the number of stoploss and target orders
    //there is always one more stoploss and target order than there are open contracts in the execution bar
    //with the .ByStrategyPosition selected there is a one bar delay in synching the number of
    //stoploss and target orders with the number of open contracts on the strategy

    //I have now also noticed an error where it may cancel all stop loss and profit target orders
    //when there are still contracts open on the strategey

    //2 COAs:
    //COA1: accept the risk that strategy hits new breakeven stop but now you are short 1 contract
    //unexpectedly. Add an if statement to exit all if Position.MarketPosition == MarketPosition.Short
    //Will also have to add some code to mitigate situation where all stops are unintentionally cancelled

    //COA2: figure out a way to make the program check the # of contracts to synch the stoploss and profit
    //targets immediately after partial exit (OnPriceUpdate, OnPositionUpdate, etc)

    }

    //COA1 handle instance where breakeven stop executed with too many sell orders.
    //This if statement must be cut and paste into all code with this type of order handling until
    //COA2 can be solved
    if (Position.MarketPosition == MarketPosition.Short)
    {
    ExitShort(Position.Quantity);

    //This works but you are risking an entire bar of price movement before it gets filled
    //Pursue COA2 as well
    }


    //Also has errors where it cancels all stops/tgts when there are still contracts on the strategy



    }



    #2
    Hello whizkpm,

    Thank you for your inquiry.

    There's a couple issues you'd hit with what you've got here. First, if you're going to be scaling out, you should separate the entry into 2 separate orders, one for the 1 contract that will be scaled out, and 1 for the remainder of the contracts. The problem then with using byStrategyPosition then becomes that you run the risk of ending up with 8 quantity for the stop and target when you're only in a 4 long position as there can be issues with scaling in/out when using this.

    I would recommend both a) using 2 orders to enter the position and b) using PerEntryExecution for the stop and target handling. I'm seeing that scale as expected and ending up with the correct number of stops and targets. I've attached a revised version that demonstrates the behavior below.

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

    Comment


      #3
      Kate,

      Thanks for the reply and the code update. I'll use that to get started with the .PerEntryExecution method.

      I'm hearing that StopTargetHandling.PerEntryExecution is the more manageable setting when scaling in or out of positions.

      I appreciate the help!

      Cheers,

      Kevin


      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by NullPointStrategies, 03-13-2026, 05:17 AM
      0 responses
      87 views
      0 likes
      Last Post NullPointStrategies  
      Started by argusthome, 03-08-2026, 10:06 AM
      0 responses
      151 views
      0 likes
      Last Post argusthome  
      Started by NabilKhattabi, 03-06-2026, 11:18 AM
      0 responses
      80 views
      0 likes
      Last Post NabilKhattabi  
      Started by Deep42, 03-06-2026, 12:28 AM
      0 responses
      53 views
      0 likes
      Last Post Deep42
      by Deep42
       
      Started by TheRealMorford, 03-05-2026, 06:15 PM
      0 responses
      62 views
      0 likes
      Last Post TheRealMorford  
      Working...
      X