聚合扩展是解决此问题的最佳方法,还是应该尝试对分组执行某些操作?

时间:2010-11-21 02:08:33

标签: streaminsight

我正在处理股票数据Feed,我想从数据中构建分钟栏(烛台)。我认为我有一个非常好的查询会给我我需要的数据,但我不确定这是最好的方法。请提供您的任何评论或批评,我愿意接受您想要提供的任何意见。

左侧输入,右侧输出

class StockTick
{
    public DateTime Timestamp { get; set; }

    public int Id { get; set; }

    public decimal LastPrice { get; set; }
}

class FirstUda : CepAggregate<decimal, decimal>
{
    public override decimal GenerateOutput(IEnumerable<decimal> payloads)
    {
        return payloads.First();
    }
}

class LastUda : CepAggregate<decimal, decimal>
{
    public override decimal GenerateOutput(IEnumerable<decimal> payloads)
    {
        return payloads.Last();
    }
}

public static class CepExtensions
{
    [CepUserDefinedAggregate(typeof(FirstUda))]
    public static decimal First<InputT>(this CepWindow<InputT> window, Expression<Func<InputT, decimal>> map)
    {
        throw CepUtility.DoNotCall();
    }

    [CepUserDefinedAggregate(typeof(LastUda))]
    public static decimal Last<InputT>(this CepWindow<InputT> window, Expression<Func<InputT, decimal>> map)
    {
        throw CepUtility.DoNotCall();
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var server = Server.Create("Default"))
        {
            var app = server.CreateApplication("app");

            var source = GetStockTick();

            var input = source.ToPointStream(
                app,
                t => PointEvent.CreateInsert(t.Timestamp, t),
                AdvanceTimeSettings.IncreasingStartTime);

            var minuteWindows = input.AlterEventDuration(e => TimeSpan.FromTicks(TimeSpan.TicksPerMinute - (e.StartTime.Ticks % TimeSpan.TicksPerMinute)));

            var highLowTicks = from e in minuteWindows
                               group e by e.Id into g
                               from win in g.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
                               select new
                               {
                                   Id = g.Key,
                                   Timestamp = win.Max(e => e.Timestamp.AddSeconds(e.Timestamp.Second * -1)),
                                   OpenPrice = win.First(e => e.LastPrice),
                                   HighPrice = win.Max(t => t.LastPrice),
                                   LowPrice = win.Min(t => t.LastPrice),
                                   ClosePrice = win.Last(e => e.LastPrice)
                               };

            foreach (var hl in highLowTicks.ToEnumerable())
            {
                Console.WriteLine(hl);
            }

            Console.ReadKey();
        }
    }

    private static IEnumerable<StockTick> GetStockTick()
    {
        var ticks = new List<StockTick>();

        var baseTime = new DateTime(2010, 1, 1, 12, 0, 0);

        ticks.Add(new StockTick() { Id = 1, Timestamp = baseTime.AddSeconds(1), LastPrice = 10 });
        ticks.Add(new StockTick() { Id = 1, Timestamp = baseTime.AddSeconds(15), LastPrice = 8 });
        ticks.Add(new StockTick() { Id = 1, Timestamp = baseTime.AddSeconds(30), LastPrice = 12 });
        ticks.Add(new StockTick() { Id = 1, Timestamp = baseTime.AddSeconds(45), LastPrice = 11 });
        ticks.Add(new StockTick() { Id = 1, Timestamp = baseTime.AddSeconds(65), LastPrice = 13 });

        ticks.Add(new StockTick() { Id = 2, Timestamp = baseTime.AddSeconds(11), LastPrice = 35 });
        ticks.Add(new StockTick() { Id = 2, Timestamp = baseTime.AddSeconds(13), LastPrice = 37 });
        ticks.Add(new StockTick() { Id = 2, Timestamp = baseTime.AddSeconds(50), LastPrice = 22 });
        ticks.Add(new StockTick() { Id = 2, Timestamp = baseTime.AddSeconds(55), LastPrice = 32 });
        ticks.Add(new StockTick() { Id = 2, Timestamp = baseTime.AddSeconds(61), LastPrice = 36 });

        return ticks.OrderBy(t => t.Timestamp);
    }
}

1 个答案:

答案 0 :(得分:0)

瑞恩 看起来不错 - 只需检查这是否是预期的语义:

您将在每分钟内获得多个结果。对于每个输入事件,您将获得具有相同开始时间的结果事件,包含第一个(在此分钟内)和当前价格,以及到目前为止在此分钟内发生的最小值和最大值。因此,只有每分钟内的最后一次结果事件将包含整个分钟的第一个,最后一个,最小值,最大值。正确?你不希望每一分钟只发生一次事件吗?

罗马