Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

NinjaScript - Modifying Active Positions with a manual Stop Loss Strategy

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

    #16
    Hi NinjaTrader_Emily​,

    So I successfully implemented the above with the trailing stop loss activating above 0.2% profit,

    However I am now trying to implement a fall off stop loss, where if profit is under 0.2% and the position has been active for more than 4 periods it will start to reduce the stop loss by a certain factor,

    I have got this working with the following code:

    Code:
    private void AdjustFalloffStopLoss()
            {
                var stopLossPercentage = InitialStopLossPercentage - ((PeriodsInPosition - 3) * StopLossFalloffFactor);
    
                if (Position.MarketPosition == MarketPosition.Long)
                {
                    var newStopLoss = Position.AveragePrice - (Position.AveragePrice * stopLossPercentage);
    
                    if (CurrentStopLossPrice != 0 && newStopLoss > CurrentStopLossPrice && newStopLoss < Close[0])
                    {
                        SetStopLoss(CalculationMode.Price, newStopLoss);
                        CurrentStopLossPrice = newStopLoss;
                    }
                }
    
                if (Position.MarketPosition == MarketPosition.Short)
                {
                    var newStopLoss = Position.AveragePrice + (Position.AveragePrice * stopLossPercentage);
    
                    if(CurrentStopLossPrice != 0 && newStopLoss < CurrentStopLossPrice && newStopLoss > Close[0])
                    {
                        SetStopLoss(CalculationMode.Price, newStopLoss);
                        CurrentStopLossPrice = newStopLoss;
                    }
                }
            }​

    In my playback connection debugging this code it works perfectly and exactly how I want it to perform, however in the simulation connection it doesn't work and continues to use the initial stop loss that is being set, even though its the same strategy that I'm running and same parameters on the same market and timeline, I am also resetting the stop loss to be the initial value of 0.2% after each time the market position enters flat.

    Do you have any idea why this might be so different between connections?

    Thank you again in advanced

    Edit:
    I have tried clearing the cache, There is no difference between the two connections as it also seems to behave incorrectly in the playback connection as well when I skip over the trades, however I then get the different (correct) result when debugging, could it be a performance issue with how the trades are populated on the chart?
    Last edited by MrHump; 08-30-2023, 07:39 AM.

    Comment


      #17
      Hello MrHump,

      Thank you for your reply.

      You mentioned that the stop loss will start to be reduced "if profit is under 0.2% and the position has been active for more than 4 periods." At the part of your strategy that checks if the profit is under that value and how long the position has been open, I suggest adding prints both inside and outside of the condition to see what values are being used for the profit and how long the position has been active. This will help you to understand if your logic is reaching the call to AdjustFalloffStopLoss() or not, and why. You could even compare the output from the prints when testing on live data vs. testing on the playback connection and this might help to understand why the two are potentially behaving differently.

      You mention you get the correct result when debugging - what is your process for debugging and what is different between that environment vs. the scenarios where you are getting unexpected/incorrect results? What steps are you taking for debugging? Have you added print statements and what are the results of those print statements? If you'd like additional assistance, I would need more details about what you are doing when it is working as expected vs. when it's not and what the print output is from both situations.

      I appreciate your patience. Please let me know if I may be of further assistance.

      Comment


        #18
        Hey NinjaTrader_Emily​,

        Thank you for getting back to me so quickly again!

        My debugging process includes turning on the debug property in the ninja script editor and using Visual Studio 2022 to attach it to the process, this allows me to check the values and step through the code instead of print statements.

        So when I use playback I get three different outcomes depending on how I replay the time all using the same version of the strategy with the same parameters on the 10 min time frame:

        Scenario 1 (Working Correctly) - I playback normal speed (If I attach my script via Visual Studio I can see the correct values being used)

        A long trade enters at 24/08/2023 on MES at 23:40:00 @ 4388

        After 4 periods have passed the price is now 4389 so its under the 2% profit price of 4475.76
        The stop loss is now set to 1.5% instead of the original 2%
        This continues until the new stop loss being generated is calculating to lower than the close price to avoid errors.
        On the 6th Period since the trade was made so at 25/08/2023 00:20:00 it will hit the stop loss at a price of 4385.25

        Click image for larger version  Name:	image.png Views:	0 Size:	54.8 KB ID:	1266770

        Scenario 2 (Not working) - Instead of using playback to simulate the trade I either load it on the simulation chart or skip the playback slider over this time period

        A long trade enters at 24/08/2023 on MES at 23:40:00 @ 4388
        After 4 periods have passed the price is now 4389 so its under the 2% profit price of 4475.76
        However this time it doesn't hit the stop loss on the 6th period like it did previously it appears to continue at the initial stop loss of 2%
        (It actually exits that trade because of logic that indicates a short trade is valid, but still should not have made it that far)

        Click image for larger version  Name:	image.png Views:	0 Size:	27.6 KB ID:	1266771

        Scenario 3 (Not working) - Same entry as the previous two however this one happens randomly and will exit the trade on end of session (Which I have that setting turned on) So actually this is probably the scenario that should be happening!

        Sorry for the massive wall of text, I hope this helps provide detail!

        Edit: I have added screenshots to help visualize how the trade is differing, I have cleared the cache and both screenshots were taken without reapplying the strategy, just my either playing over that time period or dragging the playback slider past that time period!
        Last edited by MrHump; 08-30-2023, 09:33 AM.

        Comment


          #19
          Hello MrHump,

          Thank you for your reply.
          • Scenario 2 (Not working) - Instead of using playback to simulate the trade I either load it on the simulation chart or skip the playback slider over this time period
            • Any time that you drag the playback slider, the strategy is disabled and then re-enabled at the new timestamp you drag the slider to. This means the historical strategy orders are re-calculated and the strategy will use its start behavior at the new timestamp. I suspect if you were to increase the playback speed multiplier to skip over time periods rather than dragging the slider and causing the strategy to disable/enable/recalculate that you would see the expected behavior.
            • What are you referring to for "load it on the simulation chart?" Do you mean enabling the strategy on a chart and reviewing the historical information? This could be a similar explanation as the first bullet point; historical behavior of the strategy may show some discrepancies compared to real-time behavior
          • Scenario 3 (Not working) - Same entry as the previous two however this one happens randomly and will exit the trade on end of session
            • Are you seeing this when leaving the strategy to run in real-time or in historical processing of the strategy?
          You may be able to review what parts of your strategy performance are in real-time and what parts are in historical:


          There are some expected discrepancies between historical/backtest results and real-time results. These differences are explained on the following page:


          Basically, historical fills are based on OHLC information for the bar and not intrabar prices, and strategy actions are processed on the close of each bar rather than on each tick/on price change. I think this is the cause of the different results you are reviewing; you will need to understand if you are reviewing results that occurred in historical processing or during real-time. Since scenario 1 is working as expected, that tells me the strategy is behaving as expected in a real-time environment and I suspect scenarios 2 and 3 are happening during historical processing rather than real-time.

          Please let me know if I may be of further assistance.

          Comment


            #20
            Hi NinjaTrader_Emily​,

            There is definitely a difference between historical and fills and real time processing, although all of my logic is in the OnBarUpdate() method so should I be seeing this discrepancy still? As it should be using the OHLC information in both the historical and real time order fills? Or am I missing something?

            And the scenario 3 only happens when I put the playback slider on the bar that the order is being created on so if I put the playback slider to 24/08/23 23:16:00 it will then do the exit on session

            Thank you again for your time on this!

            Comment


              #21
              Hello MrHump,

              Thank you for your reply.

              In your strategy settings, what do you have Calculate set to?
              In State.Historical, OnBarUpdate() will only be called on the close of each bar. If you want intrabar data for OnBarUpdate() in State.Historical, you need to develop for TickReplay to be enabled or use a multi-time frame script. This means the logic in OnBarUpdate() to modify your stops will only be evaluated once per bar rather than processing OnPriceChange or OnEachTick like it does in State.Realtime. Adding print statements will help you to understand when actions are taken; to gain a better understanding of your strategy's behavior please add prints as suggested in my previous reply.

              I appreciate your time and patience.

              Comment


                #22
                My Calculate option for this strategy is set to "On bar close" in the drop down menu, I do not expect to be using any intrabar data as calculating the new stop loss on the previous bar close is fine for this strategy,

                I will add the prints instead of stepping through the code like you suggest to see if I can spot why this discrepancy is occurring.

                Thank you again for your insight on this its really helpful!

                Comment


                  #23
                  Just wanted to update this post with what ended up being the problem above, it turned out to be the way I was calculating the CurrentStopLossPrice, instead of saving my market order to a variable and using that objects stopLossPrice property i was trying to calculate the current stop loss from the position. So when I was debugging and stepping through the position was being created quick enough that the data was there, however when the algorithm was filling historical orders I can only assume the position was not getting created fast enough for the next line of code to use the Position.AveragePrice meaning this returned 0 and my SetStopLoss() code was not being hit due to this CurrentStopLossPrice property needing to have a value!

                  Edit: Hi NinjaTrader_Emily​ sorry to keep bothering you, I have tried to google this and the things I'm currently trying to get the current stop loss are not working

                  this is my code:

                  var order = EnterLong(Convert.ToInt32(DefaultQuantity), @"Long Position");
                  CurrentStopLossPrice = order.StopPrice;

                  However that returns 0, is there a better way to get the stop loss other than calculating it from the previous close price?

                  Thank you again in advance!​
                  Last edited by MrHump; 08-30-2023, 01:11 PM.

                  Comment


                    #24
                    Hello MrHump,

                    Thank you for your reply.

                    EnterLong() generates a buy market order, so it does not have a StopPrice in the same way that an EnterLongStopLimit() or EnterLongStopMarket() would. Are you trying to get the entry price when the EnterLong() order will signalName "LongPosition" is filled? Or are you trying to get the average entry price? I'm not sure what you mean by trying to get the stop loss.

                    I look forward to your reply.

                    Comment


                      #25
                      Hi NinjaTrader_Emily​,

                      Ahh okay I thought that if I SetStopLoss() at the beginning on the script that stop loss would be set on any EnterLong() orders I create, is this not the case? I think I am trying to get the entry price, however I'm not 100% sure on the difference to be honest! Even after reading the documentation provided.

                      When I say I'm trying to get the stop loss, i want to get whatever the stop price is on the order that i just submitted so for example I enter a order at 4500, I want to get the stop loss price (which should be 2% under this value if its a long position and 2% above if its a short position. So if its a long order the stop loss price would be 4,410 and the short stop loss price returned would be 4590

                      Thank you again!

                      Comment


                        #26
                        Hello MrHump,

                        Thank you for your reply.

                        I thought that if I SetStopLoss() at the beginning on the script that stop loss would be set on any EnterLong() orders I create, is this not the case?
                        If you call SetStopLoss() and do not specify fromEntrySignal, the stop will be attached to all entries. If you do use a string for fromEntrySignal, the stop will be attached to only entries using that signalName.

                        The following reference sample from the help guide demonstrates how to monitor stop loss and profit target orders:


                        Thank you for your time and patience.

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by NullPointStrategies, Yesterday, 05:17 AM
                        0 responses
                        64 views
                        0 likes
                        Last Post NullPointStrategies  
                        Started by argusthome, 03-08-2026, 10:06 AM
                        0 responses
                        139 views
                        0 likes
                        Last Post argusthome  
                        Started by NabilKhattabi, 03-06-2026, 11:18 AM
                        0 responses
                        75 views
                        0 likes
                        Last Post NabilKhattabi  
                        Started by Deep42, 03-06-2026, 12:28 AM
                        0 responses
                        45 views
                        0 likes
                        Last Post Deep42
                        by Deep42
                         
                        Started by TheRealMorford, 03-05-2026, 06:15 PM
                        0 responses
                        50 views
                        0 likes
                        Last Post TheRealMorford  
                        Working...
                        X