'How to remove weekend datetime gaps from x-axis of a financial chart?

I have a use case where I pull and plot Forex data in the form of ask and bid on the graph and this is based on minute, hour or day candlesticks and I am only plotting the closing value for bid and ask as a spline.

Issue

The endpoints that I am using their Forex data feed is not available from Friday 8pm to Sunday 9pm. Let's say I have the following use case

  • Plot a 200 data points (i.e. hourly candle) on the graph at a time, on new candle phase out the oldest and plot the newest
  • The X-Axis is the data point's datetime in UTC ISO Format
  • The Y-Axis is the value of ask and bid
  • At a time the graph shows 4.1 days worth of hourly candle

The graph is pretty and smooth when the datetime on x-axis do not have any gaps. The candle timestamps are returned in the following form

2018-06-29T16:00:00.000000000Z
2018-06-29T17:00:00.000000000Z
2018-06-29T19:00:00.000000000Z
2018-06-29T20:00:00.000000000Z (Friday last candle 8pm)
2018-07-01T21:00:00.000000000Z (Sunday first candle 9pm) 
2018-07-01T22:00:00.000000000Z
2018-07-01T23:00:00.000000000Z
2018-07-02T00:00:00.000000000Z

As soon as there is a gap (around 47-49 hours) everything gets compressed to accommodate for the stretched part of the graph as shown below (Using plotly.js)

Using PlotlyJS Library

Mostly, financial graphs do not show the gap. For example, looking at the TradingView interactive chart you will see the following for weekend

enter image description here

If you know how to tackle this issue with open source charting libraries (excluding TradingView) then please share your solution.



Solution 1:[1]

TL;DR

Based on my findings, you can exclude the gaps using HighStock of Highcharts library. Highcharts is open source and only free to use for Non-commercial use, for more details see highcharts licensing

plotly.js

I initially started off with plotly.js because it really is a very good charting library to be honest. After I came across the datetime gap issue (see screenshot in question) on x-axis I researched for solution and came across the following issues

https://community.plot.ly/t/tickformat-without-weekends/1286/5 (forum)

https://github.com/plotly/plotly.js/issues/1382 (locked github thread)

https://community.plot.ly/t/x-axis-without-weekends/1091/2

As per the Github issue link above, this is not achievable at the moment for how the datetime is handled on x-axis. There are workaround (like 3rd link above) but, I tried some and it either didn't work or I lost some piece of information.

I came to the conclusion that even though plotly is a great library, it simply cannot help me in this case. If you think it does, please share your solution :)

C3.js

After some more research of charting libraries, I give C3.js a try and after editing their live demo example with datetime for x-axis I observed the same weekend gap issue (see below)

C3.js

I did not bother researching why and that's probably because of being based on D3.js just like plotly.js. If you think the datetime gap can be handled with C3.js then please feel free to share your solution.

Highcharts

I finally came across the family of Highxxxxx charting library and at first look it looked so pretty and offered all the functionalities that I wanted. I tried Highchart and I got the same weekend gap issue

Highcharts attempt

Well, I started to think that the only solution is to NOT TO PLOT the datetime in x-axis at all and somehow show the datetime in tooltip and that seem to do the job as shown below

Highcharts with x-axis

But, being too stubborn to give up I continued my research. I really wanted to get the charting done like TradingView and other stock visualization.

I decided to do some more research and little did I knew that I was so so close to a solution by the very same charting library Highcharts and it is called HighStock

Highstock of Highcharts

HighStock by default takes care of the gaps as shown below

HighStock of Highcharts

I used the following piece of Javascript

  Highcharts.setOptions({
    global: {
      useUTC: false
    }
  });

  Highcharts.StockChart('chart', {
    chart: {
        type: 'spline',
        events: {
            load: function () {
              console.log('Highcharts is Loaded! Creating a reference to Chart dom.')

              //store a reference to the chart to update the data series
              var index=$("#chart").data('highchartsChart');
              highchartRef = Highcharts.charts[index]; //global var

              //Initiating the data pull here
            }
        }
    },
    title: {
        text: 'Chart title'
    },
    series: [
      {
        name: 'Ask',
        data: [],
        tooltip: {
            valueDecimals: 7
        },
        marker: {
          enabled: true
        }
      },
      {
        name: 'Bid',
        data: [],
        tooltip: {
            valueDecimals: 7
        },
        marker: {
          enabled: true
        }
      }
    ]
  });

There you have it, a gapless (not sure if it is a real word) financial chart with datetime x-axis for financial data.

Libraries I did not try

