public void ApplyData(DataAroundEvent[] data_, int numberAroundEvent_, DataAroundEventField field_) { var con = Helper.TransformToCon(data_, numberAroundEvent_, field_); if (con == null) return; for (int i = 0; i < con.Dates.Count; i++) { ApplyData(con.Dates[i].ToString("dd-MM-yy") + " " + data_[i].EventCode /*+ ": \n" + data_[i].Instrument*/, con.ColumnHeadings, con.GetValues(con.Dates[i])); } }
private DataAroundEvent[] ComputeOffsetBetweenEvents(IGrouping<string, DataAroundEvent>[] orderEventGroups, IGrouping<string, DataAroundEvent> midGroup) { // compute offset between each event to center group DataAroundEvent[] repivotEvents; repivotEvents = orderEventGroups.SelectMany(@group => @group.Select(d => { var eventPicked = @group.OrderByDescending(e => e.EventDate).FirstOrDefault(g => g.EventDate > DateTime.Today.AddDays(-numberOfPointsAroundEvent)); int busDayDiff = 0; if (eventPicked != null) { busDayDiff = BusDayDiff(midGroup.OrderByDescending(e => e.EventDate).First(x => x.EventDate > DateTime.Today.AddDays(-numberOfPointsAroundEvent)).EventDate, eventPicked.EventDate); } var ar = new DataAroundEvent(d.EventDate, d.Instrument, d.RawData, d.NumPointsAroundEvent, d.EventCode, busDayDiff) { PivotIndex = pivotIndex, }; return ar; })).ToArray(); return repivotEvents; }
/// <summary> /// |______|______|_____|_____| /// -3 0 3 /// if event numbers are odd numbers, we would have one in the middle and even on two sides /// /// |___|____|___|__|____| /// -3 0 2 3 /// if event numbers are even numbers, we would have one in the middle, one more event on the right side /// </summary> private void ComputePivotIndexAndOffset() { var eventGroups = data.GroupBy(d => d.EventCode).ToArray(); repivotEvents = data; var orderEventGroups = eventGroups.OrderBy( g => { var groupItems = g.OrderBy(e => e.EventDate) .FirstOrDefault(x => x.EventDate > DateTime.Today.AddDays(-numberOfPointsAroundEvent)); return groupItems != null ? groupItems.EventDate : DateTime.MinValue; }) .Where(o => o.Any(x => x.EventDate > DateTime.Today.AddDays(-numberOfPointsAroundEvent))).ToArray(); var eventCount = orderEventGroups.Count(); var rightCount = (int)(eventCount/2); var leftCount = (int) (eventCount - rightCount - 1); if (eventCount == 0) return; var leftGroup = orderEventGroups.Take(leftCount); var rightGroup = orderEventGroups.TakeLast(rightCount); var midGroup = orderEventGroups[leftCount]; // we only need to repivot to yesterday close when all events are in future, otherwise, we can pivot from the first event. if (eventGroups.All(g => g.Any(e => e.DaysToEvents.HasValue))) { // all events in future // find out the days to event to the first event var daysToEvent = orderEventGroups.First().Select(g => g.DaysToEvents).First(); pivotIndex = numberOfPointsAroundEvent - (daysToEvent + 1 ?? 0); if (pivotIndex == -1) return; } else { // we need to find the first event and pivot from there var firstEvent = orderEventGroups.First().OrderBy(e => e.EventDate).FirstOrDefault(x => x.EventDate > DateTime.Today.AddDays(-numberOfPointsAroundEvent)); if (firstEvent != null) { var busDayDiff = BusDayDiff(firstEvent.EventDate, midGroup.OrderByDescending(e => e.EventDate).First(x => x.EventDate > DateTime.Today.AddDays(-numberOfPointsAroundEvent)).EventDate); pivotIndex = numberOfPointsAroundEvent + busDayDiff; } } MidEvent = midGroup.First(); MidEvent.PivotIndex = pivotIndex; repivotEvents = ComputeOffsetBetweenEvents(orderEventGroups, midGroup); }
public MultiEventDisplayOrganiser(DataAroundEvent[] data, int numberOfPointsAroundEvent) { this.data = data; this.numberOfPointsAroundEvent = numberOfPointsAroundEvent; pivotIndex = numberOfPointsAroundEvent; }
public static Tuple<ConstructGen<double>, int, DateTime> TransformToCompoChartDataAndShift(DataAroundEvent[] data_, int numberAroundEvents_, DataAroundEventField field_) { ConstructGen<double> ret = new ConstructGen<double>(numberAroundEvents_ + 1); ret.ColumnHeadings = new string[ret.ArrayLength]; //ret.ColumnHeadings[0] = DateTime.Today.ToString("dd-MMM-yyyy"); for (int i = 0; i <= numberAroundEvents_; ++i) { ret.ColumnHeadings[i] = i.ToString(); } var headings = new List<string>(ret.ColumnHeadings); int dayShift=0; DateTime closestEvent=DateTime.MinValue; if (data_ != null) { var eventdates = data_.Select(d => d.EventDate).ToArray(); // first find out any events falls within next 15 days var maxAllowEventDate = DateTime.Today.AddDays(numberAroundEvents_); var includeEvents = eventdates .Where(newEvent => newEvent >= DateTime.Today && newEvent <= maxAllowEventDate); if (includeEvents.Any()) { closestEvent = includeEvents.OrderBy(e => e).First(); dayShift = (int)(closestEvent -DateTime.Today).TotalDays; int firstDataIndex = numberAroundEvents_ - dayShift; foreach (var eve in data_.OrderBy(x => x.EventDate)) { // initialise to NaN ret.SetValues(eve.EventDate, Utils.GetArrayOfValue<double>(double.NaN, ret.ArrayLength)); var subData = eve[field_]; if (subData != null) for (int i = 0; i <= numberAroundEvents_; i++) { if (firstDataIndex + i > subData.Data.Length -1) continue; if (subData.Data[firstDataIndex+i] == null) continue; ret.SetValue(eve.EventDate, i, subData.Data[firstDataIndex+i].Value); } } } } return new Tuple<ConstructGen<double>, int, DateTime>(ret, dayShift, closestEvent); }
public static ConstructGen<double> TransformToCon(DataAroundEvent[] data_, int numberAroundEvents_, DataAroundEventField field_) { ConstructGen<double> ret = new ConstructGen<double>((numberAroundEvents_ * 2) + 1); ret.ColumnHeadings = new string[ret.ArrayLength]; ret.ColumnHeadings[numberAroundEvents_] = "0"; for (int i = 1; i <= numberAroundEvents_; ++i) { ret.ColumnHeadings[numberAroundEvents_ - i] = (-i).ToString(); ret.ColumnHeadings[numberAroundEvents_ + i] = i.ToString(); } var headings = new List<string>(ret.ColumnHeadings); if(data_!=null) foreach (var eve in data_.OrderBy(x => x.EventDate)) { // initialise to NaN ret.SetValues(eve.EventDate, Utils.GetArrayOfValue<double>(double.NaN, ret.ArrayLength)); var subData = eve[field_]; if(subData!=null) foreach (var point in subData.Data) { if (point == null) continue; var index = headings.IndexOf((point.Index - data_.First().Offset).ToString()); ret.SetValue(eve.EventDate, index, point.Value); } } return ret; }
public void ApplyStats(DataAroundEvent[] data_, int numberAroundEvent_, DataAroundEventField field_) { var con = Helper.TransformToCon(data_, numberAroundEvent_, field_); if (con == null) return; var avgs = new double[con.ArrayLength]; var zscore = new double[con.ArrayLength]; for (int i = 0; i < avgs.Length; ++i) { var validNumberSeries = con.GetColumnValues(i).Where(x => double.IsNaN(x) == false); if (!validNumberSeries.Any()) continue; avgs[i] = validNumberSeries.ToArray().Average(); var sd = Statistics.Stdev(validNumberSeries.ToArray()); zscore[i] = avgs[i]/sd; } ApplyData("Average", con.ColumnHeadings, avgs); ApplyData("Avg/S.d.", con.ColumnHeadings, zscore); }
private void BuildCurrentVsHistchart(DataAroundEvent[] data_) { scsHistVsCurrent.ClearData(); lock (lockobj) { ViewModel.LiveIndex = -1; } var histAvgs = new List<double[]>(); string[] headings = null; var multiEventOrganiser = new MultiEventDisplayOrganiser(data_, m_displayOptions.NumberOfPointsAroundEvent); var repivotEvents = multiEventOrganiser.RepivotEvents; var eventGroups = repivotEvents.GroupBy(d => d.EventCode).ToArray(); int idx = 0; var offsetsToAdd = new Dictionary<string,string>(); int pivotIndex = 0; //var daysToEvent = data_.OrderBy(e => e.EventDate).FirstOrDefault(x => x.DaysToEvents.HasValue); foreach (var @group in eventGroups) { //var eventDataTup = new List<Tuple<string, DataAroundEvent[]>>(); var histEvents = @group.Where(e => e.EventDate < DateTime.Today.AddDays(-m_displayOptions.NumberOfPointsAroundEvent)).ToArray(); // eventDataTup.Add(new Tuple<string, DataAroundEvent[]>("Past Avg", histEvents)); // hist events var con = Helper.TransformToCon(histEvents, m_displayOptions.NumberOfPointsAroundEvent, m_displayOptions.FieldToShow); headings = con.ColumnHeadings; double[] avgs = new double[con.ArrayLength]; for (int i = 0; i < avgs.Length; ++i) { var validNumberSeries = con.GetColumnValues(i).Where(x => double.IsNaN(x) == false).ToArray(); if (!validNumberSeries.Any()) { avgs[i] = double.NaN; continue; } avgs[i] = validNumberSeries.ToArray().Average(); } if (offsetsToAdd.ContainsKey(([email protected]().Offset).ToString())) offsetsToAdd[([email protected]().Offset).ToString()] = offsetsToAdd[([email protected]().Offset).ToString()] + "\n" + @group.Key; else offsetsToAdd.Add(([email protected]().Offset).ToString(), @group.Key); histAvgs.Add(avgs); idx++; } if (headings != null) { // Hist series // average of all the hist average double[] avgs = new double[histAvgs.First().Length]; foreach (var avg in histAvgs) { for (int i = 0; i < avgs.Length; i++) { avgs[i] += avg[i]; } } var avgavg = avgs.Select(a => a/histAvgs.Count).ToArray(); scsHistVsCurrent.ApplyData("Past Avg", headings, avgavg); scsHistVsCurrent.Chart.VerticalLinesXValuesLabels = offsetsToAdd; // set seconardy y-axis var axisValues = avgavg.Where(a => !double.IsNaN(a)).ToArray(); if (axisValues.Any()) { if (m_displayOptions.YAXesSymmetric) { var largerValue = Math.Max(Math.Abs(axisValues.Max()), Math.Abs(axisValues.Min())); scsHistVsCurrent.Chart.SetSecondaryYAxis("Past Avg", largerValue, -largerValue); } else { scsHistVsCurrent.Chart.SetSecondaryYAxis("Past Avg", axisValues.Max(), axisValues.Min()); } } if (!data_.First().IsIntraday) { // Current series //var curEvents = repivotEvents.OrderBy(x => x.EventDate).FirstOrDefault(e => e.EventDate > DateTime.Today.AddDays(-m_displayOptions.NumberOfPointsAroundEvent)); var curEvents = multiEventOrganiser.MidEvent; //if (eventData.Item1 == "Current") if (curEvents != null) { // current level var currentCon = Helper.TransformToCon(new[] {curEvents}, m_displayOptions.NumberOfPointsAroundEvent, DataAroundEventField.Filled_Level); var currentPivot = currentCon.GetColumnValues(repivotEvents.First().PivotIndex).Average(); ViewModel.Pivot = currentPivot; var con = Helper.TransformToCon(new[] {curEvents}, m_displayOptions.NumberOfPointsAroundEvent, m_displayOptions.FieldToShow); if (curEvents != null) { double busday; if (curEvents.EventDate > DateTime.Today) busday = -1*(MyCalendar.NumBusinessDaysBetween(DateTime.Today, curEvents.EventDate) - 1); else busday = MyCalendar.NumBusinessDaysBetween(curEvents.EventDate, DateTime.Today) - 1; //ViewModel.PivotIndex = repivotEvents.First().PivotIndex; ViewModel.LiveIndex = m_displayOptions.NumberOfPointsAroundEvent + (int) busday; scsHistVsCurrent.ApplyData("Current", headings, con.LastValues()); } } ViewModel.Headings = headings; var todayPts = ExtensionMethods.CreateArrayRep<double>(double.NaN, headings.Length); if (ViewModel.LiveIndex > 0) { todayPts[ViewModel.LiveIndex] = avgavg[ViewModel.LiveIndex]; // mark today's point scsHistVsCurrent.ApplyScatterData("Now", headings, todayPts); var axisValues2 = avgavg.Where(a => !double.IsNaN(a)).ToArray(); if (axisValues2.Any()) { if (m_displayOptions.YAXesSymmetric) { var largerValue = Math.Max(Math.Abs(axisValues2.Max()), Math.Abs(axisValues2.Min())); scsHistVsCurrent.Chart.SetSecondaryYAxis("Now", largerValue, -largerValue); } else { scsHistVsCurrent.Chart.SetSecondaryYAxis("Now", axisValues2.Max(), axisValues2.Min()); } } } } } scsHistVsCurrent.SetupForDataType(m_displayOptions.FieldToShow); }
internal void Apply(DataAroundEvent[] data_) { try { chartScaleLimit = 0.0; // recent { scsRecent.ClearData(); var recentEvents = data_.GroupBy(d => d.EventDate).Select(g => new DataAroundEvent(g.First().EventDate, g.Select(x => x.Instrument).Aggregate((a, b) => a + "\n" + b), g.First().RawData, g.First().NumPointsAroundEvent, g.Select(x => x.EventCode).Aggregate((a, b) => a + "\n" + b))) .OrderByDescending(x => x.EventDate) .Where(ev => ev.EventDate <= DateTime.Today.AddDays(m_displayOptions.NumberOfRecentQuartersToShow)) .Take(m_displayOptions.NumberOfRecentEventsToShow).ToArray(); scsRecent.ApplyData(recentEvents, m_displayOptions.NumberOfPointsAroundEvent, m_displayOptions.FieldToShow); scsRecent.SetupForDataType(m_displayOptions.FieldToShow); scsRecent.ApplyStats(recentEvents, m_displayOptions.NumberOfPointsAroundEvent, m_displayOptions.FieldToShow); updateRecentChartSeries(); } // quarters { scsQuarterly.ClearData(); var quarters = data_.Select(x => getQuarterEnd(x.EventDate)).Distinct().OrderByDescending(x => x).ToList(); quarters = quarters.Count > m_displayOptions.NumberOfRecentQuartersToShow ? quarters.Take(m_displayOptions.NumberOfRecentQuartersToShow).ToList() : quarters; foreach (var quarterEnd in quarters) { var des = data_.Where(x => quarterEnd == getQuarterEnd(x.EventDate)).OrderBy(x => x.EventDate).ToArray(); var con = Helper.TransformToCon(des, m_displayOptions.NumberOfPointsAroundEvent, m_displayOptions.FieldToShow); double[] avgs = new double[con.ArrayLength]; for (int i = 0; i < avgs.Length; ++i) { var validNumberSeries = con.GetColumnValues(i).Where(x => double.IsNaN(x) == false); if (!validNumberSeries.Any()) continue; avgs[i] = validNumberSeries.ToArray().Average(); } scsQuarterly.ApplyData(getQuarterHeading(quarterEnd), con.ColumnHeadings, avgs); } scsQuarterly.SetupForDataType(m_displayOptions.FieldToShow); } // year-on-year { scsYearly.ClearData(); var years = data_.Select(x => x.EventDate.Year).Distinct().OrderByDescending(x => x).ToList(); // going to use -1 for 'all' if (m_displayOptions.AddLineForAllToYearly) years.Add(-1); var currentYearlyProbComboText = cmbYearlyProb.Text; m_reloadingCombo = true; cmbYearlyProb.Items.Clear(); cmbYearlyProb.Items.Add("None"); m_yearlyProbs.Clear(); foreach (var year in years) { // default combo to last year if not previously set if (string.Compare(string.Empty, currentYearlyProbComboText) == 0) currentYearlyProbComboText = year.ToString(); var yearString = year == -1 ? "All" : year.ToString(); cmbYearlyProb.Items.Add(yearString); // get dataaroundevent that is within this year var des = year == -1 ? data_ : data_.Where(x => x.EventDate.Year == year).OrderBy(x => x.EventDate).ToArray(); var con = Helper.TransformToCon(des, m_displayOptions.NumberOfPointsAroundEvent, m_displayOptions.FieldToShow); var conForProbability = Helper.TransformToCon(des, m_displayOptions.NumberOfPointsAroundEvent, DataAroundEventField.RawDataAroundEvent_Diffs); double[] avgs = new double[con.ArrayLength]; double[] yearlyProbs = new double[conForProbability.ArrayLength]; for (int i = 0; i < avgs.Length; ++i) { var validNumberSeries = con.GetColumnValues(i).Where(x => double.IsNaN(x) == false); if (!validNumberSeries.Any()) continue; avgs[i] = validNumberSeries.ToArray().Average(); { var alldiffs = conForProbability.GetColumnValues(i).Where(x => double.IsNaN(x) == false).ToList(); yearlyProbs[i] = ProbabilityCalc.CalcProb(alldiffs, m_displayOptions.ProbCalcMethod); } } m_yearlyProbs.Add(yearString, new Tuple<string[], double[]>(conForProbability.ColumnHeadings, yearlyProbs)); scsYearly.ApplyData(yearString, con.ColumnHeadings, avgs); } m_lastLoadedMaxProbability = ProbabilityCalc.GetMaxValue(m_displayOptions.ProbCalcMethod); // re-set the selected combobox to its original value if it's there if (!string.IsNullOrEmpty(currentYearlyProbComboText)) { for (int i = 0; i < cmbYearlyProb.Items.Count; ++i) if (string.Compare(currentYearlyProbComboText, cmbYearlyProb.Items[i].ToString()) == 0) { cmbYearlyProb.SelectedIndex = i; break; } } m_reloadingCombo = false; reloadYearlyProbability(); scsYearly.SetupForDataType(m_displayOptions.FieldToShow); } // current vs hist chart BuildCurrentVsHistchart(data_); // hist chart // filter n/a for chart series var rawData = data_.First().EODData ?? data_.First().RawData; var filteredData = rawData.Dates.Where(d => !double.IsNaN(rawData.ValueOnDate(d))) .Select(date => new { d = date, data = rawData.ValueOnDate(date) }).ToArray(); if (filteredData.Any()) { var filteredSeries = new DatedDataCollectionGen<double>(filteredData.Select(x => x.d).ToArray(), filteredData.Select(x => x.data).ToArray()); AddChartSeries(filteredSeries, "Time Series"); var eventdates = data_.Select(d => new {d.EventCode, d.EventDate}).ToArray(); var eventGroup = eventdates.GroupBy(ev => ev.EventCode).ToArray(); var eventDateList = eventGroup.Select(g => g.Select(x => x.EventDate).ToArray()).ToList(); var desc = eventGroup.Select((g,i) => string.IsNullOrEmpty(g.Key) ? "test"+ i+1 : g.Key).ToArray(); EventHistChart.SetScatterValues(eventDateList, desc); //AddScatterSeries(eventdates, eventdates.Select(x => data_.First().RawData.ValueOnDate(x)).ToArray(), "Events", Color.GreenYellow, 40, "##0.000", null, Infragistics.UltraChart.Shared.Styles.NullHandling.DontPlot, null, SymbolIcon.Triangle); } // scale y-axis { var ctrls = new[] {scsRecent.Chart, scsYearly.Chart, scsQuarterly.Chart, scsHistVsCurrent.Chart}; Rescale(ctrls); } } catch (Exception ex_) { Logger.Error("Error loading charts", typeof (SeasonalityCharts), ex_); } }