Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Resetting Profit Target and Stop Loss for Total Position in NinjaTrader Strategy

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

    Resetting Profit Target and Stop Loss for Total Position in NinjaTrader Strategy

    Hello everyone,

    I'm working on a NinjaTrader strategy where I'm facing an issue with managing the profit target and stop loss for the total position. My strategy creates a new profit target and stop loss for each individual order, but I want to reset these for the total position instead.

    In essence, each time a new order is placed, I want to cancel the existing profit target and stop loss orders and set new ones that reflect the total position (sum of all individual orders).

    I've attempted to solve this with a method called ResetStopANDProfitTarget, but it's not working as expected. Here's a snippet of the relevant code for reference:


    HTML Code:
    // ... [include other relevant portions of your code here, but avoid too long excerpts]
    
    private void ManageRebuyOrders(int rebuyTicks, int limitTicks, int stopLossTicks)
    {
        double priceChange = Position.MarketPosition == MarketPosition.Long ? Position.AveragePrice - Close[0] : Close[0] - Position.AveragePrice;
    
        if (priceChange / TickSize >= rebuyTicks && RebuyRepetitions > RebuyCounter && Position.AveragePrice > 0)
        {
            RebuyCounter++;
            string orderName = signalDirection == SignalDirection.Long ? "LongPosition" : "ShortPosition";
            if (Position.MarketPosition == MarketPosition.Long)
            {
                EnterLong(DefaultQuantity, orderName);
                ResetStopANDProfitTarget(orderName);
            }
            else if (Position.MarketPosition == MarketPosition.Short)
            {
                EnterShort(DefaultQuantity, orderName);
                ResetStopANDProfitTarget(orderName);
            }
            Print("Rebuy: " + orderName);
        }
    }
    
    private void ResetStopANDProfitTarget(string orderName)
    {
        foreach (var order in Account.Orders)
        {
            if ((order.OrderType == OrderType.Limit && order.OrderState == OrderState.Working) ||
                (order.OrderType == OrderType.StopLimit && order.OrderState == OrderState.Accepted))
            {
                CancelOrder(order);
                Print("Cancel Order: " + order.Name);
            }
        }
    
        SetProfitTarget(orderName, CalculationMode.Ticks, StopLossProfitTicks, false);
        SetStopLoss(orderName, CalculationMode.Ticks, StopLossTicks, false);
    }
    
    // ... [any additional relevant code]
    ​
    The issue is that my ResetStopANDProfitTarget method doesn't seem to correctly reset the profit target and stop loss for the total position after each new order.

    I would really appreciate any insights or suggestions on how to resolve this issue. Specifically, I'm looking for guidance on how to correctly cancel existing profit target and stop loss orders and set new ones based on the total position size after each new order is executed.

    Thanks in advance for your help!

    #2
    Hello TradingJo,

    Thank you for your post and welcome to the NinjaScript forum community!

    The ChangeOrder() and CancelOrder() methods may not be used for the Set() methods such as SetStopLoss() and SetProfitTarget(). Based on your snippet, it seems that you want the Profit Target to be set StopLossProfitTicks number of ticks away from the average entry price and you want the Stop Loss set to StopLossTicks away from the average entry price. This could be done by calling these methods in OnStateChange() during State.Configure to use static stop loss and profit target values. This would not require a string for fromEntrySignal, and even so when an empty string is used the order will be attached to all entries instead of a specific entry whose signal is used. Here is an example of what a static stop loss and profit target to apply to all entries would look like:
    Code:
    protected override void OnStateChange()
    {
    if (State == State.Configure)
    {
    SetProfitTarget(CalculationMode.Ticks, StopLossProfitTicks);
    SetStopLoss(CalculationMode.Ticks, StopLossTicks);
    }
    }
    You could also always test out the logic in the Strategy Builder and click the View Code button to see how the code is set up in the NinjaScript Editor. The "Stops and Targets" screen of the Strategy Builder has options for a stop loss applied to the total position and a profit target applied to the total position that you could check out:
    World's leading screen capture + recorder from Snagit + Screencast by Techsmith. Capture, edit and share professional-quality content seamlessly.


    For more info on getting started with NinjaScript development and using the Strategy Builder as a helpful tool, please see the following post:


    If and when you'd like to use dynamic stops and targets that can change prices, I suggest checking out the following reference sample. It can be used to view a contrast to the behavior you currently desire of a static profit target and stop loss applied to the whole position:


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

    Comment


      #3
      Thank you very much for the prompt response. What I am trying to implement is an Average Down strategy. In this, I intend to maintain the existing position and additionally increase the quantity. When I try this with the suggested method, a separate stop loss and take profit position are created for each increase in quantity. Unfortunately, I didn't quite understand how to do this with the provided solution.

      I have now written my own function that essentially does what I want, but the position loses its connection to the strategy. When my function has closed all positions, they are only closed in the account positions, but still open in the strategy positions. I have already read several posts on this topic, but unfortunately, I still do not understand how to manage to close the positions in both the account and the strategy.


      Here's the relevant portion of my code for your review:

      HTML Code:
            private void ManageRebuyOrders(int rebuyTicks, int limitTicks, int stopLossTicks)
            {
                double priceChange = Position.MarketPosition == MarketPosition.Long ? Position.AveragePrice - Close[0] : Close[0] - Position.AveragePrice;
      
                // Überprüfen Sie, ob der Preis entsprechend gestiegen oder gefallen ist
                if (priceChange / TickSize >= rebuyTicks && RebuyRepetitions > RebuyCounter && Position.AveragePrice > 0)
                {
                    RebuyCounter++;
              string orderName = signalDirection == SignalDirection.Long ? "LongPosition" : "ShortPosition";
                    int newQuantity = DefaultQuantity;
                    if (Position.MarketPosition == MarketPosition.Long)
                    {
                        EnterLong(DefaultQuantity, orderName);
                        EnterTakeProfitStopLoss();
      
                    }
                    else if (Position.MarketPosition == MarketPosition.Short)
                    {
                        EnterShort(DefaultQuantity, orderName);
                        EnterTakeProfitStopLoss();
                    }
      
                    // Passen Sie die Limit-Position an
                    Print("Rebuy: " + orderName);
                }
            }
      
            private void CancelExistingOrders()
            {
                // Erstellen einer Liste, um alle zu stornierenden Orders zu sammeln
                List<Cbi.Order> ordersToCancel = new List<Cbi.Order>();
      
                foreach (Cbi.Order order in Account.Orders)
                {
                    if (order.Instrument == Instrument && order.OrderState == OrderState.Working)
                    {
                        ordersToCancel.Add(order);
                    }
                }
      
                // Stornieren aller gesammelten Orders
                if (ordersToCancel.Count > 0)
                {
                    Account.Cancel(ordersToCancel);
                }
      
            }
      
            private void EnterTakeProfitStopLoss()
            {
                CancelExistingOrders();
                string ocoid = Guid.NewGuid().ToString(); // Eindeutige ID für die Order-Kette
                double takeProfitPrice, stopLossPrice;
      
                switch (Position.MarketPosition)
                {
                    case MarketPosition.Long:
                        // Berechnung des Take-Profit und Stop-Loss Preises für Long-Position
                        takeProfitPrice = Position.AveragePrice + (StopLossProfitTicks * TickSize);
                        stopLossPrice = Position.AveragePrice - (StopLossTicks * TickSize);
      
                        // Erstellen und Senden der Take-Profit-Order
                        MyLimit = Account.CreateOrder(Instrument, OrderAction.Sell, OrderType.Limit, TimeInForce.Gtc, Position.Quantity, takeProfitPrice, 0, ocoid, "Take Profit Long", null);
                        Account.Submit(new[] { MyLimit });
      
                        // Erstellen und Senden der Stop-Loss-Order
                        MyStop = Account.CreateOrder(Instrument, OrderAction.Sell, OrderType.StopMarket, TimeInForce.Gtc, Position.Quantity, 0, stopLossPrice, ocoid, "Stop Loss Long", null);
                        Account.Submit(new[] { MyStop });
                        break;
      
                    case MarketPosition.Short:
                        // Berechnung des Take-Profit und Stop-Loss Preises für Short-Position
                        takeProfitPrice = Position.AveragePrice - (StopLossProfitTicks * TickSize);
                        stopLossPrice = Position.AveragePrice + (StopLossTicks * TickSize);
      
                        // Erstellen und Senden der Take-Profit-Order
                        MyLimit = Account.CreateOrder(Instrument, OrderAction.Buy, OrderType.Limit, TimeInForce.Gtc, Position.Quantity, takeProfitPrice, 0, ocoid, "Take Profit Short", null);
                        Account.Submit(new[] { MyLimit });
      
                        // Erstellen und Senden der Stop-Loss-Order
                        MyStop = Account.CreateOrder(Instrument, OrderAction.Buy, OrderType.StopMarket, TimeInForce.Gtc, Position.Quantity, 0, stopLossPrice, ocoid, "Stop Loss Short", null);
                        Account.Submit(new[] { MyStop });
                        break;
      
                    case MarketPosition.Flat:
                        // Keine Aktion erforderlich, wenn keine Position offen ist
                        break;
                }
            }​
      Thank you in advance for your assistance. I look forward to your valuable input.

      Comment


        #4
        Originally posted by TradingJo View Post
        Thank you very much for the prompt response. What I am trying to implement is an Average Down strategy. In this, I intend to maintain the existing position and additionally increase the quantity. When I try this with the suggested method, a separate stop loss and take profit position are created for each increase in quantity. Unfortunately, I didn't quite understand how to do this with the provided solution.

        I have now written my own function that essentially does what I want, but the position loses its connection to the strategy. When my function has closed all positions, they are only closed in the account positions, but still open in the strategy positions. I have already read several posts on this topic, but unfortunately, I still do not understand how to manage to close the positions in both the account and the strategy.


        Here's the relevant portion of my code for your review:

        HTML Code:
        private void ManageRebuyOrders(int rebuyTicks, int limitTicks, int stopLossTicks)
        {
        double priceChange = Position.MarketPosition == MarketPosition.Long ? Position.AveragePrice - Close[0] : Close[0] - Position.AveragePrice;
        
        // Überprüfen Sie, ob der Preis entsprechend gestiegen oder gefallen ist
        if (priceChange / TickSize >= rebuyTicks && RebuyRepetitions > RebuyCounter && Position.AveragePrice > 0)
        {
        RebuyCounter++;
        string orderName = signalDirection == SignalDirection.Long ? "LongPosition" : "ShortPosition";
        int newQuantity = DefaultQuantity;
        if (Position.MarketPosition == MarketPosition.Long)
        {
        EnterLong(DefaultQuantity, orderName);
        EnterTakeProfitStopLoss();
        
        }
        else if (Position.MarketPosition == MarketPosition.Short)
        {
        EnterShort(DefaultQuantity, orderName);
        EnterTakeProfitStopLoss();
        }
        
        // Passen Sie die Limit-Position an
        Print("Rebuy: " + orderName);
        }
        }
        
        private void CancelExistingOrders()
        {
        // Erstellen einer Liste, um alle zu stornierenden Orders zu sammeln
        List<Cbi.Order> ordersToCancel = new List<Cbi.Order>();
        
        foreach (Cbi.Order order in Account.Orders)
        {
        if (order.Instrument == Instrument && order.OrderState == OrderState.Working)
        {
        ordersToCancel.Add(order);
        }
        }
        
        // Stornieren aller gesammelten Orders
        if (ordersToCancel.Count > 0)
        {
        Account.Cancel(ordersToCancel);
        }
        
        }
        
        private void EnterTakeProfitStopLoss()
        {
        CancelExistingOrders();
        string ocoid = Guid.NewGuid().ToString(); // Eindeutige ID für die Order-Kette
        double takeProfitPrice, stopLossPrice;
        
        switch (Position.MarketPosition)
        {
        case MarketPosition.Long:
        // Berechnung des Take-Profit und Stop-Loss Preises für Long-Position
        takeProfitPrice = Position.AveragePrice + (StopLossProfitTicks * TickSize);
        stopLossPrice = Position.AveragePrice - (StopLossTicks * TickSize);
        
        // Erstellen und Senden der Take-Profit-Order
        MyLimit = Account.CreateOrder(Instrument, OrderAction.Sell, OrderType.Limit, TimeInForce.Gtc, Position.Quantity, takeProfitPrice, 0, ocoid, "Take Profit Long", null);
        Account.Submit(new[] { MyLimit });
        
        // Erstellen und Senden der Stop-Loss-Order
        MyStop = Account.CreateOrder(Instrument, OrderAction.Sell, OrderType.StopMarket, TimeInForce.Gtc, Position.Quantity, 0, stopLossPrice, ocoid, "Stop Loss Long", null);
        Account.Submit(new[] { MyStop });
        break;
        
        case MarketPosition.Short:
        // Berechnung des Take-Profit und Stop-Loss Preises für Short-Position
        takeProfitPrice = Position.AveragePrice - (StopLossProfitTicks * TickSize);
        stopLossPrice = Position.AveragePrice + (StopLossTicks * TickSize);
        
        // Erstellen und Senden der Take-Profit-Order
        MyLimit = Account.CreateOrder(Instrument, OrderAction.Buy, OrderType.Limit, TimeInForce.Gtc, Position.Quantity, takeProfitPrice, 0, ocoid, "Take Profit Short", null);
        Account.Submit(new[] { MyLimit });
        
        // Erstellen und Senden der Stop-Loss-Order
        MyStop = Account.CreateOrder(Instrument, OrderAction.Buy, OrderType.StopMarket, TimeInForce.Gtc, Position.Quantity, 0, stopLossPrice, ocoid, "Stop Loss Short", null);
        Account.Submit(new[] { MyStop });
        break;
        
        case MarketPosition.Flat:
        // Keine Aktion erforderlich, wenn keine Position offen ist
        break;
        }
        }​
        Thank you in advance for your assistance. I look forward to your valuable input.
        Rather than using the Account.CreateOrder() method for MyLimit and MyStop, you could use the strategy methods ExitLongLimit() and ExitLongStopMarket() to generate exit orders, which can be changed with ChangeOrder() when using the isLiveUntilCancelled bool, instead of using the Set() methods or generating orders from the Account class:More details about Live Until Cancelled orders may be found on the following page:


        The SampleOnOrderUpdate() strategy demonstrates how to keep track of order objects and uses Exit() methods for the stops and targets rather than Set() methods:


        Please let us know if we may be of further 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