I have researched but, did not try the following charting libraries

  • Google charts (didn't feel right for unknown reasons)
  • Chartist (didn't see much of interactivity and financial related chart types and examples
  • Chartjs (same as Chartist)
  • TradingView (I give up after reading their terms of use - weird clause, my point of view)
  • A majority of others that lacked the level of documentation, interactivity, finance-related charts like Plotly and Highcharts.

Final thought

I found Highcharts to be

  1. Well documented
  2. A ton of jsfiddles examples around
  3. Lots of useful SO answers
  4. Pretty and very functional
  5. Many options
  6. Easy to use

Similar SO questions relating to gaps

How can I hide data gaps in plotly?

HighCharts datetime xAxis without missing values (weekends) (Highcharts)

Remove weekend gaps in gnuplot for candlestick chart (candlestick-chart, gunplot)

How to remove gaps in C3 timeseries chart? (c3/d3 - fiddles are not working so its hard to see the solution)

How to remove weekends dates from x axis in dc js chart (c3.js - the gap is some gap)

Solution 2:[2]

According to documentation

try to add this before fig.show()

fig.update_xaxes(
    rangebreaks=[
        dict(bounds=["sat", "sun"]), #hide weekends
    ]
)

or

fig.layout.xaxis.type = 'category'

Solution 3:[3]

Plotly is now supporting to hide weekend and holidays in chart with help of rangebreaks. check this link:https://plotly.com/python/time-series/ go to the section:"Hiding Weekends and Holidays"

Below is section copied from this link, example is for plotly.express but it also works for plotly.graph_objects

Hiding Weekends and Holidays The rangebreaks attribute available on x- and y-axes of type date can be used to hide certain time-periods. In the example below, we show two plots: one in default mode to show gaps in the data, and one where we hide weekends and holidays to show an uninterrupted trading history. Note the smaller gaps between the grid lines for December 21 and January 4, where holidays were removed. Check out the reference for more options: https://plotly.com/python/reference/#layout-xaxis-rangebreaks

import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')

fig = px.scatter(df, x='Date', y='AAPL.High', range_x=['2015-12-01', '2016-01-15'],
                 title="Default Display with Gaps")
fig.show()

enter image description here

Display without Gaps

import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')

fig = px.scatter(df, x='Date', y='AAPL.High', range_x=['2015-12-01', '2016-01-15'],
                 title="Hide Gaps with rangebreaks")
fig.update_xaxes(
    rangebreaks=[
        dict(bounds=["sat", "mon"]), #hide weekends
        dict(values=["2015-12-25", "2016-01-01"])  # hide Christmas and New Year's
    ]
)
fig.show()

enter image description here

Solution 4:[4]

Using category as the xaxis type worked for me quite nicely (notice the go.Layout object):

    import plotly.graph_objects as go

    layout = go.Layout(
        xaxis=dict(
            type='category',
        )
    )

    fig = go.Figure(data=[go.Candlestick(x=self.price_df.index.to_series(),
                                         open=self.price_df[e.OHLCV.OPEN.value],
                                         high=self.price_df[e.OHLCV.HIGH.value],
                                         low=self.price_df[e.OHLCV.LOW.value],
                                         close=self.price_df[e.OHLCV.CLOSE.value])],
                    layout=layout)

    fig.show()

Solution 5:[5]

First of all, no need to quit on Plotly. The use of rangebreaks is indeed the tool to use, but that’s one side of it. I say this because for stock data bounds aren't practical compared to values, but you would be specifying dates for many holidays per year, and most of them change from one year to the other. So use values for rangebreaks and feed it with a list of every date that you don’t have in the CSV file you are loading. In case you need a bigger push to solve this, what I mean is taking the ‘date’ column aside, looping through it, and appending dates that are not there in another list. Then you can go fig.update_xaxes(rangebreaks=[dict(values=mylistofdates)]) Hope this brings you back to Plotly!

Solution 6:[6]

To remove empty columns such as Weekends from Financial Data using plotly ,Use below code.

Code-

import plotly.express as px


#Daily Percentage change in Nifty 50 Index
daily_returns = np.log(1+df_close.pct_change())*100

fig = px.bar(daily_returns,y = "Close", orientation='v')
fig.update_xaxes( rangeslider_visible=True, rangebreaks=[
        dict(bounds=["sat", "mon"]), #hide weekends
    ])
fig.update_layout(
    title='Nifty 50 Daily Returns in %',
    yaxis_title='Daily % Change')
fig.update_layout( xaxis_tickformat = ' %d %B (%a)<br> %Y')

fig.show()

Snap-

Removing Weekends

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2
Solution 3
Solution 4 Lukas Z.
Solution 5 chrix
Solution 6 Divyank