@stocksharp/trading-controls 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +92 -6
  2. package/dist/esm/active-orders-widget.js +9 -0
  3. package/dist/esm/active-orders-widget.js.map +1 -1
  4. package/dist/esm/control-types.js +3 -0
  5. package/dist/esm/control-types.js.map +1 -1
  6. package/dist/esm/grid-menu.js +54 -0
  7. package/dist/esm/grid-menu.js.map +1 -0
  8. package/dist/esm/index.js +8 -0
  9. package/dist/esm/index.js.map +1 -1
  10. package/dist/esm/order-entry-widget.js +654 -0
  11. package/dist/esm/order-entry-widget.js.map +1 -0
  12. package/dist/esm/orderbook-depth.js +51 -0
  13. package/dist/esm/orderbook-depth.js.map +1 -0
  14. package/dist/esm/orderbook-widget.js +792 -0
  15. package/dist/esm/orderbook-widget.js.map +1 -0
  16. package/dist/esm/positions-widget.js +9 -0
  17. package/dist/esm/positions-widget.js.map +1 -1
  18. package/dist/esm/trade-history-widget.js +8 -0
  19. package/dist/esm/trade-history-widget.js.map +1 -1
  20. package/dist/esm/tradefeed-aggregator.js +58 -0
  21. package/dist/esm/tradefeed-aggregator.js.map +1 -0
  22. package/dist/esm/tradefeed-bubbles.js +131 -0
  23. package/dist/esm/tradefeed-bubbles.js.map +1 -0
  24. package/dist/esm/tradefeed-widget.js +692 -0
  25. package/dist/esm/tradefeed-widget.js.map +1 -0
  26. package/dist/esm/trading-host.js +2 -0
  27. package/dist/esm/trading-host.js.map +1 -1
  28. package/dist/esm/watchlist-widget.js +2 -0
  29. package/dist/esm/watchlist-widget.js.map +1 -1
  30. package/dist/sstradingcontrols.js +3346 -25
  31. package/dist/sstradingcontrols.js.map +3 -3
  32. package/dist/types/active-orders-widget.d.ts.map +1 -1
  33. package/dist/types/control-types.d.ts +3 -0
  34. package/dist/types/control-types.d.ts.map +1 -1
  35. package/dist/types/grid-menu.d.ts +4 -0
  36. package/dist/types/grid-menu.d.ts.map +1 -0
  37. package/dist/types/index.d.ts +13 -0
  38. package/dist/types/index.d.ts.map +1 -1
  39. package/dist/types/order-entry-widget.d.ts +86 -0
  40. package/dist/types/order-entry-widget.d.ts.map +1 -0
  41. package/dist/types/orderbook-depth.d.ts +19 -0
  42. package/dist/types/orderbook-depth.d.ts.map +1 -0
  43. package/dist/types/orderbook-widget.d.ts +105 -0
  44. package/dist/types/orderbook-widget.d.ts.map +1 -0
  45. package/dist/types/positions-widget.d.ts.map +1 -1
  46. package/dist/types/trade-history-widget.d.ts.map +1 -1
  47. package/dist/types/tradefeed-aggregator.d.ts +15 -0
  48. package/dist/types/tradefeed-aggregator.d.ts.map +1 -0
  49. package/dist/types/tradefeed-bubbles.d.ts +39 -0
  50. package/dist/types/tradefeed-bubbles.d.ts.map +1 -0
  51. package/dist/types/tradefeed-widget.d.ts +78 -0
  52. package/dist/types/tradefeed-widget.d.ts.map +1 -0
  53. package/dist/types/trading-data.d.ts +22 -0
  54. package/dist/types/trading-data.d.ts.map +1 -1
  55. package/dist/types/trading-host.d.ts +8 -0
  56. package/dist/types/trading-host.d.ts.map +1 -1
  57. package/dist/types/watchlist-widget.d.ts.map +1 -1
  58. package/package.json +21 -2
  59. package/screenshots/panels.jpg +0 -0
  60. package/src/active-orders-widget.ts +9 -0
  61. package/src/control-types.ts +3 -0
  62. package/src/grid-menu.ts +67 -0
  63. package/src/index.ts +31 -0
  64. package/src/order-entry-widget.ts +733 -0
  65. package/src/orderbook-depth.ts +99 -0
  66. package/src/orderbook-widget.ts +896 -0
  67. package/src/positions-widget.ts +9 -0
  68. package/src/trade-history-widget.ts +8 -0
  69. package/src/tradefeed-aggregator.ts +95 -0
  70. package/src/tradefeed-bubbles.ts +194 -0
  71. package/src/tradefeed-widget.ts +744 -0
  72. package/src/trading-data.ts +168 -121
  73. package/src/trading-host.ts +326 -300
  74. package/src/watchlist-widget.ts +2 -0
  75. package/styles/theme.css +23 -0
  76. package/styles/trading-controls.css +911 -0
  77. package/translation-keys.json +103 -2
