sclass JTickerView is Swingable { settable S coin; settable TickerSequence ticker; settable AbstractTickerPainter painter; settable IImageSurfaceMaker imageSurfaceMaker = -> imageSurfaceWithToolTip(); settable ImageSurface isTicker; settable G22TradingStrategy strategy; JSlider timeZoomSlider = jSlider(1, 10, 1); ReliableSingleThread rstPaint = rst(l0 repaintImpl); swappable void makePainter() { painter = new TickerGraphPainter; painter.w(300*intFromSlider(timeZoomSlider)).h(200); painter.ticker(ticker); painter.drawPercentLines(false); /*painter.horizontalRange( transformBetweenDoubleRanges (varTimeZoom get) (zeroToOne) (painter horizontalRangeForTicker ticker) zoomedRange <- transformBetweenDoubleRanges (varTimeZoom get) (zeroToOne) (toDoubleRange < ticker timeRange) painter verticalRange < painter verticalRangeForTicker (ticker subSequenceByTimestamps (lround < zoomedRange start) (lround < zoomedRange end)) */ //painter.additionalObjects.add(g -> painter drawTimeGrid(g, 60)); if (strategy != null) for (p : strategy.closedPositions()) { painter.positions.add(new TradingPosition() .openingTime(p.openingTime()) .closingTime(p.closingTime()) .openingPrice(p.openingPrice()) .closingPrice(p.closingPrice()) .isLong(p.direction > 0) .leverage(iround(p.leverage))); } //painter addVerticalLine < backTest latestAllowedOpeningTime } void repaintImpl() { makePainter(); isTicker.setImage(painter.render()); } cachedVisualize { if (isTicker == null) isTicker = imageSurfaceMaker.newImageSurface(); onChange(timeZoomSlider, rstPaint); rstPaint.trigger(); ret jCenteredSection(str(ticker), centerAndSouthWithMargin( jscroll_borderless(isTicker), withLabel("Time zoom:", timeZoomSlider) )); } }