UNPKG

bluebot

Version:

A bitcoin trading bot for auto trading at various exchanges

149 lines (115 loc) 4.3 kB
import _ from 'lodash' // techanjs based candle chart, unused at the moment export default function(_data, _trades) { let MAX_WIDTH = window.innerWidth - 20; var margin = {top: 20, right: 20, bottom: 30, left: 50}, width = MAX_WIDTH - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var x = techan.scale.financetime() .range([0, width]); var y = d3.scaleLinear() .range([height, 0]); var zoom = d3.zoom() .on("zoom", zoomed); var zoomableInit; var candlestick = techan.plot.candlestick() .xScale(x) .yScale(y); var tradearrow = techan.plot.tradearrow() .xScale(x) .yScale(y) .orient(function(d) { return d.type.startsWith("buy") ? "up" : "down"; }) .on("mouseenter", enter) .on("mouseout", out); var xAxis = d3.axisBottom(x); var yAxis = d3.axisLeft(y); var svg = d3.select("#chart").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 + ")"); svg.append("clipPath") .attr("id", "clip") .append("rect") .attr("x", 0) .attr("y", y(1)) .attr("width", width) .attr("height", y(0) - y(1)); svg.append("g") .attr("class", "candlestick") .attr("clip-path", "url(#clip)"); svg.append("g") .attr("class", "tradearrow") .attr("clip-path", "url(#clip)"); 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)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Price ($)"); svg.append("rect") .attr("class", "pane") .attr("width", width) .attr("height", height) .call(zoom); var accessor = candlestick.accessor(); const data = _data.map(function(d) { return { date: new Date(d.start), 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)); }); const trades = _trades.map(function(t) { let trade = _.pick(t, ['price']); trade.quantity = 1; trade.type = t.action; trade.date = new Date(t.date); return trade; }); console.log(trades); x.domain(data.map(accessor.d)); y.domain(techan.scale.plot.ohlc(data, accessor).domain()); svg.select("g.tradearrow").datum(trades); svg.select("g.candlestick").datum(data); draw(); // Associate the zoom with the scale after a domain has been applied // Stash initial settings to store as baseline for zooming zoomableInit = x.zoomable().clamp(false).copy(); function zoomed() { var rescaledY = d3.event.transform.rescaleY(y); yAxis.scale(rescaledY); candlestick.yScale(rescaledY); tradearrow.yScale(rescaledY); // Emulates D3 behaviour, required for financetime due to secondary zoomable scale x.zoomable().domain(d3.event.transform.rescaleX(zoomableInit).domain()); draw(); } function draw() { svg.select("g.tradearrow").call(tradearrow); svg.select("g.candlestick").call(candlestick); // using refresh method is more efficient as it does not perform any data joins // Use this if underlying data is not changing // svg.select("g.candlestick").call(candlestick.refresh); svg.select("g.x.axis").call(xAxis); svg.select("g.y.axis").call(yAxis) } function enter(d) { valueText.style("display", "inline"); refreshText(d); } function out() { valueText.style("display", "none"); } function refreshText(d) { valueText.text("Trade: " + dateFormat(d.date) + ", " + d.type + ", " + valueFormat(d.price)); } };