Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

candlestick chart with volume chart and range selector using highcharts? #320

Open
Arbitrageur opened this issue Jan 1, 2014 · 35 comments

Comments

@Arbitrageur
Copy link

Could you give me an example?

I'm not sure that this is the right place for asking.. but thanks anyway.

@ramnathv
Copy link
Owner

ramnathv commented Jan 1, 2014

If you can find an example implemented in javascript, I can investigate how you might do the same from R using rCharts.

@Arbitrageur
Copy link
Author

Here's an example from highcharts.com

Happy new year!

$(function() {
    $.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function(data) {

        // split the data set into ohlc and volume
        var ohlc = [],
            volume = [],
            dataLength = data.length;

        for (i = 0; i < dataLength; i++) {
            ohlc.push([
                data[i][0], // the date
                data[i][1], // open
                data[i][2], // high
                data[i][3], // low
                data[i][4] // close
            ]);

            volume.push([
                data[i][0], // the date
                data[i][5] // the volume
            ])
        }

        // set the allowed units for data grouping
        var groupingUnits = [[
            'week',                         // unit name
            [1]                             // allowed multiples
        ], [
            'month',
            [1, 2, 3, 4, 6]
        ]];

        // create the chart
        $('#container').highcharts('StockChart', {

            rangeSelector: {
                selected: 1
            },

            title: {
                text: 'AAPL Historical'
            },

            yAxis: [{
                title: {
                    text: 'OHLC'
                },
                height: 200,
                lineWidth: 2
            }, {
                title: {
                    text: 'Volume'
                },
                top: 300,
                height: 100,
                offset: 0,
                lineWidth: 2
            }],

            series: [{
                type: 'candlestick',
                name: 'AAPL',
                data: ohlc,
                dataGrouping: {
                    units: groupingUnits
                }
            }, {
                type: 'column',
                name: 'Volume',
                data: volume,
                yAxis: 1,
                dataGrouping: {
                    units: groupingUnits
                }
            }]
        });
    });
});

@ramnathv
Copy link
Owner

ramnathv commented Jan 1, 2014

I will check how this can be achieved using the rCharts binding. Meanwhile, here is an example of a candlestick chart with range selector using eCharts. echarts is not yet in the main branch of rCharts, so you will have to download the echarts binding and make sure that you refer to its correct path in the setLib step in the code I linked to earlier.

echarts-candle

@nemonominem
Copy link

