I have some strategies that use a TemplateName in the templates so us users can verify we’ve pulled up the correct template. I’d like to have a performance metric display the field from the template in a few spots in the strategy analyzer. comparing results from various templates is a pain when we can’t distinguish them. Can a string be pulled from the strategy and be displayed in the columns? I can get one to compile, and the field shows up in the summary, but nowhere else, and theres no data where the field shows up.
I am not a coder but I asked GitHub Copilot for you - for this you will need to edit your strategies in the Editor or Visual Studio:
You can display a custom string (such as TemplateName) in the Strategy Analyzer’s performance columns, but there are some NinjaTrader limitations and requirements:
Step-by-step Solution
- Add a Public Property for TemplateName
Make sure your strategy has a public property for the template name: e.g. in MyCustomStrategy.cs add this:
[NinjaScriptProperty]
[Display(Name = “Template Name”, Description = “Name of the strategy template”, Order = 99, >GroupName = “Template”)]
public string TemplateName { get; set; } = “DefaultTemplate”;
- Set the Property in the Strategy Wizard or Code
Set TemplateName in the strategy parameters (either in the UI or programmatically):
(Copilot says here: Active Document - which would be the Strategy, not sure if that is correct though)
TemplateName = “MyCustomTemplate”;
-
Expose the Property for Analyzer Columns
To show TemplateName in custom columns, you need to create a custom MarketAnalyzerColumn or use NinjaTrader’s built-in summary reporting. However, NinjaTrader’s Strategy Analyzer only displays built-in metrics in the main grid. Custom properties typically only show in the summary or parameter list.
To show in a column:
• Create a custom Market Analyzer column that references your strategy’s property.
• Or, use the DisplayName property for the strategy, which will show in the Analyzer’s summary. -
Example: Custom MarketAnalyzerColumn
Create a new file for your column: e.g. TemplateNameColumn.cs
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.MarketAnalyzerColumns;namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public class TemplateNameColumn : MarketAnalyzerColumn
{
protected override void OnBarUpdate()
{
if (Strategy != null && Strategy is Strategies.PatternTrading pt)
{
Value[0] = pt.TemplateName;
}
else
{
Value[0] = “N/A”;
}
}
}
}
Add this column to your Market Analyzer, and it will display the template name for each strategy instance.
-
Limitations
• Strategy Analyzer grid: Only shows built-in metrics and parameters. Custom string properties are not shown in the main results grid, only in the summary or parameter list.
• Market Analyzer: Custom columns can display any property, including strings, for live strategies. -
Workaround for Strategy Analyzer
If you want to distinguish templates in the Strategy Analyzer grid, set the strategy’s Name or Description property dynamically: again in the Active Document which should be the Strategy
Name = $“PatternTrading [{TemplateName}]”;
Description = $“Template: {TemplateName}”;
This will show up in the summary and parameter list, making it easier to compare runs.
Summary:
• Use a public property for TemplateName.
• Set it in the strategy parameters.
• For grid display, use custom Market Analyzer columns.
• For Strategy Analyzer, set Name/Description to include the template name.
It’s not the best solution but I used the Print command to Print in the Ninja Outliner.
Or you can print directly in the chart with string.
E.g. like this, it sits in my case at the last spot in the public class MyStrategy : Strategy
#region Collecting Data on Trade Results protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity, Cbi.MarketPosition marketPosition, string orderId, DateTime time) { string weekday = time.ToString("dddd"); // e.g., "Monday" Print($"Trade executed on: {weekday}"); // Only act when a trade is closed if (SystemPerformance.AllTrades.Count > 0)
{
NinjaTrader.Cbi.Trade lastTrade = SystemPerformance.AllTrades[SystemPerformance.AllTrades.Count - 1];
string signalName = lastTrade.Entry.Name;
double profit = lastTrade.ProfitCurrency;if (signalName.Contains("PatternLong_Asia") && profit > 0) asiaLongProfits++; else if (signalName.Contains("PatternShort_Asia") && profit > 0) asiaShortProfits++; else if (signalName.Contains("PatternLong_Europe") && profit > 0) europeLongProfits++; else if (signalName.Contains("PatternShort_Europe") && profit > 0) europeShortProfits++; else if (signalName.Contains("PatternLong_US") && profit > 0) usLongProfits++; else if (signalName.Contains("PatternShort_US") && profit > 0) usShortProfits++; else if (signalName.Contains("PatternLong_Other") && profit > 0) otherLongProfits++; else if (signalName.Contains("PatternShort_Other") && profit > 0) otherShortProfits++; } } #endregion
and to actually print it on the chart I used this sitting at the end of protected override void OnBarUpdate()
string stats =
$“Asia: Longs={asiaLongTrades} (Profit={asiaLongProfits}), Shorts={asiaShortTrades} (Profit={asiaShortProfits})\n” +
$“Europe: Longs={europeLongTrades} (Profit={europeLongProfits}), Shorts={europeShortTrades} (Profit={europeShortProfits})\n” +
$“US: Longs={usLongTrades} (Profit={usLongProfits}), Shorts={usShortTrades} (Profit={usShortProfits})\n” +
$“Other: Longs={otherLongTrades} (Profit={otherLongProfits}), Shorts={otherShortTrades} (Profit={otherShortProfits})”;//Draw.Text(this, “SessionTradeStats”, stats, 0, High[0] + (TickSize * 10), Brushes.White);
Draw.TextFixed(this, “SessionTradeStats”, stats, TextPosition.BottomLeft, Brushes.CornflowerBlue, new SimpleFont(“Arial”, 15),
Brushes.Transparent, Brushes.Transparent, 0);
hope this helps
Thats great information, now I have more reference points and terminology.
Thank you
Perfect, that gives me information to ask the right questions.
Thanks