@stocksharp/trading-controls 0.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 (59) hide show
  1. package/LICENSE +30 -0
  2. package/NOTICE +21 -0
  3. package/README.md +240 -0
  4. package/dist/esm/active-orders-widget.js +382 -0
  5. package/dist/esm/active-orders-widget.js.map +1 -0
  6. package/dist/esm/control-types.js +23 -0
  7. package/dist/esm/control-types.js.map +1 -0
  8. package/dist/esm/dom.js +55 -0
  9. package/dist/esm/dom.js.map +1 -0
  10. package/dist/esm/formatters.js +69 -0
  11. package/dist/esm/formatters.js.map +1 -0
  12. package/dist/esm/index.js +12 -0
  13. package/dist/esm/index.js.map +1 -0
  14. package/dist/esm/positions-widget.js +258 -0
  15. package/dist/esm/positions-widget.js.map +1 -0
  16. package/dist/esm/trade-history-widget.js +197 -0
  17. package/dist/esm/trade-history-widget.js.map +1 -0
  18. package/dist/esm/trading-data.js +26 -0
  19. package/dist/esm/trading-data.js.map +1 -0
  20. package/dist/esm/trading-host.js +79 -0
  21. package/dist/esm/trading-host.js.map +1 -0
  22. package/dist/esm/watchlist-widget.js +481 -0
  23. package/dist/esm/watchlist-widget.js.map +1 -0
  24. package/dist/sstradingcontrols.js +1740 -0
  25. package/dist/sstradingcontrols.js.map +7 -0
  26. package/dist/types/active-orders-widget.d.ts +52 -0
  27. package/dist/types/active-orders-widget.d.ts.map +1 -0
  28. package/dist/types/control-types.d.ts +8 -0
  29. package/dist/types/control-types.d.ts.map +1 -0
  30. package/dist/types/dom.d.ts +6 -0
  31. package/dist/types/dom.d.ts.map +1 -0
  32. package/dist/types/formatters.d.ts +8 -0
  33. package/dist/types/formatters.d.ts.map +1 -0
  34. package/dist/types/index.d.ts +16 -0
  35. package/dist/types/index.d.ts.map +1 -0
  36. package/dist/types/positions-widget.d.ts +37 -0
  37. package/dist/types/positions-widget.d.ts.map +1 -0
  38. package/dist/types/trade-history-widget.d.ts +25 -0
  39. package/dist/types/trade-history-widget.d.ts.map +1 -0
  40. package/dist/types/trading-data.d.ts +55 -0
  41. package/dist/types/trading-data.d.ts.map +1 -0
  42. package/dist/types/trading-host.d.ts +62 -0
  43. package/dist/types/trading-host.d.ts.map +1 -0
  44. package/dist/types/watchlist-widget.d.ts +60 -0
  45. package/dist/types/watchlist-widget.d.ts.map +1 -0
  46. package/package.json +129 -0
  47. package/src/active-orders-widget.ts +411 -0
  48. package/src/control-types.ts +24 -0
  49. package/src/dom.ts +68 -0
  50. package/src/formatters.ts +72 -0
  51. package/src/index.ts +52 -0
  52. package/src/positions-widget.ts +305 -0
  53. package/src/trade-history-widget.ts +221 -0
  54. package/src/trading-data.ts +121 -0
  55. package/src/trading-host.ts +300 -0
  56. package/src/watchlist-widget.ts +513 -0
  57. package/styles/theme.css +86 -0
  58. package/styles/trading-controls.css +469 -0
  59. package/translation-keys.json +58 -0
