【Python】D3.js でWEBページにローソク足チャートを描画する
おはようございます。
大分間が空いてしまいました。なんだか極端ですね。
予定通り、D3.jsとTechan.js を使ってチャートの描画をしてみました。
プログラムは前回のものを流用します。
スポンサーリンク
目次
画面の修正
描画用のライブラリ読み込み
「head」要素に次の記述を追加
Main.html
1 2 | <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
1 2 3 4 5 6 7 8 9 10 | <div style="clear:both; padding-top:10px;"> <div class="entry_title"> <div class="pull_left">ローソク足チャート</div> <div class="pull_right"> <input type="button"value="更新"onclick="updateChart();" /> </div> </div> <div id="chartContainer"> </div> </div> |
スタイルの追加
style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** * ローソク足チャート用の定義 */ 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | classGetOhlcJson(RequestHandler): """ OHLC情報を取得 """ definitialize(self): logging.info("GetOhlcJson [initialize]") defget(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')formi inrange(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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | /** * JSON形式でローソク足情報を取得して表示. */ functionupdateChart(){ // 表示領域の設定 varmargin={top:20,right:20,bottom:30,left:50}, width=960-margin.left-margin.right, height=500-margin.top-margin.bottom; // 日付変換メソッド varparseDate=d3.timeParse("%Y-%m-%d %H:%M:%S"); // 横軸の設定 varx=techan.scale.financetime() .range([0,width]); // 縦軸の設定 vary=d3.scaleLinear() .range([height,0]); // ローソク足の設定 varcandlestick=techan.plot.candlestick() .xScale(x) .yScale(y); varxAxis=d3.axisBottom() .scale(x) .tickFormat(d3.timeFormat("%H:%M"))// 分足なので、時:分表示にする .ticks(5)// 5データずつにメモリ表示; varyAxis=d3.axisLeft() .scale(y); // チャートをクリアしてから表示 if($("#chartContainer svg").length) { $("#chartContainer svg").remove(); } varsvg=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){ // 日時で並び替えを行う varaccessor=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){returnd3.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)); }); /** * 描画関数 */ functiondraw(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分単位で再描画すればリアルタイムチャートになりそうですね。
まとめ
次回は取引高や移動平均線なんかもやってみたいと思います。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません