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

Limit a strategy to firing off once per day

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

    Limit a strategy to firing off once per day

    Hello, I'm trying to figure out a solution to prevent my strategy from firing after the target has been reached. Currently, I have the strategy timeboxed to the from market open to 12:30 PM PT and set it to calculate on price change and limited to 1 entry per direction. The problem is that if take profit or stop loss is reached and it is still within the valid time window, it will try to open a new trade.

    How can I tell the strategy to stop after the first trade is complete? Here is my execution logic for reference:

    ​if(
    ((mar****pen >= noTradeHigh)
    || (mar****pen <= noTradeLow))
    && ((Times[0][0].TimeOfDay > new TimeSpan(6, 30, 01))
    && (Times[0][0].TimeOfDay <= new TimeSpan(12, 30, 0))))
    {
    //execute trade

    if (Direction == "Long")
    {
    SetProfitTarget( CalculationMode.Price, PrimeTargetPrice);
    SetStopLoss( CalculationMode.Price, PrimeStp1Price);

    EnterLongLimit( MiniQuantityInt, PrimeEntryPrice );

    }
    else if (Direction == "Short")
    {
    SetProfitTarget( CalculationMode.Price, PrimeTargetPrice);
    SetStopLoss( CalculationMode.Price, PrimeStp1Price);

    EnterShortLimit( MiniQuantityInt, PrimeEntryPrice);


    }​

    #2
    Perhaps add a boolean variable that keeps track of whether you've traded. Reset it on the first bar of the session.

    You might be able to check the Account variable, I think, as well.

    Comment


      #3
      Hello maltin,

      Thanks for your post.

      masilver is correct. A bool variable could be used to control when trades are made by a strategy.

      You could create a bool named something like OkToTrade that is initially set to say 'true'. In your condition to place an entry order, you would check if the bool is true. Then flip your bool to false after calling your Entry order method. The variable could be reset on the first bar of the session.

      IsFirstBarOfSession could be used to detect if the current bar processing is the first bar in a trading session.

      See this help guide page for more information about IsFirstBarOfSession: https://ninjatrader.com/support/help...rofsession.htm
      Brandon H.NinjaTrader Customer Service

      Comment


        #4
        Thank you for the response. I use this approach in my code, but I notice that it will keep entering the trade if the trade closes on the current bar (I was using a 5 min chart). Otherwise it works perfectly. My workaround is to place this strategy on a 30 second chart because the odds of it closing on the bar are extremely low. Still, the bool logic is set to flip after the trade is entered, once flipped I would expect the entry block of code to be skipped. However, it will continue to fire as long as the first bar is active. My calculate is set to on price change.

        Is there something I'm missing?
        Code:
        if(Times[dataSeries][0].TimeOfDay == new TimeSpan(6, 30, 30)&& tradeComplete == false &&  IsFirstTickOfBar == false)
                        {
        
        
                            //execute trade
                            SetProfitTarget( "PrimeEntry", CalculationMode.Price, PrimeTargetPrice);
                            SetStopLoss( "PrimeEntry", CalculationMode.Price, PrimeStp1Price, false);
        
                            SetProfitTarget( "HMEntry", CalculationMode.Price, PrimeTargetPrice);
                            SetStopLoss( "HMEntry", CalculationMode.Price, PrimeStp1Price, false);
        
                            SetProfitTarget( "PrimeMicroEntry", CalculationMode.Price, PrimeTargetPrice);
                            SetStopLoss( "PrimeMicroEntry", CalculationMode.Price, PrimeStp1Price, false);
        
                            SetProfitTarget( "HMMicroEntry", CalculationMode.Price, PrimeTargetPrice);
                            SetStopLoss( "HMMicroEntry", CalculationMode.Price, PrimeStp1Price, false);
        
        
                            if (direction == "LONG")
                            {                
        //                        if (MicroInstrument == false)
        //                        {
                                    if (MiniQuantityInt > 0)
                                        EnterLongLimit(miniTradeDataSeries, liveUntilCancelled, MiniQuantityInt, PrimeEntryPrice, "PrimeEntry" );
        
                                    if (HMMiniQtyInt > 0)
                                        EnterLongLimit(miniTradeDataSeries, liveUntilCancelled,  HMMiniQtyInt, HMEntryPrice, "HMEntry" );
        //                        }
        
                                if (MicroInstrument == true)
                                {                    
                                    if (MicroQuantityInt > 0)
                                        EnterLongLimit(microTradeDataSeries, liveUntilCancelled, MicroQuantityInt, PrimeEntryPrice, "PrimeMicroEntry" );
        
                                    if (HMMicroQtyInt > 0)
                                        EnterLongLimit(microTradeDataSeries, liveUntilCancelled, HMMicroQtyInt, HMEntryPrice, "HMMicroEntry" );
                                }
                                //tradeComplete = true;
        
                            }
                            else if (direction == "SHORT")
                            {
        //                        if (MicroInstrument == false)
        //                        {
        
                                    if (MiniQuantityInt > 0)
                                        EnterShortLimit( miniTradeDataSeries, liveUntilCancelled, MiniQuantityInt, PrimeEntryPrice, "PrimeEntry");
        
                                    if (HMMiniQtyInt > 0)    
                                        EnterShortLimit( miniTradeDataSeries, liveUntilCancelled, HMMiniQtyInt, HMEntryPrice, "HMEntry");    
        
        //                        }
        
                                if (MicroInstrument == true)
                                {
                                    if (MicroQuantityInt > 0)
                                        EnterShortLimit( 2, liveUntilCancelled, MicroQuantityInt, PrimeEntryPrice, "PrimeMicroEntry");
        
                                    if (HMMicroQtyInt > 0)        
                                        EnterShortLimit(microTradeDataSeries, liveUntilCancelled,  HMMicroQtyInt, HMEntryPrice, "HMMicroEntry");
        
                                }
        
                            }
        
                            tradeComplete = true; // ensures trade is entered only once per day
        
                        } // end timebox for trade execution​

        Comment


          #5
          Hello maltin,

          Thanks for your note.

          It is likely that the bool is being flipped back to false at some point which is allowing orders to continue being submitted. I have attached a very simple example script you could view demonstrating how a bool could be used to control when trades are placed. Ultimately, debugging prints would need to be used to determine exactly how the bool is behaving as orders are being placed. In the strategy add prints (outside of any conditions) that print the values of every variable used in every condition that places an order along with the time of that bar to understand how the conditions (including the bool) are evaluating.

          Below is a link to a forum post that demonstrates how to use prints to understand behavior.
          https://ninjatrader.com/support/foru...121#post791121

          I see that you are using the same Signal Names for your Long and Short Entry orders. The strategy should be modified so that Long and Short entry orders have different Signal Names such as "PrimeMicroEntryLong" for Long Entry orders and "PrimeMicroEntryShort" for Short Entry orders since you are using the Price parameter for your SetStopLoss()/SetProfitTarget() methods. Each entry order will also need to have a pair of SetStopLoss()/SetProfitTarget() orders with the appropriate fromSignalName.

          Also, the SetStopLoss()/SetProfitTarget() orders should be called before the Entry order is placed since Set methods prep NinjaTrader to submit protective orders on the incoming execution of entry orders.

          For example:

          SetProfitTarget( "PrimeEntryLong", CalculationMode.Price, PrimeTargetPrice);
          SetStopLoss( "PrimeEntryLong", CalculationMode.Price, PrimeStp1Price, false);​
          EnterLongLimit(miniTradeDataSeries, liveUntilCancelled, MiniQuantityInt, PrimeEntryPrice, "PrimeEntryLong" );
          Attached Files
          Brandon H.NinjaTrader Customer Service

          Comment


            #6
            Hi Brandon,

            Thanks for you help on this. I went through the code and found the error! You mentioned that my SetStopLoss and ProfitTarget were called after the enter limit orders. While they were physically above the enter limit orders, could you share why they wouldn't be process first?

            Is order of execution impacted by my logic? I'm still very new to C# so I don't want to assume anything.

            Thanks again,
            Mark
            Last edited by maltin; 05-17-2023, 06:36 AM.

            Comment


              #7
              Hello maltin,

              Thanks for your notes.

              Set methods (SetProfitTarget/SetStopLoss) prep NinjaTrader to submit protective orders when an entry order is executed. If your stop loss/profit target price is static, you should call the Set methods within OnStateChange() when the State == State.Configure.

              Otherwise, if you are calling the Set methods in OnBarUpdate() then the Set methods should be called prior to the entry order method in the script as seen below.

              For example:

              if (condition)
              {
              SetProfitTarget( "PrimeEntryLong", CalculationMode.Price, PrimeTargetPrice);
              SetStopLoss( "PrimeEntryLong", CalculationMode.Price, PrimeStp1Price, false);​
              EnterLongLimit(miniTradeDataSeries, liveUntilCancelled, MiniQuantityInt, PrimeEntryPrice, "PrimeEntryLong" );​
              }


              Note the tips below from the SetStopLoss and SetProfitTarget help guide pages:
              • It is suggested to call this method from within the strategy OnStateChange() method if your stop loss price/offset is static
              • You may call this method from within the strategy OnBarUpdate() method should you wish to dynamically change the stop loss price while in an open position
              • Should you call this method to dynamically change the stop loss price in the strategy OnBarUpdate() method, you should always reset the stop loss price / offset value when your strategy is flat otherwise, the last price/offset value set will be used to generate your stop loss order on your next open position
              We have a reference sample you could view linked below demonstrating the above:
              https://ninjatrader.com/support/help..._lo.htm​

              See the help guide documentation below for more information.

              SetStopLoss: https://ninjatrader.com/support/help...etstoploss.htm
              SetProfitTarget: https://ninjatrader.com/support/help...ofittarget.htm
              Brandon H.NinjaTrader Customer Service

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by fx.practic, 10-15-2013, 12:53 AM
              5 responses
              5,404 views
              0 likes
              Last Post Bidder
              by Bidder
               
              Started by Shai Samuel, 07-02-2022, 02:46 PM
              4 responses
              95 views
              0 likes
              Last Post Bidder
              by Bidder
               
              Started by DJ888, Yesterday, 10:57 PM
              0 responses
              8 views
              0 likes
              Last Post DJ888
              by DJ888
               
              Started by MacDad, 02-25-2024, 11:48 PM
              7 responses
              160 views
              0 likes
              Last Post loganjarosz123  
              Started by Belfortbucks, Yesterday, 09:29 PM
              0 responses
              9 views
              0 likes
              Last Post Belfortbucks  
              Working...
              X