Libraryless. Click here for Pure Java version (30928L/197K).
1 | asclass AbstractTickerPainter extends ScaledDiagram is G2Drawable, MakesBufferedImage { |
2 | settable TickerSequence ticker; |
3 | |
4 | // the following two are old, use priceCells instead |
5 | settable double percentLineDistance; |
6 | settable bool drawPercentLines; |
7 | |
8 | settable PriceCells priceCells; |
9 | settable Color percentStripesColor = Color.darkGray; |
10 | |
11 | new L<TradingPosition> positions; |
12 | |
13 | new L<G2Drawable> additionalObjects; |
14 | |
15 | public BufferedImage render aka getBufferedImage() { |
16 | // Make black image |
17 | var img = blackImage(w, h); |
18 | var g = img.createGraphics(); |
19 | drawOn(g); |
20 | ret img; |
21 | } |
22 | |
23 | void drawPercentLines(Graphics2D g) { |
24 | if (priceCells != null) { |
25 | int cellNumber = ifloor(priceCells.toCellNumber(verticalRange.end)); |
26 | int safety = 250; |
27 | while (safety-- > 0) { |
28 | double y2 = priceCells.fromCellNumber(cellNumber-1); |
29 | if (y2 < verticalRange.start) break; |
30 | double y = priceCells.fromCellNumber(cellNumber); |
31 | var yy = iround(yToScreen(y)); |
32 | var yy2 = iround(yToScreen(y2)); |
33 | //drawLine(g, 0, yy, w-1, yy, Color.gray); |
34 | fillRect(g, 0, yy, w-1, yy2-yy, percentStripesColor); |
35 | cellNumber -= 2; |
36 | } |
37 | } |
38 | } |
39 | |
40 | void drawPositions(Graphics2D g) { |
41 | for (position : positions) { |
42 | var time = position.openingTime(); |
43 | var price = position.openingPrice(); |
44 | var x = xToScreen(time); |
45 | var y = yToScreen(price); |
46 | |
47 | var color = colorForPosition(position); |
48 | |
49 | // Mark opening point |
50 | fillRect(g, rectAroundPt(iround(x), iround(y), 10), color); |
51 | |
52 | if (not(position.isOpen())) { |
53 | time = position.closingTime(); |
54 | price = position.closingPrice(); |
55 | var x2 = xToScreen(time); |
56 | var y2 = yToScreen(price); |
57 | drawArrowBetweenPoints(g, toPt_round(doublePt(x, y)), toPt_round(doublePt(x2, y2)), color); |
58 | } |
59 | } |
60 | } |
61 | |
62 | void drawAdditionalObjects(Graphics2D g) { |
63 | for (o : additionalObjects) pcall { |
64 | o.drawOn(g); |
65 | } |
66 | } |
67 | |
68 | void addVerticalLine(double x, Color color default Color.gray) { |
69 | additionalObjects.add(g -> drawVerticalLine(g, x, color)); |
70 | } |
71 | |
72 | void add(G2Drawable object) { |
73 | addIfNotNull(additionalObjects, object); |
74 | } |
75 | |
76 | void drawVerticalLine(Graphics2D g, double x, Color color default Color.gray) { |
77 | int xScreen = iround(xToScreen(x)); |
78 | drawLine(g, xScreen, 0, xScreen, h-1, color); |
79 | } |
80 | |
81 | void addHorizontalLine(double y, Color color default Color.gray) { |
82 | additionalObjects.add(g -> drawHorizontalLine(g, y, color)); |
83 | } |
84 | |
85 | void drawHorizontalLine(Graphics2D g, double y, Color color default Color.gray) { |
86 | int yScreen = iround(yToScreen(y)); |
87 | drawLine(g, 0, yScreen, w-1, yScreen, color); |
88 | } |
89 | |
90 | DoubleRange horizontalRangeForTicker(TickerSequence ticker) { |
91 | var timeRange = ticker.timeRange(); |
92 | if (timeRange == null) null; |
93 | ret doubleRange(timeRange.startTime().unixDate(), timeRange.endTime().unixDate()); |
94 | } |
95 | |
96 | DoubleRange verticalRangeForTicker(TickerSequence ticker) { |
97 | ret doubleRange(ticker.minPrice(), ticker.maxPrice()); |
98 | } |
99 | |
100 | void addTimeGrid(double minutes) { |
101 | additionalObjects.add(g -> drawTimeGrid(g, minutes)); |
102 | } |
103 | |
104 | void drawTimeGrid(Graphics2D g, double minutes) { |
105 | double ms = minutesToMS(minutes); |
106 | assertTrue(ms >= 100); |
107 | double time = roundUpTo(ms, horizontalRange().start); |
108 | while (time < horizontalRange().end) { |
109 | drawVerticalLine(g, time); |
110 | time += ms; |
111 | } |
112 | } |
113 | |
114 | class LineIndicator is G2Drawable { |
115 | settable TickerSequence values; |
116 | settable Color color = Color.yellow; |
117 | |
118 | *() {} |
119 | *(TickerSequence *values) {} |
120 | *(TickerSequence *values, Color *color) {} |
121 | |
122 | public void drawOn(Graphics2D g) { |
123 | g.setColor(color); |
124 | var xRange = roundToIntRange(xRange()); |
125 | var sub = values.subSequenceByTimestamps( |
126 | lround(xFromScreen(xRange.start)), |
127 | lround(xFromScreen(xRange.end))); |
128 | int lastx = 0, lasty = 0; |
129 | for (int i = 0; i < sub.size(); i++) { |
130 | double price = sub.getPrice(i); |
131 | long time = sub.getTimestamp(i); |
132 | int x = iround(xToScreen(time)); |
133 | int y = iround(yToScreen(price)); |
134 | if (i != 0) |
135 | g.drawLine(lastx, lasty, x, y); |
136 | lastx = x; |
137 | lasty = y; |
138 | } |
139 | } |
140 | } |
141 | |
142 | selfType priceCells aka cellSize(double cellSize) { |
143 | ret priceCells(new GeometricPriceCells(cellSize)); |
144 | } |
145 | |
146 | swappable Color colorForPosition(TradingPosition position) { |
147 | bool winner = position.isWinner(); |
148 | //bool green = position.isLong(); |
149 | //var color = colorFromHex(green ? "1da2b4" : "f1493f"); |
150 | ret winner |
151 | ? directionToCandleColor(position.direction()) |
152 | : position.isLong() ? Color.yellow : Color.blue; |
153 | } |
154 | } |
Began life as a copy of #1036145
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): elmgxqgtpvxh, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1036168 |
Snippet name: | AbstractTickerPainter |
Eternal ID of this version: | #1036168/50 |
Text MD5: | b75d655f5ea426a3b4dcdc3a1be8d9fe |
Transpilation MD5: | 88ff371cdde460ddc76d03dcc7021b41 |
Author: | stefan |
Category: | javax / gazelle 22 |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2023-03-12 23:27:44 |
Source code size: | 4899 bytes / 154 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 280 / 543 |
Version history: | 49 change(s) |
Referenced in: | [show references] |