FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Removing gaps for irregular time data on DateTimeAxis · Issue #83 · oxyplot/oxyplot · GitHub

Repository navigation

Removing gaps for irregular time data on DateTimeAxis #83

Description

Imported from http://oxyplot.codeplex.com/workitem/10089

cwevers 2013-10-18 15:44
I'm currently building a candlestick graph for stock quotes. I only have data (OHLC) for the trading days so this leaves gaps for weekend days. Of course I can work with a category axis but this throws out all the neat DateTimeAxis features. Is it possible
to remove these gaps (see attached example)? I've looked into IntervalType = DateTimeIntervalType.Manual but that seems to do nothing.

Activity

  1. MrJul commented on Nov 11, 2014

    +1, I need to show only business hours in some graph (removing week-ends and night hours).

  2. Jofta commented on Feb 26, 2015

    Anything new here? I’ve got this code for displaying currency pair EUR/USD one hour (H1) chart:

            DateTimeAxis timeSpanAxis1 = new DateTimeAxis()
            {
                Position = AxisPosition.Bottom,
                IntervalType= DateTimeIntervalType.Auto
            };
            document.ChartPlotModel.Axes.Add(timeSpanAxis1);
    
            LinearAxis linearAxis1 = new LinearAxis() { Position = AxisPosition.Left };
            document.ChartPlotModel.Axes.Add(linearAxis1);
    
            CandleStickSeries series = new CandleStickSeries()
            {
                Color = OxyColors.Black,
                IncreasingColor = OxyColors.DarkGreen,
                DecreasingColor = OxyColors.Red,
                DataFieldX = "Time",
                DataFieldHigh = "H",
                DataFieldLow = "L",
                DataFieldOpen = "O",
                DataFieldClose = "C",
                TrackerFormatString = "Date: {2}\nOpen: {5:0.00000}\nHigh: {3:0.00000}\nLow: {4:0.00000}\nClose: {6:0.00000}"
            };
            ReadData(series);
    
            int itemsCount = series.Items.Count;
    
            timeSpanAxis1.Minimum = series.Items[itemsCount - 46].X;
            timeSpanAxis1.Maximum = series.Items[itemsCount - 1].X;
    
            double yMin = series.Items.Skip(itemsCount - 46).Take(45).Select(x => x.Low).Min();
            double yMax = series.Items.Skip(itemsCount - 46).Take(45).Select(x => x.High).Max();
            double extent = yMax - yMin;
            double margin = extent * .05;
    
            linearAxis1.Minimum = yMin - margin;
            linearAxis1.Maximum = yMax + margin;
    
            document.ChartPlotModel.Series.Add(series);
    
            timeSpanAxis1.AxisChanged += (sender, e) => AdjustYExtent(series, timeSpanAxis1, linearAxis1);
    

    There is for example gap between Friday 2015.02.13 23:00 and Monday 2015.02.16 00:00. My solution with OxyPlot gives me that gap on the chart:


    But, I’d like to have a chart without that gap. For example this is a MT4 chart with this situation:


    A lot of financial series are with gaps. I think to solve this problem would by a great improvement.
    Any help will be welcome.

    P.S.: OxyPlot is a good job. Thanks a lot.

  3. PsykotropyK commented on May 29, 2015

    Hello.

    One way to deal with this problem is to use a category axis. Unfortunately it means some adjustments which are not very convenient:
    1/ category axis is using the index of the label collection items as coordinates. If you have 5 categories in the Labels collection, the categories will be placed at coordinates 0 to 4
    2/ CandleStickAndVolumeSeries is using a datetime converted as double (to convert, use DateTimeAxis.ToDouble(YourDateTimeValue))

    So to have it working I currently use a variable storing my list of datetimes (to later pass them to the category axes), and I replace them in the CandleStickAndVolumeSeries by the index. It allows to correctly plot the data on a category axis and remove the gaps. Unfortunately it has a few downsides:
    1/ the auto update of the interval doesn't exist with CategoryAxes (and it looks awful)
    2/ it can delete gaps that are not real gaps. Exemple: let's imagine a H1 (1 hour interval) chart on the Forex without any quotation received on Tuesday from 3pm until 6pm, those 3 hours will not appear on your x axis, if you don't pass a "fake" candle (open = high = low = close = pastclose).

    So can it be possible to have a DateTimeCategoryAxis that would plot using the label index, but will automatically update the label format (changing from hh:mm to dd/MM/yyyy regarding the zoom, like a DateTimeAxis) and its interval?
    At best, the CandleStickAndVolumeSeries should have a Xprime value representing the index, with an option to choose to plot using X (the double representing the datetime, for graphs using a proper DateTimeAxis) or Xprime (the index, for graph using the new DateTimeCategoryAxis).

  4. BrianARice commented on Nov 22, 2017

    +1, this is super important for financial charts.

  5. BrianARice commented on Nov 22, 2017

    This works pretty easily though:

           CandleStickSeries candleStickSeries = new CandleStickSeries();
            var n = 0;
            foreach (var bar in bars)
                candleStickSeries.Items.Add(new HighLowItem(n++, (double)bar.High, (double)bar.Low, (double)bar.Open, (double)bar.Close));
            model.Series.Add(candleStickSeries);
    
            model.Axes.Add(new LinearAxis()
            {
                Position = AxisPosition.Bottom,
                LabelFormatter = (value) =>
                {
                    return bars[(int)value].Date.ToString("MM/dd");
                }
            });
    
  6. andreas-it-dev commented on Dec 27, 2017

    @BrianARice should your code remove the gaps?

  7. p80ric commented on Aug 31, 2018

    Hi,
    i took the approach of BrianARice and modified it for my needs. I ve added a new class Financial Axis that uses indexes instead of DateTimes. With that i was able to fix eaven the tooltip dates which were otherwise broken here is my code:

    public class FinancialChartAxis : LinearAxis
        {
            public FinancialChartAxis(List<DateTime> dateTimes, string axisDateFormatString)
                : base()
            {
                DateTimes = dateTimes;
                LabelFormatter = (value) =>
                {
                    return value >= 0 && value < dateTimes.Count ? dateTimes[(int)value].ToString(axisDateFormatString) : string.Empty;
                };
            }
    
            private List<DateTime> DateTimes { get; set; }
    
            public override object GetValue(double x)
            {
                int indexValue = (int)x;
                if (indexValue >= 0 && indexValue < DateTimes.Count)
                {
                    return DateTimes[indexValue];
                }
    
                return base.GetValue(x);
            }
        }
    
     private PlotModel GeneratePricePlotModel(IPriceStreamReader priceStreamReader, PriceInfo priceInfo)
            {
                var plotModel = new PlotModel { Title = priceInfo.Name + " " + priceInfo.PriceStreamId.Interval };
    
                var priceAxis = new LinearAxis { Position = AxisPosition.Left };
                plotModel.Axes.Add(priceAxis);
    
                List<Price> prices = priceStreamReader.ToList();
                List<HighLowItem> ohlvItems = prices.Select((p, i) => new HighLowItem(i, p.High, p.Low, p.Open, p.Close)).ToList();
    
                var candleStickSeries = new CandleStickSeries()
                {
                    Color = OxyColors.Black,
                    StrokeThickness = 1,
                    IncreasingColor = OxyColors.LightSlateGray,
                    DecreasingColor = OxyColors.DarkRed,
                    DataFieldX = "Time",
                    DataFieldHigh = "H",
                    DataFieldLow = "L",
                    DataFieldOpen = "O",
                    DataFieldClose = "C",
                    ItemsSource = ohlvItems,
                    TrackerFormatString = "Date: {2}\nHigh: {3:0.00}\nLow: {4:0.00}\nOpen: {5:0.00}\nClose: {6:0.00}"
                };
    
                string dateFormat = priceStreamReader.PriceInfo.PriceStreamId.Interval < Interval.Day ? "dd.MM.yy\nHH:mm" : "dd.MM.yy";
    
                var timeAxis = new FinancialChartAxis(prices.Select(p => p.TimeStamp).ToList(), dateFormat)
                {
                    Position = AxisPosition.Bottom,
                    MaximumRange = 750
                };
    
                plotModel.Axes.Add(timeAxis);
    
                int itemCount = ohlvItems.Count;
    
                int itemWindowSize = 100;
    
                timeAxis.Minimum = ohlvItems[itemCount - itemWindowSize].X;
                timeAxis.Maximum = ohlvItems[itemCount - 1].X;
    
                priceAxis.Minimum = ohlvItems.Skip(itemCount - itemWindowSize).Take(itemWindowSize).Select(x => x.Low).Min();
                priceAxis.Maximum = ohlvItems.Skip(itemCount - itemWindowSize).Take(itemWindowSize).Select(x => x.High).Max();
    
                plotModel.Series.Add(candleStickSeries);
                timeAxis.AxisChanged += (sender, e) => AdjustYExtent(candleStickSeries, timeAxis, priceAxis);
      
                return plotModel;
            }
    
    

    using the code of the example:

    private static void AdjustYExtent(CandleStickSeries series, Axis xaxis, Axis yaxis)
            {
                var xmin = xaxis.ActualMinimum;
                var xmax = xaxis.ActualMaximum;
    
                var istart = series.FindByX(xmin);
                var iend = series.FindByX(xmax, istart);
    
                var ymin = double.MaxValue;
                var ymax = double.MinValue;
                for (int i = istart; i <= iend; i++)
                {
                    var bar = series.Items[i];
                    ymin = Math.Min(ymin, bar.Low);
                    ymax = Math.Max(ymax, bar.High);
                }
    
                var extent = ymax - ymin;
                var margin = extent * 0.10;
    
                yaxis.Zoom(ymin - margin, ymax + margin);
            }
    
  8. lefig commented on Jan 11, 2020

    This is a fascinating thread and a great project. I deal with similar time series data and learnt a good deal to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL