@stocksharp/trading-controls 1.1.1 → 1.3.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 +95 -16
  2. package/dist/esm/active-orders-widget.js +38 -25
  3. package/dist/esm/active-orders-widget.js.map +1 -1
  4. package/dist/esm/black-scholes.js +147 -0
  5. package/dist/esm/black-scholes.js.map +1 -0
  6. package/dist/esm/control-types.js +4 -0
  7. package/dist/esm/control-types.js.map +1 -1
  8. package/dist/esm/index.js +18 -0
  9. package/dist/esm/index.js.map +1 -1
  10. package/dist/esm/log-monitor-widget.js +265 -0
  11. package/dist/esm/log-monitor-widget.js.map +1 -0
  12. package/dist/esm/log-tree.js +96 -0
  13. package/dist/esm/log-tree.js.map +1 -0
  14. package/dist/esm/option-desk-widget.js +322 -0
  15. package/dist/esm/option-desk-widget.js.map +1 -0
  16. package/dist/esm/pnl-curve.js +129 -0
  17. package/dist/esm/pnl-curve.js.map +1 -0
  18. package/dist/esm/statistics-widget.js +194 -0
  19. package/dist/esm/statistics-widget.js.map +1 -0
  20. package/dist/esm/strategies-widget.js +348 -0
  21. package/dist/esm/strategies-widget.js.map +1 -0
  22. package/dist/esm/trade-history-widget.js +14 -6
  23. package/dist/esm/trade-history-widget.js.map +1 -1
  24. package/dist/esm/tradefeed-widget.js +3 -3
  25. package/dist/esm/tradefeed-widget.js.map +1 -1
  26. package/dist/esm/trading-host.js +1 -0
  27. package/dist/esm/trading-host.js.map +1 -1
  28. package/dist/sstradingcontrols.js +1358 -78
  29. package/dist/sstradingcontrols.js.map +4 -4
  30. package/dist/types/active-orders-widget.d.ts +11 -3
  31. package/dist/types/active-orders-widget.d.ts.map +1 -1
  32. package/dist/types/black-scholes.d.ts +28 -0
  33. package/dist/types/black-scholes.d.ts.map +1 -0
  34. package/dist/types/control-types.d.ts +4 -0
  35. package/dist/types/control-types.d.ts.map +1 -1
  36. package/dist/types/index.d.ts +16 -1
  37. package/dist/types/index.d.ts.map +1 -1
  38. package/dist/types/log-monitor-widget.d.ts +42 -0
  39. package/dist/types/log-monitor-widget.d.ts.map +1 -0
  40. package/dist/types/log-tree.d.ts +34 -0
  41. package/dist/types/log-tree.d.ts.map +1 -0
  42. package/dist/types/option-desk-widget.d.ts +68 -0
  43. package/dist/types/option-desk-widget.d.ts.map +1 -0
  44. package/dist/types/pnl-curve.d.ts +43 -0
  45. package/dist/types/pnl-curve.d.ts.map +1 -0
  46. package/dist/types/statistics-widget.d.ts +29 -0
  47. package/dist/types/statistics-widget.d.ts.map +1 -0
  48. package/dist/types/strategies-widget.d.ts +63 -0
  49. package/dist/types/strategies-widget.d.ts.map +1 -0
  50. package/dist/types/trade-history-widget.d.ts +3 -1
  51. package/dist/types/trade-history-widget.d.ts.map +1 -1
  52. package/dist/types/trading-data.d.ts +9 -0
  53. package/dist/types/trading-data.d.ts.map +1 -1
  54. package/dist/types/trading-host.d.ts +1 -0
  55. package/dist/types/trading-host.d.ts.map +1 -1
  56. package/package.json +27 -2
  57. package/screenshots/log-monitor.png +0 -0
  58. package/screenshots/option-desk.png +0 -0
  59. package/screenshots/panels.jpg +0 -0
  60. package/screenshots/statistics.png +0 -0
  61. package/screenshots/strategies.png +0 -0
  62. package/src/active-orders-widget.ts +49 -25
  63. package/src/black-scholes.ts +199 -0
  64. package/src/control-types.ts +4 -0
  65. package/src/index.ts +41 -0
  66. package/src/log-monitor-widget.ts +312 -0
  67. package/src/log-tree.ts +131 -0
  68. package/src/option-desk-widget.ts +422 -0
  69. package/src/pnl-curve.ts +204 -0
  70. package/src/statistics-widget.ts +226 -0
  71. package/src/strategies-widget.ts +435 -0
  72. package/src/trade-history-widget.ts +19 -6
  73. package/src/tradefeed-widget.ts +3 -3
  74. package/src/trading-data.ts +22 -0
  75. package/src/trading-host.ts +8 -0
  76. package/styles/trading-controls.css +356 -0
  77. package/translation-keys.json +70 -1
@@ -0,0 +1,265 @@
1
+ // Log monitor — multi-instance.
2
+ //
3
+ // Two panes: the tree of everything that writes a log on the left, and on the right what the
4
+ // selected source and everything under it has written. The desktop version copies each message
5
+ // into every ancestor's list, so one line is held as many times as it has ancestors and its own
6
+ // counter reports copies rather than messages. Here a message is held once and carries the id
7
+ // of the source that wrote it; selecting a node filters by its subtree.
8
+ //
9
+ // A live log has no end, so this one has a cap. The desktop's grows for the lifetime of the
10
+ // window - nothing trims it - which a browser tab cannot afford.
11
+ import { makeElement, makeIconButton, makePanelId, makePanelRoot } from './dom.js';
12
+ import { ControlTypes } from './control-types.js';
13
+ import { makeGridMenu } from './grid-menu.js';
14
+ import { assertHost } from './trading-host.js';
15
+ import { LogLevels, buildLogTree, keepLog, subtreeOf, } from './log-tree.js';
16
+ import { DataGrid } from '@stocksharp/grids/data-grid';
17
+ const DEFAULT_MAX = 5000;
18
+ /// The letter a level shows in the narrow column, and the class that colours the row.
19
+ ///
20
+ /// Info gets a letter here. The desktop leaves its cell blank - there is simply no trigger for
21
+ /// it among the four that exist - so the commonest level is the one with no marking at all,
22
+ /// which is an omission rather than a decision.
23
+ const LEVEL_LETTER = {
24
+ [LogLevels.Error]: 'E',
25
+ [LogLevels.Warning]: 'W',
26
+ [LogLevels.Info]: 'I',
27
+ [LogLevels.Debug]: 'D',
28
+ [LogLevels.Verbose]: 'V',
29
+ };
30
+ const ALL_LEVELS = [LogLevels.Error, LogLevels.Warning, LogLevels.Info, LogLevels.Debug, LogLevels.Verbose];
31
+ export class LogMonitorWidget {
32
+ static create(hostEl, state, deps) {
33
+ const host = assertHost(deps?.host, 'LogMonitorWidget');
34
+ const root = LogMonitorWidget._buildRoot(host);
35
+ root.id = makePanelId(LogMonitorWidget.TYPE);
36
+ hostEl.appendChild(root);
37
+ return new LogMonitorWidget(root, state || {}, deps);
38
+ }
39
+ // The panel's markup: a source tree, a toolbar of level toggles and a text box, and the
40
+ // message table. The level toggles are buttons rather than checkboxes because they are read
41
+ // as a row of states, and each carries its letter so the toolbar and the column agree.
42
+ static _buildRoot(host) {
43
+ const title = host.t('LogMonitor');
44
+ return makePanelRoot('log-monitor-panel', title, [
45
+ makeElement('div', 'panel-header', {}, [
46
+ makeElement('span', '', {}, [title]),
47
+ makeIconButton('bt-icon-btn bt-icon-cancel panel-close-btn', host.t('ClosePanel'), 'bi-x', { type: 'button' }),
48
+ ]),
49
+ makeElement('div', 'panel-body log-monitor-body', {}, [
50
+ makeElement('div', 'log-sources', { role: 'tree', 'aria-label': host.t('LogSources') }, []),
51
+ makeElement('div', 'log-messages', {}, [
52
+ makeElement('div', 'log-toolbar', { role: 'toolbar', 'aria-label': host.t('LogMonitorActions') }, [
53
+ ...ALL_LEVELS.map(level => makeElement('button', `log-level-toggle log-level-${level} is-on`, {
54
+ type: 'button',
55
+ 'data-level': level,
56
+ 'aria-pressed': 'true',
57
+ title: levelTitle(host, level),
58
+ }, [LEVEL_LETTER[level]])),
59
+ makeElement('input', 'form-control form-control-sm log-filter', {
60
+ type: 'search',
61
+ placeholder: host.t('Filter'),
62
+ 'aria-label': host.t('Filter'),
63
+ }, []),
64
+ makeIconButton('bt-icon-btn log-clear-btn', host.t('ClearItems'), 'bi-eraser', {}),
65
+ makeIconButton('bt-icon-btn panel-export-btn', host.t('ExportToExcel'), 'bi-file-earmark-spreadsheet', {}),
66
+ ]),
67
+ // The table sits in a box of its own rather than being a flex child: a table
68
+ // told to fill a column stretches its rows to do it, so a log holding one
69
+ // line drew that line a panel tall - and with the toolbar and the table as
70
+ // the only two children there was nowhere for a long log to scroll.
71
+ makeElement('div', 'log-table-scroll', {}, [
72
+ makeElement('table', 'terminal-table log-table', { role: 'table', 'aria-label': host.t('LogMessages') }, [
73
+ makeElement('thead', '', {}, []),
74
+ makeElement('tbody', 'log-body', {}, []),
75
+ ]),
76
+ ]),
77
+ ]),
78
+ ]),
79
+ ]);
80
+ }
81
+ constructor(rootEl, _state, deps) {
82
+ this._host = assertHost(deps?.host, 'LogMonitorWidget');
83
+ this._max = deps?.maxMessages && deps.maxMessages > 0 ? deps.maxMessages : DEFAULT_MAX;
84
+ this.rootEl = rootEl;
85
+ this.el = this.rootEl.querySelector('.log-body');
86
+ this._treeEl = this.rootEl.querySelector('.log-sources');
87
+ this._filterEl = this.rootEl.querySelector('.log-filter');
88
+ this._closeBtn = this.rootEl.querySelector('.panel-close-btn');
89
+ this._clearBtn = this.rootEl.querySelector('.log-clear-btn');
90
+ this._exportBtn = this.rootEl.querySelector('.panel-export-btn');
91
+ this._sources = [];
92
+ this._messages = [];
93
+ this._levels = new Set(ALL_LEVELS);
94
+ this._text = '';
95
+ this._selected = null;
96
+ this._closeBtn?.addEventListener('click', (e) => { e.preventDefault(); this._host.close(); });
97
+ this._clearBtn?.addEventListener('click', (e) => { e.preventDefault(); this.clear(); });
98
+ this._exportBtn?.addEventListener('click', (e) => { e.preventDefault(); this._export(); });
99
+ for (const toggle of Array.from(this.rootEl.querySelectorAll('.log-level-toggle'))) {
100
+ toggle.addEventListener('click', (e) => {
101
+ e.preventDefault();
102
+ const level = toggle.getAttribute('data-level') ?? '';
103
+ if (this._levels.has(level))
104
+ this._levels.delete(level);
105
+ else
106
+ this._levels.add(level);
107
+ toggle.classList.toggle('is-on', this._levels.has(level));
108
+ toggle.setAttribute('aria-pressed', this._levels.has(level) ? 'true' : 'false');
109
+ this._render();
110
+ });
111
+ }
112
+ this._filterEl?.addEventListener('input', () => {
113
+ this._text = this._filterEl?.value ?? '';
114
+ this._render();
115
+ });
116
+ const head = this.rootEl.querySelector('.log-table thead');
117
+ this._grid = head && this.el
118
+ ? new DataGrid({
119
+ head: head,
120
+ body: this.el,
121
+ columns: this._columns(),
122
+ // The order it happened in. A log read out of order is not a log.
123
+ defaultSort: { col: 'time', dir: 'asc' },
124
+ rowKey: (m) => String(m.id),
125
+ emptyText: this._host.t('NoLogMessages'),
126
+ rowClass: (m) => `log-row log-row-${m.level}`,
127
+ contextMenu: makeGridMenu(this._host),
128
+ selection: 'multi',
129
+ })
130
+ : null;
131
+ this._host.register(this);
132
+ }
133
+ dispose() {
134
+ this._grid?.destroy();
135
+ this._host.unregister(this);
136
+ try {
137
+ this.rootEl.remove();
138
+ }
139
+ catch { /* already detached */ }
140
+ }
141
+ /// The sources that exist. Sent whole: a source that has gone is gone from the tree, and
142
+ /// the selection falls back to everything rather than to a node nobody can see.
143
+ setSources(sources) {
144
+ this._sources = sources || [];
145
+ if (this._selected !== null && !this._sources.some(s => s.id === this._selected))
146
+ this._selected = null;
147
+ this._renderTree();
148
+ this._render();
149
+ }
150
+ /// Add what has just been written. The oldest fall off the front once the cap is reached.
151
+ append(messages) {
152
+ if (!messages || messages.length === 0)
153
+ return;
154
+ this._messages.push(...messages);
155
+ if (this._messages.length > this._max)
156
+ this._messages.splice(0, this._messages.length - this._max);
157
+ this._render();
158
+ }
159
+ /// Forget every message. The sources stay: they still exist, they have just gone quiet.
160
+ clear() {
161
+ this._messages = [];
162
+ this._render();
163
+ }
164
+ /// Show one source's subtree, or everything when given null.
165
+ select(sourceId) {
166
+ this._selected = sourceId;
167
+ this._renderTree();
168
+ this._render();
169
+ }
170
+ /// What is on screen, after every filter.
171
+ visible() {
172
+ const sources = subtreeOf(this._sources, this._selected);
173
+ return this._messages.filter(m => keepLog(m, { levels: this._levels, text: this._text, sources }));
174
+ }
175
+ _render() {
176
+ this._grid?.setRows(this.visible());
177
+ }
178
+ _renderTree() {
179
+ const tree = this._treeEl;
180
+ if (tree === null)
181
+ return;
182
+ tree.innerHTML = '';
183
+ tree.appendChild(this._treeRow({ id: '', name: this._host.t('AllSources'), depth: 0, children: [] }, null));
184
+ for (const root of buildLogTree(this._sources))
185
+ this._appendNode(tree, root);
186
+ }
187
+ _appendNode(into, node) {
188
+ into.appendChild(this._treeRow(node, node.id));
189
+ for (const child of node.children)
190
+ this._appendNode(into, child);
191
+ }
192
+ // Flat rows with an indent rather than nested lists: the tree is read, not restructured,
193
+ // and one list is what a keyboard walks through in the order the eye does.
194
+ _treeRow(node, id) {
195
+ const selected = this._selected === id;
196
+ const row = makeElement('button', `log-source${selected ? ' is-selected' : ''}`, {
197
+ type: 'button',
198
+ role: 'treeitem',
199
+ 'aria-selected': selected ? 'true' : 'false',
200
+ 'aria-level': String(node.depth + 1),
201
+ style: `padding-left: ${0.5 + node.depth * 0.85}rem`,
202
+ }, [node.name]);
203
+ row.addEventListener('click', (e) => { e.preventDefault(); this.select(id); });
204
+ return row;
205
+ }
206
+ _export() {
207
+ this._grid?.download('log', this._host.t('LogMonitor'));
208
+ }
209
+ _columns() {
210
+ const label = (key) => this._host.t(key);
211
+ return [
212
+ {
213
+ key: 'source',
214
+ header: label('Source'),
215
+ exportable: true,
216
+ value: (m) => m.source ?? this._sourceName(m.sourceId),
217
+ },
218
+ {
219
+ key: 'time',
220
+ header: label('Time'),
221
+ exportable: true,
222
+ value: (m) => m.time,
223
+ render: (m) => this._host.presentation.timeText(m.time),
224
+ exportValue: (m) => this._host.presentation.timeText(m.time),
225
+ },
226
+ {
227
+ key: 'level',
228
+ header: label('Type'),
229
+ headerClass: 'log-level-col',
230
+ exportable: true,
231
+ cellClass: (m) => `log-level-cell log-level-${m.level}`,
232
+ value: (m) => m.level,
233
+ render: (m) => LEVEL_LETTER[m.level] ?? String(m.level ?? '').slice(0, 1).toUpperCase(),
234
+ // The sheet carries the level's name, not the letter the column has room for.
235
+ exportValue: (m) => m.level,
236
+ },
237
+ {
238
+ key: 'message',
239
+ header: label('Message'),
240
+ exportable: true,
241
+ cellClass: () => 'log-message-cell',
242
+ value: (m) => m.message,
243
+ },
244
+ ];
245
+ }
246
+ _sourceName(id) {
247
+ return this._sources.find(s => s.id === id)?.name ?? id;
248
+ }
249
+ }
250
+ LogMonitorWidget.TYPE = ControlTypes.LogMonitor;
251
+ /// What a level's toggle is called.
252
+ ///
253
+ /// Literal keys at the point they are asked for - see the note on the same shape in
254
+ /// strategies-widget: a key built from a value is invisible to the scan that generates
255
+ /// `translation-keys.json`, and reaches the user untranslated.
256
+ function levelTitle(host, level) {
257
+ switch (level) {
258
+ case LogLevels.Error: return host.t('Errors');
259
+ case LogLevels.Warning: return host.t('Warnings');
260
+ case LogLevels.Info: return host.t('Messages');
261
+ case LogLevels.Debug: return host.t('Debug');
262
+ default: return host.t('Verbose');
263
+ }
264
+ }
265
+ //# sourceMappingURL=log-monitor-widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-monitor-widget.js","sourceRoot":"","sources":["../../src/log-monitor-widget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ // The log monitor's shape, as pure functions: how sources nest, and which messages a view of
2
+ // them keeps.
3
+ //
4
+ // A log source announces its parent, not its children, and it can announce itself before its
5
+ // parent has said anything — so the tree is assembled from whatever has arrived rather than
6
+ // walked from a root that may not exist yet. Keeping that here is what makes it checkable: a
7
+ // cycle, an orphan and an unnamed source are all things a live feed produces, and none of them
8
+ // should be discovered as a hung page.
9
+ /// The levels a log message carries. The names are the wire's; the letter is what a narrow
10
+ /// column shows.
11
+ export const LogLevels = {
12
+ Error: 'error',
13
+ Warning: 'warning',
14
+ Info: 'info',
15
+ Debug: 'debug',
16
+ Verbose: 'verbose',
17
+ };
18
+ /// Assemble the sources into a forest, roots first, each node carrying its depth.
19
+ ///
20
+ /// A source whose parent is not among these is a root: it is the only honest place for it, and
21
+ /// dropping it would silently lose a whole strategy's log because its connector had not spoken
22
+ /// yet. A cycle is broken the same way, by rooting the first node of it — a wrong tree beats a
23
+ /// walk that never ends.
24
+ export function buildLogTree(sources) {
25
+ const byId = new Map();
26
+ for (const s of sources)
27
+ byId.set(s.id, { ...s, name: s.name && s.name.length > 0 ? s.name : '—', depth: 0, children: [] });
28
+ const roots = [];
29
+ for (const node of byId.values()) {
30
+ const parent = node.parentId != null ? byId.get(node.parentId) : undefined;
31
+ if (parent !== undefined && parent !== node && !descends(byId, parent, node.id))
32
+ parent.children.push(node);
33
+ else
34
+ roots.push(node);
35
+ }
36
+ const setDepth = (node, depth) => {
37
+ node.depth = depth;
38
+ for (const child of node.children)
39
+ setDepth(child, depth + 1);
40
+ };
41
+ for (const root of roots)
42
+ setDepth(root, 0);
43
+ return roots;
44
+ }
45
+ /// Whether `node` already sits under `id`, which is how a cycle is spotted before it is made.
46
+ function descends(byId, node, id) {
47
+ const seen = new Set();
48
+ let at = node;
49
+ while (at !== undefined && !seen.has(at.id)) {
50
+ if (at.id === id)
51
+ return true;
52
+ seen.add(at.id);
53
+ at = at.parentId != null ? byId.get(at.parentId) : undefined;
54
+ }
55
+ return false;
56
+ }
57
+ /// The ids a selected node covers: itself and everything under it, or null for no selection.
58
+ ///
59
+ /// Null rather than every id, because "everything" and "this node, which happens to be the
60
+ /// root" are different questions and only one of them narrows when a new source appears.
61
+ export function subtreeOf(sources, selectedId) {
62
+ if (selectedId === null)
63
+ return null;
64
+ const children = new Map();
65
+ for (const s of sources) {
66
+ if (s.parentId == null)
67
+ continue;
68
+ const siblings = children.get(s.parentId);
69
+ if (siblings === undefined)
70
+ children.set(s.parentId, [s.id]);
71
+ else
72
+ siblings.push(s.id);
73
+ }
74
+ const out = new Set();
75
+ const walk = (id) => {
76
+ if (out.has(id))
77
+ return;
78
+ out.add(id);
79
+ for (const child of children.get(id) ?? [])
80
+ walk(child);
81
+ };
82
+ walk(selectedId);
83
+ return out;
84
+ }
85
+ /// Whether this message belongs in that view. Every filter applies at once.
86
+ export function keepLog(message, view) {
87
+ if (!view.levels.has(message.level))
88
+ return false;
89
+ if (view.sources !== null && !view.sources.has(message.sourceId))
90
+ return false;
91
+ const text = view.text.trim();
92
+ if (text.length === 0)
93
+ return true;
94
+ return (message.message ?? '').toLowerCase().includes(text.toLowerCase());
95
+ }
96
+ //# sourceMappingURL=log-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-tree.js","sourceRoot":"","sources":["../../src/log-tree.ts"],"names":[],"mappings":"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"}