@mathieuc/tradingview 3.0.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/examples/AllPrivateIndicators.js +4 -4
- package/examples/CustomChartType.js +1 -0
- package/examples/Errors.js +147 -153
- package/examples/FakeReplayMode.js +41 -0
- package/examples/PinePermManage.js +57 -0
- package/examples/ReplayMode.js +97 -0
- package/main.js +2 -0
- package/package.json +5 -7
- package/src/FormData.js +35 -0
- package/src/chart/session.js +190 -16
- package/src/classes/PinePermManager.js +142 -0
- package/src/client.js +1 -1
- package/src/miscRequests.js +5 -33
- package/src/quote/session.js +1 -0
- package/src/request.js +37 -0
- package/test.js +56 -147
- package/tests/1. Search.js +18 -0
- package/tests/2. QuoteSession.js +54 -0
- package/tests/3. SimpleChart.js +61 -0
- package/tests/4. Indicators.js +99 -0
- package/tests/5. BuiltInIndicator.js +41 -0
- package/tests/6. FakeReplayMode.js +59 -0
- package/tests/7. ReplayMode.js +51 -0
- package/tests/8. CustomChartTypes.js +115 -0
- package/tests/9. AllErrors.js +146 -0
- package/tests/disabled/x. Template.js +24 -0
- package/.github/FUNDING.yml +0 -1
- package/tests/alerts/discordWH.js +0 -76
- package/tests/alerts/drawings.js +0 -41
- package/tests/alerts/envLoader.js +0 -11
- package/tests/alerts/manualAlert.js +0 -77
- package/tests/alerts/sentNotifs.js +0 -16
- package/tests/alerts/strategyAlert.js +0 -94
- package/tests/analysis.js +0 -13
- package/tests/indicator.js +0 -42
- package/tests/prices.js +0 -33
- package/tests/strategy.js +0 -56
package/README.md
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
# TradingView API
|
|
1
|
+
# TradingView API [](https://open.vscode.dev/Mathieu2301/TradingView-API) [](https://GitHub.com/Mathieu2301/TradingView-API/stargazers/)
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Mathieu2301/TradingView-API/actions/workflows/node.js.yml)
|
|
4
|
+
[](https://npmjs.com/@mathieuc/tradingview)
|
|
5
|
+
[](https://npmjs.com/@mathieuc/tradingview)
|
|
6
|
+
[](https://GitHub.com/Mathieu2301/TradingView-API/commit/)
|
|
7
|
+
[](https://npmjs.com/package/@mathieuc/tradingview)
|
|
8
|
+
|
|
2
9
|
Get realtime market prices and indicator values from Tradingview !
|
|
3
10
|
|
|
4
11
|
## Features
|
|
@@ -9,6 +16,7 @@ Get realtime market prices and indicator values from Tradingview !
|
|
|
9
16
|
- [x] Unlimited simultaneous indicators
|
|
10
17
|
- [x] Realtime
|
|
11
18
|
- [x] Get TradingView's technical analysis
|
|
19
|
+
- [x] Replay mode + Fake Replay mode (for free plan)
|
|
12
20
|
- [x] Get values from a specific date range
|
|
13
21
|
- [ ] TradingView socket server emulation
|
|
14
22
|
- [ ] Interract with public chats
|
|
@@ -27,9 +35,14 @@ Get realtime market prices and indicator values from Tradingview !
|
|
|
27
35
|
___
|
|
28
36
|
## Installation
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
Stable version:
|
|
39
|
+
```ruby
|
|
31
40
|
npm i @mathieuc/tradingview
|
|
32
41
|
```
|
|
42
|
+
Last version:
|
|
43
|
+
```ruby
|
|
44
|
+
npm i github:Mathieu2301/TradingView-API
|
|
45
|
+
```
|
|
33
46
|
|
|
34
47
|
## Examples
|
|
35
48
|
You can find all the examples and snippets in `./examples` folder.
|
|
@@ -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
|
-
|
|
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(
|
|
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, '...');
|
package/examples/Errors.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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,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 });
|
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;
|
package/package.json
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mathieuc/tradingview",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Tradingview instant stocks API, indicator alerts, trading bot, and more !",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test
|
|
8
|
-
"test-analysis": "node ./tests/analysis.js",
|
|
9
|
-
"test-indicator": "node ./tests/indicator.js",
|
|
10
|
-
"test-manual-alerts": "node ./tests/alerts/manualAlert.js",
|
|
11
|
-
"test-strat-alerts": "node ./tests/alerts/strategyAlert.js",
|
|
12
|
-
"test": "npm run test-prices"
|
|
7
|
+
"test": "node test"
|
|
13
8
|
},
|
|
14
9
|
"repository": {
|
|
15
10
|
"type": "git",
|
|
16
11
|
"url": "git+https://github.com/Mathieu2301/TradingView-API.git"
|
|
17
12
|
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=14.0.0"
|
|
15
|
+
},
|
|
18
16
|
"keywords": [
|
|
19
17
|
"tradingwiew",
|
|
20
18
|
"market",
|
package/src/FormData.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class FormData {
|
|
2
|
+
#string = '';
|
|
3
|
+
|
|
4
|
+
#boundary = '';
|
|
5
|
+
|
|
6
|
+
get boundary() {
|
|
7
|
+
return this.#boundary;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
const random = (Math.random() * 10 ** 20).toString(36);
|
|
12
|
+
this.#boundary = `${random}`;
|
|
13
|
+
this.#string = `--${this.boundary}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Adds a property to the FormData object
|
|
18
|
+
* @param {string} key Property key
|
|
19
|
+
* @param {string} value Property value
|
|
20
|
+
*/
|
|
21
|
+
append(key, value) {
|
|
22
|
+
this.#string += `\r\nContent-Disposition: form-data; name="${key}"`;
|
|
23
|
+
this.#string += `\r\n\r\n${value}`;
|
|
24
|
+
this.#string += `\r\n--${this.boundary}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @returns {string}
|
|
29
|
+
*/
|
|
30
|
+
toString() {
|
|
31
|
+
return `${this.#string}--`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = FormData;
|