@mathieuc/tradingview 3.0.1 → 3.3.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.
Files changed (50) hide show
  1. package/.eslintrc.js +6 -0
  2. package/README.md +28 -2
  3. package/docs/DOCS.md +3 -0
  4. package/examples/AllPrivateIndicators.js +4 -4
  5. package/examples/BuiltInIndicator.js +1 -1
  6. package/examples/CustomChartType.js +1 -0
  7. package/examples/Errors.js +147 -153
  8. package/examples/FakeReplayMode.js +41 -0
  9. package/examples/GetDrawings.js +26 -0
  10. package/examples/PinePermManage.js +57 -0
  11. package/examples/ReplayMode.js +97 -0
  12. package/examples/UserLogin.js +16 -0
  13. package/main.js +2 -0
  14. package/package.json +6 -9
  15. package/src/FormData.js +36 -0
  16. package/src/chart/session.js +193 -17
  17. package/src/chart/study.js +68 -68
  18. package/src/classes/BuiltInIndicator.js +1 -0
  19. package/src/classes/PineIndicator.js +7 -7
  20. package/src/classes/PinePermManager.js +143 -0
  21. package/src/client.js +17 -10
  22. package/src/miscRequests.js +148 -103
  23. package/src/protocol.js +7 -1
  24. package/src/quote/session.js +1 -0
  25. package/src/request.js +37 -0
  26. package/src/types.js +6 -2
  27. package/src/utils.js +6 -0
  28. package/test.js +58 -147
  29. package/tests/1. Search.js +18 -0
  30. package/tests/2. QuoteSession.js +54 -0
  31. package/tests/3. SimpleChart.js +61 -0
  32. package/tests/4. Indicators.js +100 -0
  33. package/tests/5. BuiltInIndicator.js +41 -0
  34. package/tests/6. FakeReplayMode.js +59 -0
  35. package/tests/7. ReplayMode.js +51 -0
  36. package/tests/8. CustomChartTypes.js +115 -0
  37. package/tests/9. AllErrors.js +146 -0
  38. package/.github/FUNDING.yml +0 -1
  39. package/examples/CurrentTimeframe.js +0 -34
  40. package/examples/_RenkoIndicator.js +0 -41
  41. package/tests/alerts/discordWH.js +0 -76
  42. package/tests/alerts/drawings.js +0 -41
  43. package/tests/alerts/envLoader.js +0 -11
  44. package/tests/alerts/manualAlert.js +0 -77
  45. package/tests/alerts/sentNotifs.js +0 -16
  46. package/tests/alerts/strategyAlert.js +0 -94
  47. package/tests/analysis.js +0 -13
  48. package/tests/indicator.js +0 -42
  49. package/tests/prices.js +0 -33
  50. package/tests/strategy.js +0 -56
package/.eslintrc.js CHANGED
@@ -14,5 +14,11 @@ module.exports = {
14
14
  },
15
15
  rules: {
16
16
  'no-console': 'off',
17
+ 'import/no-extraneous-dependencies': [
18
+ 'error',
19
+ {
20
+ devDependencies: ['./test.js', './tests/**'],
21
+ },
22
+ ],
17
23
  },
18
24
  };
