我是Linq的初学者,所以只是想找人告诉我是否可以通过Linq实现以下操作,如果有的话,可以指出如何实现。
我想将一个金融时间序列列表转换为另一个金融时间序列列表,其中第二个系列列表将与第一个列表相同或更短(通常它会更短,即,它变成一个新列表,其中元素本身代表聚合来自第1列表的一个或多个元素的信息)。它如何将列表从一个折叠到另一个取决于第一个列表中的数据。该算法需要跟踪在添加到第二个列表的新元素时重置的计算。通过示例描述可能更容易:
清单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 = 3},{P = 8,V = 1}
列表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.然后我们正在寻找从这个初始起始价格的第一个价格,其中delta是3离3(通过参数1设置)。在列表1中,当我们通过列表移动时,下一步是向上移动到10,因此我们已经建立了“上升趋势”。所以现在我们在列表2中构建我们的第一个元素,其中Open = 7,Close = 10并总结第一个列表中使用的所有条形的体积以进入列表2中的第一步。现在,下一个元素起始点是10.建立另一个上升步骤,我们需要向上推进另外3个以创建另一个上升步骤,或者我们可以反转并向下移动6(参数2)。使用列表1中的数据,我们首先达到13,因此在列表2中构建我们的第二个元素,并总结用于执行此步骤的所有V属性。我们继续这个过程,直到列表1处理结束。
注意列表1中发生的间隙跳转。我们仍然想要创建{O = 13,C = 16,V = 0}的步长元素。 V的0只是简单地说我们有一个范围移动通过这一步但是体积为0(这里没有列表1的实际价格 - 它高于它但是我们想要建立导致价格的一组步骤它在它之上)。
列表2中的倒数第二个条目表示从上到下的反转。
列表2中的最终条目仅使用列表1中的最终关闭,即使它尚未完成建立全范围步骤。
感谢您提供有关如何通过Linq进行此操作的指示。
答案 0 :(得分:1)
我的第一个想法是,为什么要尝试使用LINQ呢?对于使用Enumerable
关键字进行部分处理然后吐出答案来制作新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;
}
}
这还没有完成。例如,它不处理间隙,并且存在未处理的边缘情况,其中可能消耗最后一个数据点,但它仍将处理“lastPoint”。但它应该足以开始。