1

我正在使用股票数据馈送,我想从数据中构建分钟柱(烛台)。我认为我有一个很好的查询,可以为我提供我需要的数据,但我不确定这是不是最好的方法。请给出您的任何意见或批评,我愿意接受您想提供的任何意见。

左边输入右边输出

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);
    }
}
4

1 回答 1

0

Ryan,看起来不错 - 只是检查这是否是预期的语义:

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

罗马

于 2010-12-09T21:34:56.560 回答