package/README.md CHANGED
@@ -1,7 +1,16 @@
1
- # TradingView API
1
+ # TradingView API [![GitHub stars](https://img.shields.io/github/stars/Mathieu2301/TradingView-API.svg?style=social&label=Star&maxAge=2592000)](https://GitHub.com/Mathieu2301/TradingView-API/stargazers/)
2
+
3
+ [![Tests](https://github.com/Mathieu2301/TradingView-API/actions/workflows/node.js.yml/badge.svg)](https://github.com/Mathieu2301/TradingView-API/actions/workflows/node.js.yml)
4
+ [![CodeFactor](https://www.codefactor.io/repository/github/mathieu2301/tradingview-api/badge/main)](https://www.codefactor.io/repository/github/mathieu2301/tradingview-api/overview/main)
5
+ [![GitHub latest commit](https://img.shields.io/github/last-commit/Mathieu2301/TradingView-API)](https://GitHub.com/Mathieu2301/TradingView-API/commit/)
6
+ [![Npm package yearly downloads](https://badgen.net/npm/dt/@mathieuc/tradingview)](https://npmjs.com/@mathieuc/tradingview)
7
+ [![Minimum node.js version](https://badgen.net/npm/node/@mathieuc/tradingview)](https://npmjs.com/@mathieuc/tradingview)
8
+ [![Npm package version](https://badgen.net/npm/v/@mathieuc/tradingview)](https://npmjs.com/package/@mathieuc/tradingview)
9
+
2
10
  Get realtime market prices and indicator values from Tradingview !
3
11
 
4
12
  ## Features
13
+
5
14
  - [x] Premium features
6
15
  - [x] Automatically backtest many strategies and try many settings in a very little time
7
16
  - [x] Get drawings you made on your chart
@@ -9,6 +18,7 @@ Get realtime market prices and indicator values from Tradingview !
9
18
  - [x] Unlimited simultaneous indicators
10
19
  - [x] Realtime
11
20
  - [x] Get TradingView's technical analysis
21
+ - [x] Replay mode + Fake Replay mode (for free plan)
12
22
  - [x] Get values from a specific date range
13
23
  - [ ] TradingView socket server emulation
14
24
  - [ ] Interract with public chats
@@ -18,6 +28,7 @@ Get realtime market prices and indicator values from Tradingview !
18
28
  - IF YOU WANT A FEATURE, ASK ME !
19
29
 
20
30
  ## Possibilities
31
+
21
32
  - Trading bot
22
33
  - Discord alerts
23
34
  - Hard backtest
@@ -25,16 +36,31 @@ Get realtime market prices and indicator values from Tradingview !
25
36
  - Free replay mode for all timeframes
26
37
 
27
38
  ___
39
+
28
40
  ## Installation
29
41
 
30
- ```
42
+ Stable version:
43
+
44
+ ```ruby
31
45
  npm i @mathieuc/tradingview
32
46
  ```
33
47
 
48
+ Last version:
49
+
50
+ ```ruby
51
+ npm i github:Mathieu2301/TradingView-API
52
+ ```
53
+
34
54
  ## Examples
55
+
35
56
  You can find all the examples and snippets in `./examples` folder.
36
57
 
58
+ ## Before opening an issue
59
+
60
+ Please look at examples and previously resolved issues before opening a new one. I can't help everyone (especially for questions that are not library related but JavaScript related). Thank you for your understanding.
37
61
  ___
62
+
38
63
  ## Problems
64
+
39
65
  If you have errors in console or unwanted behavior,
40
66
  please create an issue [here](https://github.com/Mathieu2301/Tradingview-API/issues).
package/docs/DOCS.md ADDED
@@ -0,0 +1,3 @@
1
+ # Documentation
2
+
3
+ ### All the project is now JSDoc-ed :)
@@ -5,10 +5,10 @@ const TradingView = require('../main');
5
5
  all user's private indicators
6
6
  */
7
7
 
8
+ if (!process.argv[2]) throw Error('Please specify your \'sessionid\' cookie');
9
+
8
10
  const client = new TradingView.Client({
9
- /* Token is only needed if at least one indicator is
10
- PRIVATE (if you have a paid TradingView account) */
11
- token: 'YOUR_SESSION_ID_COOKIE',
11
+ token: process.argv[2],
12
12
  });
13
13
 
14
14
  const chart = new client.Session.Chart();
@@ -16,7 +16,7 @@ chart.setMarket('BINANCE:BTCEUR', {
16
16
  timeframe: 'D',
17
17
  });
18
18
 
19
- TradingView.getPrivateIndicators('YOUR_SESSION_ID_COOKIE').then((indicList) => {
19
+ TradingView.getPrivateIndicators(process.argv[2]).then((indicList) => {
20
20
  indicList.forEach(async (indic) => {
21
21
  const privateIndic = await indic.get();
22
22
  console.log('Loading indicator', indic.name, '...');
@@ -7,7 +7,7 @@ const TradingView = require('../main');
7
7
 
8
8
  const volumeProfile = new TradingView.BuiltInIndicator('VbPFixed@tv-basicstudies-139!');
9
9
 
10
- if (!process.argv[2] && volumeProfile.type !== 'VbPFixed@tv-basicstudies-139!') {
10
+ if (!process.argv[2] && !['VbPFixed@tv-basicstudies-139!', 'Volume@tv-basicstudies-144'].includes(volumeProfile.type)) {
11
11
  throw Error('Please specify your \'sessionid\' cookie');
12
12
  }
13
13
 
@@ -17,6 +17,7 @@ const chart = new client.Session.Chart();
17
17
 
18
18
  chart.onError((...err) => {
19
19
  console.log('Chart error:', ...err);
20
+ process.exit(1);
20
21
  });
21
22
 
22
23
  chart.onUpdate(() => {
@@ -1,153 +1,147 @@
1
- const TradingView = require('../main');
2
-
3
- /*
4
- This example tests many types of errors
5
- */
6
-
7
- const client = new TradingView.Client(); // Creates a websocket client
8
-
9
- const tests = [
10
- (next) => { /* Testing "Credentials error" */
11
- console.info('\nTesting "Credentials error" error:');
12
-
13
- const client2 = new TradingView.Client({
14
- token: 'FAKE_CREDENTIALS', // Set wrong credentials
15
- });
16
-
17
- client2.onError((...err) => {
18
- console.error(' => Client error:', err);
19
- client2.end();
20
- next();
21
- });
22
- },
23
-
24
- (next) => { /* Testing "Invalid symbol" */
25
- console.info('\nTesting "Invalid symbol" error:');
26
-
27
- const chart = new client.Session.Chart();
28
- chart.onError((...err) => { // Listen for errors
29
- console.error(' => Chart error:', err);
30
- chart.delete();
31
- next();
32
- });
33
-
34
- chart.setMarket('XXXXX'); // Set a wrong market
35
- },
36
-
37
- (next) => { /* Testing "Invalid timezone" */
38
- console.info('\nTesting "Invalid timezone" error:');
39
-
40
- const chart = new client.Session.Chart();
41
- chart.onError((...err) => { // Listen for errors
42
- console.error(' => Chart error:', err);
43
- next();
44
- });
45
-
46
- chart.setMarket('BINANCE:BTCEUR'); // Set a market
47
- chart.setTimezone('Nowhere/Nowhere'); // Set a fake timezone
48
- },
49
-
50
- (next) => { /* Testing "Custom timeframe" */
51
- console.info('\nTesting "Custom timeframe" error:');
52
-
53
- const chart = new client.Session.Chart();
54
- chart.onError((...err) => { // Listen for errors
55
- console.error(' => Chart error:', err);
56
- chart.delete();
57
- next();
58
- });
59
-
60
- chart.setMarket('BINANCE:BTCEUR', { // Set a market
61
- timeframe: '20', // Set a custom timeframe
62
- /*
63
- Timeframe '20' isn't available because we are
64
- not logged in as a premium TradingView user
65
- */
66
- });
67
- },
68
-
69
- (next) => { /* Testing "Invalid timeframe" */
70
- console.info('\nTesting "Invalid timeframe" error:');
71
-
72
- const chart = new client.Session.Chart();
73
- chart.onError((...err) => { // Listen for errors
74
- console.error(' => Chart error:', err);
75
- next();
76
- });
77
-
78
- chart.setMarket('BINANCE:BTCEUR', { // Set a market
79
- timeframe: 'XX', // Set a wrong timeframe
80
- });
81
- },
82
-
83
- (next) => { /* Testing "Study not auth" */
84
- console.info('\nTesting "Study not auth" error:');
85
-
86
- const chart = new client.Session.Chart();
87
- chart.onError((...err) => { // Listen for errors
88
- console.error(' => Chart error:', err);
89
- next();
90
- });
91
-
92
- chart.setMarket('BINANCE:BTCEUR', { // Set a market
93
- timeframe: '15',
94
- type: 'Renko',
95
- });
96
-
97
- chart.onUpdate(() => {
98
- console.log('DATA', chart.periods[0]);
99
- });
100
- },
101
-
102
- (next) => { /* Testing "Set the market before" */
103
- console.info('\nTesting "Set the market before..." error:');
104
-
105
- const chart = new client.Session.Chart();
106
- chart.onError((...err) => { // Listen for errors
107
- console.error(' => Chart error:', err);
108
- chart.delete();
109
- next();
110
- });
111
-
112
- chart.setSeries('15'); // Set series before setting the market
113
- },
114
-
115
- (next) => { /* Testing "Inexistent indicator" */
116
- console.info('\nTesting "Inexistent indicator" error:');
117
-
118
- TradingView.getIndicator('STD;XXXXXXX')
119
- .catch((err) => {
120
- console.error(' => API error:', [err.message]);
121
- next();
122
- });
123
- },
124
-
125
- async (next) => { /* Testing "Invalid value" */
126
- console.info('\nTesting "Invalid value" error:');
127
-
128
- const chart = new client.Session.Chart();
129
- chart.setMarket('BINANCE:BTCEUR'); // Set a market
130
-
131
- const ST = await TradingView.getIndicator('STD;Supertrend');
132
- ST.setOption('Factor', -1); // This will cause an error
133
-
134
- const Supertrend = new chart.Study(ST);
135
- Supertrend.onError((...err) => {
136
- console.error(' => Study error:', err);
137
- chart.delete();
138
- next();
139
- });
140
- },
141
- ];
142
-
143
- let i = 0;
144
- const execTest = () => {
145
- if (tests[i + 1]) {
146
- tests[(i += 1) - 1](execTest);
147
- } else {
148
- tests[(i += 1) - 1](() => {
149
- console.log(`\nTests ${i}/${i} done !`);
150
- });
151
- }
152
- };
153
- execTest();
1
+ const TradingView = require('../main');
2
+
3
+ /*
4
+ This example tests many types of errors
5
+ */
6
+
7
+ const client = new TradingView.Client(); // Creates a websocket client
8
+
9
+ const tests = [
10
+ (next) => { /* Testing "Credentials error" */
11
+ console.info('\nTesting "Credentials error" error:');
12
+
13
+ const client2 = new TradingView.Client({
14
+ token: 'FAKE_CREDENTIALS', // Set wrong credentials
15
+ });
16
+
17
+ client2.onError((...err) => {
18
+ console.error(' => Client error:', err);
19
+ client2.end();
20
+ next();
21
+ });
22
+ },
23
+
24
+ (next) => { /* Testing "Invalid symbol" */
25
+ console.info('\nTesting "Invalid symbol" error:');
26
+
27
+ const chart = new client.Session.Chart();
28
+ chart.onError((...err) => { // Listen for errors
29
+ console.error(' => Chart error:', err);
30
+ chart.delete();
31
+ next();
32
+ });
33
+
34
+ chart.setMarket('XXXXX'); // Set a wrong market
35
+ },
36
+
37
+ (next) => { /* Testing "Invalid timezone" */
38
+ console.info('\nTesting "Invalid timezone" error:');
39
+
40
+ const chart = new client.Session.Chart();
41
+ chart.onError((...err) => { // Listen for errors
42
+ console.error(' => Chart error:', err);
43
+ next();
44
+ });
45
+
46
+ chart.setMarket('BINANCE:BTCEUR'); // Set a market
47
+ chart.setTimezone('Nowhere/Nowhere'); // Set a fake timezone
48
+ },
49
+
50
+ (next) => { /* Testing "Custom timeframe" */
51
+ console.info('\nTesting "Custom timeframe" error:');
52
+
53
+ const chart = new client.Session.Chart();
54
+ chart.onError((...err) => { // Listen for errors
55
+ console.error(' => Chart error:', err);
56
+ chart.delete();
57
+ next();
58
+ });
59
+
60
+ chart.setMarket('BINANCE:BTCEUR', { // Set a market
61
+ timeframe: '20', // Set a custom timeframe
62
+ /*
63
+ Timeframe '20' isn't available because we are
64
+ not logged in as a premium TradingView account
65
+ */
66
+ });
67
+ },
68
+
69
+ (next) => { /* Testing "Invalid timeframe" */
70
+ console.info('\nTesting "Invalid timeframe" error:');
71
+
72
+ const chart = new client.Session.Chart();
73
+ chart.onError((...err) => { // Listen for errors
74
+ console.error(' => Chart error:', err);
75
+ next();
76
+ });
77
+
78
+ chart.setMarket('BINANCE:BTCEUR', { // Set a market
79
+ timeframe: 'XX', // Set a wrong timeframe
80
+ });
81
+ },
82
+
83
+ (next) => { /* Testing "Study not auth" */
84
+ console.info('\nTesting "Study not auth" error:');
85
+
86
+ const chart = new client.Session.Chart();
87
+ chart.onError((...err) => { // Listen for errors
88
+ console.error(' => Chart error:', err);
89
+ next();
90
+ });
91
+
92
+ chart.setMarket('BINANCE:BTCEUR', { // Set a market
93
+ timeframe: '15',
94
+ type: 'Renko',
95
+ });
96
+
97
+ chart.onUpdate(() => {
98
+ console.log('DATA', chart.periods[0]);
99
+ });
100
+ },
101
+
102
+ (next) => { /* Testing "Set the market before" */
103
+ console.info('\nTesting "Set the market before..." error:');
104
+
105
+ const chart = new client.Session.Chart();
106
+ chart.onError((...err) => { // Listen for errors
107
+ console.error(' => Chart error:', err);
108
+ chart.delete();
109
+ next();
110
+ });
111
+
112
+ chart.setSeries('15'); // Set series before setting the market
113
+ },
114
+
115
+ (next) => { /* Testing "Inexistent indicator" */
116
+ console.info('\nTesting "Inexistent indicator" error:');
117
+
118
+ TradingView.getIndicator('STD;XXXXXXX')
119
+ .catch((err) => {
120
+ console.error(' => API error:', [err.message]);
121
+ next();
122
+ });
123
+ },
124
+
125
+ async (next) => { /* Testing "Invalid value" */
126
+ console.info('\nTesting "Invalid value" error:');
127
+
128
+ const chart = new client.Session.Chart();
129
+ chart.setMarket('BINANCE:BTCEUR'); // Set a market
130
+
131
+ const ST = await TradingView.getIndicator('STD;Supertrend');
132
+ ST.setOption('Factor', -1); // This will cause an error
133
+
134
+ const Supertrend = new chart.Study(ST);
135
+ Supertrend.onError((...err) => {
136
+ console.error(' => Study error:', err);
137
+ chart.delete();
138
+ next();
139
+ });
140
+ },
141
+ ];
142
+
143
+ (async () => {
144
+ // eslint-disable-next-line no-restricted-syntax, no-await-in-loop
145
+ for (const t of tests) await new Promise(t);
146
+ console.log(`\nTests ${tests.length}/${tests.length} done !`);
147
+ })();
@@ -0,0 +1,41 @@
1
+ const { Client } = require('../main');
2
+
3
+ /*
4
+ This example tests the fake
5
+ replay mode which works in
6
+ intraday even with free plan
7
+ */
8
+
9
+ console.log('----- Testing FakeReplayMode: -----');
10
+
11
+ const client = new Client();
12
+ const chart = new client.Session.Chart();
13
+
14
+ chart.setMarket('BINANCE:BTCEUR', {
15
+ timeframe: 'D',
16
+ range: -1, // Range is negative, so 'to' means 'from'
17
+ to: Math.round(Date.now() / 1000) - 86400 * 7, // Seven days before now
18
+ // to: 1600000000,
19
+ });
20
+
21
+ let interval = NaN;
22
+
23
+ chart.onUpdate(async () => {
24
+ const times = chart.periods.map((p) => p.time);
25
+
26
+ const intrval = times[0] - times[1];
27
+ if (Number.isNaN(interval) && times.length >= 2) interval = intrval;
28
+
29
+ if (!Number.isNaN(interval) && interval !== intrval) {
30
+ throw new Error(`Wrong interval: ${intrval} (should be ${interval})`);
31
+ }
32
+
33
+ console.log('Next ->', times[0]);
34
+
35
+ if ((times[0] + 86400) * 1000 > Date.now()) {
36
+ await client.end();
37
+ console.log('Done !', times.length);
38
+ }
39
+
40
+ chart.fetchMore(-1);
41
+ });
@@ -0,0 +1,26 @@
1
+ const TradingView = require('../main');
2
+
3
+ /*
4
+ This example tests the
5
+ getDrawings function
6
+ */
7
+
8
+ // First parameter must be the layoutID
9
+ // (if the layout is private) Second parameter must be the sessionid cookie
10
+ // (if the layout is private) Third parameter must be the userid (you can use getUser function)
11
+
12
+ if (!process.argv[2]) throw Error('Please specify a layoutID');
13
+
14
+ TradingView.getDrawings(process.argv[2], null, {
15
+ session: process.argv[3],
16
+ id: process.argv[4],
17
+ }).then((drawings) => {
18
+ console.log(`Found ${drawings.length} drawings:`, drawings.map((d) => ({
19
+ id: d.id,
20
+ symbol: d.symbol,
21
+ type: d.type,
22
+ text: d.state.text,
23
+ })));
24
+ }).catch((err) => {
25
+ console.error('Error:', err.message);
26
+ });
@@ -0,0 +1,57 @@
1
+ const { PinePermManager } = require('../main');
2
+
3
+ /*
4
+ This example creates a pine
5
+ permission manager and tests
6
+ all the available functions
7
+ */
8
+
9
+ const sessionid = process.argv[2];
10
+ const pineid = process.argv[3];
11
+
12
+ const manager = new PinePermManager(sessionid, pineid);
13
+
14
+ (async () => {
15
+ console.log('Users:', await manager.getUsers());
16
+
17
+ console.log('Adding user \'TradingView\'...');
18
+
19
+ switch (await manager.addUser('TradingView')) {
20
+ case 'ok':
21
+ console.log('Done !');
22
+ break;
23
+ case 'exists':
24
+ console.log('This user is already authorized');
25
+ break;
26
+ default:
27
+ console.error('Unknown error...');
28
+ break;
29
+ }
30
+
31
+ console.log('Users:', await manager.getUsers());
32
+
33
+ console.log('Modifying expiration date...');
34
+
35
+ const newDate = new Date(Date.now() + 24 * 3600000); // Add one day
36
+ if (await manager.modifyExpiration('TradingView', newDate) === 'ok') {
37
+ console.log('Done !');
38
+ } else console.error('Unknown error...');
39
+
40
+ console.log('Users:', await manager.getUsers());
41
+
42
+ console.log('Removing expiration date...');
43
+
44
+ if (await manager.modifyExpiration('TradingView') === 'ok') {
45
+ console.log('Done !');
46
+ } else console.error('Unknown error...');
47
+
48
+ console.log('Users:', await manager.getUsers());
49
+
50
+ console.log('Removing user \'TradingView\'...');
51
+
52
+ if (await manager.removeUser('TradingView') === 'ok') {
53
+ console.log('Done !');
54
+ } else console.error('Unknown error...');
55
+
56
+ console.log('Users:', await manager.getUsers());
57
+ })();
@@ -0,0 +1,97 @@
1
+ const TradingView = require('../main');
2
+
3
+ /*
4
+ This example tests the real replay
5
+ mode by fetching indicator data and
6
+ stores it in a 'periods' variable
7
+ */
8
+
9
+ const config = {
10
+ symbol: 'BINANCE:BTCEUR',
11
+ timeframe: 'D',
12
+ startFrom: Math.round(Date.now() / 1000) - 86400 * 7, // Seven days before now
13
+ // startFrom: 1600000000,
14
+ };
15
+
16
+ console.log('----- Testing ReplayMode: -----');
17
+
18
+ const client = new TradingView.Client();
19
+ const chart = new client.Session.Chart();
20
+
21
+ chart.setMarket(config.symbol, {
22
+ timeframe: config.timeframe,
23
+ replay: config.startFrom,
24
+ range: 1,
25
+ });
26
+
27
+ // chart.onReplayLoaded(() => {
28
+ // console.log('STARTING REPLAY MODE');
29
+ // chart.replayStart(1000);
30
+
31
+ // // setTimeout(() => {
32
+ // // console.log('STOPPING REPLAY MODE');
33
+ // // chart.replayStop();
34
+ // // }, 7000);
35
+ // });
36
+
37
+ let loading = 0;
38
+ const indicators = [];
39
+ const periods = {};
40
+
41
+ let interval = NaN;
42
+
43
+ async function step() {
44
+ const period = { ...chart.periods[0] };
45
+
46
+ const times = Object.keys(periods);
47
+ const intrval = times[times.length - 1] - times[times.length - 2];
48
+ if (Number.isNaN(interval) && times.length >= 2) interval = intrval;
49
+
50
+ if (!Number.isNaN(interval) && interval !== intrval) {
51
+ throw new Error(`Wrong interval: ${intrval} (should be ${interval})`);
52
+ }
53
+
54
+ indicators.forEach(([n, i]) => {
55
+ const plots = { ...i.periods[0] };
56
+ delete plots.$time;
57
+ period[n] = { plots };
58
+
59
+ Object.keys(i.graphic).forEach((g) => {
60
+ if (!i.graphic[g].length) return;
61
+ if (!period[n].graphics) period[n].graphics = {};
62
+ period[n].graphics[g] = i.graphic[g];
63
+ });
64
+ });
65
+
66
+ periods[period.time] = period;
67
+
68
+ console.log('Next ->', period.time, times.length);
69
+
70
+ await chart.replayStep(1);
71
+ step();
72
+ }
73
+
74
+ chart.onReplayEnd(async () => {
75
+ await client.end();
76
+ console.log('Done !', Object.keys(periods).length);
77
+ });
78
+
79
+ async function addIndicator(name, pineId, options = {}) {
80
+ loading += 1;
81
+
82
+ const indic = pineId.includes('@')
83
+ ? new TradingView.BuiltInIndicator(pineId)
84
+ : await TradingView.getIndicator(pineId);
85
+ Object.keys(options).forEach((o) => { indic.setOption(o, options[o]); });
86
+
87
+ const std = new chart.Study(indic);
88
+
89
+ std.onReady(() => {
90
+ indicators.push([name, std]);
91
+ if (loading === indicators.length) step();
92
+ });
93
+ }
94
+
95
+ addIndicator('Volume', 'Volume@tv-basicstudies-144');
96
+ addIndicator('EMA_50', 'STD;EMA', { Length: 50 });
97
+ addIndicator('EMA_200', 'STD;EMA', { Length: 200 });
@@ -0,0 +1,16 @@
1
+ const TradingView = require('../main');
2
+
3
+ /*
4
+ This example tests the
5
+ user login function
6
+ */
7
+
8
+ if (!process.argv[2]) throw Error('Please specify your username/email');
9
+ if (!process.argv[3]) throw Error('Please specify your password');
10
+
11
+ TradingView.loginUser(process.argv[2], process.argv[3], false).then((user) => {
12
+ console.log('User:', user);
13
+ console.log('Sessionid:', user.session);
14
+ }).catch((err) => {
15
+ console.error('Login error:', err.message);
16
+ });
package/main.js CHANGED
@@ -2,8 +2,10 @@ const miscRequests = require('./src/miscRequests');
2
2
  const Client = require('./src/client');
3
3
  const BuiltInIndicator = require('./src/classes/BuiltInIndicator');
4
4
  const PineIndicator = require('./src/classes/PineIndicator');
5
+ const PinePermManager = require('./src/classes/PinePermManager');
5
6
 
6
7
  module.exports = { ...miscRequests };
7
8
  module.exports.Client = Client;
8
9
  module.exports.BuiltInIndicator = BuiltInIndicator;
9
10
  module.exports.PineIndicator = PineIndicator;
11
+ module.exports.PinePermManager = PinePermManager;