Ich arbeite mit einem Stock-Daten-Feed und möchte aus den Daten winzige Balken (Candlesticks) erstellen. Ich denke, dass ich eine ziemlich gute Frage habe, die mir die Daten geben wird, die ich brauche, aber ich bin nicht sicher, dass es der beste Weg ist, darüber zu gehen. Bitte geben Sie Kommentare oder Kritik, die Sie haben, ich bin offen für jede Eingabe, die Sie geben möchten.Sind Aggregaterweiterungen der beste Weg, um dieses Problem zu lösen, oder sollte ich versuchen, etwas mit der Gruppierung zu tun?
Eingang auf der linken Seite und Ausgang auf der rechten Seite
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);
}
}
Ich möchte nicht ein Ereignis für jede ganze Minute. Ich möchte eine aktualisierte "Minutenleiste" jedes Mal, wenn ein Ereignis kommt. Sie haben Recht, das allerletzte Ereignis in der Minute wird den Endstatus der Minutenleiste definieren, aber jedes Ereignis innerhalb der Minute wird eine aktualisierte Minutenleiste zur Verfügung stellen verwendet werden, um Abfragen in der Mitte der Minute zu erfüllen. –
Ich versuche 1min Balken mit Hopping Window der Länge 1min Länge alle 1min zu erstellen. Was ich nicht verstehe, ist, wie man die aktuelle Zeitrahmenzeit erhält, weil es keine First() - Methode für HoppingWindow gibt. – Chris