market-data-tradingview-ws 0.0.11 → 0.0.13
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/lib/client.js +84 -65
- package/lib/tradingView.js +16 -7
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -13,10 +13,13 @@ const periods = {
|
|
|
13
13
|
3600: '60',
|
|
14
14
|
14400: '240',
|
|
15
15
|
86400: '1D',
|
|
16
|
+
604800: '1W',
|
|
17
|
+
2592000: '1M',
|
|
16
18
|
};
|
|
17
19
|
|
|
20
|
+
let ws = null;
|
|
21
|
+
|
|
18
22
|
module.exports = class Client {
|
|
19
|
-
#ws;
|
|
20
23
|
#charts = {
|
|
21
24
|
values: {},
|
|
22
25
|
set({ key, data }) {
|
|
@@ -29,6 +32,7 @@ module.exports = class Client {
|
|
|
29
32
|
frame: data.frame,
|
|
30
33
|
i: data.i,
|
|
31
34
|
deleted: data.deleted || false,
|
|
35
|
+
limit: data.limit || 1500,
|
|
32
36
|
};
|
|
33
37
|
}
|
|
34
38
|
},
|
|
@@ -84,17 +88,29 @@ module.exports = class Client {
|
|
|
84
88
|
if (index !== -1) arr.splice(index, 1);
|
|
85
89
|
},
|
|
86
90
|
};
|
|
91
|
+
#symbols = {
|
|
92
|
+
values: {},
|
|
93
|
+
max: 1,
|
|
94
|
+
getSymbol({ key, symbol }) {
|
|
95
|
+
// let data = this.values[symbol];
|
|
96
|
+
// if (data === undefined) data = this.set({ key, symbol });
|
|
97
|
+
// return data;
|
|
98
|
+
const symbolKey = 'sds_sym_' + this.max++;
|
|
99
|
+
ws.send(tv.resolveSymbol({ chartSession: key, symbolKey, symbol }));
|
|
100
|
+
this.values[symbol] = { key: symbolKey };
|
|
101
|
+
return this.values[symbol];
|
|
102
|
+
},
|
|
103
|
+
};
|
|
87
104
|
|
|
88
|
-
// #resolved;
|
|
89
105
|
#token = null;
|
|
90
|
-
#maxSymbolKey = 1;
|
|
91
106
|
|
|
92
107
|
constructor() {
|
|
93
108
|
// this.#resolved = new Map();
|
|
94
109
|
}
|
|
95
110
|
|
|
96
|
-
close() {
|
|
97
|
-
|
|
111
|
+
async close() {
|
|
112
|
+
// token delete !!!
|
|
113
|
+
ws.close();
|
|
98
114
|
}
|
|
99
115
|
|
|
100
116
|
getAll() {
|
|
@@ -130,22 +146,31 @@ module.exports = class Client {
|
|
|
130
146
|
});
|
|
131
147
|
}
|
|
132
148
|
|
|
133
|
-
async connect({ url, options, login, pass, result }) {
|
|
134
|
-
this.#token = await this.getToken({ login, pass });
|
|
149
|
+
async connect({ url, options, login, pass, result, token }) {
|
|
150
|
+
this.#token = token || await this.getToken({ login, pass });
|
|
151
|
+
|
|
135
152
|
if (this.#token.length > 10) {
|
|
136
153
|
return new Promise((resolv, reject) => {
|
|
137
|
-
|
|
154
|
+
url += '?from=chart%2FKq8EfKQU%2F';
|
|
155
|
+
const date = new Date();
|
|
156
|
+
url += '&date=' + date.getFullYear() + '_' + String(date.getMonth() + 1).padStart(2, '0') + '_' + String(date.getDate()).padStart(2, '0') + '-11_25';
|
|
157
|
+
url += '&type=chart';
|
|
158
|
+
ws = new WebSocket(url, options);
|
|
159
|
+
|
|
160
|
+
const originalSend = ws.send;
|
|
161
|
+
ws.send = function(data) {
|
|
162
|
+
// console.log('Message sent:', data);
|
|
163
|
+
originalSend.apply(ws, arguments);
|
|
164
|
+
};
|
|
138
165
|
|
|
139
|
-
|
|
166
|
+
ws.onclose = () => console.log('disconnected');
|
|
140
167
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
168
|
+
ws.onerror = (error) => reject(console.error('error: ', error));
|
|
169
|
+
ws.onopen = () => {
|
|
170
|
+
ws.send(this.auth(this.#token));
|
|
171
|
+
ws.send(tv.setLocaleRu());
|
|
145
172
|
|
|
146
|
-
// const chartKey = this.createChartSession();
|
|
147
173
|
const quoteKey = this.createQuoteSmallSession();
|
|
148
|
-
// this.addQuoteSymbols({ symbols: ['NASDAQ:PYPL'] });
|
|
149
174
|
|
|
150
175
|
this.messageListner({ result });
|
|
151
176
|
resolv('open');
|
|
@@ -158,24 +183,24 @@ module.exports = class Client {
|
|
|
158
183
|
createQuoteSmallSession() {
|
|
159
184
|
const key = tv.createSession({ startsWith: 'qs_' });
|
|
160
185
|
this.#quotes.set({ key, data: { id: key, type: 'small', symbols: [] } });
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
//
|
|
186
|
+
ws.send(tv.quoteCreateSession({ session: key }));
|
|
187
|
+
ws.send(tv.setFieldsSmall({ session: key }));
|
|
188
|
+
// ws.send(tv.setFields({ session: key }));
|
|
164
189
|
return key;
|
|
165
190
|
}
|
|
166
191
|
|
|
167
192
|
createQuoteFullSession() {
|
|
168
193
|
const key = tv.createSession({ startsWith: 'qs_' });
|
|
169
194
|
this.#quotes.set({ key, data: { id: key, type: 'full', symbols: [] } });
|
|
170
|
-
|
|
195
|
+
ws.send(tv.quoteCreateSession({ session: key }));
|
|
171
196
|
return key;
|
|
172
197
|
}
|
|
173
198
|
|
|
174
199
|
createChartSession() {
|
|
175
200
|
const key = tv.createSession({ startsWith: 'cs_' });
|
|
176
201
|
this.#charts.set({ key, data: { id: key, symbol: '', period: 0, symbolKey: '', frame: '', i: '', deleted: false } });
|
|
177
|
-
|
|
178
|
-
|
|
202
|
+
ws.send(tv.chartCreateSession({ chartSession: key }));
|
|
203
|
+
ws.send(tv.switchTimezone({ chartSession: key, tz: 'Etc/UTC' }));
|
|
179
204
|
return key;
|
|
180
205
|
}
|
|
181
206
|
|
|
@@ -188,9 +213,8 @@ module.exports = class Client {
|
|
|
188
213
|
result.exist.push(symbol);
|
|
189
214
|
} else {
|
|
190
215
|
key = this.#quotes.add({ symbol });
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
// this.#ws.send(tv.quoteFastSymbol({ session: key, symbol }));
|
|
216
|
+
ws.send(tv.quoteAddSymbol({ session: key, symbol }));
|
|
217
|
+
// ws.send(tv.quoteFastSymbol({ session: key, symbol }));
|
|
194
218
|
result.add.push(symbol);
|
|
195
219
|
}
|
|
196
220
|
});
|
|
@@ -201,39 +225,31 @@ module.exports = class Client {
|
|
|
201
225
|
const key = this.#quotes.getBySymbol({ symbol });
|
|
202
226
|
if (!key) return 'unlisted';
|
|
203
227
|
this.#quotes.delete({ key, symbol });
|
|
204
|
-
|
|
228
|
+
ws.send(tv.quoteRemoveSymbols({ session: key, symbol }));
|
|
205
229
|
return 'delete';
|
|
206
230
|
}
|
|
207
231
|
|
|
208
|
-
resolveSymbol({ key, symbol }) {
|
|
209
|
-
const symbolKey = 'sds_sym_' + this.#maxSymbolKey++;
|
|
210
|
-
this.#ws.send(tv.resolveSymbol({ chartSession: key, symbolKey, symbol }));
|
|
211
|
-
return symbolKey;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
232
|
addChartSymbol({ symbol, period, limit }) {
|
|
215
233
|
let key = this.#charts.getBySymbolPeriod({ symbol, period });
|
|
216
234
|
if (key) {
|
|
217
|
-
console.warn('addChartSymbol exist');
|
|
235
|
+
console.warn('addChartSymbol exist:', key, symbol, period);
|
|
218
236
|
return 'exist';
|
|
219
237
|
}
|
|
220
|
-
|
|
221
238
|
// console.warn('modules addChartSymbol1', symbol, period, limit, key);
|
|
222
|
-
const
|
|
223
|
-
if (
|
|
239
|
+
const deleted = this.#charts.getDeleted();
|
|
240
|
+
if (deleted !== null && deleted.limit >= limit) return this.updateChartSymbol({ symbol, period, limit, last: { symbol: deleted.symbol, period: parseInt(deleted.period) }});
|
|
224
241
|
|
|
225
242
|
key = this.createChartSession();
|
|
226
243
|
const data = this.#charts.get({ key });
|
|
227
244
|
|
|
228
|
-
data.symbolKey = this.
|
|
245
|
+
data.symbolKey = this.#symbols.getSymbol({ key, symbol }).key;
|
|
229
246
|
data.symbol = symbol;
|
|
230
247
|
data.period = period;
|
|
231
248
|
data.frame = 'sds_' + Object.keys(this.#charts.values).length;
|
|
232
249
|
data.i = 's' + 1;
|
|
250
|
+
data.limit = limit;
|
|
233
251
|
|
|
234
|
-
|
|
235
|
-
// this.#resolved.set(symbol, { key: data.symbolKey });
|
|
236
|
-
this.#ws.send(
|
|
252
|
+
ws.send(
|
|
237
253
|
tv.createSeries({
|
|
238
254
|
chartSession: key,
|
|
239
255
|
frame: data.frame,
|
|
@@ -243,49 +259,56 @@ module.exports = class Client {
|
|
|
243
259
|
limit,
|
|
244
260
|
}),
|
|
245
261
|
);
|
|
246
|
-
// console.
|
|
262
|
+
// console.warn('addChartSymbol4', periods[period], data);
|
|
247
263
|
this.#charts.set({ key, data });
|
|
248
|
-
|
|
249
264
|
return 'add';
|
|
250
265
|
}
|
|
251
266
|
|
|
252
267
|
updateChartSymbol({ symbol, period, limit, last }) {
|
|
253
|
-
// period = parseInt(period);
|
|
254
|
-
// last.period = parseInt(last.period);
|
|
255
268
|
const key = this.#charts.getBySymbolPeriod({ symbol: last.symbol, period: last.period });
|
|
256
269
|
const data = this.#charts.get({ key });
|
|
257
270
|
|
|
258
271
|
// console.warn('modules updateChartSymbol 1: ', symbol, period, limit, last, data);
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
272
|
+
// const alreadyKey = this.#charts.getBySymbolPeriod({ symbol, period })
|
|
273
|
+
// if (alreadyKey) {
|
|
274
|
+
// // console.warn('updateChartSymbol exist: ', alreadyKey);
|
|
275
|
+
// this.#charts.delete({ key });
|
|
276
|
+
// // console.warn('updateChartSymbol exist');
|
|
277
|
+
// return 'exist';
|
|
278
|
+
// }
|
|
267
279
|
|
|
268
|
-
data.symbolKey = this.
|
|
280
|
+
data.symbolKey = this.#symbols.getSymbol({ key, symbol }).key;
|
|
269
281
|
data.symbol = symbol;
|
|
270
282
|
data.period = period;
|
|
271
283
|
data.i = 's' + (parseInt(data.i.replace(/[^0-9]/g, '')) + 1);
|
|
272
|
-
|
|
284
|
+
|
|
285
|
+
ws.send(
|
|
273
286
|
tv.modifySeries({
|
|
274
287
|
chartSession: key,
|
|
275
288
|
frame: data.frame,
|
|
276
289
|
increment: data.i,
|
|
277
290
|
symbolKey: data.symbolKey,
|
|
278
291
|
interval: periods[period],
|
|
279
|
-
limit,
|
|
280
292
|
}),
|
|
281
293
|
);
|
|
282
294
|
this.#charts.set({ key, data });
|
|
295
|
+
if (data.limit < limit) {
|
|
296
|
+
ws.send(tv.moreData({ chartSession: key, frame: data.frame, add: limit - data.limit }));
|
|
297
|
+
data.limit = limit;
|
|
298
|
+
}
|
|
283
299
|
return 'update';
|
|
284
300
|
}
|
|
285
301
|
|
|
302
|
+
deleteChartSymbol({ symbol, period }) {
|
|
303
|
+
let key = this.#charts.getBySymbolPeriod({ symbol, period });
|
|
304
|
+
if (!key) return void console.warn('deleteChartSymbol empty key');
|
|
305
|
+
this.#charts.delete({ key });
|
|
306
|
+
return void console.log('deleteChartSymbol: ', key);
|
|
307
|
+
}
|
|
308
|
+
|
|
286
309
|
messageListner({ result }) {
|
|
287
|
-
|
|
288
|
-
if (
|
|
310
|
+
ws.on('message', (raw) => {
|
|
311
|
+
if (ws.readyState !== ws.OPEN) return;
|
|
289
312
|
|
|
290
313
|
// console.log('raw: ', JSON.stringify(raw.toString()));
|
|
291
314
|
let session = '';
|
|
@@ -295,17 +318,13 @@ module.exports = class Client {
|
|
|
295
318
|
if (packet === undefined) {
|
|
296
319
|
console.warn('undefined: ', raw.toString());
|
|
297
320
|
} else {
|
|
298
|
-
// eslint-disable-next-line no-lonely-if
|
|
299
321
|
if (packet.type === 'ping') {
|
|
300
322
|
// console.info('pong', packet);
|
|
301
|
-
|
|
302
|
-
// } else if (packet.type === 'protocol_error') {
|
|
303
|
-
// console.warn('protocol_error', packet);
|
|
304
|
-
// this.close();
|
|
323
|
+
ws.send(tv.createPong({ value: packet.data }));
|
|
305
324
|
} else if (packet.type === 'qsd') {
|
|
306
325
|
send = packet.data[1].v;
|
|
307
326
|
name = send.bid === undefined && send.ask === undefined ? 'data' : 'levelI';
|
|
308
|
-
// console.
|
|
327
|
+
// console.warn(packet.data[1]);
|
|
309
328
|
// console.log(JSON.parse(packet.data[1].n.substring(1)).symbol);
|
|
310
329
|
send.symbol = JSON.parse(packet.data[1].n.substring(1)).symbol;
|
|
311
330
|
result(name, send);
|
|
@@ -334,12 +353,12 @@ module.exports = class Client {
|
|
|
334
353
|
} else if (['series', 'symbol', 'quote', 'session'].includes(packet.type)) {
|
|
335
354
|
// console.info(packet);
|
|
336
355
|
} else {
|
|
337
|
-
console.
|
|
356
|
+
// console.error('error', raw.toString());
|
|
338
357
|
result('error', raw.toString())
|
|
339
358
|
}
|
|
340
359
|
}
|
|
341
|
-
name = null;
|
|
342
|
-
send = null;
|
|
360
|
+
// name = null;
|
|
361
|
+
// send = null;
|
|
343
362
|
});
|
|
344
363
|
});
|
|
345
364
|
}
|
package/lib/tradingView.js
CHANGED
|
@@ -35,7 +35,7 @@ class TradingView {
|
|
|
35
35
|
// }
|
|
36
36
|
|
|
37
37
|
// await utils.pause();
|
|
38
|
-
return 'eyJhbGciOiJSUzUxMiIsImtpZCI6IkdaeFUiLCJ0eXAiOiJKV1QifQ.
|
|
38
|
+
return 'eyJhbGciOiJSUzUxMiIsImtpZCI6IkdaeFUiLCJ0eXAiOiJKV1QifQ.eyJ1c2VyX2lkIjoxMjI1ODcxMiwiZXhwIjoxNzI0OTI1MjkyLCJpYXQiOjE3MjQ5MTA4OTIsInBsYW4iOiJwcm9fcHJlbWl1bSIsImV4dF9ob3VycyI6MSwicGVybSI6InVzLXN0b2NrcyxuYXNkYXFfZ2lkcyxvdGMsbnlzZSxuYXNkYXEsYW1leCIsInN0dWR5X3Blcm0iOiJ0di1jaGFydHBhdHRlcm5zLHR2LXByb3N0dWRpZXMsdHYtY2hhcnRfcGF0dGVybnMsdHYtdm9sdW1lYnlwcmljZSIsIm1heF9zdHVkaWVzIjoyNSwibWF4X2Z1bmRhbWVudGFscyI6MTAsIm1heF9jaGFydHMiOjgsIm1heF9hY3RpdmVfYWxlcnRzIjo0MDAsIm1heF9zdHVkeV9vbl9zdHVkeSI6MjQsImZpZWxkc19wZXJtaXNzaW9ucyI6WyJyZWZib25kcyJdLCJtYXhfb3ZlcmFsbF9hbGVydHMiOjIwMDAsIm1heF9hY3RpdmVfcHJpbWl0aXZlX2FsZXJ0cyI6NDAwLCJtYXhfYWN0aXZlX2NvbXBsZXhfYWxlcnRzIjo0MDAsIm1heF9jb25uZWN0aW9ucyI6NTB9.UT2AdPBEAWk6HJEa6isX4gjVqlfThn8bgOVl3Xa36U36Qifg5xXz9Va8q7DWSY3Smaap2wX4cBF4UQXv1t66Q0TQvFudLuvA2dnetBAHYZSOJIi2PGdG1KuMaCRshUuuH9mxgw_xPGITAuQsbBPZJLTOxq5pQN05pZnedC7SaMs';
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
async getSymbol({ symbol, type }) {
|
|
@@ -59,9 +59,7 @@ class TradingView {
|
|
|
59
59
|
|
|
60
60
|
createSession({ startsWith }) {
|
|
61
61
|
let session = startsWith;
|
|
62
|
-
while (session.length < 12)
|
|
63
|
-
session += letters[Math.floor(Math.random() * letters.length)];
|
|
64
|
-
}
|
|
62
|
+
while (session.length < 12) session += letters[Math.floor(Math.random() * letters.length)];
|
|
65
63
|
return session;
|
|
66
64
|
}
|
|
67
65
|
|
|
@@ -173,6 +171,8 @@ class TradingView {
|
|
|
173
171
|
'logoid',
|
|
174
172
|
'lp',
|
|
175
173
|
'lp_time',
|
|
174
|
+
'rtc',
|
|
175
|
+
'rtc_time',
|
|
176
176
|
'trade',
|
|
177
177
|
'bid',
|
|
178
178
|
'bid_size',
|
|
@@ -266,10 +266,10 @@ class TradingView {
|
|
|
266
266
|
// symbolKey - id запрошенного тиккера
|
|
267
267
|
// frame - рамка или окно для данной серии
|
|
268
268
|
// increment - инкрементируемый номер изменений запрашиваемого графика в данном frame (таймефрейм)
|
|
269
|
-
createSeries({ chartSession, frame = 'sds_1', increment = 's1', symbolKey,
|
|
269
|
+
createSeries({ chartSession, frame = 'sds_1', increment = 's1', symbolKey, period = '60', limit = 1000 }) {
|
|
270
270
|
// console.warn('createSeries', chartSession, frame, increment, symbolKey, interval, limit);
|
|
271
271
|
return this.formatWSPacket({
|
|
272
|
-
packet: { m: 'create_series', p: [chartSession, frame, increment, symbolKey,
|
|
272
|
+
packet: { m: 'create_series', p: [chartSession, frame, increment, symbolKey, period, limit] },
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
|
|
@@ -284,13 +284,22 @@ class TradingView {
|
|
|
284
284
|
return this.formatWSPacket({ packet: { m: 'remove_study', p: [ session, st ] } });
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
modifySeries({ chartSession, frame = 'sds_1', increment = 's1', symbolKey, interval = '60'
|
|
287
|
+
modifySeries({ chartSession, frame = 'sds_1', increment = 's1', symbolKey, interval = '60' }) {
|
|
288
288
|
// console.warn('modify_series', chartSession, frame, increment, symbolKey, interval, limit);
|
|
289
289
|
return this.formatWSPacket({
|
|
290
290
|
packet: { m: 'modify_series', p: [chartSession, frame, increment, symbolKey, interval] },
|
|
291
291
|
});
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
moreData({ chartSession, frame, add }) {
|
|
295
|
+
return this.formatWSPacket({ packet: { m: 'request_more_data', p: [chartSession, frame, add] } });
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
moreTickmark({chartSession, frame, add}) {
|
|
299
|
+
// "m":"request_more_tickmarks","p":["cs_lslcBHYaqGTT","sds_1",10]
|
|
300
|
+
return this.formatWSPacket({ packet: { m: 'request_more_tickmarks', p: [chartSession, frame, add] } });
|
|
301
|
+
}
|
|
302
|
+
|
|
294
303
|
createPong({ value }) {
|
|
295
304
|
return this.formatWSPacket({ packet: '~h~' + value });
|
|
296
305
|
}
|