0

I am working in Ninjatrader script to find within a bar where a certain price resides. So far I have a value "price" that is one of the values in a list. So within the bar there are x number of prices from Low to High I use a for loop to find those values. I need the list to be sorted High to Low. The count will vary from bar to bar. So say I have 16 values in the list. I need to determine the top 3rd, middle 3rd and bottom third of those values then once determined to compare the certain "price" as to which third it resides. the count will vary and wont be cleanly divisible by 3.

for ( double myPrice = Low[0]; myPrice = High[0]; myPrice += Ticksize)
{
    myList.Add(myPrice);
}

From here I need to figure out how to divide list into thirds, then check if ABC_Price is in the top, middle or bottom third of the list, with list sorted High to Low.

Daevin
  • 778
  • 3
  • 14
  • 31
atljam
  • 1
  • 2
  • What you need is a [Percentile calculation](https://stackoverflow.com/q/8137391/880990). The algorithm shown by @Marco interpolates the values when the range is not divisible by a whole number. – Olivier Jacot-Descombes Aug 31 '22 at 13:47
  • What have you tried so far? StackOverflow is supposed to be a help forum, not somewhere to get code written for you. Also, I have no idea what Ninjatrader script is, but a quick Google says it's C# based. If it abides by C# syntax, your loop shouldn't be working; `myPrice = High[0]` is not boolean, and if you corrected the `=` to `==` to make it boolean then the loop would only run when `myPrice` and `High[0]` are equal in value (which likely is not the case since `myPrice` is changing in every iteration of the loop). – Daevin Aug 31 '22 at 13:49
  • @Daevin sorry but you are not understanding that is a working loop, I'm not looking for code to be written just an idea to help me, Oliver thanks I will look into that idea. – atljam Aug 31 '22 at 13:56
  • @atljam apologies about the syntax then, as I said I'm not familiar with Ninjatrader script. However, StackOverflow is also not an ideas forum, so be careful with those kinds of questions too. That being said, if you want to segment by count, do you care which segments will be larger in the event of a size not divisible by 3? You can do `var segmentSize = Math.Ceiling((decimal)myList.Count / 3);` then `var bottomMaxIndex = segmentSize - 1;` and `var topMinIndex = myList.Count - segment size;` to get the upper/lower index bounds for the bottom/top segments. This shorts the middle section though – Daevin Aug 31 '22 at 14:50

2 Answers2

0

To know which price limits are delimiting the thirds of your list, you can calculate the 1/3 and 2/3 percentiles of the price list.

We can calculate the percentiles like this with the percentile given in the range 0 to 1:

public static double Percentile(IList<double> sortedValues, double percentile)
{
    double realIndex = percentile * (sortedValues.Count - 1);
    int index = (int)realIndex;
    if (index < sortedValues.Count - 1) {
        double fraction = realIndex - index;
        return sortedValues[index] * (1 - fraction) + sortedValues[index + 1] * fraction;
    } else {
        return sortedValues[sortedValues.Count - 1];
    }
}

Example: Percentile(prices, 1.0 / 3.0) yields the price that lies at 1/3 of the price list sorted in ascending order.

This test

double[] prices = { 6.0, 10.0, 10.0, 10.0, 25.0, 30.0, 40.0, 45.0, 50.0, 55.0, 60.0, 100.0, 115.0, 250.0 };
double lowerPriceLimit = Percentile(prices, 1.0 / 3.0);
double upperPriceLimit = Percentile(prices, 2.0 / 3.0);
Console.WriteLine($"Price limits = {lowerPriceLimit:n3}, {upperPriceLimit:n3}");

Prints

Price limits = 26.667, 53.333

The values are fractions, because 1/3 and 2/3 of the list lie between real list positions. This means that the algorithm works well with any list size.

With these calculated lowerPriceLimit and upperPriceLimit you can determine in which 3rd a price resides with

if (price <= lowerPriceLimit) {
    // bottom third
} else if (price <= upperPriceLimit) {
    // middle third
} else {
    // top third
}

Whether you use <= or < in the comparisons depends on your decision in which category a price has to belong when it is equal to one of the limits.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • I think I have solved it, I will post soon. My issue now is probably a Ninjatrader script issue where the count starts up into the current bar that is not completed and botches the script loop because it has a negative value for the count . But I will also review the Answer that was posted it might help. – atljam Aug 31 '22 at 17:41
0

Thanks for the suggestions unfortunately they were not what I was looking for. I had multiple issues to resolve:

  1. loop to find all prices within a bar. I used a for loop and added them to a List.

  2. Sort the list . MyList.Sort();

  3. Determine the count of the list, myCount =divide by 3. used (decimal) Math.Round

  4. Divide the List into 3 sections: used 3 for loops that cycled through the List based on myCount

    for ( double aDouble = myList[myCount - myCount]; aDouble =  
        myList[TotalCount - (myCount*2))-2); aDouble += TickSize)
        {
            Bottom_List.Add(aDouble);
        }
    
  5. Create a bool for each section:

    if (Bottom_List.Contains(myPrice)) BotPrice = true; else BotPrice= 
        false;
    
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
atljam
  • 1
  • 2