【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分単位で再描画すればリアルタイムチャートになりそうですね。
まとめ
次回は取引高や移動平均線なんかもやってみたいと思います。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません