@tradecanvas/svelte 1.1.0 → 1.2.2
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 +1 -1
- package/dist/TradeCanvas.svelte +40 -26
- package/dist/TradeCanvas.svelte.d.ts +7 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Streams live Binance data by default. Pass `data={bars}` for static OHLC, or `ad
|
|
|
35
35
|
|
|
36
36
|
## Props
|
|
37
37
|
|
|
38
|
-
`symbol`, `timeframe`, `theme`, `chartType`, `indicators
|
|
38
|
+
`symbol`, `timeframe`, `theme`, `chartType`, `indicators` (ids, or `{ id, params, position }`), `data` (bars of your own; no stream), `adapter`, `stream` (`false`: no stream of its own), `historyLimit`, `features` (changes apply after mount too), `autoScale`, `signalMarkers`, `signalMarkerStyle`, `tradeZones`, `tradeZoneStyle`, `overrides` (style overrides by key, all of your app's), `watermarkText`, `onReady`, and `bind:chart`.
|
|
39
39
|
|
|
40
40
|
Reach the underlying `Chart` (drawings, trading, execution adapters, plugins, resizable panes) via `bind:chart` or `onReady`. See the [main docs](https://github.com/bonguynvan/tradecanvas).
|
|
41
41
|
|
package/dist/TradeCanvas.svelte
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
BinanceAdapter,
|
|
6
6
|
DARK_THEME,
|
|
7
7
|
LIGHT_THEME,
|
|
8
|
+
syncIndicators,
|
|
8
9
|
} from '@tradecanvas/chart';
|
|
9
10
|
import type {
|
|
10
11
|
ChartType,
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
TradeZoneStyle,
|
|
19
20
|
DataAdapter,
|
|
20
21
|
ChartStyleOverrides,
|
|
22
|
+
IndicatorSpec,
|
|
21
23
|
} from '@tradecanvas/chart';
|
|
22
24
|
|
|
23
25
|
interface Props {
|
|
@@ -25,10 +27,15 @@
|
|
|
25
27
|
timeframe?: TimeFrame;
|
|
26
28
|
theme?: 'dark' | 'light' | Theme;
|
|
27
29
|
chartType?: ChartType;
|
|
28
|
-
|
|
30
|
+
/** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */
|
|
31
|
+
indicators?: IndicatorSpec[];
|
|
32
|
+
/** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */
|
|
29
33
|
data?: OHLCBar[];
|
|
30
34
|
adapter?: DataAdapter;
|
|
35
|
+
/** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */
|
|
36
|
+
stream?: boolean;
|
|
31
37
|
historyLimit?: number;
|
|
38
|
+
/** What users can do on the chart; changes after mount are applied too (the keys given). */
|
|
32
39
|
features?: FeaturesConfig;
|
|
33
40
|
autoScale?: boolean;
|
|
34
41
|
signalMarkers?: SignalMarker[];
|
|
@@ -47,9 +54,10 @@
|
|
|
47
54
|
timeframe = '5m' as TimeFrame,
|
|
48
55
|
theme = 'dark' as 'dark' | 'light' | Theme,
|
|
49
56
|
chartType = 'candlestick' as ChartType,
|
|
50
|
-
indicators = [] as
|
|
57
|
+
indicators = [] as IndicatorSpec[],
|
|
51
58
|
data = undefined as OHLCBar[] | undefined,
|
|
52
59
|
adapter = undefined as DataAdapter | undefined,
|
|
60
|
+
stream = true,
|
|
53
61
|
historyLimit = 500,
|
|
54
62
|
features = undefined as FeaturesConfig | undefined,
|
|
55
63
|
autoScale = true,
|
|
@@ -72,8 +80,10 @@
|
|
|
72
80
|
let container: HTMLDivElement;
|
|
73
81
|
let instance: Chart | null = null;
|
|
74
82
|
const indicatorIds = new Map<string, string>();
|
|
75
|
-
|
|
76
|
-
let
|
|
83
|
+
/** The stream open now (`symbol|timeframe`), or null. */
|
|
84
|
+
let streamKey: string | null = null;
|
|
85
|
+
/** The features last applied, as text. */
|
|
86
|
+
let featuresKey: string | null = null;
|
|
77
87
|
|
|
78
88
|
onMount(() => {
|
|
79
89
|
instance = new Chart(container, {
|
|
@@ -108,10 +118,12 @@
|
|
|
108
118
|
|
|
109
119
|
if (data) {
|
|
110
120
|
instance.setData(data);
|
|
111
|
-
} else {
|
|
121
|
+
} else if (stream) {
|
|
112
122
|
const dataAdapter = adapter ?? new BinanceAdapter();
|
|
113
123
|
instance.connect({ adapter: dataAdapter, symbol, timeframe, historyLimit });
|
|
124
|
+
streamKey = `${symbol}|${timeframe}`;
|
|
114
125
|
}
|
|
126
|
+
featuresKey = JSON.stringify($state.snapshot(features) ?? null);
|
|
115
127
|
|
|
116
128
|
onReady?.(instance);
|
|
117
129
|
});
|
|
@@ -125,38 +137,40 @@
|
|
|
125
137
|
}
|
|
126
138
|
});
|
|
127
139
|
|
|
140
|
+
// A stream of its own while it has no data; `stream={false}` closes it. Data given later leaves it be.
|
|
128
141
|
$effect(() => {
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
const key = `${symbol}|${timeframe}`;
|
|
143
|
+
const on = stream;
|
|
144
|
+
const hasData = !!data;
|
|
145
|
+
if (!instance) return;
|
|
146
|
+
if (!on) {
|
|
147
|
+
if (streamKey !== null) instance.disconnectStream();
|
|
148
|
+
streamKey = null;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (hasData || streamKey === key) return;
|
|
152
|
+
streamKey = key;
|
|
135
153
|
instance.disconnectStream();
|
|
136
154
|
const dataAdapter = adapter ?? new BinanceAdapter();
|
|
137
|
-
instance.connect({ adapter: dataAdapter, symbol
|
|
155
|
+
instance.connect({ adapter: dataAdapter, symbol, timeframe, historyLimit });
|
|
138
156
|
if (watermarkText) instance.setWatermark(watermarkText);
|
|
139
157
|
});
|
|
140
158
|
|
|
159
|
+
$effect(() => {
|
|
160
|
+
const next = $state.snapshot(features);
|
|
161
|
+
const key = JSON.stringify(next ?? null);
|
|
162
|
+
if (!instance || key === featuresKey) return;
|
|
163
|
+
featuresKey = key;
|
|
164
|
+
if (next) instance.setFeatures(next);
|
|
165
|
+
});
|
|
166
|
+
|
|
141
167
|
$effect(() => { instance?.setTheme(resolveTheme(theme)); });
|
|
142
168
|
$effect(() => { instance?.setChartType(chartType); });
|
|
143
169
|
$effect(() => { if (data) instance?.setData(data); });
|
|
144
170
|
|
|
145
171
|
$effect(() => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
for (const [name, instanceId] of indicatorIds) {
|
|
149
|
-
if (!desired.has(name)) {
|
|
150
|
-
instance.removeIndicator(instanceId);
|
|
151
|
-
indicatorIds.delete(name);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
for (const name of indicators) {
|
|
155
|
-
if (!indicatorIds.has(name)) {
|
|
156
|
-
const instanceId = instance.addIndicator(name);
|
|
157
|
-
if (instanceId) indicatorIds.set(name, instanceId);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
172
|
+
const specs = $state.snapshot(indicators) as IndicatorSpec[];
|
|
173
|
+
if (instance) syncIndicators(instance, specs, indicatorIds);
|
|
160
174
|
});
|
|
161
175
|
|
|
162
176
|
$effect(() => { if (signalMarkers) instance?.setSignalMarkers(signalMarkers); });
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { Chart } from '@tradecanvas/chart';
|
|
2
|
-
import type { ChartType, TimeFrame, FeaturesConfig, Theme, OHLCBar, SignalMarker, TradeZone, SignalMarkerStyle, TradeZoneStyle, DataAdapter, ChartStyleOverrides } from '@tradecanvas/chart';
|
|
2
|
+
import type { ChartType, TimeFrame, FeaturesConfig, Theme, OHLCBar, SignalMarker, TradeZone, SignalMarkerStyle, TradeZoneStyle, DataAdapter, ChartStyleOverrides, IndicatorSpec } from '@tradecanvas/chart';
|
|
3
3
|
interface Props {
|
|
4
4
|
symbol?: string;
|
|
5
5
|
timeframe?: TimeFrame;
|
|
6
6
|
theme?: 'dark' | 'light' | Theme;
|
|
7
7
|
chartType?: ChartType;
|
|
8
|
-
|
|
8
|
+
/** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */
|
|
9
|
+
indicators?: IndicatorSpec[];
|
|
10
|
+
/** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */
|
|
9
11
|
data?: OHLCBar[];
|
|
10
12
|
adapter?: DataAdapter;
|
|
13
|
+
/** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */
|
|
14
|
+
stream?: boolean;
|
|
11
15
|
historyLimit?: number;
|
|
16
|
+
/** What users can do on the chart; changes after mount are applied too (the keys given). */
|
|
12
17
|
features?: FeaturesConfig;
|
|
13
18
|
autoScale?: boolean;
|
|
14
19
|
signalMarkers?: SignalMarker[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradecanvas/svelte",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Svelte 5 component for @tradecanvas/chart — reactive props, runes, zero boilerplate.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"README.md"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@tradecanvas/chart": "1.
|
|
38
|
+
"@tradecanvas/chart": "1.16.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"svelte": ">=5.0.0"
|