Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Custom Performance Metric

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

    Custom Performance Metric

    This Performance Metric is almost identical the "SampleCumProfit".

    Would you please educate me on why this Performance Metric is displaying the Total Net Profit value and not 5.00 that is hard coded in protected override void OnMergePerformanceMetric.



    PHP Code:
    //This namespace holds Performance metrics in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.PerformanceMetrics
    {
        public class MyCustomPerformanceMetric : PerformanceMetric
        {
            private Cbi.Currency denomination = (Cbi.Currency) (-1);
            
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Enter the description for your new custom Performance Metric here.";
                    Name                                        = "MyCustomPerformanceMetric";
                }
                else if (State == State.Configure)
                {
                    Values    = new double[5];                    // There needed to be one value per Cbi.PerformanceUnit, which is why the values are managed in an array of length "ValueArrayLength"
                }
                else if (State == State.Active)    
                {
                    Array.Clear(Values, 0, Values.Length);        // Needed to be reset before every backtest iteration.
                }
            }
    
            protected override void OnAddTrade(Trade trade)
            {
                if (denomination == (Cbi.Currency) (-1))
                    denomination = trade.Exit.Account.Denomination;
    
                Values[(int)Cbi.PerformanceUnit.Currency]    += trade.ProfitCurrency;
                Values[(int)Cbi.PerformanceUnit.Percent]    = (1.0 + Values[(int)Cbi.PerformanceUnit.Percent]) * (1.0 + trade.ProfitPercent) - 1;
                Values[(int)Cbi.PerformanceUnit.Pips]        += trade.ProfitPips;
                Values[(int)Cbi.PerformanceUnit.Points]        += trade.ProfitPoints;
                Values[(int)Cbi.PerformanceUnit.Ticks]        += trade.ProfitTicks;
            }
    
            // This is called as the values of a trade metric are saved, which occurs e.g. in the strategy analyzer on optimizer runs
            protected override void OnCopyTo(PerformanceMetricBase target)
            {
                // You need to cast, in order to access the right type
                MyCustomPerformanceMetric targetMetrics = (target as MyCustomPerformanceMetric);
    
                if (targetMetrics != null)
                    Array.Copy(Values, targetMetrics.Values, Values.Length);
            }
    
            protected override void OnMergePerformanceMetric(PerformanceMetricBase target)
            {
                // You need to cast, in order to access the right type
                MyCustomPerformanceMetric targetMetrics = (target as MyCustomPerformanceMetric);
    
                // This is just a simple weighted average sample
                if (targetMetrics != null && TradesPerformance.TradesCount + targetMetrics.TradesPerformance.TradesCount > 0)
                    for (int i = 0; i < Values.Length; i++)
                    {
                        targetMetrics.Values[i] = 5.00;
                        //    Will eventually  be:
                        //    TradesPerformance.NetProfit / TradesPerformance.Currency.Drawdown
                    }
            }
    
            // The display attribute determines the name of the performance value on the grid (the actual property name below is irrelevant for that matter)
            [Display(Name = "MyCustomPerformanceMetric", Description = "Enter the description for your new custom Performance Metric here.", Order = 0)]
            public double[] Values
            { get; private set; }
    
            #region Miscellaneous
            // The format method allows you to customize the rendering of the performance value on the summary grid.
            public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)
            {
                double[] tmp = value as double[];
                if (tmp != null && tmp.Length == 5)
                    switch (unit)
                    {
                        case Cbi.PerformanceUnit.Currency    : return Core.Globals.FormatCurrency(tmp[0], denomination);
                        case Cbi.PerformanceUnit.Percent    : return tmp[1].ToString("P");
                        case Cbi.PerformanceUnit.Pips        : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCulture);
                        case Cbi.PerformanceUnit.Points        : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCulture);
                        case Cbi.PerformanceUnit.Ticks        : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCulture);
                    }
                return value.ToString();            // should not happen
            }
            #endregion        
    
        }
    }&#8203; 
    
    This is the image of the Analyzer:
    Click image for larger version

Name:	Nt Support 1.png
Views:	72
Size:	30.6 KB
ID:	1333149


    ​Thanks.

    #2
    Hello TAJTrades,

    After making the assignment may I confirm you have compiled the script without errors?

    If you restart NinjaTrader and run a new backtest, does the merged values show 5?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      After making the assignment may I confirm you have compiled the script without errors? Compiles. No Errors

      If you restart NinjaTrader and run a new backtest, does the merged values show 5? Will reboot computer and try.

      Comment


        #4
        Chelsea,

        I rebooted the computer and restarted NT8 8.1.4.1 (latest download)

        MyCustomPerformanceMetric is showing the same value as SampleCumProfit and top line Total net profit.

        I tried with Backtest and Optimization. Same results.



        Click image for larger version

