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

How can I merge the Sample PnL code into my strategy's code?

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

    How can I merge the Sample PnL code into my strategy's code?

    I'm testing a simple strategy that only uses a EMA crossover as entry/exit signals
    I want the strategy to stop trading after $200 profit has been reached in one trading day (from hours 9:30 EST to 16:00 EST).
    I have downloaded the Sample PnL code from this thread: http://ninjatrader.com/support/forum...ead.php?t=4084 and I have tried merging the two together but it doesn't seem to work.

    It seems really easy to do but for some reason I cannot figure it out.

    This is my simple code:

    // This namespace holds all strategies and is required. Do not change it.
    namespace NinjaTrader.Strategy
    {
    /// <summary>
    /// Enter the description of your strategy here
    /// </summary>
    [Description("Enter the description of your strategy here")]
    public class Original : Strategy
    {
    #region Variables
    // Wizard generated variables
    private int myInput0 = 1; // Default setting for MyInput0
    // User defined variables (add any user defined variables below)
    #endregion

    /// <summary>
    /// This method is used to configure the strategy and is called once before any strategy method is called.
    /// </summary>
    protected override void Initialize()
    {

    CalculateOnBarClose = true;
    }

    /// <summary>
    /// Called on each bar update event (incoming tick)
    /// </summary>
    protected override void OnBarUpdate()
    {
    // Condition set 1
    if (CrossAbove(EMA(9), EMA(21), 1)
    && ToTime(Time[0]) >= ToTime(9, 30, 0)
    && ToTime(Time[0]) <= ToTime(16, 0, 0))
    {
    EnterLong(DefaultQuantity, "");
    }

    // Condition set 2
    if (CrossBelow(EMA(9), EMA(21), 1)
    && ToTime(Time[0]) >= ToTime(9, 30, 0)
    && ToTime(Time[0]) <= ToTime(16, 0, 0))
    {
    EnterShort(DefaultQuantity, "");
    }

    }

    #region Properties
    [Description("")]
    [GridCategory("Parameters")]
    public int MyInput0
    {
    get { return myInput0; }
    set { myInput0 = Math.Max(1, value); }
    }
    #endregion
    }
    }
    This is an excerpt from the downloaded Sample PnL code from the link above that I think is what I need to add:
    /// <summary>
    /// Called on each bar update event (incoming tick)
    /// </summary>
    protected override void OnBarUpdate()
    {
    // At the start of a new session
    if (Bars.FirstBarOfSession)
    {
    // Store the strategy's prior cumulated realized profit and number of trades
    priorTradesCount = Performance.AllTrades.Count;
    priorTradesCumProfit = Performance.AllTrades.TradesPerformance.Currency.C umProfit;

    /* NOTE: Using .AllTrades will include both historical virtual trades as well as real-time trades.
    If you want to only count profits from real-time trades please use .RealtimeTrades. */
    }

    /* Prevents further trading if the current session's realized profit exceeds $1000 or if realized losses exceed $400.
    Also prevent trading if 10 trades have already been made in this session. */
    if (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 1000
    || Performance.AllTrades.TradesPerformance.Currency.C umProfit - priorTradesCumProfit <= -400
    || Performance.AllTrades.Count - priorTradesCount > 10)
    {
    /* TIP FOR EXPERIENCED CODERS: This only prevents trade logic in the context of the OnBarUpdate() method. If you are utilizing
    other methods like OnOrderUpdate() or OnMarketData() you will need to insert this code segment there as well. */

    // Returns out of the OnBarUpdate() method. This prevents any further evaluation of trade logic in the OnBarUpdate() method.
    return;
    }
    Any help would be much appreciated my friends.

    #2
    Hello turbro21,

    I find in situations like this it is easiest to write out what I am trying to do in pseudo code. Taking what you wrote,

    I want the strategy to stop trading after $200 profit has been reached in one trading day (from hours 9:30 EST to 16:00 EST
    We can turn that into pseudo code as follows

    Code:
    if we have made more than $200 profit...
    ... or it's before 9:30 EST ...
    ... or it's after 16:00 EST ...
    ... then stop
    Otherwise...
    ... if we cross above the EMA...
    ... enter long,
    ... and if we cross below the EMA...
    ... enter short
    Then we can start turning that into regular code, first with a skeleton,
    Code:
    if (<stuff that prevents trading>)
    {
      return;
    }
    if (<ema above>)
    {
      EnterLong(<enter long options>);
    }
    if (<ema below>)
    {
      EnterShort(<enter short options>);
    }
    Finally, we just need to identify the conditions that we want. We can copy those from the code samples. First we'll need to do a bit of detective work. We see this comment,

    Code:
    /*
    Prevents further trading if the current session's realized profit exceeds $1000...
    */
    And we see a matching conditional...
    Code:
    (Performance.AllTrades.TradesPerformance.Currency.CumProfit - priorTradesCumProfit >= 1000)
    The same with the time being before 9 AM or after 4 PM,
    Code:
    (ToTime(Time[0]) >= ToTime(9, 30, 0))
    (ToTime(Time[0]) <= ToTime(16, 0, 0))
    Simply insert these conditionals into our pseudo-code, replacing every "or" with ||, and we get
    Code:
    if (
        // ... we have made more than $200 profit...
        (Performance.AllTrades.TradesPerformance.Currency.CumProfit - priorTradesCumProfit >= 1000)
    
        // ... OR it's before 9:30 EST ...
        || (ToTime(Time[0]) >= ToTime(9, 30, 0))
    
        // ... OR it's after 16:00 EST ...
        || (ToTime(Time[0]) <= ToTime(16, 0, 0))
        )
    And now we have all the code to replace <stuff that prevents trading> by.

    Please let us know if there is any other way we can help.
    Jessica P.NinjaTrader Customer Service

    Comment


      #3
      Thanks for the help Jessica, I have made the changes (I think) but it doesn't seem to work. I am sure I am omitting something simple. Now I sure wish I took some programming classes in school! Here's the code now:

      /// </summary>
      [Description("Sample strategy utilizing PnL statistics")]
      public class SamplePnL : Strategy
      {
      #region Variables
      private int priorTradesCount = 0;
      private double priorTradesCumProfit = 0;
      #endregion


      /// <summary>
      /// Called on each bar update event (incoming tick)
      /// </summary>
      protected override void OnBarUpdate()
      {
      if (
      // ... we have made more than $200 profit...
      (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)

      // ... OR it's before 9:30 EST ...
      || (ToTime(Time[0]) >= ToTime(9, 30, 0))

      // ... OR it's after 16:00 EST ...
      || (ToTime(Time[0]) <= ToTime(16, 0, 0))
      )

      // ENTRY CONDITION: If current close is greater than previous close, enter long
      if (CrossAbove(EMA(9), EMA(21), 1)
      && ToTime(Time[0]) >= ToTime(9, 30, 0)
      && ToTime(Time[0]) <= ToTime(16, 0, 0))
      {
      EnterLong(DefaultQuantity, "");
      }

      if (CrossBelow(EMA(9), EMA(21), 1)
      && ToTime(Time[0]) >= ToTime(9, 30, 0)
      && ToTime(Time[0]) <= ToTime(16, 0, 0))
      {
      EnterShort(DefaultQuantity, "");
      }
      }

      #region Properties
      #endregion
      }
      }
      Here is yesterday's NQ 5M chart. It should have stopped trading after the second trade of the day as it would have resulted in $400+ (minus the loss from the first trade but it would still be over $200).



      I'm going to try tweaking it on my end but if you have any suggestions then please let me know.

      Thanks again!
      Last edited by turbro21; 02-24-2016, 03:04 PM.

      Comment


        #4
        Hello again turbro21,

        I did notice a few problems with your code. Sometimes, when copying and pasting, we can introduce new errors if we are not familiar with each line of code and why it was implemented. Compiling after each block of code is also helpful in learning the code.

        First, you'll notice in the pseudo-code, where we had

        Code:
        ...then stop
        This was replaced by

        Code:
        {
          return;
        }
        I noticed that was missing in your code.

        Second, a few of the variables from one of your conditions - the one that checks to see if we have more than $200 profit - need to be set up in advance. You see you use something called "priorTradesCumProfit" .

        Third, if you look at the pseudo code, you moved all your checks for what time it is to the first if statement. You may go ahead and remove these checks from the if statements where you check for EMA crosses.

        I will go ahead and provide a sample. I will bold where I made changes.

        Code:
        /// </summary>
        [Description("Sample strategy utilizing PnL statistics")]
        public class SamplePnL : Strategy
        {
          #region Variables
          private int priorTradesCount = 0;
          private double priorTradesCumProfit = 0;
          #endregion
        
        
          /// <summary>
          /// Called on each bar update event (incoming tick)
          /// </summary>
          protected override void OnBarUpdate()
          {[B]
            // At the start of a new session
            if (Bars.FirstBarOfSession)
            {
              // Store the strategy's prior cumulated realized profit and number of trades
                              priorTradesCount = Performance.AllTrades.Count;
              priorTradesCumProfit = Performance.AllTrades.TradesPerformance.Currency.CumProfit;
                        
            /*
              NOTE:
              Using .AllTrades will include both historical virtual trades
              as well as real-time trades.
              If you want to only count profits from real-time trades
              please use .RealtimeTrades.
             */
            }[/B]
        
            if (
                // ... we have made more than $200 profit...
                (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
        
                // ... OR it's before 9:30 EST ...
                || (ToTime(Time[0]) [SIZE=5][B]<[/B][/SIZE] ToTime(9, 30, 0))
        
                // ... OR it's after 16:00 EST ...
                || (ToTime(Time[0]) [SIZE=7][SIZE=5][B]>[/B][/SIZE] [/SIZE]ToTime(16, 0, 0))
                )[SIZE=5]
        [/SIZE][SIZE=7][B][SIZE=5]    {
              return;
            }[/SIZE][/B][/SIZE]
        
            // ENTRY CONDITION: If current close is greater than previous close,
            // enter long
            if (CrossAbove(EMA(9), EMA(21), 1)[SIZE=5][B])[/B][/SIZE]
            {
              EnterLong(DefaultQuantity, "");
            }
        
            if (CrossBelow(EMA(9), EMA(21), 1)[SIZE=5][B])[/B][/SIZE]
            {
              EnterShort(DefaultQuantity, "");
            }
          }
        
          #region Properties
          #endregion
        }
        Jessica P.NinjaTrader Customer Service

        Comment


          #5
          Hi Jessica, thanks again for helping me.
          I have a good feeling about the code this time but for some reason when I run it to back test no trades go through, meaning the profit and loss is $0, 0 trades are made in my selected period, etc. For some reason the trades are not triggering.

          Comment


            #6
            We're happy to help.

            So there are three steps you can use for debugging.

            First, I would like to ask, does your original simple code sample make trades by itself? If so, your EMA crosses are not the problem.

            If your original simple code is not making trades, on the other hand, you will need to review the following help guide pages to better understand the EMA indicator, and CrossAbove / Below methods.






            Secondly, I would like you to replace the if statement we put together with the following code, to make it easier to isolate exactly which condition (if any) is preventing you from making trades :

            Code:
                if ([SIZE=5][B]false[/B][/SIZE]
            // ... we have made more than $200 profit...
            [SIZE=5][B]// [/B][/SIZE](Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
            // ... OR it's before 9:30 EST ...
            [SIZE=5][B]// [/B][/SIZE]|| (ToTime(Time[0]) [SIZE=3]<[/SIZE] ToTime(9, 30, 0))
            // ... OR it's after 16:00 EST ...
            [SIZE=5][B]// [/B][/SIZE]|| (ToTime(Time[0]) [SIZE=7][SIZE=3]>[/SIZE] [/SIZE]ToTime(16, 0, 0))
            )
                {
                     return;
                }
            You should continue to make trades. If not, it means we copied something wrong from the EMA indicator methods originally.

            Finally, remove the bold word "false" and one by one, remove the bold // from your code. Like so :

            Code:
                if (
            // ... we have made more than $200 profit...         (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
            // ... OR it's before 9:30 EST ...
            [SIZE=5][B]// [/B][/SIZE]|| (ToTime(Time[0]) [SIZE=3]<[/SIZE] ToTime(9, 30, 0))
            // ... OR it's after 16:00 EST ...
            [SIZE=5][B]// [/B][/SIZE]|| (ToTime(Time[0]) [SIZE=7][SIZE=3]>[/SIZE] [/SIZE]ToTime(16, 0, 0))
            )
                {
                     return;
                }
            Then

            Code:
            if (
            // ... we have made more than $200 profit...         (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
            // ... OR it's before 9:30 EST ...
            || (ToTime(Time[0]) [SIZE=3]<[/SIZE] ToTime(9, 30, 0))
            // ... OR it's after 16:00 EST ...
            [SIZE=5][B]// [/B][/SIZE]|| (ToTime(Time[0]) [SIZE=7][SIZE=3]>[/SIZE] [/SIZE]ToTime(16, 0, 0))
            )
                {
                     return;
                }
            Then

            Code:
                if (
            // ... we have made more than $200 profit...         
            (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
            // ... OR it's before 9:30 EST ...
            || (ToTime(Time[0]) [SIZE=3]<[/SIZE] ToTime(9, 30, 0))
            // ... OR it's after 16:00 EST ...
            || (ToTime(Time[0]) [SIZE=7][SIZE=3]>[/SIZE] [/SIZE]ToTime(16, 0, 0))
            )
                {
                  return;
                }
            As soon as you stop seeing trades, you have found out which line of code is faulty.
            Last edited by NinjaTrader_JessicaP; 02-25-2016, 01:04 PM.
            Jessica P.NinjaTrader Customer Service

            Comment


              #7
              Hi Jessica,

              I recopied/pasted your code and now it works; however, a new problem came up: the strategy stops after a profit of $200 or more is reached, which is good, but this happened on the first day of my time range and then the strategy stops, meaning it does not start trading on subsequent days.

              Comment


                #8
                If you would like your profit to reset, the pseudo code for that is

                Code:
                IF...
                ... it is before 9:30 am OR after 4 pm...
                ... AND you have $200 profit or more...
                ...THEN...
                ...set priorTradesCumProfit to your current profit level
                ...DONE WITH THE NEW IF BLOCK
                You will want this code before the if statement we put together, but still inside OnBarUpdate.

                In real code, that looks like this.

                Code:
                if (
                    ( (ToTime(Time[0]) < ToTime(9, 30, 0)) || (ToTime(Time[0]) > ToTime(16, 0, 0)) )
                    && (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
                    )
                  {
                    priorTradesCumProfit = Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit;
                  }
                Jessica P.NinjaTrader Customer Service

                Comment


                  #9
                  I added your new code but the same error is still occurring: on the first day a profit of over $200 is reached therefore the strategy does not run for the rest of the days in my time range.

                  Here is the final code (bold is your new section):

                  /// <summary>
                  /// Called on each bar update event (incoming tick)
                  /// </summary>
                  protected override void OnBarUpdate()
                  {
                  if (
                  ( (ToTime(Time[0]) < ToTime(9, 30, 0)) || (ToTime(Time[0]) > ToTime(16, 0, 0)) )
                  && (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)
                  )
                  {
                  priorTradesCumProfit = Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit;
                  }

                  // At the start of a new session
                  if (Bars.FirstBarOfSession)
                  {
                  // Store the strategy's prior cumulated realized profit and number of trades
                  priorTradesCount = Performance.AllTrades.Count;
                  priorTradesCumProfit = Performance.AllTrades.TradesPerformance.Currency.C umProfit;

                  /*
                  NOTE:
                  Using .AllTrades will include both historical virtual trades
                  as well as real-time trades.
                  If you want to only count profits from real-time trades
                  please use .RealtimeTrades.
                  */
                  }

                  if (
                  // ... we have made more than $200 profit...
                  (Performance.AllTrades.TradesPerformance.Currency. CumProfit - priorTradesCumProfit >= 200)

                  // ... OR it's before 9:30 EST ...
                  || (ToTime(Time[0]) < ToTime(9, 30, 0))

                  // ... OR it's after 16:00 EST ...
                  || (ToTime(Time[0]) > ToTime(16, 0, 0))
                  )
                  {
                  return;
                  }

                  // ENTRY CONDITION: If current close is greater than previous close,
                  // enter long
                  if (CrossAbove(EMA(5), EMA(6), 1))
                  {
                  EnterLong(DefaultQuantity, "");
                  }

                  if (CrossBelow(EMA(5), EMA(6), 1))
                  {
                  EnterShort(DefaultQuantity, "");
                  }
                  }

                  Comment


                    #10
                    I am sorry to hear that the code I sent is not resetting between days as I expected it to.

                    Developing and testing this feature goes beyond the scope of merely combining two other pieces of code, which was our original goal. I will be happy to work on this over the weekend. However, I would invite you to experiment with modifying the priorTradesCumProfit variable between now and then, so you do not have to wait for me.

                    The way your code works without the bolded code, is to set priorTradesCumProfit to a "carry over" value on the first bar of the session. All the rest of the code relies on this as your "zero", and treats everything above it as "real" profit. This is similar to the "tare" button on the kind of scale you stand on or measure food on.

                    So my plan was to increase this "tare" value so that it included your profit on any day in which you made $200 profit, so that the next day only profit beyond that would be included.
                    Jessica P.NinjaTrader Customer Service

                    Comment


                      #11
                      Well Jessica, it looks like the problem was on my end. Today I started up NinjaTrader and re-ran the code and the strategy worked as it should for the most part. A small issue lies in that when a profit of over $200 is reached the startegy stops trading but it keeps one position open.

                      For example:


                      We see the strategy stopped after the second trade of the day as the profit target was surpassed but it still bought 1 contract which was closed at the end of the session. If you can think of an easy way to prevent this from happening then let me know. If it will required too complex of a code then do not worry about it and I will just focus on other strategies.

                      Overall the strategy is profitable now after some adjustments to the EMA period; however it makes many trades which is why I want to see how much of a difference in profit this little change would make.

                      Comment


                        #12
                        I believe this will be a simple fix. I am including Help Guide references for the ExitShort() and ExitLong() methods.




                        I am also including a quote from the ExitShort() Help Guide page that I linked.

                        Tips (also see Overview)
                        This method is ignored if a short position does not exist
                        It is helpful to provide a signal name if your strategy has multiple exit points to help identify your exits on a chart
                        You can tie an exit to an entry by providing the entry signal name in the parameter "fromEntrySignal"
                        If you do not specify a quantity the entire position is exited rendering your strategy flat
                        If you do not specify a "fromEntrySignal" parameter the entire position is exited rendering your strategy flat
                        This means that, in the code, where we called "return" we can call,

                        Code:
                        {
                          ExitShort();
                          ExitLong();
                          return;
                        }
                        To flatten your position.
                        Jessica P.NinjaTrader Customer Service

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by GLFX005, Today, 03:23 AM
                        0 responses
                        1 view
                        0 likes
                        Last Post GLFX005
                        by GLFX005
                         
                        Started by XXtrader, Yesterday, 11:30 PM
                        2 responses
                        11 views
                        0 likes
                        Last Post XXtrader  
                        Started by Waxavi, Today, 02:10 AM
                        0 responses
                        6 views
                        0 likes
                        Last Post Waxavi
                        by Waxavi
                         
                        Started by TradeForge, Today, 02:09 AM
                        0 responses
                        11 views
                        0 likes
                        Last Post TradeForge  
                        Started by Waxavi, Today, 02:00 AM
                        0 responses
                        2 views
                        0 likes
                        Last Post Waxavi
                        by Waxavi
                         
                        Working...
                        X