简体   繁体   中英

Creating candlestick chart with Yahoo Api

I have found following code that creates candlestick stock charts using Yahoo Api.

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.25.0"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.time.js?1.25.0"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  </head>
  <body>

    <div id="chart"></div>

    <script type="text/javascript">
      var width = 900;
      var height = 500;
       String.prototype.format = function() {
        var formatted = this;
        for (var i = 0; i < arguments.length; i++) {
          var regexp = new RegExp('\\{'+i+'\\}', 'gi');
          formatted = formatted.replace(regexp, arguments[i]);
    }
    return formatted;
      };


      var dateFormat = d3.time.format("%Y-%m-%d");
      var end = new Date();
      var start = new Date(end.getTime() - 1000 * 60 * 60 * 24 * 60);
      var data = [];

      function min(a, b){ return a < b ? a : b ; }

      function max(a, b){ return a > b ? a : b; }    

      function buildChart(data){        

          var margin = 50;         

      var chart = d3.select("#chart")
          .append("svg:svg")
          .attr("class", "chart")
          .attr("width", width)
          .attr("height", height);
      var y = d3.scale.linear()
          .domain([d3.min(data.map(function(x) {return x["Low"];})), d3.max(data.map(function(x){return x["High"];}))])
          .range([height-margin, margin]);
      var x = d3.scale.linear()
          .domain([d3.min(data.map(function(d){return dateFormat.parse(d.Date).getTime();})),
               d3.max(data.map(function(d){return dateFormat.parse(d.Date).getTime();}))])
          .range([margin,width-margin]);

          chart.selectAll("line.x")
           .data(x.ticks(10))
           .enter().append("svg:line")
           .attr("class", "x")
           .attr("x1", x)
           .attr("x2", x)
           .attr("y1", margin)
           .attr("y2", height - margin)
           .attr("stroke", "#ccc");

          chart.selectAll("line.y")
           .data(y.ticks(10))
           .enter().append("svg:line")
           .attr("class", "y")
           .attr("x1", margin)
           .attr("x2", width - margin)
           .attr("y1", y)
           .attr("y2", y)
           .attr("stroke", "#ccc");

          chart.selectAll("text.xrule")
           .data(x.ticks(10))
           .enter().append("svg:text")
           .attr("class", "xrule")
           .attr("x", x)
           .attr("y", height - margin)
           .attr("dy", 20)
           .attr("text-anchor", "middle")
           .text(function(d){ var date = new Date(d * 1000);  return (date.getMonth() + 1)+"/"+date.getDate(); });

         chart.selectAll("text.yrule")
          .data(y.ticks(10))
          .enter().append("svg:text")
          .attr("class", "yrule")
          .attr("x", width - margin)
          .attr("y", y)
          .attr("dy", 0)
          .attr("dx", 20)        
          .attr("text-anchor", "middle")
          .text(String);

    chart.selectAll("rect")
      .data(data)
      .enter().append("svg:rect")
      .attr("x", function(d) { return x(dateFormat.parse(d.Date).getTime()); })
          .attr("y", function(d) {return y(max(d.Open, d.Close));})       
      .attr("height", function(d) { return y(min(d.Open, d.Close))-y(max(d.Open, d.Close));})
      .attr("width", function(d) { return 0.5 * (width - 2*margin)/data.length; })
          .attr("fill",function(d) { return d.Open > d.Close ? "red" : "green" ;});

        chart.selectAll("line.stem")
          .data(data)
          .enter().append("svg:line")
          .attr("class", "stem")
          .attr("x1", function(d) { return x(dateFormat.parse(d.Date).getTime()) + 0.25 * (width - 2 * margin)/ data.length;})
          .attr("x2", function(d) { return x(dateFormat.parse(d.Date).getTime()) + 0.25 * (width - 2 * margin)/ data.length;})          
          .attr("y1", function(d) { return y(d.High);})
          .attr("y2", function(d) { return y(d.Low); })
          .attr("stroke", function(d){ return d.Open > d.Close ? "red" : "green"; })

      }       


      function appendToData(x){
    if(data.length > 0){
        return;
        }
        data = x.query.results.quote;
        for(var i=0;i<data.length;i++){
          data[i].timestamp = (new Date(data[i].date).getTime() / 1000);
        }         
        data = data.sort(function(x, y){ return dateFormat.parse(x.Date).getTime() - dateFormat.parse(y.Date).getTime(); });            
        buildChart(data);         
      }

      function buildQuery(){
        var symbol = window.location.hash;
        if(symbol === ""){
           symbol = "AMZN";
        }
        symbol = symbol.replace("#", "");         
        var base = "select * from yahoo.finance.historicaldata where symbol = \"{0}\" and startDate = \"{1}\" and endDate = \"{2}\"";
        var getDateString = d3.time.format("%Y-%m-%d");
        var query = base.format(symbol, getDateString(start), getDateString(end));
        query = encodeURIComponent(query);          
        var url = "http://query.yahooapis.com/v1/public/yql?q={0}&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=appendToData".format(query);
        return url;
      }
      function fetchData(){       
        url = buildQuery();       
        scriptElement = document.createElement("SCRIPT");
        scriptElement.type = "text/javascript";
        // i add to the url the call back function
        scriptElement.src = url;
        document.getElementsByTagName("HEAD")[0].appendChild(scriptElement);
      }

      $(document).ready(fetchData);

    </script>
  </body>
</html>

Unfortunatley this chart only shows the last few weeks of the Amazon stock.Now I would like to change the chart so it shows me 1 year chart of Amazon. What parameters do I have to change?

change

var start = new Date(end.getTime() - 1000 * 60 * 60 * 24 * 60);

to:

var start = new Date(end.getTime() - 1000 * 60 * 60 * 24 * 365);

because the last number is how many days it will take.

Unfortunatly your solution doesnt provide the result I am in search for. Instead I tried out couple of numbers and here is how you can get a 1 year chart.

Change the line to

var start = new Date(end.getTime() - 18200 * 60 * 20 * 24 * 60);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM