techan.jsとd3.jsを使ってjqueryでロウソク足を表示

2015年10月26日更新 view: 372 view
matomater-original

ロウソク足を表示してみる

一番上に表示してあるのがサンプル。

色などはCSSで変更できる。

ロウソク足表示ライブラリはたくさんあるみたいだが、

・ロウソク足
・出来高
・移動平均線 (5日線 , 25日線)

の3つをjqueryで表示してみる

以下をコピペで動くはず

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
font: 10px sans-serif;
}

.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}

text.symbol {
fill: #BBBBBB;
}

path {
fill: none;
stroke-width: 1;
}

path.candle {
stroke: #000000;
}

path.candle.body {
stroke-width: 0;
}

path.candle.up {
fill: #00AA00;
stroke: #00AA00;
}

path.candle.down {
fill: #FF0000;
stroke: #FF0000;
}

.close.annotation.up path {
fill: #00AA00;
}

path.volume {
fill: #DDDDDD;
}

.indicator-plot path.line {
fill: none;
stroke-width: 1;
}

.ma-0 path.line {
stroke: #1f77b4;
}

.ma-1 path.line {
stroke: #aec7e8;
}

.ma-2 path.line {
stroke: #ff7f0e;
}

button {
position: absolute;
right: 110px;
top: 25px;
}

path.macd {
stroke: #0000AA;
}

path.signal {
stroke: #FF9999;
}

path.zero {
stroke: #BBBBBB;
stroke-dasharray: 0;
stroke-opacity: 0.5;
}

path.difference {
fill: #BBBBBB;
opacity: 0.5;
}

path.rsi {
stroke: #000000;
}

path.overbought, path.oversold {
stroke: #FF9999;
stroke-dasharray: 5, 5;
}

path.middle, path.zero {
stroke: #BBBBBB;
stroke-dasharray: 5, 5;
}

.analysis path, .analysis circle {
stroke: blue;
stroke-width: 0.8;
}

.trendline circle {
stroke-width: 0;
display: none;
}

.mouseover .trendline path {
stroke-width: 1.2;
}

.mouseover .trendline circle {
stroke-width: 1;
display: inline;
}

.dragging .trendline path, .dragging .trendline circle {
stroke: darkblue;
}

.interaction path, .interaction circle {
pointer-events: all;
}

.interaction .body {
cursor: move;
}

.trendlines .interaction .start, .trendlines .interaction .end {
cursor: nwse-resize;
}

.supstance path {
stroke-dasharray: 2, 2;
}

.supstances .interaction path {
pointer-events: all;
cursor: ns-resize;
}

.mouseover .supstance path {
stroke-width: 1.5;
}

.dragging .supstance path {
stroke: darkblue;
}

.crosshair {
cursor: crosshair;
}

.crosshair path.wire {
stroke: #DDDDDD;
stroke-dasharray: 1, 1;
}

.crosshair .axisannotation path {
fill: #DDDDDD;
}

</style>
<body>
<button>Reset</button>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://techanjs.org/techan.min.js"></script>
<script>

var TITLE = "日経平均";

var dim = {
width: 960, height: 500,
margin: { top: 20, right: 50, bottom: 30, left: 50 },
ohlc: { height: 305 },
indicator: { height: 65, padding: 5 }
};
dim.plot = {
width: dim.width - dim.margin.left - dim.margin.right,
height: dim.height - 195
};
dim.indicator.top = dim.ohlc.height+dim.indicator.padding;
dim.indicator.bottom = dim.indicator.top+dim.indicator.height+dim.indicator.padding;

var indicatorTop = d3.scale.linear()
.range([dim.indicator.top, dim.indicator.bottom]);

// var parseDate = d3.time.format("%d-%b-%y").parse;
var parseDate = d3.time.format("%Y-%m-%d").parse;



var zoom = d3.behavior.zoom()
.on("zoom", draw);

var zoomPercent = d3.behavior.zoom();

var x = techan.scale.financetime()
.range([0, dim.plot.width]);

var y = d3.scale.linear()
.range([dim.ohlc.height, 0]);

var yPercent = y.copy(); // Same as y at this stage, will get a different domain later

