【Python】D3.js でWEBページにローソク足チャートを描画する
おはようございます。
大分間が空いてしまいました。なんだか極端ですね。
予定通り、D3.jsとTechan.js を使ってチャートの描画をしてみました。
プログラムは前回のものを流用します。
スポンサーリンク
目次
画面の修正
描画用のライブラリ読み込み
「head」要素に次の記述を追加
Main.html
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="http://techanjs.org/techan.min.js"></script>
チャート表示領域の追加
資産情報の下に表示用の領域を追加します。
Main.html
<div style="clear:both; padding-top:10px;">
<div class="entry_title">
<div class="pull_left">ローソク足チャート</div>
<div class="pull_right">
<input type="button" value="更新" />
</div>
</div>
<div id="chartContainer">
</div>
</div>
スタイルの追加
style.css
/**
* ローソク足チャート用の定義
*/
text {
fill: #000;
}
path.candle {
stroke: #000000;
}
path.candle.body {
stroke-width: 0;
}
path.candle.up {
fill: #00AA00;
stroke: #00AA00;
}
path.candle.down {
fill: #FF0000;
stroke: #FF0000;
}
プログラム修正
サーバー側
OHLCの情報をJSON形式に変換して返すメソッドを追加
BfTool.py
class GetOhlcJson(RequestHandler):
"""
OHLC情報を取得
"""
def initialize(self):
logging.info("GetOhlcJson [initialize]")
def get(self):
logging.info("GetOhlcJson [post]")
api = BfApi()
# 過去1時間のデータを取得
end = datetime.now()
start = end - timedelta(hours=2)
df = api.get_ohlc(start=start, end=end, span=60)
# X軸に表示するための時間配列を生成
dates = [(start + timedelta(minutes=mi)).strftime('%Y-%m-%d %H:%M:%S') for mi in range(121)]
# Json形式に変換
data = pd.DataFrame({'Date': dates, 'Open': df[1], 'High': df[2], 'Low': df[3], 'Close': df[4], 'Vlume': df[5]})
self.write(data.to_json(orient="records"))URLマッピングの追加
BfTool.py
app = tornado.web.Application([
(r"/", MainHandler),
(r"/ws", SendWebSocket),
(r"/balance", GetBalanceHandler),
(r"/execution", GetExecutionHandler),
(r"/childOrder", GetChildOrderHandler),
(r"/sendOrder", SendChildOrderHandler),
(r"/cancelOrder", CancelChildOrderHandler),
(r"/sendTicker", SendTicker),
(r"/startTicker", StartTicker),
(r"/stopTicker", StopTicker),
(r"/sendLine", SendLine),
(r"/getTicker", GetTicker),
(r"/getOhlc", GetOhlc),
(r"/getOhlcJson", GetOhlcJson)
],
template_path=os.path.join(os.getcwd(), "templates"),
static_path=os.path.join(os.getcwd(), "static"),
js_path=os.path.join(os.getcwd(), "js"),
)クライアント側
JSONデータを取得し、D3.js でチャートを描画する処理を追加
script.js
/**
* JSON形式でローソク足情報を取得して表示.
*/
function updateChart() {
// 表示領域の設定
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// 日付変換メソッド
var parseDate = d3.timeParse("%Y-%m-%d %H:%M:%S");
// 横軸の設定
var x = techan.scale.financetime()
.range([0, width]);
// 縦軸の設定
var y = d3.scaleLinear()
.range([height, 0]);
// ローソク足の設定
var candlestick = techan.plot.candlestick()
.xScale(x)
.yScale(y);
var xAxis = d3.axisBottom()
.scale(x)
.tickFormat(d3.timeFormat("%H:%M")) // 分足なので、時:分表示にする
.ticks(5) // 5データずつにメモリ表示;
var yAxis = d3.axisLeft()
.scale(y);
// チャートをクリアしてから表示
if ($("#chartContainer svg").length)
{
$("#chartContainer svg").remove();
}
var svg = d3.select("#chartContainer").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// サーバーからJSONデータを取得し、コールバック関数で描画処理を実施
d3.json("getOhlcJson", function(error, data) {
// 日時で並び替えを行う
var accessor = candlestick.accessor();
data = data.slice(0, 200).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)); });
// ページに要素を追加していく
svg.append("g")
.attr("class", "candlestick");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
svg.append("g")
.attr("class", "y axis")
.append("text")
.attr("transform", "rotate(-90)") // Y軸ラベルを縦書きに
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("価格(円)");
draw(data.slice(0, data.length-20));
});
/**
* 描画関数
*/
function draw(data) {
x.domain(data.map(candlestick.accessor().d));
y.domain(techan.scale.plot.ohlc(data, candlestick.accessor()).domain());
svg.selectAll("g.candlestick").datum(data).call(candlestick);
svg.selectAll("g.x.axis").call(xAxis);
svg.selectAll("g.y.axis").call(yAxis);
}
}上記メソッドを画面起動時に呼び出せばOKです。
起動してみる
無事に描画されました。
とりあえずは起動時のみですが、1分単位で再描画すればリアルタイムチャートになりそうですね。
まとめ
次回は取引高や移動平均線なんかもやってみたいと思います。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません