#region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.SuperDom; using NinjaTrader.Gui.Tools; using NinjaTrader.Data; using NinjaTrader.NinjaScript; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.DrawingTools; using NinjaTrader.CQG.ProtoBuf; #endregion //This namespace holds Indicators in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Indicators { [CategoryOrder("Plots", 1)] public class TRIN : Indicator { // Top 15 stocks by index weighting. private static readonly string[] Tickers = { "AAPL", "AMZN", "GOOG", "GOOGL", "META", "MSFT", "NVDA", "TSLA", "BRK_B", "UNH", "LLY", "XOM", "JPM", "V", "JNJ" }; private const int PrimaryBars = 0; private class OpenCloseVolume { public double Open { get; set; } public double Close { get; set; } public double Volume { get; set; } } private Dictionary OpenCloseVolumes; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"TRading INdex"; Name = "TRIN"; Calculate = Calculate.OnPriceChange; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = false; AddPlot(new Stroke(Brushes.Yellow, 2), PlotStyle.Line, "TRIN"); } else if (State == State.Configure) { OpenCloseVolumes = new Dictionary(); foreach (string ticker in Tickers) { AddDataSeries(ticker); } } } protected override void OnBarUpdate() { string currentTicker = Instrument.FullName; if (Tickers.Contains(currentTicker)) { if (!OpenCloseVolumes.ContainsKey(currentTicker)) OpenCloseVolumes[currentTicker] = new OpenCloseVolume(); OpenCloseVolumes[currentTicker].Open = Opens[BarsInProgress][0]; OpenCloseVolumes[currentTicker].Close = Closes[BarsInProgress][0]; OpenCloseVolumes[currentTicker].Volume = Volumes[BarsInProgress][0]; return; } if (PrimaryBars == BarsInProgress) { int advancingTickers = 0; int decliningTickers = 0; double advancingVolume = 0.0; double decliningVolume = 0.0; foreach (var ocv in OpenCloseVolumes) { if (ocv.Value.Close > ocv.Value.Open) { advancingTickers++; advancingVolume += ocv.Value.Volume; } else if (ocv.Value.Close < ocv.Value.Open) { decliningTickers++; decliningVolume += ocv.Value.Volume; } } // TODO: Handle case where advancing tickers / volume is 0. if (decliningTickers == 0 || decliningVolume == 0) Value[0] = 0; else Value[0] = ((double)advancingTickers / (double)decliningTickers) / (advancingVolume / decliningVolume); } } public override string DisplayName { get { return Name; } } } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private TRIN[] cacheTRIN; public TRIN TRIN() { return TRIN(Input); } public TRIN TRIN(ISeries input) { if (cacheTRIN != null) for (int idx = 0; idx < cacheTRIN.Length; idx++) if (cacheTRIN[idx] != null && cacheTRIN[idx].EqualsInput(input)) return cacheTRIN[idx]; return CacheIndicator(new TRIN(), input, ref cacheTRIN); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.TRIN TRIN() { return indicator.TRIN(Input); } public Indicators.TRIN TRIN(ISeries input ) { return indicator.TRIN(input); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.TRIN TRIN() { return indicator.TRIN(Input); } public Indicators.TRIN TRIN(ISeries input ) { return indicator.TRIN(input); } } } #endregion