var yVolume = d3.scale.linear()
.range([y(0), y(0.2)]);//出来高をどれだけ大きく表示するか

var candlestick = techan.plot.candlestick()
.xScale(x)
.yScale(y);

var sma0 = techan.plot.sma()
.xScale(x)
.yScale(y);

var sma1 = techan.plot.sma()
.xScale(x)
.yScale(y);

var ema2 = techan.plot.ema()
.xScale(x)
.yScale(y);

var volume = techan.plot.volume()
.accessor(candlestick.accessor()) // Set the accessor to a ohlc accessor so we get highlighted bars
.xScale(x)
.yScale(yVolume);



var xAxis = d3.svg.axis()
.scale(x)
.tickFormat(d3.time.format("%m/%d"))//横軸の日時表示
.orient("bottom");















var timeAnnotation = techan.plot.axisannotation()
.axis(xAxis)
.format(d3.time.format('%Y-%m-%d'))
.width(65)
.translate([0, dim.plot.height]);

var yAxis = d3.svg.axis()
.scale(y)
.orient("left");

var ohlcAnnotation = techan.plot.axisannotation()
.axis(yAxis)
.format(d3.format(',.2fs'))
.translate([0, 0]);


var volumeAxis = d3.svg.axis()
.scale(yVolume)
.orient("left")
.ticks(0)
.tickFormat(d3.format(",.3s"));

var volumeAnnotation = techan.plot.axisannotation()
// .axis(volumeAxis)
.width(35);


var ohlcCrosshair = techan.plot.crosshair()
.xScale(timeAnnotation.axis().scale())
.yScale(ohlcAnnotation.axis().scale())
.xAnnotation(timeAnnotation)
.yAnnotation([ohlcAnnotation, volumeAnnotation])
.verticalWireRange([0, dim.plot.height]);


var svg = d3.select("body").append("svg")
.attr("width", dim.width)
.attr("height", dim.height);

var defs = svg.append("defs");

defs.append("clipPath")
.attr("id", "ohlcClip")
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", dim.plot.width)
.attr("height", dim.ohlc.height);

defs.selectAll("indicatorClip").data([0, 1])
.enter()
.append("clipPath")
.attr("id", function(d, i) { return "indicatorClip-" + i; })
.append("rect")
.attr("x", 0)
.attr("y", function(d, i) { return indicatorTop(i); })
.attr("width", dim.plot.width)
.attr("height", dim.indicator.height);

svg = svg.append("g")
.attr("transform", "translate(" + dim.margin.left + "," + dim.margin.top + ")");

svg.append('text')
.attr("class", "symbol")
.attr("x", 20)
.text(TITLE);

svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + dim.plot.height + ")");

var ohlcSelection = svg.append("g")
.attr("class", "ohlc")
.attr("transform", "translate(0,0)");

ohlcSelection.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,0)")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -12)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("");

ohlcSelection.append("g")
.attr("class", "close annotation up");

ohlcSelection.append("g")
.attr("class", "volume")
.attr("clip-path", "url(#ohlcClip)");

ohlcSelection.append("g")
.attr("class", "candlestick")
.attr("clip-path", "url(#ohlcClip)");

ohlcSelection.append("g")
.attr("class", "indicator sma ma-0")
.attr("clip-path", "url(#ohlcClip)");

ohlcSelection.append("g")
.attr("class", "indicator sma ma-1")
.attr("clip-path", "url(#ohlcClip)");

ohlcSelection.append("g")
.attr("class", "indicator ema ma-2")
.attr("clip-path", "url(#ohlcClip)");

ohlcSelection.append("g")
.attr("class", "percent axis");

ohlcSelection.append("g")
.attr("class", "volume axis");

var indicatorSelection = svg.selectAll("svg > g.indicator").data(["macd", "rsi"]).enter()
.append("g")
.attr("class", function(d) { return d + " indicator"; });

indicatorSelection.append("g")
.attr("class", "axis right")
.attr("transform", "translate(" + x(1) + ",0)");

indicatorSelection.append("g")
.attr("class", "axis left")
.attr("transform", "translate(" + x(0) + ",0)");

indicatorSelection.append("g")
.attr("class", "indicator-plot")
.attr("clip-path", function(d, i) { return "url(#indicatorClip-" + i + ")"; });