Ramanth, do you have any plan to support Highstock (http://www.highcharts.com/stock/demo/candlestick) in rCharts?

With a quick hack (copying rCharts highchart library into a custom hightock libray, modifying the config.yml and a few files there), I could to get highstock to work within rCharts and I am now trying to reproduce some of the Highstock examples.
In particular the candlestick graphs work fine (to answer Arbitrageur's exact request, one can also easily add a volume graph to the candlestick graphs).

capture

One problem I have is that Highstock is supposed to include Highcharts in itself (it's a superset of functionnalities), so it seems a bit redundant to support both highcharts and highstock under rCharts. I am doing a few tests but so far it seems I can altogether drop the rCharts Highcharts library in my custom build and avoid any possible conflict down the line.

For info:
The data format expected by Highstock is straightforward. Here is an example:

require(rCharts)
require(quantmod)  #Load the quantmod Library

startDate <- as.Date("2010-01-01") #Specify period of time we are interested in
endDate   <- as.Date("2013-12-31")

tickers   <- c('AAPL', 'MSFT', 'MMM', 'V', 'HD', 'GE') #Define the tickers we are interested in
getSymbols(tickers, src = "google", from = startDate, to = endDate)

processQuantmodOHLC = function(name)
{
    tmp           <- OHLC(get(name))
    colnames(tmp) <- c('Open','High', 'Low', 'Close')

    stock         <- data.frame(t=index(tmp), coredata(tmp)) 
    stock$date    <- as.numeric(as.POSIXct(stock$t, origin="1970-01-01")) * 1000
    stock$stock   <- name

    return( stock )
}

stocks  <- do.call(rbind, lapply(tickers, processQuantmodOHLC))

aapl    <- subset(stocks, stock=='AAPL')
ohlcPlot(data = aapl, title='AAPL')

with:

ohlcPlot <- highstockOHLC <- function(name='a stock', data=data, radius = 3, title = NULL, subtitle = NULL)
{
    rChart <- Highstock$new()

    nrows <- nrow(data)
    data  <- na.omit(data) # remove remaining observations with NA's

    if (nrows != nrow(data))
        warning("Observations with NA has been removed")  

    rChart$series(
        data = toJSONArray2(data[c('date', 'Open', 'High', 'Low', 'Close')], json = F, names = F),
        type = 'candlestick',
        name = name,
        marker = list(radius = radius))

    rChart$legend(enabled = FALSE)

    ## title
    rChart$title(text = title, replace = T)

    ## subtitle
    rChart$subtitle(text = subtitle, replace = T)

    return(rChart$copy())
}

and with Hightstock being just a direct translation of the rChart code for Highcharts:

Highstock <- setRefClass("Highstock", contains = "rCharts", methods = list(
initialize = function()
{
    callSuper(); lib <<- 'highstock'; LIB <<- get_lib(lib)

    params <<- c(params, list(
                            credits = list(href = NULL, text = NULL),
                            exporting = list(enabled = F),
                            title = list(text = NULL),
                            yAxis = list(title = list(text = NULL))
                        ))
},

getPayload = function(chartId){

    # Set params before rendering
    params$chart$renderTo <<- chartId

    list(chartParams = toJSON2(params, digits = 13), chartId = chartId)
},

#' Wrapper methods
chart = function(..., replace = T)
{
    params$chart <<- setSpec(params$chart, ..., replace = replace)
},

colors = function(..., replace = T)
{
    args <- unlist(list(...))

    if (replace) {
        params$colors <<- args
    } else {
        params$colors <<- c(params$colors, args)
    }
},

credits = function(..., replace = T){
    params$credits <<- setSpec(params$credits, ..., replace = replace)
},

exporting = function(..., replace = T){
    params$exporting <<- setSpec(params$exporting, ..., replace = replace)
},

global = function(..., replace = T){
    params$global <<- setSpec(params$global, ..., replace = replace)
},

labels = function(..., replace = T){
    params$labels <<- setSpec(params$labels, ..., replace = replace)
},

lang = function(..., replace = T){
    params$lang <<- setSpec(params$lang, ..., replace = replace)
},

legend = function(..., replace = T){
    params$legend <<- setSpec(params$legend, ..., replace = replace)
},

loading = function(..., replace = T){
    params$loading <<- setSpec(params$loading, ..., replace = replace)
},

navigation = function(..., replace = T){
    params$navigation <<- setSpec(params$navigation, ..., replace = replace)
},

pane = function(..., replace = T){
    params$pane <<- setSpec(params$pane, ..., replace = replace)
},

plotOptions = function(..., replace = T){
    params$plotOptions <<- setSpec(params$plotOptions, ..., replace = replace)
},

series = function(..., replace = F) {
    params$series <<- setListSpec(params$series, ..., replace = replace)
},

subtitle = function(..., replace = T){
    params$subtitle <<- setSpec(params$subtitle, ..., replace = replace)
},

title = function(..., replace = T){
    params$title <<- setSpec(params$title, ..., replace = replace)
},

tooltip = function(..., replace = T){
    params$tooltip <<- setSpec(params$tooltip, ..., replace = replace)
},

xAxis = function(..., replace = T) {
    params$xAxis <<- setListSpec(params$xAxis, ..., replace = replace)
},

yAxis = function(..., replace = T) {
    params$yAxis <<- setListSpec(params$yAxis, ..., replace = replace)
},

# Custom add data method
data = function(x = NULL, y = NULL, ...)
{
    if (is.data.frame(x))
    {
        for (i in colnames(x))
        {
            if (is.numeric(x[[i]]))
                series(name = i, data = x[[i]], ...)
            else
                warning (sprintf("Column '%s' wasn't added since it's not a numeric", i))
        }
    } else
    {
        if (is.null(y) || !is.numeric(y))
            series(data = x, ...)
        else
        {
            if (length(x) != length(y))
                stop ("Arguments x and y must be of the same length")

            xy <- lapply(1:length(x), function(i) list(x[i], y[i]))
            series(data = xy, ...)
        }
    }
}))

@ramnathv
Copy link
Owner

ramnathv commented Jan 6, 2014

This is cool. Can you post your highstock library folder on github, so that I can see what changes are required when compared to highcharts? If it is only about extra js/css assets, there might be a way to absorb things into the highcharts library itself, especially since the R code for the class seems to be exactly identical.

@nemonominem
Copy link

You can see my quick go at of a highstock library on https://github.com/nemonominem/Highstock-rCharts-hack.
The files under the 'hack' directory are standalone for the time being (I have not tried to rebuild the rCharts package).
Otherwise it is just some changes in the js libraries and in the config.yml, and also in the layout chart.html (to call the right constructor).
This should be able to support both Highchart and Highstock functionalities. The https://github.com/nemonominem/Highstock-rCharts-hack/blob/master/highstock/examples_highstock.R file is still rudimentary but it shows that it can work.
capture1

@nemonominem
Copy link

It looks like one may have to have some separate Highcharts and Highstock R objects as the methods and default behaviors are slightly different.

Per http://api.highcharts.com/highstock and http://api.highcharts.com/highcharts:

  • pane() is not in Highstock
  • Highstock adds navigator(), scrollbar() and rangeSelector()

As an example of slightly different behavior, legend is enabled by default in Highcharts and not enabled in Highstock. I suspect a few subtle minor differences like that.

One may also want to change the data() method of the Highstock object to reflect the more specific data series usage. I have not bothered with that yet.

Then one can simply add an sPlot wrapper function and maybe some ohlcPlot wrapper function too (or alternatively one could create a dedicated R object inheriting from Highstock for OHLC).

This could all be packed in a revised highchart library under rCharts.

@ramnathv
Copy link
Owner

ramnathv commented Jan 9, 2014

This is looking really good! Let me spend some time this weekend going over your code and trying to figure out if it makes most sense to roll this into the highcharts library or create a separate highstock library.

@ramnathv
Copy link
Owner

I apologise for not getting back on this. I have been really busy with stuff. I will certainly take a closer look at this in the next couple of weeks and figure out the best way to add highstocks bindings.

@smbache
Copy link

smbache commented Apr 28, 2014

Any progress on this? I'll add myself to the list of interested individuals :)

@asosnovsky
Copy link

For all of those who don't feel like diving into the magical world of rCharts.
I created a simple package based on ramnathv and nemonominem code.
Here is the package, you will have to download and install it manually (I don't want to upload it to github, since its not my original all the credit belongs to those guys and those guys only!)
Here is the link:
https://mega.co.nz/#!kRJggTrK!NsGz1AWcFZxfRrfNCsm2sXR8F0mCzGbD917Ebjatie8

Just download it and manually install the package in R.
sPlot and highstock should work well!
(It will simply update the rCharts package with the Highstocks library)

@ramnathv
Copy link
Owner

@Vapri Thanks for your efforts in doing this. I was thinking more along the lines of creating a sister package rChartsHighstocks that would import rCharts as a dependency. This would allow you to maintain rChartsHighstocks independent of rCharts and not having to rewrite it. If you are interested, I can help set it up. Maybe @nemonominem will also be interested in this.

@asosnovsky
Copy link

yea sure, I am willing to help if you want to.

@asosnovsky
Copy link

email me at [email protected]

@danielkrizian
Copy link
Contributor

Please note, that this is planned feature of dygraph library in the near future:
https://github.com/danielkrizian/dygraphs/issues?state=open

I did research couple of months ago when looking for interactive time-series charting library, also compared highcharts vs dygraphs and settled for dygraphs for three reasons: friendlier licencing, fully open-sourced and speed (direct rendering on canvas, instead of SVG, which might get bogged down on dense datasets)

Plugins introduced recently include arrow annotations with popups (trading orders) and synchronized charts with crosshair (for multiple indicators):
http://rawgit.com/danielkrizian/dygraphs/master/tests/canvas-annotation-synchronize-series.html
http://rawgit.com/danielkrizian/rCharts_dygraphs/master/examples/multi-layout.html

Working R wrapper here (thank you @ramnathv & @timelyportfolio for indispensable kickstart advice):
https://github.com/danielkrizian/rCharts_dygraphs

If you decide to jump on the dygraphs bandwagon, let me know (danielDOTkrizianATgmail)

@ramnathv
Copy link
Owner

I would agree with @danielkrizian that dygraphs is a great choice due to speed and friendlier licensing. @danielkrizian has done some awesome work and I look forward to more people using the rChartsDygraph library as it develops.

@ramnathv
Copy link
Owner

@Vapri I will send you an email and copy to @nemonominem as well so you guys can get together to discuss the best way to put a rChartsHighStock package in place.

@asosnovsky
Copy link

Very excited for Dygraph, looks very nice.
I'd still want to make Highstock as a package though, already started working on it.
Though I wouldn't mind lending a hand on Dygraph. It looks like it has lots of potential.

@ramnathv
Copy link
Owner

I agree @Vapri that it makes sense to develop both packages. Highstocks is very refined, with cost probably being the only barrier. But then again, given that it is in the finance domain, cost may not be an issue for many firms.

@danielkrizian
Copy link
Contributor

Candlestick chart is now implemented in dygraphs, thanks to @pshevtsov

Demo here:
http://rawgit.com/danielkrizian/dygraphs/candlestick/tests/candlestick.html

Issue tracker if you are interested in tweaking it:
danielkrizian/dygraphs#11 (comment)

@ctrlbrk42
Copy link

I want to ask if @ramnathv has made progress on making a Highstock library. I just stumbled on Highstock today, and it is exactly what I need and have been trying to make Highcharts do. So instead of re-inventing the wheel, I am now looking for an R library for Highstock.

@ramnathv
Copy link
Owner

I don't have the bandwidth to focus on Highstock. If someone is interested in consolidating the Highstock efforts so far and create a highstocks binding, I would be happy to help and add it to rCharts.

@ctrlbrk42
Copy link

I am willing to kick in some $$ in a crowdsourced fundraiser if it will help to get this done.

@timelyportfolio
Copy link
Contributor

I would suggest having a peek at rChartsDygraphs . He has been doing a great job and has also kicked in some $ for help on the js side.

@ramnathv
Copy link
Owner

I think most of the work to integrate highstock has already been done.

https://github.com/Vapri/rChartsHighStockMod
https://github.com/nemonominem/Highstock-rCharts-hack

At this point, I believe it only requires to be cleaned up, documented and packaged appropriately. If anyone is interested, let me know.

@ctrlbrk42
Copy link

dygraphs looks good but I would rather stick with rCharts only because I am very familiar with Highcharts at this point, and assume Highstocks to be very similar. I do not have the skills to "clean up and package appropriately", so must rely on others to do this. I can only contribute $$$ to help expedite.

@KrysD
Copy link

KrysD commented Oct 21, 2015

Hi, I'm really interested by the work done to use Highstock library in rCharts.
is-it implemented for now in rCharts or did I need to use the hack standalone code ?

@danielkrizian
Copy link
Contributor

@KrysD, rCharts project has been abandoned and its main ideas restructured into www.htmlwidgets.org project AFAIK. Concerning candlesticks, R porting of dygraphs is now the actively maintained and developed route and implements the interactive time series charting on top of htmlwidgets plumbing.
Candlestick add-in under development is here

@KrysD
Copy link

KrysD commented Oct 21, 2015

O sad news !
Thank's @danielkrizian , i will take a look

@ramnathv
Copy link
Owner

@danielkrizian rCharts has not been abandoned. The ideas were ported to htmlwidgets to make a generic framework that would support creating javascript based widgets. I am in the process porting rCharts to the htmlwidgets framework and once that is complete, all functionality in rCharts will be available there and continue to be developed there.

@ramnathv
Copy link
Owner

@KrysD once I port rCharts, I will take a look at the highstock implementation. It should not be hard adding it to what is already out there currently.

@KrysD
Copy link

KrysD commented Oct 22, 2015

@ramnathv, it means I could continue to use rCharts nice !!!

@jbkunst
Copy link

jbkunst commented Jan 20, 2016

Hi everyone, @KrysD ,

If anyone still interested in highstock funcionalities you can check highcharter package.

Regards

screenshot_1

@KrysD
Copy link

KrysD commented Jan 20, 2016

Hi @jbkunst ,
i will check this, it look interesting.

@yash27
Copy link

yash27 commented Feb 9, 2018

Hi @Arbitrageur , can you please help me in making that candlestick highchart dynamic.

$(function() {
    $.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function(data) {
        // split the data set into ohlc and volume
        var ohlc = [],
            volume = [],
            dataLength = data.length;

        for (i = 0; i < dataLength; i++) {
            ohlc.push([
                data[i][0], // the date
                data[i][1], // open
                data[i][2], // high
                data[i][3], // low
                data[i][4] // close
            ]);

            volume.push([
                data[i][0], // the date
                data[i][5] // the volume
            ])
        }

        // set the allowed units for data grouping
        var groupingUnits = [[
            'week',                         // unit name
            [1]                             // allowed multiples
        ], [
            'month',
            [1, 2, 3, 4, 6]
        ]];

        // create the chart
        $('#container').highcharts('StockChart', {

            rangeSelector: {
                selected: 1
            },

            title: {
                text: 'AAPL Historical'
            },

            yAxis: [{
                title: {
                    text: 'OHLC'
                },
                height: 200,
                lineWidth: 2
            }, {
                title: {
                    text: 'Volume'
                },
                top: 300,
                height: 100,
                offset: 0,
                lineWidth: 2
            }],

            series: [{
                type: 'candlestick',
                name: 'AAPL',
                data: ohlc,
                dataGrouping: {
                    units: groupingUnits
                }
            }, {
                type: 'column',
                name: 'Volume',
                data: volume,
                yAxis: 1,
                dataGrouping: {
                    units: groupingUnits
                }
            }]
        });
    });
});

Dynamic in the sense that whatever data we're getting from the JSON file, that should come one by one after every second and using splice technique also we should remove the first data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests