@stocksharp/trading-controls 1.1.0 → 1.2.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.
- package/dist/esm/active-orders-widget.js +38 -25
- package/dist/esm/active-orders-widget.js.map +1 -1
- package/dist/esm/trade-history-widget.js +14 -6
- package/dist/esm/trade-history-widget.js.map +1 -1
- package/dist/esm/tradefeed-widget.js +3 -3
- package/dist/esm/tradefeed-widget.js.map +1 -1
- package/dist/esm/trading-host.js +1 -0
- package/dist/esm/trading-host.js.map +1 -1
- package/dist/sstradingcontrols.js +51 -31
- package/dist/sstradingcontrols.js.map +2 -2
- package/dist/types/active-orders-widget.d.ts +11 -3
- package/dist/types/active-orders-widget.d.ts.map +1 -1
- package/dist/types/trade-history-widget.d.ts +3 -1
- package/dist/types/trade-history-widget.d.ts.map +1 -1
- package/dist/types/trading-host.d.ts +1 -0
- package/dist/types/trading-host.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/active-orders-widget.ts +49 -25
- package/src/trade-history-widget.ts +19 -6
- package/src/tradefeed-widget.ts +3 -3
- package/src/trading-host.ts +8 -0
|
@@ -73,6 +73,7 @@ var SSTradingControls = (() => {
|
|
|
73
73
|
_required(host.presentation.isBuy, "host.presentation.isBuy", "function", controlName);
|
|
74
74
|
_required(host.presentation.typeText, "host.presentation.typeText", "function", controlName);
|
|
75
75
|
_required(host.presentation.statusText, "host.presentation.statusText", "function", controlName);
|
|
76
|
+
_required(host.presentation.timeText, "host.presentation.timeText", "function", controlName);
|
|
76
77
|
_required(host.presentation.sideClass, "host.presentation.sideClass", "function", controlName);
|
|
77
78
|
_required(host.presentation.pnlClass, "host.presentation.pnlClass", "function", controlName);
|
|
78
79
|
_required(host.presentation.canvasPalette, "host.presentation.canvasPalette", "function", controlName);
|
|
@@ -1863,7 +1864,7 @@ var SSTradingControls = (() => {
|
|
|
1863
1864
|
var _ActiveOrdersWidget = class _ActiveOrdersWidget {
|
|
1864
1865
|
static create(hostEl, state, deps) {
|
|
1865
1866
|
const host = assertHost(deps?.host, "ActiveOrdersWidget");
|
|
1866
|
-
const root = _ActiveOrdersWidget._buildRoot(host);
|
|
1867
|
+
const root = _ActiveOrdersWidget._buildRoot(host, deps?.readOnly === true);
|
|
1867
1868
|
root.id = makePanelId(_ActiveOrdersWidget.TYPE);
|
|
1868
1869
|
hostEl.appendChild(root);
|
|
1869
1870
|
return new _ActiveOrdersWidget(root, state || {}, deps);
|
|
@@ -1879,7 +1880,7 @@ var SSTradingControls = (() => {
|
|
|
1879
1880
|
// already give the identical button — and are wired to deps. Cancel-all
|
|
1880
1881
|
// keeps a distinct accessible name from its tooltip, which is why it states
|
|
1881
1882
|
// `aria-label` rather than taking the tooltip for both.
|
|
1882
|
-
static _buildRoot(host) {
|
|
1883
|
+
static _buildRoot(host, readOnly = false) {
|
|
1883
1884
|
return makePanelRoot("active-orders-panel", host.t("ActiveOrders"), [
|
|
1884
1885
|
makeElement("div", "panel-header", {}, [
|
|
1885
1886
|
makeElement("span", "", {}, [host.t("OpenOrders")]),
|
|
@@ -1893,13 +1894,15 @@ var SSTradingControls = (() => {
|
|
|
1893
1894
|
])
|
|
1894
1895
|
]),
|
|
1895
1896
|
makeElement("div", "panel-rail", { role: "toolbar", "aria-label": host.t("ActiveOrdersActions") }, [
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1897
|
+
...readOnly ? [] : [
|
|
1898
|
+
makeIconButton(
|
|
1899
|
+
"bt-icon-btn bt-icon-cancel-all panel-cancel-all-btn",
|
|
1900
|
+
host.t("CancelAll"),
|
|
1901
|
+
"bi-x-circle",
|
|
1902
|
+
{ "aria-label": host.t("CancelAllOrders") }
|
|
1903
|
+
),
|
|
1904
|
+
makeIconButton("bt-icon-btn panel-refresh-btn", host.t("Refresh"), "bi-arrow-clockwise", {})
|
|
1905
|
+
],
|
|
1903
1906
|
makeIconButton("bt-icon-btn panel-export-btn", host.t("ExportToExcel"), "bi-file-earmark-spreadsheet", {})
|
|
1904
1907
|
])
|
|
1905
1908
|
])
|
|
@@ -1907,9 +1910,16 @@ var SSTradingControls = (() => {
|
|
|
1907
1910
|
}
|
|
1908
1911
|
constructor(rootEl, _state, deps) {
|
|
1909
1912
|
this._host = assertHost(deps?.host, "ActiveOrdersWidget");
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
+
this._readOnly = deps?.readOnly === true;
|
|
1914
|
+
if (this._readOnly) {
|
|
1915
|
+
this._actions = null;
|
|
1916
|
+
} else {
|
|
1917
|
+
const actions = deps;
|
|
1918
|
+
for (const name of ["cancelOrder", "dismissOrder", "editOrderField", "replaceOrder", "cancelAllOrders", "refreshOrders"]) {
|
|
1919
|
+
if (typeof actions?.[name] !== "function")
|
|
1920
|
+
throw new Error(`ActiveOrdersWidget: dep "${name}" is required`);
|
|
1921
|
+
}
|
|
1922
|
+
this._actions = actions;
|
|
1913
1923
|
}
|
|
1914
1924
|
this.rootEl = rootEl;
|
|
1915
1925
|
this._deps = deps;
|
|
@@ -1925,11 +1935,11 @@ var SSTradingControls = (() => {
|
|
|
1925
1935
|
});
|
|
1926
1936
|
this._cancelAllBtn?.addEventListener("click", (e) => {
|
|
1927
1937
|
e.preventDefault();
|
|
1928
|
-
this.
|
|
1938
|
+
this._actions?.cancelAllOrders();
|
|
1929
1939
|
});
|
|
1930
1940
|
this._refreshBtn?.addEventListener("click", (e) => {
|
|
1931
1941
|
e.preventDefault();
|
|
1932
|
-
this.
|
|
1942
|
+
this._actions?.refreshOrders();
|
|
1933
1943
|
});
|
|
1934
1944
|
this._exportBtn?.addEventListener("click", (e) => {
|
|
1935
1945
|
e.preventDefault();
|
|
@@ -2032,7 +2042,7 @@ var SSTradingControls = (() => {
|
|
|
2032
2042
|
}
|
|
2033
2043
|
const updated = { quantity: order.quantity, limitPrice: order.limitPrice, stopPrice: order.stopPrice };
|
|
2034
2044
|
updated[field] = newVal;
|
|
2035
|
-
this.
|
|
2045
|
+
this._actions?.replaceOrder(orderId, updated.quantity, updated.limitPrice, updated.stopPrice);
|
|
2036
2046
|
};
|
|
2037
2047
|
input.addEventListener("blur", commit);
|
|
2038
2048
|
input.addEventListener("keydown", (e) => {
|
|
@@ -2092,7 +2102,7 @@ var SSTradingControls = (() => {
|
|
|
2092
2102
|
exportable: true,
|
|
2093
2103
|
value: (o) => o.quantity,
|
|
2094
2104
|
render: (o) => formatQty(o.quantity),
|
|
2095
|
-
cellClass: (o) => _ActiveOrdersWidget._editableClass(o, "quantity"),
|
|
2105
|
+
cellClass: (o) => this._readOnly ? "" : _ActiveOrdersWidget._editableClass(o, "quantity"),
|
|
2096
2106
|
bindCell: (td, o) => this._bindInlineEdit(td, o, "quantity")
|
|
2097
2107
|
},
|
|
2098
2108
|
{
|
|
@@ -2101,7 +2111,7 @@ var SSTradingControls = (() => {
|
|
|
2101
2111
|
exportable: true,
|
|
2102
2112
|
value: (o) => o.limitPrice,
|
|
2103
2113
|
render: (o) => o.limitPrice ? formatPrice(o.limitPrice) : label("MKT"),
|
|
2104
|
-
cellClass: (o) => _ActiveOrdersWidget._editableClass(o, "limitPrice"),
|
|
2114
|
+
cellClass: (o) => this._readOnly ? "" : _ActiveOrdersWidget._editableClass(o, "limitPrice"),
|
|
2105
2115
|
bindCell: (td, o) => this._bindInlineEdit(td, o, "limitPrice"),
|
|
2106
2116
|
exportValue: (o) => o.limitPrice ?? label("MKT")
|
|
2107
2117
|
},
|
|
@@ -2111,7 +2121,7 @@ var SSTradingControls = (() => {
|
|
|
2111
2121
|
exportable: true,
|
|
2112
2122
|
value: (o) => o.stopPrice,
|
|
2113
2123
|
render: (o) => o.stopPrice ? formatPrice(o.stopPrice) : "--",
|
|
2114
|
-
cellClass: (o) => _ActiveOrdersWidget._editableClass(o, "stopPrice"),
|
|
2124
|
+
cellClass: (o) => this._readOnly ? "" : _ActiveOrdersWidget._editableClass(o, "stopPrice"),
|
|
2115
2125
|
bindCell: (td, o) => this._bindInlineEdit(td, o, "stopPrice"),
|
|
2116
2126
|
exportValue: (o) => o.stopPrice ?? ""
|
|
2117
2127
|
},
|
|
@@ -2123,14 +2133,14 @@ var SSTradingControls = (() => {
|
|
|
2123
2133
|
render: (o) => this._statusCell(o),
|
|
2124
2134
|
exportValue: (o) => presentation.statusText(o.status)
|
|
2125
2135
|
},
|
|
2126
|
-
{
|
|
2136
|
+
...this._readOnly ? [] : [{
|
|
2127
2137
|
key: "actions",
|
|
2128
2138
|
header: label("Actions"),
|
|
2129
2139
|
headerHidden: true,
|
|
2130
2140
|
exportable: false,
|
|
2131
2141
|
cellClass: () => "position-actions",
|
|
2132
2142
|
render: (o) => this._actionButton(o)
|
|
2133
|
-
}
|
|
2143
|
+
}]
|
|
2134
2144
|
];
|
|
2135
2145
|
}
|
|
2136
2146
|
static _rowClass(order) {
|
|
@@ -2152,8 +2162,9 @@ var SSTradingControls = (() => {
|
|
|
2152
2162
|
// Double-click to edit belongs to the whole cell rather than to a control
|
|
2153
2163
|
// inside it, which is why it is wired here instead of returned by render().
|
|
2154
2164
|
_bindInlineEdit(td, order, field) {
|
|
2155
|
-
if (!_ActiveOrdersWidget._canEdit(order, field)) return;
|
|
2156
|
-
|
|
2165
|
+
if (this._actions === null || !_ActiveOrdersWidget._canEdit(order, field)) return;
|
|
2166
|
+
const edit = this._actions.editOrderField;
|
|
2167
|
+
td.addEventListener("dblclick", () => edit(order.id, field));
|
|
2157
2168
|
}
|
|
2158
2169
|
// Status text, plus a hoverable icon carrying the rejection reason. Some
|
|
2159
2170
|
// venues wrap the human-readable rejection inside a JSON blob;
|
|
@@ -2189,8 +2200,9 @@ var SSTradingControls = (() => {
|
|
|
2189
2200
|
icon.className = "bi bi-x-circle";
|
|
2190
2201
|
button.appendChild(icon);
|
|
2191
2202
|
button.addEventListener("click", () => {
|
|
2192
|
-
if (
|
|
2193
|
-
|
|
2203
|
+
if (this._actions === null) return;
|
|
2204
|
+
if (isTerminal) this._actions.dismissOrder(order.id);
|
|
2205
|
+
else this._actions.cancelOrder(order.id);
|
|
2194
2206
|
});
|
|
2195
2207
|
return button;
|
|
2196
2208
|
}
|
|
@@ -2447,14 +2459,14 @@ var SSTradingControls = (() => {
|
|
|
2447
2459
|
var _TradeHistoryWidget = class _TradeHistoryWidget {
|
|
2448
2460
|
static create(hostEl, state, deps) {
|
|
2449
2461
|
const host = assertHost(deps?.host, "TradeHistoryWidget");
|
|
2450
|
-
const root = _TradeHistoryWidget._buildRoot(host);
|
|
2462
|
+
const root = _TradeHistoryWidget._buildRoot(host, deps?.readOnly === true);
|
|
2451
2463
|
root.id = makePanelId(_TradeHistoryWidget.TYPE);
|
|
2452
2464
|
hostEl.appendChild(root);
|
|
2453
2465
|
return new _TradeHistoryWidget(root, state || {}, deps);
|
|
2454
2466
|
}
|
|
2455
2467
|
// The panel's markup. The host stylesheet reads this structure, and a
|
|
2456
2468
|
// docking host lifts `.panel-header`'s children into its tab strip.
|
|
2457
|
-
static _buildRoot(host) {
|
|
2469
|
+
static _buildRoot(host, readOnly = false) {
|
|
2458
2470
|
const title = host.t("TradeHistory");
|
|
2459
2471
|
return makePanelRoot("trade-history-panel", title, [
|
|
2460
2472
|
makeElement("div", "panel-header", {}, [
|
|
@@ -2469,7 +2481,7 @@ var SSTradingControls = (() => {
|
|
|
2469
2481
|
])
|
|
2470
2482
|
]),
|
|
2471
2483
|
makeElement("div", "panel-rail", { role: "toolbar", "aria-label": host.t("TradeHistoryActions") }, [
|
|
2472
|
-
makeIconButton("bt-icon-btn panel-refresh-btn", host.t("Refresh"), "bi-arrow-clockwise", {}),
|
|
2484
|
+
...readOnly ? [] : [makeIconButton("bt-icon-btn panel-refresh-btn", host.t("Refresh"), "bi-arrow-clockwise", {})],
|
|
2473
2485
|
makeIconButton("bt-icon-btn panel-export-btn", host.t("ExportToExcel"), "bi-file-earmark-spreadsheet", {})
|
|
2474
2486
|
])
|
|
2475
2487
|
])
|
|
@@ -2545,6 +2557,14 @@ var SSTradingControls = (() => {
|
|
|
2545
2557
|
this._host.log(`TradeHistoryWidget: failed to load trade history: ${err}`);
|
|
2546
2558
|
}
|
|
2547
2559
|
}
|
|
2560
|
+
/// Show these rows. The push path, for a consumer that already holds the
|
|
2561
|
+
/// trades - a finished run's report - rather than an account to load them
|
|
2562
|
+
/// from. `refresh` is the pull path and the two do not mix: whichever ran
|
|
2563
|
+
/// last is what the grid shows.
|
|
2564
|
+
update(rows) {
|
|
2565
|
+
this._rows = rows || [];
|
|
2566
|
+
this._grid?.setRows(this._rows);
|
|
2567
|
+
}
|
|
2548
2568
|
// Export the table to .xlsx in the currently rendered (sorted) order.
|
|
2549
2569
|
_export() {
|
|
2550
2570
|
this._grid?.download("trades", this._host.t("TradeHistory"));
|
|
@@ -2568,8 +2588,8 @@ var SSTradingControls = (() => {
|
|
|
2568
2588
|
header: label("Time"),
|
|
2569
2589
|
exportable: true,
|
|
2570
2590
|
value: (t) => t.executedAt || t.time,
|
|
2571
|
-
render: (t) =>
|
|
2572
|
-
exportValue: (t) =>
|
|
2591
|
+
render: (t) => presentation.timeText(t.executedAt || t.time),
|
|
2592
|
+
exportValue: (t) => presentation.timeText(t.executedAt || t.time)
|
|
2573
2593
|
},
|
|
2574
2594
|
{
|
|
2575
2595
|
key: "symbol",
|
|
@@ -4713,7 +4733,7 @@ var SSTradingControls = (() => {
|
|
|
4713
4733
|
header: label("Time"),
|
|
4714
4734
|
exportable: true,
|
|
4715
4735
|
value: (t) => String(t.time || t.executedAt || ""),
|
|
4716
|
-
render: (t) =>
|
|
4736
|
+
render: (t) => this._host.presentation.timeText(t.time || t.executedAt)
|
|
4717
4737
|
},
|
|
4718
4738
|
{
|
|
4719
4739
|
key: "symbol",
|
|
@@ -5018,7 +5038,7 @@ var SSTradingControls = (() => {
|
|
|
5018
5038
|
const side = bubble.side;
|
|
5019
5039
|
const lines = [];
|
|
5020
5040
|
if (this._extraSymbols.size > 0) lines.push(this._tooltipLine(this._host.t("Symbol"), bubble.symbol, ""));
|
|
5021
|
-
lines.push(this._tooltipLine(this._host.t("Time"),
|
|
5041
|
+
lines.push(this._tooltipLine(this._host.t("Time"), this._host.presentation.timeText(bubble.time), ""));
|
|
5022
5042
|
lines.push(this._tooltipLine(aggregated ? this._host.t("VWAP") : this._host.t("Price"), formatPrice(bubble.price), ""));
|
|
5023
5043
|
lines.push(this._tooltipLine(aggregated ? this._host.t("Total qty") : this._host.t("Qty"), formatQty(bubble.quantity), ""));
|
|
5024
5044
|
lines.push(this._tooltipLine(this._host.t("Side"), presentation.sideText(side), presentation.sideClass(side)));
|