// Add trendlines and other interactions last to be above zoom pane
svg.append('g')
.attr("class", "crosshair ohlc");


d3.select("button").on("click", reset);












data = [{"Date":"2015-01-05","Open":17325.7,"High":17540.9,"Low":17219.2,"Close":17408.7,"Volume":873},{"Date":"2015-01-06","Open":17101.6,"High":17111.4,"Low":16881.7,"Close":16883.2,"Volume":145},{"Date":"2015-01-07","Open":16808.3,"High":16974.6,"Low":16808.3,"Close":16885.3,"Volume":841},{"Date":"2015-01-08","Open":17067.4,"High":17243.7,"Low":17016.1,"Close":17167.1,"Volume":294},{"Date":"2015-01-09","Open":17318.7,"High":17342.7,"Low":17129.5,"Close":17197.7,"Volume":176},{"Date":"2015-01-13","Open":16970.9,"High":17087.7,"Low":16828.3,"Close":17087.7,"Volume":148},{"Date":"2015-01-14","Open":16961.8,"High":17036.7,"Low":16770.6,"Close":16796,"Volume":860},{"Date":"2015-01-15","Open":16872.9,"High":17142,"Low":16856.2,"Close":17108.7,"Volume":206},{"Date":"2015-01-16","Open":16813,"High":16864.3,"Low":16592.6,"Close":16864.2,"Volume":446},{"Date":"2015-01-19","Open":17000.8,"High":17039.8,"Low":16911.6,"Close":17014.3,"Volume":476},{"Date":"2015-01-20","Open":17071.7,"High":17366.3,"Low":17066.8,"Close":17366.3,"Volume":799}]





// A-0 A-1とともにコメントアウトを外すとCSVから読み込む 1つめ
// d3.csv("/js/data2.csv", function(error, data) {

var accessor = candlestick.accessor(),
indicatorPreRoll = 0; // 移動平均線を計算するために多く読み込んでおく。最初のCSVデータの33個はロウソク足として表示されない。

data = data.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)); });

x.domain(techan.scale.plot.time(data).domain());
y.domain(techan.scale.plot.ohlc(data.slice(indicatorPreRoll)).domain());
yVolume.domain(techan.scale.plot.volume(data).domain());


svg.select("g.candlestick").datum(data).call(candlestick);
svg.select("g.volume").datum(data).call(volume);
svg.select("g.sma.ma-0").datum(techan.indicator.sma().period(5)(data)).call(sma0);
svg.select("g.sma.ma-1").datum(techan.indicator.sma().period(25)(data)).call(sma1);

svg.select("g.crosshair.ohlc").call(ohlcCrosshair).call(zoom);


var zoomable = x.zoomable();
zoomable.domain([indicatorPreRoll, data.length]); // Zoom in a little to hide indicator preroll

draw();

// A-1 A-0と共にコメントアウトを外すとCSVから読み込む
// });

























function reset() {
zoom.scale(1);
zoom.translate([0,0]);
draw();
}

function draw() {
zoomPercent.translate(zoom.translate());
zoomPercent.scale(zoom.scale());

svg.select("g.x.axis").call(xAxis);
svg.select("g.ohlc .axis").call(yAxis);
svg.select("g.volume.axis").call(volumeAxis);

svg.select("g.candlestick").call(candlestick.refresh);
svg.select("g.volume").call(volume.refresh);
svg.select("g .sma.ma-0").call(sma0.refresh);
svg.select("g .sma.ma-1").call(sma1.refresh);
svg.select("g .ema.ma-2").call(ema2.refresh);

svg.select("g.crosshair.ohlc").call(ohlcCrosshair.refresh);


}

</script>
スポンサードリンク

A-1 A-0と共にコメントアウトを外すとCSVから読み込む
の所のコメントアウトを外せば指定したCSVからデータを読み込むようになる。

スポンサードリンク

関連記事

関連カテゴリ

コロ助

web関連の記事や制作系の記事をどんどんまとめていきます。 宜しくお願いします!

ピックアップ

パソコン・ソフトウェア ランキング

7月22日 ( 月 ) にアクセスが多かった記事はこちら!