Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Changing Trail Stops in Strategy

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

    Changing Trail Stops in Strategy

    Hi. I'm trying to change the trail stop as my profit increases in a position, like how ATM strategy would work. I have the below code, but the issue of course is that the trail stop will change if the instrument goes above 50 ticks, then falls below 50 ticks later. I wanted to see how the ATM strategy code works to copy it, but couldn't find it. Could someone tell me where to find it? Also, is there an easy way to fix the below? Thanks!

    if (CurrentBar < BarsRequiredToTrade)
    return;

    if (MidTermBottom[0] > ExecutionValueBot)
    EnterLong();

    SetTrailStop(@"", CalculationMode.Ticks, TrailDefault, false);

    if (BarsInProgress > 1 && Close[0] >= Position.AveragePrice + 30 * TickSize)
    SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);

    if (BarsInProgress > 1 && Close[0] >= Position.AveragePrice + 50 * TickSize)
    SetTrailStop(@"", CalculationMode.Ticks, TrailDefault3, false);

    #2
    Hello GoodTradingFun,

    Thanks for your post.

    The code for ATMs is not exposed and is not publicly available.

    I recommend that you set the initial trailstop level before placing the order as this will prevent using a previous level. You can also use Position.MarketPosition to make sure you are only entering when flat, Like this:

    if (MidTermBottom[0] > ExecutionValueBot && Position.MarketPosition == MarketPosition.Flat)
    {
    SetTrailStop(@"", CalculationMode.Ticks, TrailDefault, false); // set the level before the entry
    EnterLong();
    }

    Generally, you can control the trailstop changes you want by using Bool variables so that each of the trail stops is only executed once and in the sequence you wish by checking that a bool is true and then setting it to false. For example:

    if (BarsInProgress > 1 && Close[0] >= Position.AveragePrice + 30 * TickSize && myBool == true)
    {
    SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
    myBool = false;
    }

    The bool called myBool is initially set true so the condition (when close >= entry price + 30 ticks) is true the SetTrailStop() is adjusted and the myBool is set false so the trail stop cannot be set again. This also means that you will need to reset the bool back to true when you are in a flat position.

    You would need another bool and the same process for the last trail stop adjustment
    Last edited by NinjaTrader_PaulH; 08-17-2021, 09:44 AM. Reason: Fixed the assignment of the myBool with a single = instead of ==
    Paul H.NinjaTrader Customer Service

    Comment


      #3
      Thank you. I tried doing something similar with setting a variable as a number last night and adjusting the number but I get the same error I am getting when I try the booleen variable. Here is my code. The error is only assignment, call, increment, decrement, await, and new object expressions can be used as a statement and it highlights the Bool1==true, Bool2==true, etc. Thanks!

      protected override void OnBarUpdate()
      {
      if (CurrentBar < BarsRequiredToTrade)
      return;


      if (MidTermBottom(Close,11,11,11,10,10,11,10,11,11,11 )[0] > ExecutionValueBot && Position.MarketPosition == MarketPosition.Flat)
      {
      SetTrailStop(@"", CalculationMode.Ticks, TrailDefault, false);
      EnterLong();
      Bool1 == true;
      Bool2 == true;
      }


      if (BarsInProgress > 1 && Close[0] >= Position.AveragePrice + 30 * TickSize && Bool1 == true)
      {
      SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
      Bool1 == false;
      }

      if (BarsInProgress > 1 && Close[0] >= Position.AveragePrice + 60 * TickSize && Bool2 == true)
      {
      SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
      Bool2 == false;
      }


      }

      Comment


        #4
        Hello GoodTradingFun,

        Thanks for your reply.

        My example is in error, my apologies for that. (I will change it in my post #2)

        Inside of the if statement you need Bool1 == true, the double equals is asking if the bool is logically equal to true.
        In the action side, when you want to assign a value to the bool you use a single equals sign. As an example, please try:

        if (BarsInProgress > 1 && Close[0] >= Position.AveragePrice + 30 * TickSize && Bool1 == true)
        {
        SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
        Bool1 = false;
        }

        Note, please make sure you have created private bool Bool1 = true, Bool2 = true; at the class level
        Paul H.NinjaTrader Customer Service

        Comment


          #5
          Thanks. So I did a similar thing last night but instead of boolean I used a number variable. I'm getting the same problem. My code is below. It 100% of the time uses the traildefault3 variable, which means it determines the final statement to always be true. The BarsInProgress wouldn't work at all so I took that out. Is that OK? Do you know why it thinks the statements are always true? I'm thinking that the "Position.AveragePrice + 50 * ticksize" is not right. Not sure what else I can do besides "Position.AveragePrice" but it doesn't seem to be working. Thanks.

          if (MidTermBottom(Close,11,11,11,10,10,11,10,11,11,11 )[0] > ExecutionValueBot && Position.MarketPosition == MarketPosition.Flat)
          {
          SetTrailStop(@"", CalculationMode.Ticks, TrailDefault, false);
          Bool1 = true;
          Bool2 = true;
          EnterLong();
          }


          if (Close[0] >= Position.AveragePrice + 30 * TickSize && Bool1 == true)
          {
          SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
          Bool1 = false;
          }

          if (Close[0] >= Position.AveragePrice + 60 * TickSize && Bool2 == true)
          {
          SetTrailStop(@"", CalculationMode.Ticks, TrailDefault3, false);
          Bool2 = false;
          }


          }

          Comment


            #6
            OK, I figured it out, haha. I have to say that the position needs to be long in those statements. Thanks for the help! Code is below....


            if (MidTermBottom(Close,11,11,11,10,10,11,10,11,11,11 )[0] > ExecutionValueBot && Position.MarketPosition == MarketPosition.Flat)
            {
            SetTrailStop(@"", CalculationMode.Ticks, TrailDefault, false);
            Bool1 = true;
            Bool2 = true;
            EnterLong();
            }


            if (Close[0] >= Position.AveragePrice + 30 * TickSize && Bool1 == true && Position.MarketPosition == MarketPosition.Long)
            {
            SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
            Bool1 = false;
            }

            if (Close[0] >= Position.AveragePrice + 60 * TickSize && Bool2 == true && Position.MarketPosition == MarketPosition.Long)
            {
            SetTrailStop(@"", CalculationMode.Ticks, TrailDefault3, false);
            Bool2 = false;
            }


            }

            Comment


              #7
              Hello GoodTradingFun,

              Thanks for your reply.

              Glad you were able to resolve it.

              I will move this thread into the Ninjatrader8 Strategy Forum as that is a better fit for it.
              Paul H.NinjaTrader Customer Service

              Comment


                #8
                Thank you. So unfortunately I can't get the code to have more than 1 long position at a time. I have Entries per direction set to 3 and Entry handling equal to All entries. If another long position would happen when I already have a long position, it closes out the long position and purchases the new one the next minute if I have Entries per direction set to 3 and the same minute if I have it on 1.

                Why is it not allowing me to purchase another contract? I also put the stop to 300 ticks to make sure it wasn't due to the "Position.AveragePrice" and it still won't execute a 2nd trade. Do I need to change the code to allow for multiple trades? Thanks.

                Comment


                  #9
                  OK, so now I see the obvious problem. I changed the code to the below so it can always initiate a new position and only looks at stops when not flat. The final piece to this would be having it treat each order independently so instead of "Position.AveragePrice" it would be the entry price of each specific order. Is there a way to do that? Sorry about the last post, strangely I didn't see the issue until after I posted. Thanks.



                  if (MidTermBottom(Close,11,11,11,10,10,11,10,11,11,11 )[0] > ExecutionValueBot)
                  {
                  SetTrailStop(@"", CalculationMode.Ticks, TrailDefault, false);
                  Bool1 = true;
                  Bool2 = true;
                  EnterLong();
                  }


                  if (Close[0] >= Position.AveragePrice + 40 * TickSize && Bool1 == true && Position.MarketPosition != MarketPosition.Flat)
                  {
                  SetTrailStop(@"", CalculationMode.Ticks, TrailDefault2, false);
                  Bool1 = false;
                  }

                  if (Close[0] >= Position.AveragePrice + 75 * TickSize && Bool2 == true && Position.MarketPosition != MarketPosition.Flat)
                  {
                  SetTrailStop(@"", CalculationMode.Ticks, TrailDefault3, false);
                  Bool2 = false;
                  }

                  Comment


                    #10
                    Hello GoodTradingFun,

                    Thanks for your reply.

                    If I understand correctly you are wanting to have up to 3 separate entries and I would assume 3 separate trail stops.

                    In order to accomplish your goal, you will have to use signal names for your entries and then provide that same signal name for each associated trail stop.

                    In order to get the actual entry price of each order, I would suggest using OnExecutionUpdate() and check for the (signal) name of the entry and then pull the price of the entry from the execution object. You can assign that to a class-level variable so that you can then use that specific price in your trail stops.
                    Reference: https://ninjatrader.com/support/help...tionupdate.htm

                    Paul H.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by AaronKoRn, Today, 09:49 PM
                    0 responses
                    11 views
                    0 likes
                    Last Post AaronKoRn  
                    Started by carnitron, Today, 08:42 PM
                    0 responses
                    10 views
                    0 likes
                    Last Post carnitron  
                    Started by strategist007, Today, 07:51 PM
                    0 responses
                    11 views
                    0 likes
                    Last Post strategist007  
                    Started by StockTrader88, 03-06-2021, 08:58 AM
                    44 responses
                    3,980 views
                    3 likes
                    Last Post jhudas88  
                    Started by rbeckmann05, Today, 06:48 PM
                    0 responses
                    9 views
                    0 likes
                    Last Post rbeckmann05  
                    Working...
                    X