@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.
- package/README.md +92 -6
- package/dist/esm/active-orders-widget.js +9 -0
- package/dist/esm/active-orders-widget.js.map +1 -1
- package/dist/esm/control-types.js +3 -0
- package/dist/esm/control-types.js.map +1 -1
- package/dist/esm/grid-menu.js +54 -0
- package/dist/esm/grid-menu.js.map +1 -0
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/order-entry-widget.js +654 -0
- package/dist/esm/order-entry-widget.js.map +1 -0
- package/dist/esm/orderbook-depth.js +51 -0
- package/dist/esm/orderbook-depth.js.map +1 -0
- package/dist/esm/orderbook-widget.js +792 -0
- package/dist/esm/orderbook-widget.js.map +1 -0
- package/dist/esm/positions-widget.js +9 -0
- package/dist/esm/positions-widget.js.map +1 -1
- package/dist/esm/trade-history-widget.js +8 -0
- package/dist/esm/trade-history-widget.js.map +1 -1
- package/dist/esm/tradefeed-aggregator.js +58 -0
- package/dist/esm/tradefeed-aggregator.js.map +1 -0
- package/dist/esm/tradefeed-bubbles.js +131 -0
- package/dist/esm/tradefeed-bubbles.js.map +1 -0
- package/dist/esm/tradefeed-widget.js +692 -0
- package/dist/esm/tradefeed-widget.js.map +1 -0
- package/dist/esm/trading-host.js +2 -0
- package/dist/esm/trading-host.js.map +1 -1
- package/dist/esm/watchlist-widget.js +2 -0
- package/dist/esm/watchlist-widget.js.map +1 -1
- package/dist/sstradingcontrols.js +3346 -25
- package/dist/sstradingcontrols.js.map +3 -3
- package/dist/types/active-orders-widget.d.ts.map +1 -1
- package/dist/types/control-types.d.ts +3 -0
- package/dist/types/control-types.d.ts.map +1 -1
- package/dist/types/grid-menu.d.ts +4 -0
- package/dist/types/grid-menu.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/order-entry-widget.d.ts +86 -0
- package/dist/types/order-entry-widget.d.ts.map +1 -0
- package/dist/types/orderbook-depth.d.ts +19 -0
- package/dist/types/orderbook-depth.d.ts.map +1 -0
- package/dist/types/orderbook-widget.d.ts +105 -0
- package/dist/types/orderbook-widget.d.ts.map +1 -0
- package/dist/types/positions-widget.d.ts.map +1 -1
- package/dist/types/trade-history-widget.d.ts.map +1 -1
- package/dist/types/tradefeed-aggregator.d.ts +15 -0
- package/dist/types/tradefeed-aggregator.d.ts.map +1 -0
- package/dist/types/tradefeed-bubbles.d.ts +39 -0
- package/dist/types/tradefeed-bubbles.d.ts.map +1 -0
- package/dist/types/tradefeed-widget.d.ts +78 -0
- package/dist/types/tradefeed-widget.d.ts.map +1 -0
- package/dist/types/trading-data.d.ts +22 -0
- package/dist/types/trading-data.d.ts.map +1 -1
- package/dist/types/trading-host.d.ts +8 -0
- package/dist/types/trading-host.d.ts.map +1 -1
- package/dist/types/watchlist-widget.d.ts.map +1 -1
- package/package.json +21 -2
- package/screenshots/panels.jpg +0 -0
- package/src/active-orders-widget.ts +9 -0
- package/src/control-types.ts +3 -0
- package/src/grid-menu.ts +67 -0
- package/src/index.ts +31 -0
- package/src/order-entry-widget.ts +733 -0
- package/src/orderbook-depth.ts +99 -0
- package/src/orderbook-widget.ts +896 -0
- package/src/positions-widget.ts +9 -0
- package/src/trade-history-widget.ts +8 -0
- package/src/tradefeed-aggregator.ts +95 -0
- package/src/tradefeed-bubbles.ts +194 -0
- package/src/tradefeed-widget.ts +744 -0
- package/src/trading-data.ts +168 -121
- package/src/trading-host.ts +326 -300
- package/src/watchlist-widget.ts +2 -0
- package/styles/theme.css +23 -0
- package/styles/trading-controls.css +911 -0
- package/translation-keys.json +103 -2
package/src/trading-data.ts
CHANGED
|
@@ -1,121 +1,168 @@
|
|
|
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
|
-
|
|
26
|
-
/// Buy or sell, in any of the spellings the wire uses: `0`/`1`, `'Buy'`/`'Sell'`
|
|
27
|
-
/// or `'BUY'`/`'SELL'`.
|
|
28
|
-
export type OrderSide = number | string;
|
|
29
|
-
|
|
30
|
-
/// A StockSharp `OrderTypes` value (`0` limit, `1` market, `2` conditional) or
|
|
31
|
-
/// its name.
|
|
32
|
-
export type OrderType = number | string;
|
|
33
|
-
|
|
34
|
-
/// A StockSharp `OrderStates` value (see `OrderStates` in
|
|
35
|
-
/// `active-orders-widget.ts`) or its name.
|
|
36
|
-
export type OrderStatus = number | string;
|
|
37
|
-
|
|
38
|
-
/// One open position in a portfolio.
|
|
39
|
-
export interface PositionRow {
|
|
40
|
-
portfolioId?: number | null;
|
|
41
|
-
/// Numeric instrument id where the source has one. Rows from an unsaved
|
|
42
|
-
/// snapshot may carry only `instrument`, which is why the identity used for
|
|
43
|
-
/// matching falls back to it.
|
|
44
|
-
instrumentId?: number | null;
|
|
45
|
-
instrument?: string;
|
|
46
|
-
quantity?: number | null;
|
|
47
|
-
avgPrice?: number | null;
|
|
48
|
-
currentPrice?: number | null;
|
|
49
|
-
unrealizedPnl?: number | null;
|
|
50
|
-
realizedPnl?: number | null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// The cash side of a portfolio, rendered as a pinned row above the positions.
|
|
54
|
-
export interface BalanceRow {
|
|
55
|
-
available?: number | null;
|
|
56
|
-
locked?: number | null;
|
|
57
|
-
total?: number | null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/// One live or recently terminal order.
|
|
61
|
-
export interface OrderRow {
|
|
62
|
-
/// The register transaction id. This is what cancel, replace and inline edit
|
|
63
|
-
/// address an order by, and what the grid keys rows on.
|
|
64
|
-
id?: number | null;
|
|
65
|
-
/// Per-user friendly counter shown in the ID column. Absent on rows cached
|
|
66
|
-
/// from before the counter shipped.
|
|
67
|
-
localId?: number | null;
|
|
68
|
-
instrument?: string;
|
|
69
|
-
side?: OrderSide;
|
|
70
|
-
type?: OrderType;
|
|
71
|
-
quantity?: number | null;
|
|
72
|
-
/// The unfilled remainder. A control that shows what is still resting on
|
|
73
|
-
/// the book reads this and falls back to `quantity` — a snapshot row taken
|
|
74
|
-
/// before anything filled carries only the latter.
|
|
75
|
-
balance?: number | null;
|
|
76
|
-
limitPrice?: number | null;
|
|
77
|
-
stopPrice?: number | null;
|
|
78
|
-
status?: OrderStatus;
|
|
79
|
-
/// Venue text for a rejection. Some adapters wrap it in a JSON blob — see
|
|
80
|
-
/// `cleanRejectReason`.
|
|
81
|
-
rejectReason?: string;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/// One executed trade.
|
|
85
|
-
export interface TradeRow {
|
|
86
|
-
id?: number | null;
|
|
87
|
-
/// Execution time. `executedAt` is what the API returns; `time` is what a
|
|
88
|
-
/// socket fill carries, and the control reads whichever is present.
|
|
89
|
-
executedAt?: string;
|
|
90
|
-
time?: string;
|
|
91
|
-
instrumentSymbol?: string;
|
|
92
|
-
symbol?: string;
|
|
93
|
-
side?: OrderSide;
|
|
94
|
-
quantity?: number | null;
|
|
95
|
-
price?: number | null;
|
|
96
|
-
/// The order this fill belongs to, under either of the two names the
|
|
97
|
-
/// endpoints use.
|
|
98
|
-
order?: number | null;
|
|
99
|
-
orderId?: number | null;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/// One tradable instrument, as the instrument search returns it.
|
|
103
|
-
export interface InstrumentRow {
|
|
104
|
-
/// Qualified symbol — `BTC@IMEX`. The display form drops the venue.
|
|
105
|
-
symbol?: string;
|
|
106
|
-
name?: string;
|
|
107
|
-
exchange?: string;
|
|
108
|
-
/// Admin-assigned grouping. The watchlist turns the distinct values into
|
|
109
|
-
/// filter tabs, so the tab set is configured rather than hardcoded.
|
|
110
|
-
category?: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
///
|
|
114
|
-
///
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
+
|
|
26
|
+
/// Buy or sell, in any of the spellings the wire uses: `0`/`1`, `'Buy'`/`'Sell'`
|
|
27
|
+
/// or `'BUY'`/`'SELL'`.
|
|
28
|
+
export type OrderSide = number | string;
|
|
29
|
+
|
|
30
|
+
/// A StockSharp `OrderTypes` value (`0` limit, `1` market, `2` conditional) or
|
|
31
|
+
/// its name.
|
|
32
|
+
export type OrderType = number | string;
|
|
33
|
+
|
|
34
|
+
/// A StockSharp `OrderStates` value (see `OrderStates` in
|
|
35
|
+
/// `active-orders-widget.ts`) or its name.
|
|
36
|
+
export type OrderStatus = number | string;
|
|
37
|
+
|
|
38
|
+
/// One open position in a portfolio.
|
|
39
|
+
export interface PositionRow {
|
|
40
|
+
portfolioId?: number | null;
|
|
41
|
+
/// Numeric instrument id where the source has one. Rows from an unsaved
|
|
42
|
+
/// snapshot may carry only `instrument`, which is why the identity used for
|
|
43
|
+
/// matching falls back to it.
|
|
44
|
+
instrumentId?: number | null;
|
|
45
|
+
instrument?: string;
|
|
46
|
+
quantity?: number | null;
|
|
47
|
+
avgPrice?: number | null;
|
|
48
|
+
currentPrice?: number | null;
|
|
49
|
+
unrealizedPnl?: number | null;
|
|
50
|
+
realizedPnl?: number | null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// The cash side of a portfolio, rendered as a pinned row above the positions.
|
|
54
|
+
export interface BalanceRow {
|
|
55
|
+
available?: number | null;
|
|
56
|
+
locked?: number | null;
|
|
57
|
+
total?: number | null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// One live or recently terminal order.
|
|
61
|
+
export interface OrderRow {
|
|
62
|
+
/// The register transaction id. This is what cancel, replace and inline edit
|
|
63
|
+
/// address an order by, and what the grid keys rows on.
|
|
64
|
+
id?: number | null;
|
|
65
|
+
/// Per-user friendly counter shown in the ID column. Absent on rows cached
|
|
66
|
+
/// from before the counter shipped.
|
|
67
|
+
localId?: number | null;
|
|
68
|
+
instrument?: string;
|
|
69
|
+
side?: OrderSide;
|
|
70
|
+
type?: OrderType;
|
|
71
|
+
quantity?: number | null;
|
|
72
|
+
/// The unfilled remainder. A control that shows what is still resting on
|
|
73
|
+
/// the book reads this and falls back to `quantity` — a snapshot row taken
|
|
74
|
+
/// before anything filled carries only the latter.
|
|
75
|
+
balance?: number | null;
|
|
76
|
+
limitPrice?: number | null;
|
|
77
|
+
stopPrice?: number | null;
|
|
78
|
+
status?: OrderStatus;
|
|
79
|
+
/// Venue text for a rejection. Some adapters wrap it in a JSON blob — see
|
|
80
|
+
/// `cleanRejectReason`.
|
|
81
|
+
rejectReason?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// One executed trade.
|
|
85
|
+
export interface TradeRow {
|
|
86
|
+
id?: number | null;
|
|
87
|
+
/// Execution time. `executedAt` is what the API returns; `time` is what a
|
|
88
|
+
/// socket fill carries, and the control reads whichever is present.
|
|
89
|
+
executedAt?: string;
|
|
90
|
+
time?: string;
|
|
91
|
+
instrumentSymbol?: string;
|
|
92
|
+
symbol?: string;
|
|
93
|
+
side?: OrderSide;
|
|
94
|
+
quantity?: number | null;
|
|
95
|
+
price?: number | null;
|
|
96
|
+
/// The order this fill belongs to, under either of the two names the
|
|
97
|
+
/// endpoints use.
|
|
98
|
+
order?: number | null;
|
|
99
|
+
orderId?: number | null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// One tradable instrument, as the instrument search returns it.
|
|
103
|
+
export interface InstrumentRow {
|
|
104
|
+
/// Qualified symbol — `BTC@IMEX`. The display form drops the venue.
|
|
105
|
+
symbol?: string;
|
|
106
|
+
name?: string;
|
|
107
|
+
exchange?: string;
|
|
108
|
+
/// Admin-assigned grouping. The watchlist turns the distinct values into
|
|
109
|
+
/// filter tabs, so the tab set is configured rather than hardcoded.
|
|
110
|
+
category?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// One price level of an order book side, as the wire delivers it. A level
|
|
114
|
+
/// whose quantity is zero is a delete instruction in a diff frame, not an empty
|
|
115
|
+
/// level, so the field carries meaning at every value including zero.
|
|
116
|
+
export interface QuoteLevel {
|
|
117
|
+
price?: number | null;
|
|
118
|
+
quantity?: number | null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// One order-book update.
|
|
122
|
+
///
|
|
123
|
+
/// The first frame of a (re)subscription is a snapshot: the receiver drops what
|
|
124
|
+
/// it holds and applies every level. The frames after it are diffs touching
|
|
125
|
+
/// only the levels that changed. `sequence` is monotonic per symbol, so a gap
|
|
126
|
+
/// means a frame was missed and the diffs after it cannot be trusted — the cure
|
|
127
|
+
/// is a fresh snapshot, which is what `MarketDataClient.resubscribe` asks for.
|
|
128
|
+
export interface OrderBookFrame {
|
|
129
|
+
symbol?: string;
|
|
130
|
+
sequence?: number | null;
|
|
131
|
+
isSnapshot?: boolean;
|
|
132
|
+
bids?: QuoteLevel[];
|
|
133
|
+
asks?: QuoteLevel[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/// One level of a book a control has already accepted: sorted, clipped to the
|
|
137
|
+
/// visible depth and free of the malformed levels a wire frame can carry. Both
|
|
138
|
+
/// fields are present, which is the difference from `QuoteLevel` — everything
|
|
139
|
+
/// that could be absent was dropped on the way in.
|
|
140
|
+
export interface BookLevel {
|
|
141
|
+
price: number;
|
|
142
|
+
quantity: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// The grid a venue will accept an order on: the sizes it trades in and the
|
|
146
|
+
/// prices it quotes at. Separate from `InstrumentRow` because it answers a
|
|
147
|
+
/// different question — that one is what an instrument IS, this one is what an
|
|
148
|
+
/// order on it may say — and the two arrive from different endpoints.
|
|
149
|
+
export interface InstrumentSpec {
|
|
150
|
+
symbol?: string;
|
|
151
|
+
/// The size an order's quantity must be a whole number of.
|
|
152
|
+
lotSize?: number | null;
|
|
153
|
+
/// The smallest price increment the venue quotes.
|
|
154
|
+
tickSize?: number | null;
|
|
155
|
+
minVolume?: number | null;
|
|
156
|
+
/// Absent (or null) means the venue states no upper bound.
|
|
157
|
+
maxVolume?: number | null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// What a control has computed about a symbol from the live tape. Handed to the
|
|
161
|
+
/// host's ticker sink as-is.
|
|
162
|
+
export interface QuoteStats {
|
|
163
|
+
lastPrice?: number | null;
|
|
164
|
+
/// First price observed this session-day, the change percentage is measured
|
|
165
|
+
/// from.
|
|
166
|
+
baseline?: number | null;
|
|
167
|
+
chgPct?: number | null;
|
|
168
|
+
}
|