asclass AbstractTickerPainter extends ScaledDiagram is G2Drawable { // how many lines are drawn to indicate percent changes settable double percentLineDistance = 0.1; settable bool drawPercentLines = true; new L positions; new L additionalObjects; BufferedImage render() { // Make black image var img = blackImage(w, h); var g = img.createGraphics(); drawOn(g); ret img; } void drawPercentLines(Graphics2D g) { if (!drawPercentLines || percentLineDistance == 0) ret; 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); } } void drawPositions(Graphics2D g) { for (position : positions) { var time = position.openingTime(); var price = position.openingPrice(); var x = xToScreen(time); var y = yToScreen(price); //bool green = position.relativeValue() > 0; bool green = position.isLong(); var color = colorFromHex(green ? "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); } } } void drawAdditionalObjects(Graphics2D g) { for (o : additionalObjects) o.drawOn(g); } void addVerticalLine(double x, Color color default Color.gray) { additionalObjects.add(g -> drawVerticalLine(g, x, color)); } void drawVerticalLine(Graphics2D g, double x, Color color default Color.gray) { int xScreen = iround(xToScreen(x)); drawLine(g, xScreen, 0, xScreen, h-1, color); } DoubleRange horizontalRangeForTicker(TickerSequence ticker) { var timeRange = ticker.timeRange(); ret doubleRange(timeRange.startTime().unixDate(), timeRange.endTime().unixDate()); } DoubleRange verticalRangeForTicker(TickerSequence ticker) { ret doubleRange(ticker.minPrice(), ticker.maxPrice()); } void drawTimeGrid(Graphics2D g, double minutes) { double ms = minutesToMS(minutes); assertTrue(ms >= 100); double time = roundUpTo(ms, horizontalRange().start); while (time < horizontalRange().end) { drawVerticalLine(g, time); time += ms; } } }