0

I am trying to loop through array and for i. I need to MAX values of previous 10 values.

So if i= 20, I need to math.max i-10, i-9, i-8... and so forth. But I am struggling to get this to work.

static public void TA(DateTime[] datePrice, double[] openPrice, double[] highPrice, double[] lowPrice, double[] closePrice)
{
    #region declare variables
    int outBegIdx;
    int outNbElement;
    int SmaPeriod = 20;
    int TOTAL_PERIODS = closePrice.Length;
    double[] outputSma = new double[closePrice.Length];
    double[] outputStdDev = new double[closePrice.Length];
    int[] outputShootingStar = new int[closePrice.Length];
    int[] outputHangingMan = new int[closePrice.Length];
    int[] outputEngulf = new int[closePrice.Length];
    int[] outputMaxIndex = new int[closePrice.Length];
    double[] outputTrueRange = new double[closePrice.Length];
    double accProfit = 0;
    int position = 0;
    double openPosPrice = 0;
    double profit = 0;
    #endregion

    #region not sure what this code is for
    //for (int i = 0; i < closePrice.Length-TOTAL_PERIODS; i++) //had to change from -1 to -TOTAL_PERIODS
    //{
    //    openPrice[i] = (double)i;
    //    highPrice[i] = (double)i;
    //    lowPrice[i] = (double)i;
    //    closePrice[i] = (double)i;
    //}
    #endregion

    #region Technical Libary
    TicTacTec.TA.Library.Core.RetCode Sma = Core.Sma(0, closePrice.Length - 1, closePrice, SmaPeriod, out outBegIdx, out outNbElement, outputSma);
    TicTacTec.TA.Library.Core.RetCode StdDev = Core.StdDev(0, closePrice.Length - 1, closePrice, closePrice.Length, 1, out outBegIdx, out outNbElement, outputStdDev);
    TicTacTec.TA.Library.Core.RetCode ShootingStar = Core.CdlShootingStar(0, closePrice.Length - 1, openPrice, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputShootingStar);
    TicTacTec.TA.Library.Core.RetCode HangingMan = Core.CdlHangingMan(0, closePrice.Length - 1, openPrice, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputHangingMan);
    TicTacTec.TA.Library.Core.RetCode BullIngulf = Core.CdlEngulfing(0, closePrice.Length - 1, openPrice, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputEngulf);
    TicTacTec.TA.Library.Core.RetCode TrueRange = Core.TrueRange(0, closePrice.Length - 1, highPrice, lowPrice, closePrice, out outBegIdx, out outNbElement, outputTrueRange);
    //TicTacTec.TA.Library.Core.RetCode xx = Core.bu
    //TicTacTec.TA.Library.Core.RetCode MaxIndex = Core.MaxIndex(0, closePrice.Length - 1, highPrice, 20, out outBegIdx, out outNbElement, outputMaxIndex);
    #endregion

    for (int i = 20; i < closePrice.Length - 1; i++)
    {
        for (int j = 0; j < 10; j--)
        {

        }
    }
}
4
  • 1
    Post some code that you have written so far Commented Feb 20, 2015 at 9:24
  • 1
    Your existing codes would help us to understand your errors :) Commented Feb 20, 2015 at 9:24
  • So you need the n greatest values? or what? Commented Feb 20, 2015 at 9:25
  • you want maximum of ten previous elements? what should be the output for first element? Commented Feb 20, 2015 at 9:45

3 Answers 3

2

You can use the following code :

int[] arr = new int[200];                // Original list of lines
List<int> maxList = new List<int>();     // Result list to hold max values
int[] range = new int[10];               // Sub-list of lines to check max value
for (int i = 0; i < arr.Length - 9; i++)
{
    Array.Copy(arr, i, range, 0, 10);    // Get sub-set of lines
    maxList.Add(range.Max());            // Find max, add it to the result list
}
Sign up to request clarification or add additional context in comments.