@@ -0,0 +1,99 @@
1
+ // The geometry of the order book's depth chart, as pure functions over
2
+ // numbers.
3
+ //
4
+ // The chart is a classic market-depth curve: price runs along X with the mid
5
+ // line in the middle, bids fanning left and asks right, and Y is the cumulative
6
+ // quantity from the best price on that side out to the price under the cursor.
7
+ // It is a step curve because a book is discrete — a horizontal run between two
8
+ // prices at the same accumulation, then a vertical jump where the next level
9
+ // adds its size.
10
+ //
11
+ // None of that needs a canvas, and keeping it here is what makes it testable:
12
+ // a fake 2D context can only record the calls a control made, so the numbers
13
+ // those calls carry are checked here instead, against arithmetic rather than
14
+ // against pixels.
15
+ import type { BookLevel } from './trading-data.js';
16
+
17
+ /// The box one paint fills, in device pixels.
18
+ export interface DepthGeometry {
19
+ /// X of the mid line, which both sides start from.
20
+ midX: number;
21
+ /// Gap left at the mid line and at the outer edge, so the curve does not
22
+ /// touch either.
23
+ pad: number;
24
+ /// Distance from the mid line to the outer edge — the width one side has.
25
+ halfWidth: number;
26
+ /// Y of the zero-volume baseline.
27
+ baseY: number;
28
+ /// Height the largest cumulative quantity rises to.
29
+ innerHeight: number;
30
+ }
31
+
32
+ /// One accumulation point: the pixel a level sits at and the running quantity
33
+ /// up to and including it.
34
+ export interface DepthPoint {
35
+ x: number;
36
+ cumulative: number;
37
+ }
38
+
39
+ /// One side of the chart, ready to be stroked.
40
+ export interface DepthSide {
41
+ points: DepthPoint[];
42
+ /// Cumulative quantity of the whole side — what the two sides are scaled
43
+ /// against, so the taller one reaches the top and the other keeps its
44
+ /// proportion.
45
+ total: number;
46
+ }
47
+
48
+ /// Accumulate one side of the book into pixel space.
49
+ ///
50
+ /// `direction` is -1 for the side drawn left of the mid line and +1 for the
51
+ /// right. Each side is scaled by its OWN price span, so both fill their half
52
+ /// even when one is quoted far wider than the other — the chart is about the
53
+ /// shape of the liquidity, not about the two spans being comparable.
54
+ ///
55
+ /// Null when there is nothing to draw: no levels, or every level at one price,
56
+ /// which has no span to spread over.
57
+ export function depthSide(levels: BookLevel[], direction: 1 | -1, geometry: DepthGeometry): DepthSide | null {
58
+ if (levels.length === 0) return null;
59
+
60
+ const best = levels[0].price;
61
+ const worst = levels[levels.length - 1].price;
62
+ const span = Math.abs(best - worst);
63
+ if (!(span > 0)) return null;
64
+
65
+ const reach = geometry.halfWidth - geometry.pad;
66
+ const points: DepthPoint[] = [{ x: geometry.midX + direction * geometry.pad, cumulative: 0 }];
67
+ let cumulative = 0;
68
+ for (const level of levels) {
69
+ cumulative += level.quantity;
70
+ const distance = Math.abs(level.price - best);
71
+ points.push({
72
+ x: geometry.midX + direction * (geometry.pad + (distance / span) * reach),
73
+ cumulative,
74
+ });
75
+ }
76
+ return { points, total: cumulative };
77
+ }
78
+
79
+ /// Turn one side into the step polyline that is both stroked and filled.
80
+ ///
81
+ /// Two points per level: the horizontal run arrives at the new price still at
82
+ /// the previous accumulation, then the vertical jump adds the level's size. The
83
+ /// first point sits on the baseline so the filled area closes against it.
84
+ ///
85
+ /// `maxTotal` is the scale both sides share — pass the larger of the two totals
86
+ /// so the halves stay comparable.
87
+ export function depthPolyline(side: DepthSide, maxTotal: number, geometry: DepthGeometry): [number, number][] {
88
+ const scale = maxTotal > 0 ? maxTotal : 1;
89
+ const yOf = (cumulative: number) => geometry.baseY - (cumulative / scale) * geometry.innerHeight;
90
+
91
+ const line: [number, number][] = [[side.points[0].x, geometry.baseY]];
92
+ for (let i = 1; i < side.points.length; i++) {
93
+ const previous = side.points[i - 1];
94
+ const current = side.points[i];
95
+ line.push([current.x, yOf(previous.cumulative)]);
96
+ line.push([current.x, yOf(current.cumulative)]);
97
+ }
98
+ return line;
99
+ }