@mathieuc/tradingview 4.0.0-beta.4 → 4.0.0-rc.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 (40) hide show
  1. package/README.md +3 -1
  2. package/assets/readme-demo.gif +0 -0
  3. package/dist/client/client.js +8 -2
  4. package/dist/http/account.js +5 -2
  5. package/dist/http/request.js +2 -1
  6. package/docs/README.es.md +1 -1
  7. package/docs/README.fr.md +1 -1
  8. package/docs/README.pt.md +1 -1
  9. package/docs/v4-backlog-triage.md +24 -12
  10. package/docs/v4-coverage.md +22 -3
  11. package/docs/v4-reliability.md +58 -0
  12. package/docs/v4-stabilization.md +87 -0
  13. package/examples/README.md +37 -0
  14. package/examples/builtin-indicator.js +22 -0
  15. package/examples/candles.js +15 -0
  16. package/examples/custom-chart-types.js +17 -0
  17. package/examples/custom-timeframe.js +14 -0
  18. package/examples/drawings.js +16 -0
  19. package/examples/errors.js +44 -0
  20. package/examples/fake-replay.js +24 -0
  21. package/examples/from-to.js +25 -0
  22. package/examples/graphic-indicator.js +18 -0
  23. package/examples/indicator-data.js +23 -0
  24. package/examples/multiple-indicators.js +16 -0
  25. package/examples/pine-permissions.js +18 -0
  26. package/examples/private-indicators.js +27 -0
  27. package/examples/quote-session.js +17 -0
  28. package/examples/quotes.js +15 -0
  29. package/examples/replay.js +36 -0
  30. package/examples/screener.js +10 -0
  31. package/examples/search.js +11 -0
  32. package/examples/simple-chart.js +36 -0
  33. package/examples/strategy-report.js +30 -0
  34. package/examples/user-login.js +15 -0
  35. package/examples/watch-candles.js +16 -0
  36. package/llms.txt +26 -0
  37. package/package.json +12 -3
  38. package/scripts/endurance.mjs +93 -0
  39. package/scripts/parity.mjs +54 -0
  40. package/scripts/probe-account.mjs +55 -0
package/README.md CHANGED
@@ -25,7 +25,7 @@ console.log(candles.at(-1)); // { time, open, high, low, close, volume }
25
25
 
26
26
  Prefer to start without code? The setup paths below work too.
27
27
 
