C# 如何通过LINQ将一个列表转换为另一个半聚合列表?
我是一个Linq初学者,所以只是想找人让我知道以下内容是否可以用Linq实现,如果可以的话,还有一些如何实现的建议 我想将一个金融时间序列列表转换为另一个金融时间序列列表,其中第二个序列列表的长度与第一个列表的长度相同或更短(通常更短,即,它成为一个新列表,其中元素本身表示来自第一个列表的一个或多个元素的信息的聚合)。它如何将列表从一个折叠到另一个取决于第一个列表中的数据。算法需要跟踪在第二个列表中添加新元素后重置的计算。通过一个例子来描述可能更容易: 清单1(从开始到结束的收盘价和成交量序列的时间顺序): {p=7,V=1},{p=10,V=2},{p=10,V=1},{p=10,V=3},{p=11,V=5},{p=12,V=1},{p=13,V=2},{p=17,V=1},{p=15,V=4},{p=14,V=10},{p=14,V=8},{p=10,V=2},{p=9,V=8},V=1,{ 列表2(使用这2个参数设置将列表1转换为列表2:参数1:价格范围步长=3,参数2:价格范围反转步长=6的一系列开盘/收盘价格范围和该范围内的交易量总和): {O=7,C=10,V=1+2+1},{O=10,C=13,V=3+5+1+2},{O=13,C=16,V=0},{O=16,C=10,V=1+4+10+8+2},{O=10,C=8,V=3+1} 在列表2中,我显式地显示了列表2中列表1中V属性的总和。但V只是一个长的数字,所以它实际上只是一个数字。所以这是如何运作的,开盘时间序列价格是7。然后,我们从初始起始价格中寻找第一个价格,其中增量为3,远离7(通过参数1设置)。在列表1中,当我们在列表中移动时,下一步是向上移动到10,因此我们建立了一个“上升趋势”。现在,我们用Open=7,Close=10构建列表2中的第一个元素,并将第一个列表中使用的所有条的数量相加,以完成列表2中的第一步。现在,下一个元素的起点是10。若要建立另一个向上阶梯,我们需要向上推进另一个3来创建另一个向上阶梯,或者我们可以反转并向下移动6(参数2)。使用列表1中的数据,我们首先到达13,这样就构建了列表2中的第二个元素,并汇总了用于执行此步骤的所有V属性。我们将继续此过程,直到列表1处理结束 注意列表1中发生的间隙跳跃。我们仍然希望创建一个step元素{O=13,C=16,V=0}。0的V只是表示我们有一个范围移动,经过这一步,但数量为0(这里没有出现列表1中的实际价格-它在它上面,但我们想建立一组步骤,导致价格高于它) 列表2中倒数第二个条目表示从上到下的反转 列表2中的最后一个条目只使用列表1中的最后一个结束,即使它还没有完成建立完整范围的步骤C# 如何通过LINQ将一个列表转换为另一个半聚合列表?,c#,.net,linq,dynamic,aggregate,C#,.net,Linq,Dynamic,Aggregate,我是一个Linq初学者,所以只是想找人让我知道以下内容是否可以用Linq实现,如果可以的话,还有一些如何实现的建议 我想将一个金融时间序列列表转换为另一个金融时间序列列表,其中第二个序列列表的长度与第一个列表的长度相同或更短(通常更短,即,它成为一个新列表,其中元素本身表示来自第一个列表的一个或多个元素的信息的聚合)。它如何将列表从一个折叠到另一个取决于第一个列表中的数据。算法需要跟踪在第二个列表中添加新元素后重置的计算。通过一个例子来描述可能更容易: 清单1(从开始到结束的收盘价和成交量序列的
感谢您提供关于如何通过Linq实现这一点的建议。我的第一个想法是,为什么要尝试在这方面使用Linq?使用
yield
关键字对新的可枚举
进行部分处理,然后给出答案,这似乎是一个更好的情况
大致如下:
public struct PricePoint
{
ulong price;
ulong volume;
}
public struct RangePoint
{
ulong open;
ulong close;
ulong volume;
}
public static IEnumerable<RangePoint> calculateRanges(IEnumerable<PricePoint> pricePoints)
{
if (pricePoints.Count() > 0)
{
ulong open = pricePoints.First().price;
ulong volume = pricePoints.First().volume;
foreach(PricePoint pricePoint in pricePoints.Skip(1))
{
volume += pricePoint.volume;
if (pricePoint.price > open)
{
if ((pricePoint.price - open) >= STEP)
{
// We have established a up-trend.
RangePoint rangePoint;
rangePoint.open = open;
rangePoint.close = close;
rangePoint.volume = volume;
open = pricePoint.price;
volume = 0;
yield return rangePoint;
}
}
else
{
if ((open - pricePoint.price) >= REVERSAL_STEP)
{
// We have established a reversal.
RangePoint rangePoint;
rangePoint.open = open;
rangePoint.close = pricePoint.price;
rangePoint.volume = volume;
open = pricePoint.price;
volume = 0;
yield return rangePoint;
}
}
}
RangePoint lastPoint;
lastPoint.open = open;
lastPoint.close = pricePoints.Last().price;
lastPoint.volume = volume;
yield return lastPoint;
}
}
公共结构价格点
{
乌龙价格;
乌龙体积;
}
公共结构范围点
{
乌龙公开赛;
乌龙关;
乌龙体积;
}
公共静态IEnumerable计算器(IEnumerable价格点)
{
如果(pricePoints.Count()>0)
{
ulong open=pricePoints.First().price;
ulong volume=pricePoints.First().volume;
foreach(PricePoint中的PricePoint PricePoint.Skip(1))
{
卷+=pricePoint.volume;
如果(pricePoint.price>open)
{
如果((pricePoint.price-打开)>=步骤)
{
//我们已经确立了上升趋势。
测距点测距点;
rangePoint.open=打开;
rangePoint.close=关闭;
rangePoint.volume=体积;
open=pricePoint.price;
体积=0;
收益率区间点;
}
}
其他的
{
如果((打开-pricePoint.price)>=反转步骤)
{
//我们已经确定了一个逆转。
测距点测距点;
rangePoint.open=打开;
rangePoint.close=pricePoint.price;
rangePoint.volume=体积;
open=pricePoint.price;
体积=0;
收益率区间点;
}
}
}
射程点;
lastPoint.open=打开;
lastPoint.close=pricePoints.Last().price;
lastPoint.volume=体积;
收益率回归点;
}
}
这还没有完成。例如,它不处理间隙,并且存在未处理的边缘情况,其中最后一个数据点可能被消耗,但它仍将处理“最后一个点”。但这应该足够开始了。我的第一个想法是,为什么要尝试在这方面使用LINQ?使用
yield
关键字对新的可枚举
进行部分处理,然后给出答案,这似乎是一个更好的情况
大致如下:
public struct PricePoint
{
ulong price;
ulong volume;
}
public struct RangePoint
{
ulong open;
ulong close;
ulong volume;
}
public static IEnumerable<RangePoint> calculateRanges(IEnumerable<PricePoint> pricePoints)
{
if (pricePoints.Count() > 0)
{
ulong open = pricePoints.First().price;
ulong volume = pricePoints.First().volume;
foreach(PricePoint pricePoint in pricePoints.Skip(1))
{
volume += pricePoint.volume;
if (pricePoint.price > open)
{
if ((pricePoint.price - open) >= STEP)
{
// We have established a up-trend.
RangePoint rangePoint;
rangePoint.open = open;
rangePoint.close = close;
rangePoint.volume = volume;
open = pricePoint.price;
volume = 0;
yield return rangePoint;
}
}
else
{
if ((open - pricePoint.price) >= REVERSAL_STEP)
{
// We have established a reversal.
RangePoint rangePoint;
rangePoint.open = open;
rangePoint.close = pricePoint.price;
rangePoint.volume = volume;
open = pricePoint.price;
volume = 0;
yield return rangePoint;
}
}
}
RangePoint lastPoint;
lastPoint.open = open;
lastPoint.close = pricePoints.Last().price;
lastPoint.volume = volume;
yield return lastPoint;
}
}
公共结构价格点
{
乌龙价格;
乌龙体积;
}
公共结构范围点
{
乌龙公开赛;
乌龙关;
乌龙体积;
}
公共静态IEnumerable计算器(IEnumerable价格点)
{
如果(pricePoints.Count()>0)
{
ulong open=pricePoints.First().price;
ulong volume=pricePoints.First().volume;
foreach(PricePoint中的PricePoint PricePoint.Skip(1))
{
卷+=pricePoint.volume;
如果(p