andredumas / techan.js

A visual, technical analysis and charting (Candlestick, OHLC, indicators) library built on D3.
http://techanjs.org/
MIT License
2.39k stars 534 forks source link

Help please! #239

Open wilburforce83 opened 5 years ago

wilburforce83 commented 5 years ago

Hello everyone, I have just discovered this chart library, and I think it is exactly what I am looking for, but I just don't understand the data feed side of it. I have data streaming in an array of {epoch, open, high, low, close] It appends the latest candle and drops the earliest one off limiting it to 200 candles.

My question is to do with all the examples being from a .csv. I don't understand how I can replace this following section of code with my dynamic array:


    d3.csv("data.csv", function(error, csv) {
        var accessor = ohlc.accessor();

        feed = csv.map(function(d) {
            return {
                date: parseDate(d.Date),
                open: +d.Open,
                high: +d.High,
                low: +d.Low,
                close: +d.Close,
                volume: +d.Volume
            };
        }).sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); });

        // Start off an initial set of data
        redraw(feed.slice(0, 163));
    });

    function redraw(data) {
        var accessor = ohlc.accessor();

        x.domain(data.map(accessor.d));
        // Show only 150 points on the plot
        x.zoomable().domain([data.length-130, data.length]);

        // Update y scale min max, only on viewable zoomable.domain()
        y.domain(techan.scale.plot.ohlc(data.slice(data.length-130, data.length)).domain());
        yVolume.domain(techan.scale.plot.volume(data.slice(data.length-130, data.length)).domain());

        // Setup a transition for all that support
        svg
//          .transition() // Disable transition for now, each is only for transitions
            .each(function() {
                var selection = d3.select(this);
                selection.select('g.x.axis').call(xAxis);
                selection.select('g.y.axis').call(yAxis);
                selection.select("g.volume.axis").call(volumeAxis);

                selection.select("g.candlestick").datum(data).call(ohlc);
                selection.select("g.sma.ma-0").datum(sma0Calculator(data)).call(sma0);
                selection.select("g.sma.ma-1").datum(sma1Calculator(data)).call(sma1);
                selection.select("g.volume").datum(data).call(volume);

                svg.select("g.crosshair.ohlc").call(crosshair);
            });

        // Set next timer expiry
        setTimeout(function() {
            var newData;

            if(data.length < feed.length) {
                // Simulate a daily feed
                newData = feed.slice(0, data.length+1);
            }
            else {
                // Simulate intra day updates when no feed is left
                var last = data[data.length-1];
                // Last must be between high and low
                last.close = Math.round(((last.high - last.low)*Math.random())*10)/10+last.low;

                newData = data;
            }

            redraw(newData);
        }, (Math.random()*1000)+400); // Randomly pick an interval to update the chart
    }

    function move(coords) {
        coordsText.text(
                timeAnnotation.format()(coords.x) + ", " + ohlcAnnotation.format()(coords.y)
        );
    }

Any help or advice would be hugely appreciated!!

Thanks!

Will

matricore commented 5 years ago

Hi Will, I think you receive your data from a websocket connection. Pass your data on a global variable and call it from your settimeout function like below:

       ` var ndata = maindata.map(function(d) {

              darray = d.split(",");
                if (inter == 1) {
                    timestring = yyyy+"-"+(mm+1)+"-"+dd+"T" + darray[4];
                }
                else if (inter == 5 || inter == 15 || inter == 30 || inter == 60 || inter == 242) {
                        //1.2397,1.2429,1.2397,1.2426,3/28/2018 5:00:00 AM
                        var dateside = darray[4].split("T");

                        var datesidestring = dateside[0].split("/");
                        timestring = datesidestring[2]+"-"+datesidestring[0]+"-"+datesidestring[1]+"T" + dateside[1];

                }       
                else 
                {
                        // 1/2/2017
                        var ds = darray[4];
                        var datestrings = ds.split("/");
                        var newds = datestrings[2]+"-"+datestrings[0]+"-"+datestrings[1];
                        timestring = newds + "T12:00:00";
                        //console.log(timestring);
                }

              return {
                  date: parseDate(timestring),
                  open: +darray[0],
                  high: +darray[2],
                  low: +darray[3],
                  close: +darray[1],
                  volume: +darray[3]
              };

    }).sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); }); `

Tezcan

wilburforce83 commented 5 years ago

@matricore Thank you so much for the quick response. I'll have a look and try this out.

Would you mind helping me out if I get stuck? I'm quite new to js so there are a few things I don't fully understand yet.

Thanks again!

wilburforce83 commented 5 years ago

@matricore Okay, so I spent longer than I feel I should admit trying to get this work last night. I am missing something really simple, but I just can't get my head around it. I'm going to try and share as much info as possible in the hope that you might see the problem straight away!!

I have made a real mess of it think!!

So, you are correct, I am collecting the data from a websocket, I've created a paste of my whole page script, which includes the data acquisition for the array, just to put it all in one place, it is normally in a separate js file.

Please don't feel like you have to help me, but if you could possibly take a look at my code and maybe guide me on how to get it working, I be hugely appreciative. I am so keen to learn, but I am really struggling with this!

https://basilisk-design.co.uk/pastebin/paste.php?id=18

thank you so much in advance!!

Will

GreatGranPa commented 5 years ago

I think the easiest way would be to translate your input into the format that Techan usually uses. ie date ohlc. Don't be afraid to use the good old Print F Debugger... only when you are 100% sure that your input is of the same format feed it into techan. Best, U-------- Ursprüngliche Nachricht --------Betreff: Re: [andredumas/techan.js] Help please! (#239)Von: Will An: "andredumas/techan.js" Cc: Subscribed @matricore Okay, so I spent longer than I feel I should admit trying to get this work last night. I am missing something really simple, but I just can't get my head around it. I'm going to try and share as much info as possible in the hope that you might see the problem straight away!! I have made a real mess of it think!! So, you are correct, I am collecting the data from a websocket, I've created a paste of my whole page script, which includes the data acquisition for the array, just to put it all in one place, it is normally in a separate js file. Please don't feel like you have to help me, but if you could possibly take a look at my code and maybe guide me on how to get it working, I be hugely appreciative. I am so keen to learn, but I am really struggling with this! https://basilisk-design.co.uk/pastebin/paste.php?id=18 thank you so much in advance!! Will

—You are receiving this because you are subscribed to this thread.Reply to this email directly, view it on GitHub, or mute the thread.

wilburforce83 commented 5 years ago

@GreatGranPa thank you for your quick response!

I'll be honest, I think I am out of my depth at the moment! I am looking at using the chart within a larger project, and I am just learning JS in the process. I think what I am going to do is work on the rest of the project (which I am learning a lot while doing) and come back to the charting once I have more experience under my belt!!

Thanks guys!