Question

I would like to achieve same results from code sample below by using syntax LINQ query to object. Please, help me guys.

public static List<OHLC> OHLC(List<FileRaw> fileRawsList, TimeSpan timeSpan, DateTime beginDate, DateTime endOfLoopDate)
    {

        List<OHLC> ohlcList = new List<OHLC>();

        for (DateTime i = beginDate; i < endOfLoopDate; )
        {
            DateTime iLow = i;
            DateTime iMax = i.Add(timeSpan);
            OHLC ohlcRaw = new OHLC()
                {
                    Open = fileRawsList.Where(p => p.Time >= iLow).Where(p => p.Time <= iMax).Select(p => p.Bid).DefaultIfEmpty().First(),
                    High = fileRawsList.Where(p => p.Time >= iLow).Where(p => p.Time <= iMax).Select(p => p.Bid).DefaultIfEmpty().Max(),
                    Low = fileRawsList.Where(p => p.Time >= iLow).Where(p => p.Time <= iMax).Select(p => p.Bid).DefaultIfEmpty().Min(),
                    Close = fileRawsList.Where(p => p.Time >= iLow).Where(p => p.Time <= iMax).Select(p => p.Bid).DefaultIfEmpty().Last(),
                    Time = fileRawsList.Where(p => p.Time >= iLow).Where(p => p.Time <= iMax).Select(p => p.Time).DefaultIfEmpty(iLow).First()
                };

            i = i.Add(timeSpan);
            ohlcList.Add(ohlcRaw);
        }
        return ohlcList;
    }

it produce

Open: 1.229570, High: 1.233580, Low: 1.221730, Close: 1.224630, Date: 01/08/2012 00:00:02
Open: 1.224620, High: 1.240460, Low: 1.213320, Close: 1.217490, Date: 02/08/2012 00:00:03
Open: 1.217530, High: 1.239160, Low: 1.217230, Close: 1.238650, Date: 03/08/2012 00:00:02
Open: 0,        High: 0,        Low: 0,        Close: 0,        Date: 04/08/2012 00:00:02
Open: 1.239720, High: 1.239830, Low: 1.239180, Close: 1.239460, Date: 05/08/2012 17:00:03
Was it helpful?

Solution

This should give the raw groups:

 return fileRawList.Where(file => file.Time >= beginDate)
                    .Where(file => file.Time < endofLoopDate)
                    .OrderBy(file => file.Time)
                    .GroupBy(file => file.Time.Ticks / timeSpan.Ticks,
                             (k, g) => new OHLC()
                                  {
                                    Open = g.Select(p => p.Bid).DefaultIfEmpty().First(),
                                    High = g.Select(p => p.Bid).DefaultIfEmpty().Max(),
                                    Low = g.Select(p => p.Bid).DefaultIfEmpty().Min(),
                                    Close = g.Select(p => p.Bid).DefaultIfEmpty().Last(),
                                    Time = g.Select(p => p.Time).DefaultIfEmpty().First()
                                          })
                     .ToList();

While this should give a regular stream of OHLC:

var rawGroups = fileRawList.Where(file => file.Time >= beginDate)
                    .Where(file => file.Time < endofLoopDate)
                    .OrderBy(file => file.Time)
                    .ToLookup(file => (file.Time.Ticks - beginDate.Ticks) / timeSpan.Ticks,
                              file => new {Bid = file.Bid, Time = file.Time})
                    .ToDictionary( g => g.Key, g => new OHLC()
                                  {
                                    Open = g.Select(p => p.Bid).DefaultIfEmpty(0).First(),
                                    High = g.Select(p => p.Bid).DefaultIfEmpty(0).Max(),
                                    Low = g.Select(p => p.Bid).DefaultIfEmpty(0).Min(),
                                    Close = g.Select(p => p.Bid).DefaultIfEmpty(0).Last(),
                                    Time = g.Select(p => p.Time).First()
                                          });

return Enumerable.Range(0,(Int32)((endofLoopDate.Ticks - beginDate.Ticks)/timeSpan.Ticks))
                 .Select(i => rawGroups.Keys.Contains(i) ? 
                              rawGroups[i] :
                              new OHLC()
                              {
                               Open = 0,
                               High = 0,
                               Low = 0,
                               Close = 0,
                               Time = new DateTime(beginDate.Ticks + k*timeSpan.Ticks)
                              }).ToList();

Alternative:

var result = Enumerable.Range(0,(Int32)((endofLoopDate.Ticks - beginDate.Ticks)/timeSpan.Ticks))
                       .GroupJoin(fileRawList.Where(file => file.Time >= beginDate)
                                             .Where(file => file.Time < endofLoopDate)
                                             .OrderBy(file => file.Time),
                                  i => i,
                                  file => (file.Time.Ticks - beginDate.Ticks) / timeSpan.Ticks,
                                  (k,g) => new OHLC()
                                      {
                                       Open = g.Select(p => p.Bid).DefaultIfEmpty(0).First(),
                                       High = g.Select(p => p.Bid).DefaultIfEmpty(0).Max(),
                                       Low = g.Select(p => p.Bid).DefaultIfEmpty(0).Min(),
                                       Close = g.Select(p => p.Bid).DefaultIfEmpty(0).Last(),
                                       Time = g.Any() ? 
                                         g.Select(p => p.Time).First() :
                                         new DateTime(beginDate.Ticks + i*timeSpan.Ticks)
                                      })
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top