@@ -0,0 +1,197 @@
1
+ // Trade history — multi-instance.
2
+ //
3
+ // Read-only table of executed trades for the active portfolio. Builds its own
4
+ // DOM (see `_buildRoot`) rather than cloning a <template> out of the page, so
5
+ // it can be constructed by any host that supplies a `TradingHost`.
6
+ //
7
+ // Which portfolio to load and what to load it through both come off the host's
8
+ // trading context rather than being read out of a singleton here: the panel
9
+ // renders what it is given, and the host decides what "the active portfolio"
10
+ // means.
11
+ //
12
+ // The table is `DataGrid` from `@stocksharp/grids`: the columns below are this
13
+ // blotter's single declaration and the <thead> is left empty for the grid to
14
+ // fill.
15
+ import { formatPrice, formatQty, formatTime } from './formatters.js';
16
+ import { makeElement, makeIconButton, makePanelId, makePanelRoot } from './dom.js';
17
+ import { ControlTypes } from './control-types.js';
18
+ import { assertHost } from './trading-host.js';
19
+ import { DataGrid } from '@stocksharp/grids/data-grid';
20
+ export class TradeHistoryWidget {
21
+ static create(hostEl, state, deps) {
22
+ // Assert before building: the markup below is localized through the
23
+ // host, so a missing host has to fail here rather than render a panel
24
+ // captioned with raw English keys.
25
+ const host = assertHost(deps?.host, 'TradeHistoryWidget');
26
+ const root = TradeHistoryWidget._buildRoot(host);
27
+ root.id = makePanelId(TradeHistoryWidget.TYPE);
28
+ hostEl.appendChild(root);
29
+ return new TradeHistoryWidget(root, state || {}, deps);
30
+ }
31
+ // The panel's markup. The host stylesheet reads this structure, and a
32
+ // docking host lifts `.panel-header`'s children into its tab strip.
33
+ static _buildRoot(host) {
34
+ const title = host.t('TradeHistory');
35
+ return makePanelRoot('trade-history-panel', title, [
36
+ makeElement('div', 'panel-header', {}, [
37
+ makeElement('span', '', {}, [title]),
38
+ makeIconButton('bt-icon-btn bt-icon-cancel panel-close-btn', host.t('ClosePanel'), 'bi-x', { type: 'button' }),
39
+ ]),
40
+ makeElement('div', 'panel-body panel-body-with-rail', {}, [
41
+ makeElement('div', 'panel-body-content', {}, [
42
+ makeElement('table', 'terminal-table trade-history-table', { role: 'table', 'aria-label': host.t('TradeHistoryList') }, [
43
+ makeElement('thead', '', {}, []),
44
+ makeElement('tbody', 'trade-history-body', {}, []),
45
+ ]),
46
+ ]),
47
+ makeElement('div', 'panel-rail', { role: 'toolbar', 'aria-label': host.t('TradeHistoryActions') }, [
48
+ makeIconButton('bt-icon-btn panel-refresh-btn', host.t('Refresh'), 'bi-arrow-clockwise', {}),
49
+ makeIconButton('bt-icon-btn panel-export-btn', host.t('ExportToExcel'), 'bi-file-earmark-spreadsheet', {}),
50
+ ]),
51
+ ]),
52
+ ]);
53
+ }
54
+ constructor(rootEl, _state, deps) {
55
+ this._host = assertHost(deps?.host, 'TradeHistoryWidget');
56
+ this.rootEl = rootEl;
57
+ this.bodyEl = this.rootEl.querySelector('.trade-history-body');
58
+ this._closeBtn = this.rootEl.querySelector('.panel-close-btn');
59
+ this._refreshBtn = this.rootEl.querySelector('.panel-refresh-btn');
60
+ this._exportBtn = this.rootEl.querySelector('.panel-export-btn');
61
+ this._closeBtn?.addEventListener('click', (e) => {
62
+ e.preventDefault();
63
+ this.dispose();
64
+ this._host.close();
65
+ });
66
+ this._refreshBtn?.addEventListener('click', (e) => {
67
+ e.preventDefault();
68
+ void this.refresh();
69
+ });
70
+ this._exportBtn?.addEventListener('click', (e) => {
71
+ e.preventDefault();
72
+ this._export();
73
+ });
74
+ this._rows = [];
75
+ const head = this.rootEl.querySelector('.trade-history-table thead');
76
+ this._grid = head && this.bodyEl
77
+ ? new DataGrid({
78
+ head: head,
79
+ body: this.bodyEl,
80
+ columns: this._columns(),
81
+ // Most recent fill on top by default — the natural way to read a trade blotter.
82
+ defaultSort: { col: 'time', dir: 'desc' },
83
+ rowKey: (t) => String(t.id),
84
+ emptyText: this._host.t('No trade history'),
85
+ })
86
+ : null;
87
+ this._host.register(this);
88
+ }
89
+ dispose() {
90
+ this._host.unregister(this);
91
+ try {
92
+ this.rootEl.remove();
93
+ }
94
+ catch { /* already detached */ }
95
+ }
96
+ /// Reload against whichever portfolio the host says is active right now.
97
+ ///
98
+ /// Two guards, and they are not the same one. No portfolio means there is
99
+ /// nothing to show — a guest session has none. A portfolio the host will
100
+ /// not `allow` reading means the session cannot make the call at all: this
101
+ /// is somebody's executed trades, so a page that has a portfolio id lying
102
+ /// around but no live credential must not fire the request and collect a
103
+ /// 401 for it. The panel asks the host rather than inspecting a token,
104
+ /// because what counts as a usable session is the host's to know.
105
+ ///
106
+ /// Order matters: the portfolio check runs first, so a session with no
107
+ /// portfolio is simply quiet — `allow` is the one that may put a sign-in
108
+ /// prompt on screen, and reaching it means the page did have an account to
109
+ /// load.
110
+ async refresh() {
111
+ const pf = this._host.trading.portfolioId();
112
+ if (!pf || !this._grid)
113
+ return;
114
+ if (!this._host.allow('load trade history'))
115
+ return;
116
+ try {
117
+ this._rows = await this._host.trading.api.getExecutions(pf, null, 200) || [];
118
+ this._grid.setRows(this._rows);
119
+ }
120
+ catch (err) {
121
+ // Through the port, not the console: this is the diagnostic the
122
+ // user cannot see and support has to, and routing it here is also
123
+ // what makes it assertable.
124
+ this._host.log(`TradeHistoryWidget: failed to load trade history: ${err}`);
125
+ }
126
+ }
127
+ // Export the table to .xlsx in the currently rendered (sorted) order.
128
+ _export() {
129
+ this._grid?.download('trades', this._host.t('TradeHistory'));
130
+ }
131
+ // The blotter's single column declaration. The two id columns read `#42` on
132
+ // screen and export the bare number, so the sheet stays sortable as a number.
133
+ _columns() {
134
+ // `label`, not `t` — every row lambda below already binds `t` as the
135
+ // trade it is rendering, and a translator sharing that name would be
136
+ // shadowed inside exactly the callbacks that read it.
137
+ const label = (key) => this._host.t(key);
138
+ const presentation = this._host.presentation;
139
+ return [
140
+ {
141
+ key: 'id',
142
+ header: label('ID'),
143
+ exportable: true,
144
+ value: (t) => t.id,
145
+ render: (t) => '#' + t.id,
146
+ cellClass: () => 'mono-id',
147
+ },
148
+ {
149
+ key: 'time',
150
+ header: label('Time'),
151
+ exportable: true,
152
+ value: (t) => t.executedAt || t.time,
153
+ render: (t) => formatTime(t.executedAt || t.time),
154
+ exportValue: (t) => formatTime(t.executedAt || t.time),
155
+ },
156
+ {
157
+ key: 'symbol',
158
+ header: label('Sym'),
159
+ exportable: true,
160
+ value: (t) => t.instrumentSymbol || t.symbol,
161
+ },
162
+ {
163
+ key: 'side',
164
+ header: label('Side'),
165
+ exportable: true,
166
+ value: (t) => t.side,
167
+ render: (t) => presentation.sideText(t.side),
168
+ cellClass: (t) => presentation.sideClass(t.side),
169
+ exportValue: (t) => presentation.sideText(t.side),
170
+ },
171
+ {
172
+ key: 'quantity',
173
+ header: label('Qty'),
174
+ exportable: true,
175
+ value: (t) => t.quantity,
176
+ render: (t) => formatQty(t.quantity),
177
+ },
178
+ {
179
+ key: 'price',
180
+ header: label('Price'),
181
+ exportable: true,
182
+ value: (t) => t.price,
183
+ render: (t) => formatPrice(t.price),
184
+ },
185
+ {
186
+ key: 'order',
187
+ header: label('Order'),
188
+ exportable: true,
189
+ value: (t) => t.order || t.orderId,
190
+ render: (t) => '#' + (t.order || t.orderId || ''),
191
+ cellClass: () => 'mono-id',
192
+ },
193
+ ];
194
+ }
195
+ }
196
+ TradeHistoryWidget.TYPE = ControlTypes.TradeHistory;
197
+ //# sourceMappingURL=trade-history-widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trade-history-widget.js","sourceRoot":"","sources":["../../src/trade-history-widget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ // The rows the controls render.
2
+ //
3
+ // These are wire shapes, not domain models: the host fetches them from
4
+ // whatever backend it has and hands them over, and this package only reads
5
+ // them. That is why every field is optional. A server that omits `realizedPnl`
6
+ // on a flat position, a snapshot row that predates a field, an optimistic
7
+ // client-side insert carrying half a fill — all of them are ordinary here, and
8
+ // every control already guards with `?? 0` / `|| ''` at the point of use. A
9
+ // required field would only move that guard to the host, which cannot honour it
10
+ // either.
11
+ //
12
+ // Two fields are deliberately unions rather than enums. `side` and `status`
13
+ // arrive in more than one spelling depending on which endpoint produced the row
14
+ // (a numeric StockSharp enum from the socket, a name from the DTO, an uppercase
15
+ // name from the history endpoint), and normalising them is the host's job —
16
+ // `TradingPresentation` is where that knowledge lives. Narrowing the type here
17
+ // would only force a cast at every call site that is already correct.
18
+ //
19
+ // Every numeric field is `number | null` as well as optional, for the same
20
+ // reason: an absent price reaches us as an omitted key from one endpoint and as
21
+ // an explicit null from another, both meaning "not set". Saying so once here is
22
+ // what lets the read sites stay the plain `?? 0` / `|| ''` they already were.
23
+ //
24
+ // This module has no imports and no behaviour.
25
+ export {};
26
+ //# sourceMappingURL=trading-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trading-data.js","sourceRoot":"","sources":["../../src/trading-data.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,EAAE;AACF,uEAAuE;AACvE,2EAA2E;AAC3E,+EAA+E;AAC/E,0EAA0E;AAC1E,+EAA+E;AAC/E,4EAA4E;AAC5E,gFAAgF;AAChF,UAAU;AACV,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,gFAAgF;AAChF,4EAA4E;AAC5E,+EAA+E;AAC/E,sEAAsE;AACtE,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,EAAE;AACF,+CAA+C"}
@@ -0,0 +1,79 @@
1
+ /// The class names `TradingPresentation` is expected to return, as data.
2
+ ///
3
+ /// Exported because it is a contract, not a detail: a host writing its own
4
+ /// presentation reads this to know which names the shipped stylesheet already
5
+ /// paints, and the style-contract check reads it to prove they are all styled.
6
+ export const PRESENTATION_CLASSES = {
7
+ sideClass: ['side-buy', 'side-sell'],
8
+ pnlClass: ['pnl-positive', 'pnl-negative'],
9
+ };
10
+ /// How much of a symbol a control wants streamed. A quote row needs the last
11
+ /// price, a tape needs every print, a ladder needs the book as well — and each
12
+ /// costs the wire something different, so a control states which it is asking
13
+ /// for rather than leaving the argument off and taking a default.
14
+ export const MarketDataLevels = {
15
+ /// Level 1 only: best bid/ask and last price.
16
+ Quotes: 'l1only',
17
+ /// Level 1 plus every tick.
18
+ Tape: 'tape',
19
+ /// Level 1, ticks and market depth.
20
+ Full: 'full',
21
+ };
22
+ /// Prove a host object satisfies the port, and say precisely what is missing
23
+ /// when it does not.
24
+ ///
25
+ /// Called from every control's constructor before anything else, so a
26
+ /// mis-wired host fails at construction with the member named, instead of at
27
+ /// the first click that needed it.
28
+ export function assertHost(host, controlName) {
29
+ _required(host, 'host', 'object', controlName);
30
+ _required(host.isPrimary, 'host.isPrimary', 'boolean', controlName);
31
+ _required(host.t, 'host.t', 'function', controlName);
32
+ _required(host.presentation, 'host.presentation', 'object', controlName);
33
+ _required(host.presentation.sideText, 'host.presentation.sideText', 'function', controlName);
34
+ _required(host.presentation.typeText, 'host.presentation.typeText', 'function', controlName);
35
+ _required(host.presentation.statusText, 'host.presentation.statusText', 'function', controlName);
36
+ _required(host.presentation.sideClass, 'host.presentation.sideClass', 'function', controlName);
37
+ _required(host.presentation.pnlClass, 'host.presentation.pnlClass', 'function', controlName);
38
+ _required(host.preferences, 'host.preferences', 'object', controlName);
39
+ _required(host.preferences.get, 'host.preferences.get', 'function', controlName);
40
+ _required(host.preferences.set, 'host.preferences.set', 'function', controlName);
41
+ _required(host.cache, 'host.cache', 'object', controlName);
42
+ _required(host.cache.get, 'host.cache.get', 'function', controlName);
43
+ _required(host.cache.set, 'host.cache.set', 'function', controlName);
44
+ _required(host.trading, 'host.trading', 'object', controlName);
45
+ _required(host.trading.api, 'host.trading.api', 'object', controlName);
46
+ // The calls, not just the objects holding them. An `api: {}` is the shape a
47
+ // half-wired host actually has — the object gets built, the methods get
48
+ // forgotten — so stopping at the object would skip exactly the members this
49
+ // function exists to catch.
50
+ _required(host.trading.api.getExecutions, 'host.trading.api.getExecutions', 'function', controlName);
51
+ _required(host.trading.api.searchInstruments, 'host.trading.api.searchInstruments', 'function', controlName);
52
+ _required(host.trading.marketData, 'host.trading.marketData', 'object', controlName);
53
+ _required(host.trading.marketData.addSymbol, 'host.trading.marketData.addSymbol', 'function', controlName);
54
+ _required(host.trading.marketData.removeSymbol, 'host.trading.marketData.removeSymbol', 'function', controlName);
55
+ _required(host.trading.marketData.resubscribe, 'host.trading.marketData.resubscribe', 'function', controlName);
56
+ _required(host.trading.marketData.getOrders, 'host.trading.marketData.getOrders', 'function', controlName);
57
+ _required(host.trading.portfolioId, 'host.trading.portfolioId', 'function', controlName);
58
+ _required(host.trading.pickInstrument, 'host.trading.pickInstrument', 'function', controlName);
59
+ _required(host.ticker, 'host.ticker', 'object', controlName);
60
+ _required(host.ticker.publish, 'host.ticker.publish', 'function', controlName);
61
+ _required(host.allow, 'host.allow', 'function', controlName);
62
+ _required(host.log, 'host.log', 'function', controlName);
63
+ _required(host.close, 'host.close', 'function', controlName);
64
+ _required(host.spawn, 'host.spawn', 'function', controlName);
65
+ _required(host.persistState, 'host.persistState', 'function', controlName);
66
+ _required(host.saveLayout, 'host.saveLayout', 'function', controlName);
67
+ _required(host.register, 'host.register', 'function', controlName);
68
+ _required(host.unregister, 'host.unregister', 'function', controlName);
69
+ _required(host.broadcast, 'host.broadcast', 'function', controlName);
70
+ return host;
71
+ }
72
+ // `typeof null` is 'object', which would let a null store through the object
73
+ // checks — the one case worth spelling out, because null is exactly what an
74
+ // unwired dependency looks like.
75
+ function _required(value, path, kind, controlName) {
76
+ if (value === null || value === undefined || typeof value !== kind)
77
+ throw new Error(`${controlName}: ${path} is required`);
78
+ }
79
+ //# sourceMappingURL=trading-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trading-host.js","sourceRoot":"","sources":["../../src/trading-host.ts"],"names":[],"mappings":"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"}