28
- > **Version 4 is a breaking rewrite** in TypeScript, with a new API and no compatibility layer. Coming from v3? Read the [migration guide](docs/migration-v4.md). Every v3 feature is still available: see the [coverage matrix](docs/v4-coverage.md) and [reliability evidence](docs/v4-reliability.md). npm versions 3.x keep the previous `Client` API; check the [npm page](https://www.npmjs.com/package/@mathieuc/tradingview) for the version you install.
28
+ > **Version 4 is a breaking rewrite** in TypeScript, with a new API and no compatibility layer. Coming from v3? Read the [migration guide](docs/migration-v4.md). Every v3 feature is still available: see the [coverage matrix](docs/v4-coverage.md) and [reliability evidence](docs/v4-reliability.md). The [RC preparation report](docs/v4-stabilization.md) tracks current checks and remaining release gates. npm versions 3.x keep the previous `Client` API; check the [npm page](https://www.npmjs.com/package/@mathieuc/tradingview) for the version you install.
29
29
 
30
30
  ## Get started
31
31
 
@@ -95,6 +95,8 @@ const { values } = await getIndicatorData({
95
95
  | Quotes: last price, change, bid/ask, volume... | `getQuote`, `getQuotes`, `watchQuotes` |
96
96
  | Indicator values, drawings and strategy reports | `getIndicatorData`, `watchIndicator` |
97
97
  | Symbol metadata | `getSymbolInfo` |
98
+ | Stock/crypto screening and ranked lists | `getScreener`, `getHotlist` |
99
+ | Account watchlists (read-only) | `getWatchlists` |
98
100
  | Search and ratings | `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis` |
99
101
 
100
102
  Websocket data functions accept `timeoutMs`, an `AbortSignal`, account `credentials`, and an optional shared `client`. HTTP lookups accept an `AbortSignal` through their options. Errors are `TradingViewError`s with a `code` such as `SYMBOL_ERROR`, `TIMEOUT` or `STUDY_ERROR`. Read the [data API guide](docs/data-api.md) for every option.
Binary file
@@ -21,6 +21,7 @@ export class TradingViewClient extends Emitter {
21
21
  ready;
22
22
  #authenticated = false;
23
23
  #authToken;
24
+ #authController = new AbortController();
24
25
  #closed = false;
25
26
  #closing = false;
26
27
  #closeRequested = false;
@@ -71,14 +72,16 @@ export class TradingViewClient extends Emitter {
71
72
  this.#authToken = options.authToken;
72
73
  }
73
74
  else if (options.credentials?.session) {
74
- getUser(options.credentials, { location: options.location, fetch: options.fetch })
75
+ getUser(options.credentials, { location: options.location, fetch: options.fetch, signal: this.#authController.signal })
75
76
  .then((user) => {
76
- if (this.#closed)
77
+ if (this.#closed || this.#closing)
77
78
  return;
78
79
  this.#authToken = user.authToken;
79
80
  this.#authenticate();
80
81
  })
81
82
  .catch((error) => {
83
+ if (this.#closed || this.#closing)
84
+ return;
82
85
  this.#fail(new TradingViewError('AUTH_ERROR', `Credentials error: ${toTradingViewError(error).message}`, {
83
86
  cause: error,
84
87
  }));
@@ -145,6 +148,7 @@ export class TradingViewClient extends Emitter {
145
148
  if (this.#closing)
146
149
  return;
147
150
  this.#closing = true;
151
+ this.#authController.abort();
148
152
  // Do not hang if the server never acknowledges the close.
149
153
  setTimeout(() => this.#onClose(1000, 'Close timeout'), 3_000).unref?.();
150
154
  this.#transport.close();
@@ -224,6 +228,7 @@ export class TradingViewClient extends Emitter {
224
228
  this.emit('error', error);
225
229
  if (!wasReady || error.code === 'AUTH_ERROR' || error.code === 'CONNECTION_ERROR') {
226
230
  this.#closing = true;
231
+ this.#authController.abort();
227
232
  this.#transport.close();
228
233
  // Some transports never emit close after a failed handshake.
229
234
  setTimeout(() => this.#onClose(undefined, error.message), 3_000).unref?.();
@@ -233,6 +238,7 @@ export class TradingViewClient extends Emitter {
233
238
  if (this.#closed)
234
239
  return;
235
240
  this.#closed = true;
241
+ this.#authController.abort();
236
242
  this.#authenticated = false;
237
243
  clearTimeout(this.#readyTimer);
238
244
  this.#log?.('close', code, reason);
@@ -112,8 +112,11 @@ export async function getUser(credentials, options = {}) {
112
112
  let location = trustedAccountLocation(options.location ?? 'https://www.tradingview.com/chart/');
113
113
  for (let redirects = 0;; redirects += 1) {
114
114
  const { status, text, headers } = await request(location, { credentials, redirect: 'manual' }, options);
115
- if (text.includes('auth_token'))
116
- return parseUserPage(text, credentials);
115
+ if (status >= 200 && status < 300 && text.includes('auth_token')) {
116
+ const user = parseUserPage(text, credentials);
117
+ if (user.authToken)
118
+ return user;
119
+ }
117
120
  const next = headers.get('location');
118
121
  const resolved = status >= 300 && status < 400 && next ? new URL(next, location).toString() : undefined;
119
122
  if (!resolved || resolved === location) {
@@ -51,6 +51,7 @@ export async function request(url, init, options = {}) {
51
51
  const body = requestBody(init, headers);
52
52
  const fetchImpl = options.fetch ?? globalThis.fetch;
53
53
  let response;
54
+ let text;
54
55
  try {
55
56
  response = await fetchImpl(target.toString(), {
56
57
  method: init.method ?? (body === undefined ? 'GET' : 'POST'),
@@ -59,11 +60,11 @@ export async function request(url, init, options = {}) {
59
60
  redirect: init.redirect ?? 'follow',
60
61
  signal: options.signal,
61
62
  });
63
+ text = await response.text();
62
64
  }
63
65
  catch (error) {
64
66
  throw toTradingViewError(error, 'HTTP_ERROR');
65
67
  }
66
- const text = await response.text();
67
68
  if (response.status >= 500) {
68
69
  throw new TradingViewError('HTTP_ERROR', `${target.host} answered HTTP ${response.status}`, {
69
70
  details: { status: response.status, body: text.slice(0, 500) },
package/docs/README.es.md CHANGED
@@ -35,7 +35,7 @@ const watcher = await watchCandles({ symbol: 'BINANCE:BTCUSDT', timeframe: '1' }
35
35
  await watcher.stop();
36
36
  ```
37
37
 
38
- Cada función gestiona la conexión, el tiempo máximo (`timeoutMs`), la cancelación (`signal`) y la limpieza. Otras funciones: `getQuotes`, `watchQuotes`, `getSymbolInfo`, `getIndicatorData`, `watchIndicator`, `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis`. Detalles: [guía de la API de datos](data-api.md).
38
+ Cada función gestiona la conexión, el tiempo máximo (`timeoutMs`), la cancelación (`signal`) y la limpieza. Otras funciones: `getQuotes`, `watchQuotes`, `getSymbolInfo`, `getIndicatorData`, `watchIndicator`, `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis`, `getScreener`, `getHotlist`, `getWatchlists`. Detalles: [guía de la API de datos](data-api.md).
39
39
 
40
40
  ## API de bajo nivel
41
41
 
package/docs/README.fr.md CHANGED
@@ -35,7 +35,7 @@ const watcher = await watchCandles({ symbol: 'BINANCE:BTCUSDT', timeframe: '1' }
35
35
  await watcher.stop();
36
36
  ```
37
37
 
38
- Chaque fonction gère la connexion, le délai maximal (`timeoutMs`), l'annulation (`signal`) et le nettoyage. Autres fonctions : `getQuotes`, `watchQuotes`, `getSymbolInfo`, `getIndicatorData`, `watchIndicator`, `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis`. Détails : [guide de l'API de données](data-api.md).
38
+ Chaque fonction gère la connexion, le délai maximal (`timeoutMs`), l'annulation (`signal`) et le nettoyage. Autres fonctions : `getQuotes`, `watchQuotes`, `getSymbolInfo`, `getIndicatorData`, `watchIndicator`, `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis`, `getScreener`, `getHotlist`, `getWatchlists`. Détails : [guide de l'API de données](data-api.md).
39
39
 
40
40
  ## API bas niveau
41
41
 
package/docs/README.pt.md CHANGED
@@ -35,7 +35,7 @@ const watcher = await watchCandles({ symbol: 'BINANCE:BTCUSDT', timeframe: '1' }
35
35
  await watcher.stop();
36
36
  ```
37
37
 
38
- Cada função cuida da conexão, do tempo máximo (`timeoutMs`), do cancelamento (`signal`) e da limpeza. Outras funções: `getQuotes`, `watchQuotes`, `getSymbolInfo`, `getIndicatorData`, `watchIndicator`, `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis`. Detalhes: [guia da API de dados](data-api.md).
38
+ Cada função cuida da conexão, do tempo máximo (`timeoutMs`), do cancelamento (`signal`) e da limpeza. Outras funções: `getQuotes`, `watchQuotes`, `getSymbolInfo`, `getIndicatorData`, `watchIndicator`, `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis`, `getScreener`, `getHotlist`, `getWatchlists`. Detalhes: [guia da API de dados](data-api.md).
39
39
 
40
40
  ## API de baixo nível
41
41
 
@@ -2,14 +2,14 @@
2
2
 
3
3
  Baseline: `da67081` / published `4.0.0-beta.1`. Snapshot: **96 open issues and 8 open PRs**.
4
4
 
5
- Follow-up: #334 was merged on 3 October 2026. The focused fixes are included in the beta.2 release candidate. Reliability tools from #330 were subsequently ported without its stale version/README changes; the completed two-hour result is recorded in [reliability evidence](v4-reliability.md). Historical rows below describe the initial snapshot, not current PR state.
5
+ Follow-up: #334 was merged on 3 October 2026. The focused fixes are included in the beta.2 release candidate. Reliability tools from #330 were subsequently ported without its stale version/README changes; the completed two-hour result is recorded in [reliability evidence](v4-reliability.md). The issue table below is refreshed through beta.5/stabilization; dated verification sections retain their original evidence.
6
6
 
7
7
  This is an issue-by-issue disposition, not a claim that 96 bugs were reproduced or fixed.
8
8
  Evidence comes from issue descriptions, current source/tests and the existing [coverage matrix](v4-coverage.md).
9
9
  “Covered by code” is weaker than a targeted regression or live reproduction. “Needs” means keep open.
10
10
  No issues/legacy PRs were closed, and no contributor comments were sent by this pass.
11
11
 
12
- ## Immediate findings
12
+ ## Initial beta.1 findings (historical)
13
13
 
14
14
  1. **Authentication gap:** PR #330 is still open. Its `/chart/` default and non-3xx redirect guard are absent from beta.1. This change ports only that focused fix with its regression test, not its old release/version text.
15
15
  2. **Concrete missing feature:** #225 country/sector search filters implemented in this change, with deterministic query coverage and a public live endpoint probe.
@@ -18,9 +18,12 @@ No issues/legacy PRs were closed, and no contributor comments were sent by this
18
18
 
19
19
  ## Issues
20
20
 
21
+ Current inventory: **95 open issues and 7 legacy open PRs** on 3 October 2026.
22
+ Rows describe capability disposition, not automatic authorization to close reports.
23
+
21
24
  | Issue | Disposition | Evidence / next action |
22
25
  | --- | --- | --- |
23
- | [#321](https://github.com/Mathieu2301/TradingView-API/issues/321) getUser reports "Too many redirects" for HTTP 200 responses without auth_token | Partial → patched | The beta avoids missing-Location loops, but still starts at the homepage and follows a Location on HTTP 200. Ported the focused fix from PR #330; HTTP regression test passes. Not yet published. |
26
+ | [#321](https://github.com/Mathieu2301/TradingView-API/issues/321) getUser reports "Too many redirects" for HTTP 200 responses without auth_token | Partial → patched | Published since beta.2: starts at /chart/ and follows Location only on 3xx. HTTP regression and authenticated live suite pass; CAPTCHA/WAF remains outside this fix. |
24
27
  | [#319](https://github.com/Mathieu2301/TradingView-API/issues/319) More Control and access to data | Missing | Paper-trading account management and order execution are not exposed by V4. |
25
28
  | [#313](https://github.com/Mathieu2301/TradingView-API/issues/313) History Create Session / Request History Data Features help | Missing / gated | No HistorySession or request_history_data implementation. PR #204 is a protocol reference, not V4-compatible code; requires entitled-account live validation. |
26
29
  | [#312](https://github.com/Mathieu2301/TradingView-API/issues/312) tradingview wss is updated? | Needs reproduction | Current transport and timeouts are implemented, but the original connection timeout has no host/network trace. Capture exact endpoint, Node version and error on V4. |
@@ -49,7 +52,7 @@ No issues/legacy PRs were closed, and no contributor comments were sent by this
49
52
  | [#232](https://github.com/Mathieu2301/TradingView-API/issues/232) Crypto Cap (e.g. CRYPTOCAP:TOTAL) symbols return "invalid symbol" | Needs reproduction | Issue is specifically CRYPTOCAP Replay, not ordinary candles. Test replay on TOTAL/OTHERS with an entitled account. |
50
53
  | [#231](https://github.com/Mathieu2301/TradingView-API/issues/231) Missing data in examples/FromToData.js - provided date and custom date | Partial / server limits | getCandles from/to pagination is implemented; historical intraday availability remains server/account limited. Reproduce original window, not just a recent range. |
51
54
  | [#230](https://github.com/Mathieu2301/TradingView-API/issues/230) os.version is not a function / Can't resolve 'os" | Unsupported environment | V4 targets Node/Bun and imports node:os/ws. Browser-extension support is not established by removing the old os.version call. |
52
- | [#225](https://github.com/Mathieu2301/TradingView-API/issues/225) Add additional filter on search market v3 | Missing → implemented | Added country/sector to searchMarkets, preserving exchange/type/offset. Unit coverage and public endpoint probe; not yet published. |
55
+ | [#225](https://github.com/Mathieu2301/TradingView-API/issues/225) Add additional filter on search market v3 | Missing → implemented | Published since beta.2: country/sector filters preserve exchange/type/offset. Deterministic forwarding checks and public endpoint probe. |
53
56
  | [#224](https://github.com/Mathieu2301/TradingView-API/issues/224) Default setting indicators | Partial | getIndicator provides defaults and PineIndicator.clone preserves a baseline. No reset-to-defaults convenience method; document reload/clone workflow. |
54
57
  | [#223](https://github.com/Mathieu2301/TradingView-API/issues/223) Premium account doesn't return 20000 bars for server='prodata' | Needs entitled account | Pagination and credentials exist, but Premium/prodata 20k-bar entitlement is not proven with Basic. |
55
58
  | [#222](https://github.com/Mathieu2301/TradingView-API/issues/222) Wrong or expired sessionid/signature - all time | Needs account reproduction | V4 credentials are { session, signature }; focused getUser patch helps page selection, but does not establish the original account entitlement or cookie validity. |
@@ -63,7 +66,7 @@ No issues/legacy PRs were closed, and no contributor comments were sent by this
63
66
  | [#201](https://github.com/Mathieu2301/TradingView-API/issues/201) Private indicators | Needs private asset | Private listing/auth paths are implemented; specific invite-only access and private study values require an authorized matching script fixture. |
64
67
  | [#199](https://github.com/Mathieu2301/TradingView-API/issues/199) Manage pine scripts | Missing | Pine permissions/listing are not script source create/update/delete APIs. |
65
68
  | [#193](https://github.com/Mathieu2301/TradingView-API/issues/193) TypeError: str.replace is not a function - Handling Buffer Input in parseWSPacket | Covered by code | src/client/transport.ts converts Buffer, Buffer[] and ArrayBuffer to text before framing. Historical caller-specific environment not reproduced. |
66
- | [#192](https://github.com/Mathieu2301/TradingView-API/issues/192) 15 minutes delay for MOEX market | Upstream entitlement / missing | Exchange real-time rights and server delays must be checked with that venue/account. General stock screener API is not implemented. |
69
+ | [#192](https://github.com/Mathieu2301/TradingView-API/issues/192) 15 minutes delay for MOEX market | Upstream entitlement / missing | Exchange real-time rights and server delays must be checked with that venue/account. getScreener is available since beta.3, but does not grant exchange real-time rights. |
67
70
  | [#191](https://github.com/Mathieu2301/TradingView-API/issues/191) How to install? | Covered | README installation/quick start, docs/data-api.md and examples cover the requested entry point; package consumer smoke passes. |
68
71
  | [#188](https://github.com/Mathieu2301/TradingView-API/issues/188) Pine 'referencing length of a series' error after about 12 hours | Needs long-run reproduction | 12-hour Pine max_bars_back failure is not a normal indicator input. Need script and long-running capture; short endurance runs cannot resolve it. |
69
72
  | [#184](https://github.com/Mathieu2301/TradingView-API/issues/184) Proxy support | Partial | Custom WebSocket transport and HTTP fetch hooks permit adapters, but no documented/tested unified proxy configuration. PR #208 cannot be merged unchanged. |
@@ -104,27 +107,27 @@ No issues/legacy PRs were closed, and no contributor comments were sent by this
104
107
  | [#101](https://github.com/Mathieu2301/TradingView-API/issues/101) FakeReplay always returning the same day | Needs targeted regression | Negative-count history is live-tested generally; exact repeated-day/gap cases and exchange holidays still need reproduction. |
105
108
  | [#89](https://github.com/Mathieu2301/TradingView-API/issues/89) No "strategyReport.trades" data for private strategy backtest | Needs private asset | Public and compressed reports are proven; missing trades for the specific private strategy is not yet reproduced. |
106
109
  | [#88](https://github.com/Mathieu2301/TradingView-API/issues/88) Data point is missing in FakeReplayMode example output | Needs targeted regression | Negative-count history is live-tested generally; exact repeated-day/gap cases and exchange holidays still need reproduction. |
107
- | [#87](https://github.com/Mathieu2301/TradingView-API/issues/87) Feature : get watchlists | Missing | No watchlist or hotlist API; useful next discovery target alongside screener. |
108
- | [#85](https://github.com/Mathieu2301/TradingView-API/issues/85) Question : Can you enable stock screener real-time ? | Upstream entitlement / missing | Exchange real-time rights and server delays must be checked with that venue/account. General stock screener API is not implemented. |
110
+ | [#87](https://github.com/Mathieu2301/TradingView-API/issues/87) Feature : get watchlists | Covered with live limits | Published in beta.4: getWatchlists and scanner-ranked getHotlist. Populated lists are fixture-tested; available account lists are empty. UI parity is not claimed. |
111
+ | [#85](https://github.com/Mathieu2301/TradingView-API/issues/85) Question : Can you enable stock screener real-time ? | Upstream entitlement / missing | Exchange real-time rights and server delays must be checked with that venue/account. getScreener is available since beta.3, but does not grant exchange real-time rights. |
109
112
  | [#84](https://github.com/Mathieu2301/TradingView-API/issues/84) Alerts feature | Missing | No TradingView alert CRUD or triggered-alert subscription. Local quote/study listeners are not server-side alerts. |
110
113
  | [#83](https://github.com/Mathieu2301/TradingView-API/issues/83) how to get update data of strategy.entry trigger signal. | Partial | Strategy reports and study updates exist; no dedicated exactly-once strategy.entry signal stream. Application must distinguish intrabar updates. |
111
114
  | [#80](https://github.com/Mathieu2301/TradingView-API/issues/80) [V3] Same output multiple times | Needs reproduction | Repeated update events may be intrabar updates or study lifecycle effects. No evidence yet of a V4 fix for this exact script. |
112
115
  | [#79](https://github.com/Mathieu2301/TradingView-API/issues/79) Where can I find the chart_id for getDrawings? | Partial documentation | getDrawings supports chartId/layout inputs, but extracting the correct internal chart ID needs a saved-layout example and private validation. |
113
116
  | [#73](https://github.com/Mathieu2301/TradingView-API/issues/73) Strategy Optimization Steps | Partial | Inputs and reports exist; no bounded optimization runner, date-window Deep Backtest or throttle-aware multithreading API. |
114
117
  | [#66](https://github.com/Mathieu2301/TradingView-API/issues/66) Maximum number of studies per chart has been reached | Upstream limits | Server study/session/calculation limits are not removed by V4. Bound concurrency, release sessions and reproduce account-specific thresholds; no bulk retry flood. |
115
- | [#53](https://github.com/Mathieu2301/TradingView-API/issues/53) Stock Screener API | Missing | No general stock screener API; getTechnicalAnalysis is only a fixed-column ratings request. |
118
+ | [#53](https://github.com/Mathieu2301/TradingView-API/issues/53) Stock Screener API | Covered HTTP API | Published in beta.3: getScreener supports columns, filters, ranking and pagination; deterministic and anonymous live checks. Not a push subscription. |
116
119
  | [#51](https://github.com/Mathieu2301/TradingView-API/issues/51) Adding some sort of documentation | Covered | README installation/quick start, docs/data-api.md and examples cover the requested entry point; package consumer smoke passes. |
117
120
  | [#30](https://github.com/Mathieu2301/TradingView-API/issues/30) Can I Hire You To Set This Up For Me? | Administrative | Collaboration/service proposal, not a reproducible library defect. No unsolicited outreach in this triage. |
118
121
  | [#24](https://github.com/Mathieu2301/TradingView-API/issues/24) Renko chart's indicator value does not match GUI-based TradingView's, given same configurations | Needs parity reproduction | Renko chart type is live-tested, but this exact multi-timeframe study/GUI value mismatch is not. Need matched bars, inputs and account. |
119
122
 
120
- ## Open pull requests
123
+ ## Legacy pull requests
121
124
 
122
125
  | PR | Verified disposition | Next action |
123
126
  | --- | --- | --- |
124
- | [#330](https://github.com/Mathieu2301/TradingView-API/pull/330) | **Not merged.** Auth fix, parity/endurance scripts and recovery live test remain useful. Version/release prose is stale. | Focused auth port included here. Retain/rebase remaining reliability work; recover saved endurance results before claiming completion. |
127
+ | [#330](https://github.com/Mathieu2301/TradingView-API/pull/330) | Closed/superseded after focused ports in #334/#335. Authentication, parity/endurance tooling and recovery checks are included in beta.2. | No remaining code port from this PR is needed for the documented scope; the recovered two-hour result is in reliability evidence. |
125
128
  | [#322](https://github.com/Mathieu2301/TradingView-API/pull/322) | Legacy V3 authentication patch; not directly applicable to TS V4. | Its chart-page/status semantics are carried through #330 into this port. Decide V3 backport separately while latest is 3.5.2. |
126
129
  | [#320](https://github.com/Mathieu2301/TradingView-API/pull/320) | V3 this-binding patch. V4 HTTP functions are standalone, not receiver-based. | Superseded for V4; possible V3 maintenance value. |
127
- | [#318](https://github.com/Mathieu2301/TradingView-API/pull/318) | Binding fix is superseded, but dependency upgrade is **not** automatically superseded: The baseline still uses Vitest 3. | Audit confirmed GHSA-82fw-gwwq-j7x9 in Vitest/mocker. Updated to patched Vitest 4.1.11+ in this change; not the older vulnerable 4.1.9 from the PR. |
130
+ | [#318](https://github.com/Mathieu2301/TradingView-API/pull/318) | V4 uses standalone HTTP functions and patched Vitest 4.1.11. The original Vitest 3 baseline no longer applies. | Audit confirmed GHSA-82fw-gwwq-j7x9 in Vitest/mocker. Updated to patched Vitest 4.1.11+ in this change; not the older vulnerable 4.1.9 from the PR. |
128
131
  | [#289](https://github.com/Mathieu2301/TradingView-API/pull/289) | General chart event registration exists via Emitter.on/onAny and event tests. | Superseded for V4; no need to port V3 callback storage. |
129
132
  | [#219](https://github.com/Mathieu2301/TradingView-API/pull/219) | Native TS build emits declarations and package smoke compiles a strict consumer. | Superseded for V4; avoid stale generated V3 declarations. |
130
133
  | [#208](https://github.com/Mathieu2301/TradingView-API/pull/208) | Axios/ws proxy patch targets removed V3 architecture. V4 offers transport/fetch injection, not a turnkey proxy. | Preserve intent; implement/test an adapter recipe across both HTTP and WS before resolving #184. |
@@ -143,10 +146,19 @@ No issues/legacy PRs were closed, and no contributor comments were sent by this
143
146
 
144
147
  Beta.3 adds `getScreener` for #53 and scanner fields relevant to #280. See
145
148
  [screener documentation](screener.md). #85 real-time exchange entitlement is not
146
- resolved by a successful HTTP scan. Watchlists and paid/private cases remain open.
149
+ resolved by a successful HTTP scan. Watchlists shipped subsequently in beta.4; paid/private case limitations remain.
147
150
 
148
151
  ## Watchlist follow-up
149
152
 
150
153
  Beta.4 adds read-only `getWatchlists` and scanner-ranked `getHotlist` (#87).
151
154
  Authenticated discovery returned two empty lists; populated entries are fixture-tested.
152
155
  Exact TradingView UI hotlist parity is not claimed. See [watchlists](watchlists.md).
156
+
157
+ ## Account and endurance follow-up
158
+
159
+ Beta.5 ships opt-in account/endurance diagnostics and documents six successful
160
+ private USER-script runs. Deep Backtesting reached the server but returned
161
+ `request_error` / `not_allowed` with the available account. This is a concrete
162
+ prerequisite blocker, not implemented Premium support. Original private-script,
163
+ CME/GUI and 12-hour issue fixtures remain necessary; no historical issue is closed
164
+ from the broader smoke results. See [reliability evidence](v4-reliability.md).
@@ -6,7 +6,7 @@ This matrix lists every capability of v3 (`main.js`, `src/`, examples, tests) an
6
6
 
7
7
  **Evidence columns**
8
8
 
9
- - **Unit**: deterministic test in `tests/unit/` (`npm test` with Vitest on Node, `npm run test:bun` with Bun's runner; 118 tests, both green). Websocket tests use a scripted fake server (`tests/helpers/fake-server.ts`) or packets captured from TradingView (`tests/fixtures/live-session.json`); HTTP tests use a mocked `fetch`.
9
+ - **Unit**: deterministic test in `tests/unit/` (`npm test` with Vitest on Node, `npm run test:bun` with Bun's runner; 135 tests in the stabilization candidate, both green). Websocket tests include the native Node/Bun transport against a loopback server (`tests/unit/transport.test.ts`), a scripted fake server (`tests/helpers/fake-server.ts`) or packets captured from TradingView (`tests/fixtures/live-session.json`); HTTP tests use a mocked `fetch`.
10
10
  - **Live**: result of `npm run test:live` (`tests/live/`) and examples against TradingView on **2 October 2026**: 16 anonymous tests locally and 21 tests (including five authenticated) in the [manual GitHub Actions run](https://github.com/Mathieu2301/TradingView-API/actions/runs/37075296707):
11
11
  - ✅ verified live anonymously;
12
12
  - 🔒 path or variant not exercised live (often requires a specific account asset); deterministic tests only;
@@ -16,6 +16,25 @@ Beta.2 follow-up on **3 October 2026**: all 22 current live tests passed locally
16
16
 
17
17
  Test names are abbreviated as `file › test`.
18
18
 
19
+ ## Stabilization checks — 3 October 2026
20
+
21
+ `npm run test:coverage` measures **source files only** with V8 (test helpers are excluded).
22
+ The CI Node 22 job enforces minimums of 90% lines, 85% statements/functions and 75%
23
+ branches, and uploads the HTML/JSON report. These are regression floors, not claims
24
+ of universal behavior. Network/account coverage is tracked independently below.
25
+ See the [stabilization report](v4-stabilization.md) for release gates and current results.
26
+
27
+ | Capability / failure path | Deterministic evidence | Live evidence / limit |
28
+ | --- | --- | --- |
29
+ | Screener pagination, fields, types and errors | `screener.test.ts` | `live/data.test.ts`: requested BTC symbol and price |
30
+ | Ranked lists (four kinds) | `watchlists.test.ts` | `live/data.test.ts`: populated volume ranking; not UI parity |
31
+ | Read-only account watchlists | `watchlists.test.ts`: populated lists, sections, metadata, auth failures | `live/authenticated.test.ts`: read-only response; available lists are empty |
32
+ | HTTP response stream failure / cancellation | `http.test.ts`: typed HTTP_ERROR / ABORTED after headers | Simulated, not an upstream failure claim |
33
+ | Authentication cancelled by close, disconnect or timeout | `client.test.ts`: request aborted, no late AUTH_ERROR or auth packet | Simulated lifecycle failures |
34
+ | Empty/malformed auth token or rejected HTTP page | `http.test.ts`: AUTH_ERROR | Existing authenticated suite checks successful lookup |
35
+ | Native websocket framing, Origin and handshake failure | `transport.test.ts`: real loopback websocket under both runners | Does not reproduce DNS, proxy or internet loss |
36
+ | Published exports and declarations | `scripts/smoke.mjs`: tarball, Node/Bun, require(esm), strict TS including discovery APIs | No TradingView access in smoke |
37
+
19
38
  ## Package and tooling
20
39
 
21
40
  | v3 capability | v4 | Unit evidence | Live |
@@ -111,7 +130,7 @@ Test names are abbreviated as `file › test`.
111
130
  | `PineIndicator` getters (`pineId`, `pineVersion`, description, inputs, plots, script, type) and `setType` | `id`, `version`, same others; `setType`, `clone` | `indicators › clones independently...` | ✅ (`sessions › loads Pine indicator definitions`) |
112
131
  | `PineIndicator.setOption` (by `in_N`, number, inline name, internal ID; type and option checks) | `setInput`, `setInputs`, `findInput` | `indicators › finds inputs by ID...` | ✅ (definition-level) |
113
132
  | `BuiltInIndicator(type)`, defaults for Volume and volume profiles, `setOption(key, value, FORCE)` | Same (+ initial options; time defaults computed per instance instead of at import) | `indicators › BuiltInIndicator › *` | ✅ (`Volume`, `VbPFixed@tv-basicstudies-241!`) |
114
- | `getIndicator(id, version, session, signature)` (pine-facade translate, input/plot naming) | `getIndicator(id, { version, credentials })`, `parseIndicatorDefinition` | `indicators › parseIndicatorDefinition...`, `http › loads an indicator definition...`, `throws NOT_FOUND...` | ✅ public scripts; 🔒 private/invite-only |
133
+ | `getIndicator(id, version, session, signature)` (pine-facade translate, input/plot naming) | `getIndicator(id, { version, credentials })`, `parseIndicatorDefinition` | `indicators › parseIndicatorDefinition...`, `http › loads an indicator definition...`, `throws NOT_FOUND...` | ✅ public scripts and six saved USER scripts; 🔒 original invite-only issue fixtures |
115
134
  | (new) One-shot / streaming indicator values | `getIndicatorData`, `watchIndicator` | `data › indicator data › *` | ✅ built-in and one-shot Pine RSI with account; Pine stream unit-tested |
116
135
 
117
136
  ## Quotes
@@ -137,7 +156,7 @@ Test names are abbreviated as `file › test`.
137
156
  | `getTA(symbol)` (8 periods × All/MA/Other, scaled) | `getTechnicalAnalysis(symbol)` (`null` instead of `false` without data) | `http › getTechnicalAnalysis › *` | ✅ |
138
157
  | `searchIndicator(text)` (built-in lists cached + community suggestions, access mapping) | `searchIndicators(text)`, `clearIndicatorCache()` | `http › searches built-in and community indicators` | ✅ |
139
158
  | `result.get()` on indicator results | `getIndicator(result.id, { version: result.version })` | `http › loads an indicator definition...` | ✅ |
140
- | `getPrivateIndicators(session, signature)` | `getPrivateIndicators(credentials)` | `http › lists private indicators with credentials` | ✅ authenticated listing endpoint; actual private item not available |
159
+ | `getPrivateIndicators(session, signature)` | `getPrivateIndicators(credentials)` | `http › lists private indicators with credentials` | ✅ authenticated listing; six saved USER scripts evaluated separately (see reliability evidence) |
141
160
  | `loginUser(username, password, remember, UA)` | `loginUser({ username, password, remember, userAgent })` (form now URL-encoded) | `http › loginUser posts an encoded form and reads cookies` | 🔒 |
142
161
  | `getUser(session, signature, location)` with redirect-loop protection | `getUser(credentials, { location, maxRedirects })` (relative redirects resolved) | `http › getUser parses the account page...`, `getUser stops redirect loops...` | ✅ authenticated success and wrong-cookie rejection |
143
162
  | `getChartToken(layout, credentials)` | `getChartToken(layoutId, { userId, credentials })` | `http › gets a chart token...` | 🔒 (needs a layout ID) |
@@ -34,3 +34,61 @@ V4 now starts the account lookup at `/chart/` and follows `Location` only on HTT
34
34
  - Basic daily Replay and strategy reports are documented in [v4-coverage.md](v4-coverage.md); this is not proof of Deep Backtesting or universal intraday entitlement.
35
35
  - Private/invite-only script cases, subscribed futures parity, owned layouts and long-running Pine failures need matching assets and targeted reproductions. See [backlog triage](v4-backlog-triage.md).
36
36
  - Live CI is non-blocking. Review its actual test results, not just the overall workflow conclusion, before release.
37
+
38
+ ## Account-scoped diagnostics (beta.5)
39
+
40
+ From a source checkout, set `SESSION` and `SIGNATURE` securely and run
41
+ `npm run probe:account`. The read-only probe authenticates, lists saved scripts,
42
+ then evaluates at most ten scripts sequentially on 100 daily BTCUSDT bars. Use
43
+ `--max-scripts=N` and `--timeout-ms=N` after `--` to change these bounds.
44
+ It prints only counts, index-based outcomes, script namespace categories and the
45
+ account token's plan claim. It does not print script IDs, names, source, values,
46
+ account identifiers or credentials. A plan claim is informational, not proof of
47
+ exchange or Deep Backtesting entitlement. Failures exit nonzero; an empty saved
48
+ script list is not considered successful private-script coverage.
49
+
50
+ The package now includes both diagnostics, so installed consumers can run:
51
+
52
+ ```sh
53
+ node node_modules/@mathieuc/tradingview/scripts/probe-account.mjs
54
+ node node_modules/@mathieuc/tradingview/scripts/endurance.mjs --minutes=7 --cycle-seconds=600 --require-post-threshold-updates
55
+ ```
56
+
57
+ The second command requires candle **and** quote callbacks after more than 30
58
+ heartbeats on the same connection. `--heartbeat-threshold=N` changes the threshold.
59
+ Counters reset per connection for threshold eligibility; ten short connections do
60
+ not constitute one long connection. Initial snapshots alone cannot satisfy this
61
+ mode. Any recorded error or interruption also makes the probe fail. Without the
62
+ flag, a completed run remains a transport/lifecycle check, not a liveness guarantee.
63
+ Run strict mode on an open market; a closed venue cannot supply the required proof.
64
+
65
+ ### Verified private scripts and outstanding paid-account prerequisite
66
+
67
+ On 3 October 2026, all six saved `USER;` scripts accessible to the available account
68
+ completed: two studies and four strategies, each returning 100 candles and 200
69
+ study rows. Three strategies returned 208, 4 and 69 trades respectively; the fourth
70
+ returned a report with zero trades. These are account-specific fixtures, not a
71
+ reproduction of the private strategy in #89 or the table payload in #251.
72
+
73
+ A bounded request to `history-data` using the protocol in PR #204 reached the server
74
+ and returned `request_error` / `not_allowed`. No Deep Backtesting success is claimed.
75
+ An eligible account and current successful protocol capture are required before
76
+ shipping that API. No subscription was purchased and no account content was modified.
77
+ The original scripts/fixtures for #188 (long-running Pine depth error), #24 (Renko
78
+ GUI parity) and #311 (subscribed CME sessions) remain unavailable for exact reproduction.
79
+
80
+ ### Unbroken-socket checks, 3 October 2026
81
+
82
+ - **BTCUSDT, six minutes, one connection:** 35 heartbeats, 85 candle callbacks,
83
+ 89 quote callbacks; after heartbeat 30 on that same connection, 13 candle and
84
+ 12 quote callbacks. Zero errors/failures; strict mode exited successfully.
85
+ - **OANDA:EURUSD HeikinAshi, seven minutes, one connection:** 41 heartbeats,
86
+ one initial candle callback and one initial quote callback, zero errors/failures.
87
+ The forex market was closed: this proves heartbeat continuity only and does not
88
+ resolve #236's reported price-stream freeze on an open market.
89
+ - Negative controls: a short initial-snapshot-only run fails strict mode, and an
90
+ interrupted run exits nonzero after cleanup. Account diagnostics also fail cleanly
91
+ without credentials; a bounded one-script run was separately verified on Bun.
92
+
93
+ Neither run is a 12-hour Pine reproduction. The full authenticated live suite on
94
+ beta.4 passed all 22 tests; beta.5 changes diagnostic tooling/documentation only.
@@ -0,0 +1,87 @@
1
+ # V4 stabilization and release-candidate gates
2
+
3
+ Snapshot: 3 October 2026, starting from beta.5 (`b793115`).
4
+ The source/package version is staged as **4.0.0-rc.0**. This is a prepared candidate,
5
+ not a claim of npm publication or promotion of `latest`. Install the published beta
6
+ until the candidate is released. [Migration guide](migration-v4.md).
7
+
8
+ ## What changed
9
+
10
+ - Normalize failures while consuming an HTTP response body, not only while fetching
11
+ headers. Cancellation remains `ABORTED`; other stream failures become `HTTP_ERROR`.
12
+ - Cancel pending account lookup when the client closes, disconnects or times out.
13
+ An intentional cancellation must not emit a late `AUTH_ERROR` or send an auth packet.
14
+ - Reject empty/malformed account tokens and token-like content in rejected HTTP pages.
15
+ - Exercise the real Node/Bun websocket transport against a Node loopback fixture:
16
+ Origin/custom headers, Unicode binary decoding, remote close and failed handshake.
17
+ - Add repeatable live scanner, ranked-list and read-only watchlist checks.
18
+ - Add source-only V8 coverage with CI floors and downloadable HTML/JSON evidence.
19
+ - Extend packed-consumer checks to discovery exports and types; include examples,
20
+ assets, the agent index and parity diagnostic in the tarball.
21
+ - Refresh the capability/backlog tables without closing unreproduced historical issues.
22
+
23
+ ## Deterministic evidence
24
+
25
+ | Check | Result |
26
+ | --- | --- |
27
+ | Typecheck, lint, build | Passed locally |
28
+ | Node unit suite | 135 passed, 14 files |
29
+ | Bun unit suite | 135 passed, 14 files |
30
+ | Source lines | 95.21% (1,235 / 1,297) |
31
+ | Source statements | 92.62% (1,394 / 1,505) |
32
+ | Source functions | 94.73% (342 / 361) |
33
+ | Source branches | 83.67% (820 / 980) |
34
+ | Dependency audit | Zero reported vulnerabilities at install |
35
+ | Packed consumer | Node ESM, Node require(esm), Bun and strict TypeScript |
36
+
37
+ Negative control: the six new lifecycle/body/token regression scenarios were run
38
+ against unmodified beta.5 source; all six failed as expected. Restoring the candidate
39
+ source makes all six pass. This verifies that the assertions detect the actual defects.
40
+
41
+ Run `npm ci && npm run check`, `npm run test:bun` and `npm run test:coverage`.
42
+ Coverage excludes test helpers and is **not** a measure of TradingView symbols,
43
+ permissions, server behavior, GUI parity or account-feature completeness. Loopback
44
+ handshake tests do not establish DNS/proxy/internet-failure coverage.
45
+
46
+ CI runs deterministic checks on Node 20/22/24 and Bun. Node 22 additionally measures
47
+ coverage with floors of 90% lines, 85% statements/functions and 75% branches.
48
+ A growing test count is not itself a release gate; assertions and tested behavior matter.
49
+
50
+ ## Live evidence
51
+
52
+ The local candidate suite passed **19 anonymous tests**; **six authenticated tests
53
+ were skipped**, not passed, because credentials were not loaded into that run.
54
+ The [manual authenticated CI run](https://github.com/Mathieu2301/TradingView-API/actions/runs/37149955645)
55
+ on candidate commit `8e0e564` subsequently passed **all 25 tests**, including all six
56
+ account tests (none skipped). Its Node 20/22/24 and Bun jobs also passed. A green
57
+ workflow with a non-blocking failed live job or skipped account tests is insufficient.
58
+
59
+ Earlier beta evidence remains in [reliability evidence](v4-reliability.md): six
60
+ private USER scripts, 22 authenticated-suite tests, BTC updates after 30 heartbeats,
61
+ and a two-hour rotating-connection endurance run. These are distinct observations,
62
+ not substitutes for running the current candidate or reproducing original reports.
63
+
64
+ ## Release gates and explicit non-goals
65
+
66
+ | Gate / limitation | Disposition |
67
+ | --- | --- |
68
+ | Candidate deterministic CI and package consumption | Passed on Node 20/22/24 and Bun in the linked CI run |
69
+ | Current authenticated live suite | Passed: 25/25 in the linked manual CI run |
70
+ | Open-market EUR/USD HeikinAshi after 30 heartbeats | Scheduled for Monday 5 October, 09:00 Europe/Paris; remains pending |
71
+ | Populated account watchlists | Deterministic fixtures only; do not modify account content just to manufacture coverage |
72
+ | Deep Backtesting | Not shipped; available account returned `not_allowed` |
73
+ | Renko GUI parity, subscribed CME, original private scripts and 12-hour Pine issue | Matching assets/reproduction needed; no resolution claimed |
74
+ | Automatic reconnection / server-side alerts / trading execution | Outside this release's scope |
75
+
76
+ Do not promote npm `latest` (still V3) as part of candidate preparation. Once the
77
+ remaining required evidence is reviewed, publish the exact validated candidate
78
+ under a prerelease tag, verify registry installation on Node/Bun, and record the
79
+ published integrity/version. A stable V4 release is a separate promotion decision.
80
+
81
+ ## Cleanup
82
+
83
+ The 13 initial local worktrees were inventoried. Two clean, fully ancestral
84
+ worktrees were removed; the old beta.1 tarball was retained separately. Branch
85
+ references were kept. The primary managed project, worktrees with local context,
86
+ and divergent/squash-merged branches were retained rather than assuming ancestry.
87
+ No remote branches, contributor PRs, account data or historical issues were deleted.
@@ -0,0 +1,37 @@
1
+ # Examples
2
+
3
+ Build once, then run any example with Node or Bun:
4
+
5
+ ```bash
6
+ npm ci && npm run build
7
+ node examples/candles.js
8
+ bun examples/candles.js # Bun loads .env automatically
9
+ node --env-file=.env examples/indicator-data.js # Examples that need an account
10
+ ```
11
+
12
+ Examples that need an account read the `SESSION` and `SIGNATURE` cookies from the environment (see `.env.sample`). Never commit them.
13
+
14
+ | Example | API | Account |
15
+ | --- | --- | --- |
16
+ | [candles.js](candles.js) | `getCandles` (count, from/to) | No |
17
+ | [watch-candles.js](watch-candles.js) | `watchCandles` | No |
18
+ | [quotes.js](quotes.js) | `getQuote`, `getQuotes`, `watchQuotes` | No |
19
+ | [indicator-data.js](indicator-data.js) | `getIndicatorData` | Pine scripts only |
20
+ | [screener.js](screener.js) | `getScreener` (filters, columns, ranking) | No |
21
+ | [search.js](search.js) | `searchMarkets`, `searchIndicators`, `getTechnicalAnalysis` | No |
22
+ | [custom-chart-types.js](custom-chart-types.js) | Heikin Ashi, Renko, Line Break, Kagi, P&F, Range | No (daily) |
23
+ | [errors.js](errors.js) | `TradingViewError` codes | Partly |
24
+ | [simple-chart.js](simple-chart.js) | `TradingViewClient`, `ChartSession` | No |
25
+ | [quote-session.js](quote-session.js) | `QuoteSession` | No |
26
+ | [builtin-indicator.js](builtin-indicator.js) | `BuiltInIndicator`, study graphics | No |
27
+ | [fake-replay.js](fake-replay.js) | Negative counts and `fetchMore` | No |
28
+ | [strategy-report.js](strategy-report.js) | Public strategy → trade records → closed/open PnL summary | Yes (Basic tested) |
29
+ | [replay.js](replay.js) | Replay mode with studies | Pine studies only |
30
+ | [custom-timeframe.js](custom-timeframe.js) | Second-based timeframes | Yes |
31
+ | [from-to.js](from-to.js) | Reference times and ranges | Yes |
32
+ | [graphic-indicator.js](graphic-indicator.js) | Labels, lines, boxes, tables | Yes |
33
+ | [multiple-indicators.js](multiple-indicators.js) | Shared connection | Yes |
34
+ | [private-indicators.js](private-indicators.js) | `getPrivateIndicators` | Yes |
35
+ | [drawings.js](drawings.js) | `getDrawings` | Private layouts |
36
+ | [pine-permissions.js](pine-permissions.js) | `PinePermissionManager` | Yes (script owner) |
37
+ | [user-login.js](user-login.js) | `loginUser`, `getUser` | Username/password |
@@ -0,0 +1,22 @@
1
+ // Built-in studies such as the fixed-range volume profile.
2
+ // Run: npm run build && node examples/builtin-indicator.js
3
+ import { BuiltInIndicator, TradingViewClient } from '@mathieuc/tradingview';
4
+
5
+ const profile = new BuiltInIndicator('VbPFixed@tv-basicstudies-241!');
6
+ profile.setOption('first_bar_time', Date.now() - 10 ** 8);
7
+
8
+ const client = new TradingViewClient();
9
+ const chart = client.createChart();
10
+ chart.setMarket('BINANCE:BTCEUR', { timeframe: '60', count: 1 });
11
+
12
+ const study = chart.createStudy(profile);
13
+ study.on('update', async () => {
14
+ const rows = study.graphics.horizHists
15
+ .filter((h) => h.lastBarTime === 0) // Profile that ends on the latest bar
16
+ .sort((a, b) => b.priceHigh - a.priceHigh);
17
+ if (!rows.length) return;
18
+ for (const h of rows) {
19
+ console.log(`~ ${Math.round((h.priceHigh + h.priceLow) / 2)} € : ${'_'.repeat(h.rate[0] / 3)}${'_'.repeat(h.rate[1] / 3)}`);
20
+ }
21
+ await client.close();
22
+ });
@@ -0,0 +1,15 @@
1
+ // One-shot candles with the high-level data API.
2
+ // Run: npm run build && node examples/candles.js [SYMBOL] [TIMEFRAME]
3
+ import { getCandles } from '@mathieuc/tradingview/data';
4
+
5
+ const symbol = process.argv[2] ?? 'BINANCE:BTCUSDT';
6
+ const timeframe = process.argv[3] ?? 'D';
7
+
8
+ // The 100 most recent bars, oldest first. Resources are released automatically.
9
+ const candles = await getCandles({ symbol, timeframe, count: 100 });
10
+ const last = candles.at(-1);
11
+ console.log(`${candles.length} ${timeframe} candles for ${symbol}; last close ${last.close} at ${new Date(last.time * 1000).toISOString()}`);
12
+
13
+ // Every 4-hour bar of the last 7 days (history is loaded as deep as needed).
14
+ const week = await getCandles({ symbol, timeframe: '240', from: new Date(Date.now() - 7 * 86_400_000) });
15
+ console.log(`${week.length} 4h candles since ${new Date(week[0].time * 1000).toISOString()}`);
@@ -0,0 +1,17 @@
1
+ // Custom bar types: Heikin Ashi, Renko, Line Break, Kagi, Point & Figure and Range.
2
+ // Run: npm run build && node examples/custom-chart-types.js
3
+ import { getCandles } from '@mathieuc/tradingview/data';
4
+
5
+ const types = {
6
+ HeikinAshi: {},
7
+ Renko: { source: 'close', sources: 'Close', boxSize: 3, style: 'ATR', atrLength: 14, wicks: true },
8
+ LineBreak: { source: 'close', lb: 3 },
9
+ Kagi: { source: 'close', style: 'ATR', atrLength: 14, reversalAmount: 1 },
10
+ PointAndFigure: { sources: 'Close', reversalAmount: 3, boxSize: 1, style: 'ATR', atrLength: 14, oneStepBackBuilding: false },
11
+ Range: { range: 1, phantomBars: false },
12
+ };
13
+
14
+ for (const [chartType, chartInputs] of Object.entries(types)) {
15
+ const candles = await getCandles({ symbol: 'BINANCE:BTCEUR', timeframe: 'D', count: 50, chartType, chartInputs });
16
+ console.log(chartType.padEnd(15), `${candles.length} bars, last close ${candles.at(-1)?.close}`);
17
+ }
@@ -0,0 +1,14 @@
1
+ // Second-based and other custom timeframes need an account with access to them.
2
+ // Run: npm run build && node --env-file=.env examples/custom-timeframe.js
3
+ import { getCandles } from '@mathieuc/tradingview/data';
4
+
5
+ if (!process.env.SESSION || !process.env.SIGNATURE) throw new Error('Please set your SESSION and SIGNATURE cookies');
6
+
7
+ const candles = await getCandles({
8
+ symbol: 'CAPITALCOM:US100',
9
+ timeframe: '1S',
10
+ count: 10,
11
+ timezone: 'Europe/Paris',
12
+ credentials: { session: process.env.SESSION, signature: process.env.SIGNATURE },
13
+ });
14
+ console.log(candles);
@@ -0,0 +1,16 @@
1
+ // Drawings of a saved layout (the ID in tradingview.com/chart/<ID>/).
2
+ // Private layouts need credentials and your user ID (see examples/user-login.js).
3
+ // Run: npm run build && node --env-file=.env examples/drawings.js <layoutId> [userId]
4
+ import { getDrawings } from '@mathieuc/tradingview';
5
+
6
+ const [layoutId, userId] = process.argv.slice(2);
7
+ if (!layoutId) throw new Error('Please specify a layout ID');
8
+
9
+ const drawings = await getDrawings(layoutId, {
10
+ credentials: process.env.SESSION ? { session: process.env.SESSION, signature: process.env.SIGNATURE } : undefined,
11
+ userId: userId ? Number(userId) : undefined,
12
+ });
13
+
14
+ console.log(`Found ${drawings.length} drawings:`, drawings.map((d) => ({
15
+ id: d.id, symbol: d.symbol, type: d.type, text: d.state?.text,
16
+ })));