Name:	Nt Support 2.png
Views:	44
Size:	41.2 KB
ID:	1333178

        Any other suggestions?

        Thanks for your help.

        Comment


          #5
          Hello TAJTrades,

          Thank you for your patience. I am looking into this on my end.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #6
            Hello TAJTrades,

            I'm finding the OnMergePerformanceMetric is only for merged results.

            As an example if you backtest over an instrument list (called a basket test) there will be a Combined results row. When selecting this row, the summary will show the 5 value you have hard coded.

            Click image for larger version  Name:	2025-02-05_07-27-49.png Views:	0 Size:	81.4 KB ID:	1333664
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              I can duplicate what you have shown in the image. The issue with OnMergePerformanceMetric makes sense.

              However, I am trying to get the $5.00 to calculate for each instrument in your example. When I do a Backtest on 1 Instrument the value shown is the same Total Net Profit.

              Can this be done?

              Is there something like this that does not require the "Merge" part: protected override void OnPerformanceMetric(PerformanceMetricBase target)



              I have searched high and low for some sample code and have come up empty.

              Thanks.



              Comment


                #8
                Hello TAJTrades,

                So instead of the merge results, you want to change the value in individual backtest results, correct?

                Set the Values[] collection to 5 in OnAddTrade().
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Not finding any joy here. Did a search on "onAddTrade" and did not find any working examples. Also tried adding in some code in "OnAddTrade" and nothing.

                  Maybe I am not making myself clear. All I am trying to do is create a Custom PerformanceMetric that acts just like the PerformanceMetric "R squared / Ulcer Index / Sortino ratio / Sharp ratio" above it when Backtesting, Optimizing or in Trade Performance.

                  The Metric I want to create is RoMaD (Return over Maximum Drawdown). The math is simply:

                  TradesPerformance.NetProfit / TradesPerformance.Currency.Drawdown.


                  Everything I have tried somehow defaults back to displaying Total net profit.

                  This image is for BackTest.
                  Click image for larger version

Name:	NT Support Backtest.png
Views:	28
Size:	74.9 KB
ID:	1333927


                  This is for Optimization on a single Instrument

                  Click image for larger version

Name:	NT Support Optimized.png
Views:	20
Size:	83.4 KB
ID:	1333928

                  Do you know of any sample code that will do this? Can we work together to create some Sample Code for other users?

                  Thanks

                  Comment


                    #10
                    Hello TAJTrades,

                    The SampleCumProfit included with NinjaTrader provides sample code.

                    On lines 38 through 42 of the sample, the metric value is assigned in OnAddTrade().
                    For Currency, the sample code is assigning the trade.ProfitCurrency on line 38. This is the value showing in the summary results.

                    In your code you posted in post #1, you have:
                    Values[(int)Cbi.PerformanceUnit.Currency] += trade.ProfitCurrency;

                    This is where you are setting the performance value to the net profit and it's in OnAddTrade(). Set this to 5 if you want it to have a value of 5. (Use '=' instead of '+=' to make the value 5 exactly and not accumulate 5 for each trade.


                    Your initial inquiry appeared to be asking about the merged results from total row and not the metric value for individual iterations. This is what would be calculated in OnMergePerformanceMetric().



                    Below is a link to an additional example custom metric script and performance metric script.

                    Chelsea B.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by rubiijonson, Today, 01:02 AM
                    0 responses
                    4 views
                    0 likes
                    Last Post rubiijonson  
                    Started by fkronloff, Today, 12:25 AM
                    0 responses
                    3 views
                    0 likes
                    Last Post fkronloff  
                    Started by Zadomani, Yesterday, 11:39 PM
                    0 responses
                    11 views
                    0 likes
                    Last Post Zadomani  
                    Started by ToNovy, 01-27-2025, 11:22 PM
                    20 responses
                    197 views
                    0 likes
                    Last Post ToNovy
                    by ToNovy
                     
                    Started by hypercube, 03-07-2025, 12:22 AM
                    2 responses
                    38 views
                    0 likes
                    Last Post hypercube  
                    Working...
                    X