У меня есть набор из около 2000 отдельных временных рядов в виде SortedList<DateTime,double>
. Каждая серия соответствует ежедневной ликвидности для данной ценной бумаги. Я хотел бы создать ежедневный рейтинг этих значений. Если бы я делал это для циклов for, я бы сделал следующее:
- Создайте новый пустой временной ряд [date, (int) rank] для каждой ценной бумаги, чтобы удерживать ее рейтинг в данный день. Это может быть в форме
SortedList<DateTime,double>
.
- Создан список всех уникальных дат (не каждый временной ряд ценных бумаг имеет значение для каждой даты.)
- Для каждой уникальной даты проведите цикл по каждому временному ряду ежедневной ликвидности ценных бумаг, чтобы определить, имеет ли оно значение на эту дату.
- Если это так, добавьте имя и значение ценной бумаги в массив ежедневного рейтинга [SecName, значение ликвидности].
- Сортировка массива от наибольшего к наименьшему (ранг 1 = наибольшее значение).
- Для каждой ценной бумаги (secName) в массиве добавьте дату и рейтинг ценных бумаг к его временному ряду (созданному на шаге 1).
Проще говоря, это ежедневный рейтинг ликвидности от самой большой до самой маленькой. Я могу заставить linq извлекать данные из объектов и групп по дате, но остальное выходит за рамки моих навыков в linq.
Любые мастера linq хотят дать этому шанс?
Упрощенная версия структуры объекта изложена ниже.
Примечание. Я специально создал одну дату (2011,01,18), в которой значения (30) совпадают. В этом случае субрейнинг по имени символа является приемлемым. Таким образом, они будут ранжированы ... 1-й 6753 JT, 2-й 6754 JT. 6752 JT не имеет значения на эту дату, поэтому оно не будет включено.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ranking_Query
{
class Program
{
static void Main(string[] args)
{
// created an instance of the datasource and add 3 securities to it
Datasource ds = new Datasource() { Name = "test" };
ds.securities.Add("6752 JT", new Security() {
timeSeries = new Dictionary<string, SortedList<DateTime, double>>() {
{ "liquidity", new SortedList<DateTime, double>() {
{new DateTime(2011,01,15),30},
{new DateTime(2011,01,16),20},
{new DateTime(2011,01,17),10} } } }
});
ds.securities.Add("6753 JT", new Security()
{
timeSeries = new Dictionary<string, SortedList<DateTime, double>>() {
{ "liquidity", new SortedList<DateTime, double>() {
{new DateTime(2011,01,15),20},
{new DateTime(2011,01,16),30},
{new DateTime(2011,01,17),20},
{new DateTime(2011,01,18),30} } } }
});
ds.securities.Add("6754 JT", new Security()
{
timeSeries = new Dictionary<string, SortedList<DateTime, double>>() {
{ "liquidity", new SortedList<DateTime, double>() {
{new DateTime(2011,01,16),10},
{new DateTime(2011,01,17),30},
{new DateTime(2011,01,18),30} } } }
});
}
class Datasource
{
public string Name { get; set; }
public Dictionary<string, Security> securities = new Dictionary<string, Security>();
}
class Security
{
public string symbol { get; set; }
public Dictionary<string, SortedList<DateTime, double>> timeSeries;
}
}
}
Вывод с использованием цикла foreach, подобного следующему ...
foreach (var sec in rankingsBySymbol)
{
Console.WriteLine(sec.Key);
foreach (var secRank in sec)
{
Console.WriteLine(" {0} value {1} rank {2}",secRank.Date, secRank.Value, secRank.Rank);
}
}
Должно быть следующим ...
6752 JT
1/15/2011 12:00:00 AM value 30 rank 1
1/16/2011 12:00:00 AM value 20 rank 2
1/17/2011 12:00:00 AM value 10 rank 3
6753 JT
1/15/2011 12:00:00 AM value 20 rank 2
1/16/2011 12:00:00 AM value 30 rank 1
1/17/2011 12:00:00 AM value 20 rank 2
1/18/2011 12:00:00 AM value 30 rank 1
6754 JT
1/16/2011 12:00:00 AM value 10 rank 3
1/17/2011 12:00:00 AM value 30 rank 1
1/18/2011 12:00:00 AM value 30 rank 2
Примечание. В окончательном выводе необязательно указывать начальное значение, используемое для расчета рейтинга, а только дату и рейтинг. Я включил его, потому что это облегчает понимание первоначального вопроса.