How to use indexOf when you have a var variable?

FranK Duc 121 Reputation points
2021-02-11T14:22:27.93+00:00

Hello,

I have a list:

List<double> listCan = new List<double>() {};

I narrowed the index scope of my list :

int Lorest = totalBarIndex - ChartBars.GetBarIdxByX(chartControl, cursorPointX);
var Lowcursor = listCan.Skip(ChartBars.GetBarIdxByX(chartControl, cursorPointX)).Take(Lorest);

Than i got the Min from that new part of the list:

double Min = Lowcursor.Min();

I want the index from the new part Lowcursor.

If i int indexOfNumber = listCan.IndexOf(Min); ill get the Min from the entire list.

But i cant do int indexOfNumber = Lowcursor.IndexOf(Min);

How I can i get the index of Min from Lowcursor?

TY

Developer technologies C#
0 comments No comments
{count} votes

Accepted answer
  1. Michael Taylor 60,161 Reputation points
    2021-02-11T15:02:32.667+00:00

    The question title is misleading here. This has nothing to do with var. Your question, if I understand correctly, is that you want to get the minimum value in Lowcursor which is an IEnumerable<double>. But you also want the index of that value. Not really sure why you need the index but unfortunately Min won't work here. Personally I think the easiest approach is to revert back to a good old looping construct.

    public static class EnumerableExtensions
    {
        public static int MinIndex<T> ( this IEnumerable<T> source ) where T: IComparable
        {            
            var minimumIndex = -1;
            var minimumValue = default(T);
    
            //IEnumerable<T> doesn't support array indexing and calling ToList or ToArray may be too expensive
            var index = 0;
            foreach (var value in source)
            {
                //If we haven't set a minimum yet OR the current value is less than our previous minimum
                if (minimumIndex == -1 || value.CompareTo(minimumValue) < 0)
                {
                    minimumIndex = index;
                    minimumValue = value;
                };
    
                //Next
                ++index;
            };
    
            return minimumIndex;
        }
    }
    

    Made this into an extension method so you can reuse it.

    int minimumIndex = Lowcursor.MinIndex();
    double minimumValue = Lowcursor.ElementAt(minimumIndex);
    

    Of course if you can ensure that the values in the collection are unique or you don't really care which index you return if there are dups then you can use Min to find the minimum value and then iterate again to get the index but that is inefficient in many cases.


2 additional answers

Sort by: Most helpful
  1. FranK Duc 121 Reputation points
    2021-02-11T16:16:35.597+00:00

    Here's and example of Ninjacode structure:

    My script fit in OnRender class, i tried to input your code above in the between :

    //This namespace holds Indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
    // Your code here is crashing
    public class MyCustomIndicator6 : Indicator
    {

    Here's an example how it looks. Its a test code i use.

    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;

    endregion

    //This namespace holds Indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
    public class MyCustomIndicator6 : Indicator
    {

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Description                                 = @"Enter the description for your new custom Indicator here.";
                Name                                        = "MyCustomIndicator6";
                Calculate                                   = Calculate.OnBarClose;
                IsOverlay                                   = true;
                DisplayInDataBox                            = true;
                DrawOnPricePanel                            = true;
                DrawHorizontalGridLines                     = true;
                DrawVerticalGridLines                       = true;
                PaintPriceMarkers                           = true;
                ScaleJustification                          = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                //Disable this property if your indicator requires custom values that cumulate with each new market data event. 
                //See Help Guide for additional information.
                IsSuspendedWhileInactive                    = true;
    
            }
            else if (State == State.Configure)
            {
            }
        }
    
        protected override void OnBarUpdate()
        {
    

    }

        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
    
    
        }
    }
    

    }

    region NinjaScript generated code. Neither change nor remove.

    namespace NinjaTrader.NinjaScript.Indicators
    {
    public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
    {
    private MyCustomIndicator6[] cacheMyCustomIndicator6;
    public MyCustomIndicator6 MyCustomIndicator6()
    {
    return MyCustomIndicator6(Input);
    }

        public MyCustomIndicator6 MyCustomIndicator6(ISeries<double> input)
        {
            if (cacheMyCustomIndicator6 != null)
                for (int idx = 0; idx < cacheMyCustomIndicator6.Length; idx++)
                    if (cacheMyCustomIndicator6[idx] != null &&  cacheMyCustomIndicator6[idx].EqualsInput(input))
                        return cacheMyCustomIndicator6[idx];
            return CacheIndicator<MyCustomIndicator6>(new MyCustomIndicator6(), input, ref cacheMyCustomIndicator6);
        }
    }
    

    }

    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
    {
    public Indicators.MyCustomIndicator6 MyCustomIndicator6()
    {
    return indicator.MyCustomIndicator6(Input);
    }

        public Indicators.MyCustomIndicator6 MyCustomIndicator6(ISeries<double> input )
        {
            return indicator.MyCustomIndicator6(input);
        }
    }
    

    }

    namespace NinjaTrader.NinjaScript.Strategies
    {
    public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
    {
    public Indicators.MyCustomIndicator6 MyCustomIndicator6()
    {
    return indicator.MyCustomIndicator6(Input);
    }

        public Indicators.MyCustomIndicator6 MyCustomIndicator6(ISeries<double> input )
        {
            return indicator.MyCustomIndicator6(input);
        }
    }
    

    }

    endregion


  2. FranK Duc 121 Reputation points
    2021-02-11T17:55:03.817+00:00

    Not the highest index, still want the index of lowest price.

    Its a chart it goes from index 0 (left side of the chart) to number of bars in the chart (right side) or ChartBars.FromIndex to ChartBars.ToIndex.

    I need to convert the number of bars in listCan to number of bars in Lowcursor.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.