6 Comments

I have tried to implement it @user3021830, it does not work as intended (therefore i will try to explain the requirement in greater detail). lets say i have 200 line of data. I start on line 20 and loop to 200. When starting at line 20, i need to look at the previous line and find the max value, which i need to store. Then i move to line 21, and here i find the max of the previous 10 lines... and so forth. So its more like a "moving 10 day max"
This code also does the same I guess. Starting from 10 and going back to last 10 elements also means starting from 1 and going forward to 10 elements. The logic is to create a subset, find the max of the subset, save it. then slide the subset index by +1 and do it again until all elements are scanned. Did I get it right?
Okay i guess. But actually i need to save 1 value for each line - even though its the same value. as i need to use it like this... if value[i] > max[i] .... so how would you do that?
for (int i = 20; i < closePrice.Length-1; i++) { Array.Copy(closePrice, i, range, 0, closePrice.Length-21); maxList.Add(range.Max());
i tried to do it like this. but i am getting "source array not long enough"
|
1

You can use extension method like this one:

public static IEnumerable<TResult> LeftSegAggregate<TItem, TResult>(
    this IEnumerable<TItem> items, 
    Func<IEnumerable<TItem>, TResult> aggregator, 
    int segmentLength)
{
    if (items == null)
        throw new ArgumentNullException("items");
    if (segmentLength <= 0)
        throw new ArgumentOutOfRangeException("segmentLength");

    int i = 0, c = 0;
    var segment = new TItem[segmentLength];
    foreach (var item in items)
    {
        c++;
        segment[i++ % segmentLength] = item;         
        yield return aggregator(segment.Take(c));
    }
}

This method create array for store current segment. For each item in target collection aggregator function applied to segment array and return next result (max of this segment for example).

  • No memory reallocation, no copying, just simple array that filled cyclically;
  • You can use collection of any type - just provide aggregation function;
  • You can get as many enumerators as you want and use them in your loop;

Example:

// Sample items (some complex objects for example).
var items = new[] { 1, -3, 6, 5, -2, 0, 3, 4, 8, 0, 4, 7, 2, 9, -3 }
    .Select(
        i => new {
            Name = string.Format("Item {0}", i), 
            Value = i                        
        }
    ).ToArray();

// Get enumerator of segment max for Value field.
var segMaxEnumerator = items.LeftSegAggregate(
    // Aggregation function (returns max value from segment of items).
    seg => seg.Select(i => i.Value).Max(),
    // Size of target segment.
    10  
).GetEnumerator();

// Here is your loop:
for (var i = 0; i < items.Length; i++)
{                
    // Move segment max enumerator to next item.
    segMaxEnumerator.MoveNext();

    // Use segMaxEnumerator.Current to take segment max.
    Console.WriteLine("{0}: {1}", i, segMaxEnumerator.Current);
}

Comments

0

here is another version in LINQ

var list = new List<int>();
var max = list.Select((x, i) => //get items (x as value, i as index
                  list.Skip(Math.Max(i - 10, 0)) //forget about previous items
                    .Take(Math.Min(10, i + 1)) // get 10(or less) elements before this element 
                    .Max()) // get maximum of them
              .ToList();//convert result to list

and a test would be like this

var l = new List<int>
{
    1, 4, 3, 8, 2, 11, 4, 3, 5, 19, 2, 8,
    11, 13, 14, 12, 12, 12, 12, 12
};
var max = l.Select((x, i) => l.Skip(Math.Max(i - 10, 0)).Take(Math.Min(10, i + 1)).Max()).ToList();
Console.WriteLine(string.Join(",", max));
//1,4,4,8,8,11,11,11,11,19,19,19,19,19,19,19,19,19,19,19,14,14,14

1 Comment

Thanks @dotctor this was what i was looking for. I got it to work as intended. Really appreciate the help. Thanks to everyone who tried to help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.