sclass TradingCandlePainter extends ScaledDiagram { settable L candles; int spikeWidth = 1; Color shortColor = java.awt.Color.blue; Color longColor = java.awt.Color.yellow; new L positions; // how many lines are drawn to indicate percent changes settable double percentLineDistance = 0.05; BufferedImage render() { var run = new TradingRun(candles); verticalRange(doubleRange(run.min(), run.max())); horizontalRange(doubleRange(run.startTime().unixDate(), run.endTime().unixDate())); // Make black image var img = blackImage(w, h); var g = img.createGraphics(); // Draw percent lines double percentStep = center(verticalRange)*percentLineDistance/100; for (double y = verticalRange.start; y <= verticalRange.end; y += percentStep) { var yy = iround(yToScreen(y)); drawLine(g, 0, yy, w-1, yy, Color.gray); } // Draw candles var nCandles = l(candles); for i to nCandles: { var candle = candles.get(i); var x1 = xRange().start()+doubleRatio(i, nCandles)*xRange().length(); var x2 = xRange().start()+doubleRatio(i+1, nCandles)*xRange().length(); x2 = blend(x1, x2, 0.75); var xCenter = avg(x1, x2); var y1 = yToScreen(candle.max()); var y2 = yToScreen(candle.min()); var yStart = yToScreen(candle.start()); var yEnd = yToScreen(candle.end()); // draw "spikes" var r = doubleRectFromPoints(xCenter, y1, xCenter+spikeWidth, y2); fillRect(g, growRectBottom(1, toRect_round(r)), candle.color()); // draw candle body r = doubleRectFromPoints(x1, min(yStart, yEnd), x2, max(yStart, yEnd)); fillRect(g, growRectBottom(1, toRect_round(r)), candle.color()); } for (position : positions) { var time = position.openingTime(); var price = position.openingPrice(); var x = xToScreen(time); var y = yToScreen(price); var color = colorFromHex(position.relativeValue() > 0 ? "1da2b4" : "f1493f"); // Mark opening point fillRect(g, rectAroundPt(iround(x), iround(y), 10), color); if (not(position.isOpen())) { time = position.closingTime(); price = position.closingPrice(); var x2 = xToScreen(time); var y2 = yToScreen(price); drawArrowBetweenPoints(g, toPt_round(doublePt(x, y)), toPt_round(doublePt(x2, y2)), color); } } ret img; } }