@iccandle/news 0.0.1
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 +340 -0
- package/dist/news-widget.cjs +12 -0
- package/dist/news-widget.d.ts +13251 -0
- package/dist/news-widget.js +7915 -0
- package/package.json +99 -0
package/README.md
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# @iccandle/news
|
|
2
|
+
|
|
3
|
+
React component that wraps an existing [TradingView Charting Library](https://www.tradingview.com/charting-library-docs/) widget and adds ICCandle's **economic calendar analysis UI**: an interactive panel that displays news events as timescale marks on the chart, draws pip-range visualizations (high/low rectangles, trend lines, pip annotations) around selected events, and lets users compare historical price reactions across similar news releases.
|
|
4
|
+
|
|
5
|
+
Published as ESM and CommonJS; component styles are bundled and injected at runtime (no separate CSS import).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @iccandle/news
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Prerequisites
|
|
14
|
+
|
|
15
|
+
- **React 18+** — `react` and `react-dom` are **peer dependencies** (install them in your app).
|
|
16
|
+
- **TradingView Charting Library** — obtain it under your own license from TradingView, host the static assets (e.g. under `/charting_library/` in your public folder), and load the library at runtime. **This package does not ship the charting library.**
|
|
17
|
+
- **ICCandle API key** — issued by ICCandle for theme, chart data, news events, and scanner validation.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { useState } from "react";
|
|
23
|
+
import type { IChartingLibraryWidget } from "charting_library/charting_library";
|
|
24
|
+
import { NewsWidget } from "@iccandle/news-widget";
|
|
25
|
+
|
|
26
|
+
function App() {
|
|
27
|
+
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
|
|
28
|
+
null,
|
|
29
|
+
);
|
|
30
|
+
const widgetKey = "your-iccandle-api-key";
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<NewsWidget
|
|
34
|
+
chartWidget={chartWidget}
|
|
35
|
+
widgetKey={widgetKey}
|
|
36
|
+
defaultSymbol="XAU_USD"
|
|
37
|
+
chartInterval="15"
|
|
38
|
+
theme="system"
|
|
39
|
+
>
|
|
40
|
+
{/* Your chart container + TradingView bootstrap; call setChartWidget when ready */}
|
|
41
|
+
<div id="tv_chart_container" style={{ height: "100%" }} />
|
|
42
|
+
</NewsWidget>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Replace the chart placeholder with your TradingView initialization and pass the `IChartingLibraryWidget` instance when `onChartReady` (or equivalent) fires.
|
|
48
|
+
|
|
49
|
+
## Usage guide
|
|
50
|
+
|
|
51
|
+
### Step 1 — Install the package
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install @iccandle/news
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Ensure `react` and `react-dom` are installed and meet the peer version range.
|
|
58
|
+
|
|
59
|
+
### Step 2 — Host the Charting Library
|
|
60
|
+
|
|
61
|
+
1. Copy the TradingView Charting Library build into a path your app can serve as static files (e.g. `public/charting_library/` in Vite or Create React App).
|
|
62
|
+
2. Import the library constructor from that path in your bundler setup (see TradingView's integration docs for your framework). The library is **not** bundled inside `@iccandle/news-widget`; it loads at runtime via `library_path` (or equivalent) on the widget options.
|
|
63
|
+
|
|
64
|
+
### Step 3 — Bootstrap TradingView and capture the widget instance
|
|
65
|
+
|
|
66
|
+
Create a ref for the chart DOM node, instantiate the widget in `useEffect`, store the instance in React state, and remove it on cleanup:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { useEffect, useRef, useState } from "react";
|
|
70
|
+
import type {
|
|
71
|
+
ChartingLibraryWidgetOptions,
|
|
72
|
+
IChartingLibraryWidget,
|
|
73
|
+
ResolutionString,
|
|
74
|
+
} from "charting_library/charting_library";
|
|
75
|
+
import { widget } from "charting_library/charting_library";
|
|
76
|
+
|
|
77
|
+
const LIBRARY_PATH = "/charting_library/"; // must match your hosted assets
|
|
78
|
+
|
|
79
|
+
// Inside your component:
|
|
80
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
81
|
+
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
|
|
82
|
+
null,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
useEffect(
|
|
86
|
+
() => {
|
|
87
|
+
const el = containerRef.current;
|
|
88
|
+
if (!el) return;
|
|
89
|
+
|
|
90
|
+
const options: ChartingLibraryWidgetOptions = {
|
|
91
|
+
container: el,
|
|
92
|
+
library_path: LIBRARY_PATH,
|
|
93
|
+
symbol: "XAU_USD",
|
|
94
|
+
interval: "15" as ResolutionString,
|
|
95
|
+
datafeed: yourDatafeed,
|
|
96
|
+
locale: "en",
|
|
97
|
+
autosize: true,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const tv = new widget(options);
|
|
101
|
+
setChartWidget(tv);
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
try {
|
|
105
|
+
tv.remove();
|
|
106
|
+
} catch {
|
|
107
|
+
/* no-op */
|
|
108
|
+
}
|
|
109
|
+
setChartWidget(null);
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
[
|
|
113
|
+
/* library_path, datafeed identity, or other inputs that should recreate the chart */
|
|
114
|
+
],
|
|
115
|
+
);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
You must supply a valid `datafeed`, `symbol`, `interval`, `locale`, and any other options required by your TradingView license and app. Import paths for `widget` and types differ by setup (`charting_library/charting_library`, `./public/charting_library`, etc.—follow TradingView's docs for your bundler). If your integration only exposes the instance after `onChartReady`, call `setChartWidget` inside that callback instead of immediately after `new widget(...)`.
|
|
119
|
+
|
|
120
|
+
### Step 4 — Wrap the chart with `NewsWidget`
|
|
121
|
+
|
|
122
|
+
`NewsWidget` must wrap the same subtree that contains the chart container so the event panel and chart visualizations position correctly. Pass the live widget instance (or `null` while mounting):
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
import { NewsWidget } from "@iccandle/news-widget";
|
|
126
|
+
|
|
127
|
+
const widgetKey = "your-iccandle-api-key";
|
|
128
|
+
|
|
129
|
+
<NewsWidget
|
|
130
|
+
chartWidget={chartWidget}
|
|
131
|
+
widgetKey={widgetKey}
|
|
132
|
+
defaultSymbol="XAU_USD"
|
|
133
|
+
chartInterval="15"
|
|
134
|
+
theme="system"
|
|
135
|
+
>
|
|
136
|
+
<div ref={containerRef} style={{ height: "100%", minHeight: 400 }} />
|
|
137
|
+
</NewsWidget>;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
When a news event is selected, the widget switches to a 50/50 split layout: the event analysis panel on the left and the chart (with pip-range overlays) on the right. On mobile (<1024px) the panels stack vertically.
|
|
141
|
+
|
|
142
|
+
### Step 5 — Interact with news events
|
|
143
|
+
|
|
144
|
+
Once the widget is mounted:
|
|
145
|
+
|
|
146
|
+
1. **Economic calendar events** appear as timescale marks on the chart's time axis.
|
|
147
|
+
2. **Clicking an event** opens the detail panel showing event metadata (actual, forecast, previous values), impact status, and a list of similar historical events.
|
|
148
|
+
3. **Pip-range visualization** draws automatically on the chart: green rectangles for upside range, red rectangles for downside range, dotted trend lines at highs/lows, and pip annotations at extremes.
|
|
149
|
+
4. **Candle window** is configurable (10–50 candles) to control how far after the event the range analysis extends.
|
|
150
|
+
|
|
151
|
+
**TypeScript:** import `NewsWidgetProps` if you wrap `NewsWidget` in your own component and want explicit prop typing. Import `IChartingLibraryWidget` from **your** Charting Library typings path (`charting_library/charting_library` or the path your project uses)—this package does not re-export TradingView types.
|
|
152
|
+
|
|
153
|
+
### Theme and remote branding
|
|
154
|
+
|
|
155
|
+
- **`theme="light"` / `"dark"`** — forces that palette for the widget chrome and chart overlays.
|
|
156
|
+
- **`theme="system"`** (recommended when you don't control parent theme) — follows `prefers-color-scheme` for light/dark resolution.
|
|
157
|
+
- On mount, the widget fetches your org's tokens from ICCandle (see [Widget key and remote theming](#widget-key-and-remote-theming)) and sets CSS custom properties on the widget root, e.g. `--iccandle-primary`, `--iccandle-border`, so the event panel and chart overlays match your configured light/dark branding.
|
|
158
|
+
|
|
159
|
+
### Full working example
|
|
160
|
+
|
|
161
|
+
Minimal end-to-end pattern: chart container ref, widget lifecycle, `NewsWidget` with event analysis. Replace `yourDatafeed` and widget options with your real datafeed and TradingView settings.
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
import { useEffect, useRef, useState } from "react";
|
|
165
|
+
import type {
|
|
166
|
+
ChartingLibraryWidgetOptions,
|
|
167
|
+
IChartingLibraryWidget,
|
|
168
|
+
ResolutionString,
|
|
169
|
+
} from "charting_library/charting_library";
|
|
170
|
+
import { widget } from "charting_library/charting_library";
|
|
171
|
+
import { NewsWidget } from "@iccandle/news-widget";
|
|
172
|
+
|
|
173
|
+
const LIBRARY_PATH = "/charting_library/";
|
|
174
|
+
const WIDGET_KEY = "your-iccandle-api-key";
|
|
175
|
+
|
|
176
|
+
export function ChartWithNewsWidget() {
|
|
177
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
178
|
+
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
|
|
179
|
+
null,
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
const el = containerRef.current;
|
|
184
|
+
if (!el) return;
|
|
185
|
+
|
|
186
|
+
const options: ChartingLibraryWidgetOptions = {
|
|
187
|
+
container: el,
|
|
188
|
+
library_path: LIBRARY_PATH,
|
|
189
|
+
symbol: "XAU_USD",
|
|
190
|
+
interval: "15" as ResolutionString,
|
|
191
|
+
datafeed: yourDatafeed,
|
|
192
|
+
locale: "en",
|
|
193
|
+
autosize: true,
|
|
194
|
+
fullscreen: false,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const tv = new widget(options);
|
|
198
|
+
setChartWidget(tv);
|
|
199
|
+
|
|
200
|
+
return () => {
|
|
201
|
+
try {
|
|
202
|
+
tv.remove();
|
|
203
|
+
} catch {
|
|
204
|
+
/* no-op */
|
|
205
|
+
}
|
|
206
|
+
setChartWidget(null);
|
|
207
|
+
};
|
|
208
|
+
}, []);
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<div style={{ height: 600, width: "100%" }}>
|
|
212
|
+
<NewsWidget
|
|
213
|
+
chartWidget={chartWidget}
|
|
214
|
+
widgetKey={WIDGET_KEY}
|
|
215
|
+
defaultSymbol="XAU_USD"
|
|
216
|
+
chartInterval="15"
|
|
217
|
+
theme="system"
|
|
218
|
+
>
|
|
219
|
+
<div ref={containerRef} style={{ height: "100%", width: "100%" }} />
|
|
220
|
+
</NewsWidget>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
For a concrete in-repo reference (custom datafeed, timezone, visibility handling), see [`src/tradingview/TradingviewChart.tsx`](src/tradingview/TradingviewChart.tsx) in this repository's dev app.
|
|
227
|
+
|
|
228
|
+
### Common patterns
|
|
229
|
+
|
|
230
|
+
| Pattern | Approach |
|
|
231
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
232
|
+
| **Full-page chart** | Set the parent container to `height: 100vh` and let `NewsWidget` fill the space with `autosize: true`. |
|
|
233
|
+
| **Dashboard embed** | Give the parent a fixed height (e.g. 600px) and `NewsWidget` handles the split layout internally. |
|
|
234
|
+
| **News / events on the time axis** | If your datafeed implements `getTimescaleMarks`, you can sync marks with `localStorage` — see [Optional: timescale marks (news/events)](#optional-timescale-marks-newsevents). |
|
|
235
|
+
| **Custom symbol list** | Pass any supported symbol as `defaultSymbol`; the widget supports 100+ forex, metals, indices, crypto, and commodity symbols. |
|
|
236
|
+
|
|
237
|
+
### Troubleshooting
|
|
238
|
+
|
|
239
|
+
| Issue | What to check |
|
|
240
|
+
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
241
|
+
| Chart area stays blank | `library_path` must point to the folder URL where TradingView static files are served; container ref must be mounted before `new widget(...)`. |
|
|
242
|
+
| `chartWidget` is always `null` | Ensure you call `setChartWidget` after the widget is created (or inside `onChartReady` if your integration requires it). |
|
|
243
|
+
| Event panel or theme looks wrong | Confirm `widgetKey` is valid; theme fetch uses `api-key: <widgetKey>`. Network or auth failures may leave defaults. |
|
|
244
|
+
| CORS / network errors on APIs | In local dev, browser calls to ICCandle APIs may be blocked by CORS unless you proxy; the widget should still function with fallback styling—verify in production or behind your proxy. |
|
|
245
|
+
| No events showing on chart | The widget falls back to `XAU_USD` if `defaultSymbol` is unrecognized, but ensure `chartInterval` is one of the accepted values (`"1"`, `"5"`, `"15"`, `"30"`, `"60"`). |
|
|
246
|
+
|
|
247
|
+
## API
|
|
248
|
+
|
|
249
|
+
### Exports
|
|
250
|
+
|
|
251
|
+
| Name | Kind | Description |
|
|
252
|
+
| ----------------- | --------- | ------------------------------------------------- |
|
|
253
|
+
| `NewsWidget` | Component | Economic calendar analysis overlay for your chart |
|
|
254
|
+
| `NewsWidgetProps` | Type | Props for `NewsWidget` |
|
|
255
|
+
|
|
256
|
+
### `NewsWidget` props
|
|
257
|
+
|
|
258
|
+
| Prop | Type | Required | Description |
|
|
259
|
+
| --------------- | ------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
260
|
+
| `chartWidget` | `IChartingLibraryWidget \| null` | Yes | Live TradingView widget instance (`null` until ready). |
|
|
261
|
+
| `children` | `ReactNode` | Yes | Your chart UI (e.g. container + library bootstrap). |
|
|
262
|
+
| `widgetKey` | `string` | Yes | ICCandle API key. Used for theme fetch, chart data, news events, and scanner validation. |
|
|
263
|
+
| `defaultSymbol` | `string` | Yes | Default trading symbol (e.g. `"XAU_USD"`, `"EURUSD"`, `"BTCUSDT"`). Falls back to `"XAU_USD"` if the symbol is unrecognized or unavailable. |
|
|
264
|
+
| `chartInterval` | `"1" \| "5" \| "15" \| "30" \| "60"` | Yes | Chart candle interval in minutes. Defaults to `"15"`. |
|
|
265
|
+
| `theme` | `"light" \| "dark" \| "system"` | No | Defaults to sensible behavior; `"system"` follows `prefers-color-scheme`. Affects resolved theme tokens and chart overlays. |
|
|
266
|
+
|
|
267
|
+
### Widget key and remote theming
|
|
268
|
+
|
|
269
|
+
On mount, the component loads branding colors from ICCandle:
|
|
270
|
+
|
|
271
|
+
- **URL:** `https://api.iccandle.ai/corporate-client/v1/widgetStyle/search/user/?service_type=search`
|
|
272
|
+
- **Header:** `api-key: <widgetKey>`
|
|
273
|
+
|
|
274
|
+
CSS custom properties (`--iccandle-primary`, `--iccandle-border`, `--iccandle-background`, `--iccandle-text`, etc.) are applied on the widget root so the event panel and chart overlays match your configured light/dark tokens.
|
|
275
|
+
|
|
276
|
+
**Theme prop vs. API tokens:** The `theme` prop (`"light"` | `"dark"` | `"system"`) chooses which variant of those tokens to apply. `"system"` tracks `prefers-color-scheme` so the widget stays aligned with the user's OS preference when you don't pass an explicit light/dark mode from your app shell.
|
|
277
|
+
|
|
278
|
+
### Behavior summary
|
|
279
|
+
|
|
280
|
+
- Subscribes to chart readiness, resolution, symbol changes, and drawing events.
|
|
281
|
+
- Displays economic calendar events as interactive timescale marks on the chart.
|
|
282
|
+
- On event selection, switches to a split layout with an event detail panel and pip-range chart visualization.
|
|
283
|
+
- Draws pip-range rectangles (green for upside, red for downside), dotted trend lines, and pip annotations on the chart.
|
|
284
|
+
- Fetches similar historical events for comparison and shows event metadata (actual, forecast, previous values).
|
|
285
|
+
- Supports configurable candle windows (10–50 candles) for range analysis.
|
|
286
|
+
- Stores selected events in `localStorage` (key `iccandle:current-news-event`) for timescale mark sync.
|
|
287
|
+
- Listens for `window` `message` events for chart/news integration.
|
|
288
|
+
|
|
289
|
+
## Optional: timescale marks (news/events)
|
|
290
|
+
|
|
291
|
+
If your data feed implements `getTimescaleMarks`, you can surface stored events (e.g. from `localStorage` under `tv:current-news-event`) as marks on the time axis. Example shape:
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
getTimescaleMarks: async (
|
|
295
|
+
symbolInfo: LibrarySymbolInfo,
|
|
296
|
+
from: number,
|
|
297
|
+
to: number,
|
|
298
|
+
onResult: GetMarksCallback<TimescaleMark>,
|
|
299
|
+
) => {
|
|
300
|
+
const marks: TimescaleMark[] = [];
|
|
301
|
+
|
|
302
|
+
//...your code here
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
const currentNewsEvent = JSON.parse(
|
|
306
|
+
localStorage.getItem("iccandle:current-news-event") || "{}",
|
|
307
|
+
) as NewsEventType;
|
|
308
|
+
|
|
309
|
+
const { id, timestamp, event_name, currency, forecast, previous, actual } =
|
|
310
|
+
currentNewsEvent;
|
|
311
|
+
|
|
312
|
+
if (!id || !Number.isFinite(timestamp) || timestamp <= 0) return;
|
|
313
|
+
const hasAlready = marks.some((m) => String(m.id) === String(id));
|
|
314
|
+
if (hasAlready) return;
|
|
315
|
+
|
|
316
|
+
marks.push({
|
|
317
|
+
id: id,
|
|
318
|
+
time: timestamp / 1000,
|
|
319
|
+
color: "green",
|
|
320
|
+
label: event_name.slice(0, 1),
|
|
321
|
+
tooltip: [
|
|
322
|
+
event_name,
|
|
323
|
+
`Current Forecast: ${forecast || "-"}`,
|
|
324
|
+
`Previous Forecast: ${previous || "-"}`,
|
|
325
|
+
`Previous Actual: ${actual || "-"}`,
|
|
326
|
+
],
|
|
327
|
+
...(currency ? { imageUrl: `/images/symbols/${currency}.svg` } : {}),
|
|
328
|
+
});
|
|
329
|
+
} catch {
|
|
330
|
+
// no-op
|
|
331
|
+
}
|
|
332
|
+
onResult(marks);
|
|
333
|
+
};
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Adjust paths and types to match your app and TradingView typings.
|
|
337
|
+
|
|
338
|
+
## License
|
|
339
|
+
|
|
340
|
+
MIT. TradingView Charting Library is subject to its own license from TradingView.
|