@mathieuc/tradingview 3.5.1 → 4.0.0-beta.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 +112 -51
- package/dist/chart/chart-session.d.ts +114 -0
- package/dist/chart/chart-session.js +339 -0
- package/dist/chart/graphics.d.ts +129 -0
- package/dist/chart/graphics.js +153 -0
- package/dist/chart/index.d.ts +11 -0
- package/dist/chart/index.js +6 -0
- package/dist/chart/strategy.d.ts +100 -0
- package/dist/chart/strategy.js +51 -0
- package/dist/chart/study.d.ts +60 -0
- package/dist/chart/study.js +171 -0
- package/dist/chart/timeframes.d.ts +7 -0
- package/dist/chart/timeframes.js +22 -0
- package/dist/chart/types.d.ts +105 -0
- package/dist/chart/types.js +9 -0
- package/dist/client/client.d.ts +89 -0
- package/dist/client/client.js +254 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +2 -0
- package/dist/client/transport.d.ts +27 -0
- package/dist/client/transport.js +38 -0
- package/dist/data/candles.d.ts +40 -0
- package/dist/data/candles.js +101 -0
- package/dist/data/history.d.ts +61 -0
- package/dist/data/history.js +101 -0
- package/dist/data/index.d.ts +28 -0
- package/dist/data/index.js +15 -0
- package/dist/data/indicators.d.ts +54 -0
- package/dist/data/indicators.js +139 -0
- package/dist/data/operation.d.ts +71 -0
- package/dist/data/operation.js +205 -0
- package/dist/data/provider.d.ts +23 -0
- package/dist/data/provider.js +11 -0
- package/dist/data/quotes.d.ts +33 -0
- package/dist/data/quotes.js +117 -0
- package/dist/data/symbols.d.ts +9 -0
- package/dist/data/symbols.js +19 -0
- package/dist/errors.d.ts +53 -0
- package/dist/errors.js +24 -0
- package/dist/events.d.ts +36 -0
- package/dist/events.js +70 -0
- package/dist/http/account.d.ts +47 -0
- package/dist/http/account.js +127 -0
- package/dist/http/index.d.ts +11 -0
- package/dist/http/index.js +5 -0
- package/dist/http/indicators.d.ts +37 -0
- package/dist/http/indicators.js +144 -0
- package/dist/http/layouts.d.ts +36 -0
- package/dist/http/layouts.js +24 -0
- package/dist/http/market.d.ts +45 -0
- package/dist/http/market.js +59 -0
- package/dist/http/pine-permissions.d.ts +29 -0
- package/dist/http/pine-permissions.js +56 -0
- package/dist/http/request.d.ts +44 -0
- package/dist/http/request.js +83 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +19 -0
- package/dist/indicators/builtin-indicator.d.ts +17 -0
- package/dist/indicators/builtin-indicator.js +75 -0
- package/dist/indicators/index.d.ts +8 -0
- package/dist/indicators/index.js +2 -0
- package/dist/indicators/pine-indicator.d.ts +63 -0
- package/dist/indicators/pine-indicator.js +101 -0
- package/dist/protocol/compression.d.ts +12 -0
- package/dist/protocol/compression.js +83 -0
- package/dist/protocol/framing.d.ts +59 -0
- package/dist/protocol/framing.js +68 -0
- package/dist/protocol/ids.d.ts +2 -0
- package/dist/protocol/ids.js +10 -0
- package/dist/protocol/index.d.ts +4 -0
- package/dist/protocol/index.js +3 -0
- package/dist/quote/fields.d.ts +35 -0
- package/dist/quote/fields.js +21 -0
- package/dist/quote/index.d.ts +4 -0
- package/dist/quote/index.js +2 -0
- package/dist/quote/quote-session.d.ts +73 -0
- package/dist/quote/quote-session.js +205 -0
- package/docs/README.es.md +58 -0
- package/docs/README.fr.md +58 -0
- package/docs/README.pt.md +58 -0
- package/docs/data-api.md +229 -0
- package/docs/low-level-api.md +213 -0
- package/docs/migration-v4.md +128 -0
- package/docs/v4-coverage.md +192 -0
- package/docs/v4-reliability.md +33 -0
- package/package.json +55 -20
- package/.env.sample +0 -2
- package/.eslintrc.js +0 -28
- package/.gitattributes +0 -2
- package/docs/DOCS.md +0 -3
- package/examples/AllPrivateIndicators.js +0 -44
- package/examples/BuiltInIndicator.js +0 -51
- package/examples/CustomChartType.js +0 -123
- package/examples/CustomTimeframe.js +0 -31
- package/examples/Errors.js +0 -155
- package/examples/FakeReplayMode.js +0 -40
- package/examples/FromToData.js +0 -35
- package/examples/GetDrawings.js +0 -27
- package/examples/GraphicIndicator.js +0 -42
- package/examples/MultipleSyncFetch.js +0 -44
- package/examples/PinePermManage.js +0 -67
- package/examples/ReplayMode.js +0 -103
- package/examples/Search.js +0 -14
- package/examples/SimpleChart.js +0 -63
- package/examples/UserLogin.js +0 -16
- package/main.js +0 -11
- package/src/chart/graphicParser.js +0 -308
- package/src/chart/session.js +0 -553
- package/src/chart/study.js +0 -435
- package/src/classes/BuiltInIndicator.js +0 -137
- package/src/classes/PineIndicator.js +0 -132
- package/src/classes/PinePermManager.js +0 -159
- package/src/client.js +0 -294
- package/src/miscRequests.js +0 -607
- package/src/protocol.js +0 -60
- package/src/quote/market.js +0 -132
- package/src/quote/session.js +0 -125
- package/src/types.js +0 -36
- package/src/utils.js +0 -20
- package/vite.config.js +0 -7
package/src/chart/session.js
DELETED
|
@@ -1,553 +0,0 @@
|
|
|
1
|
-
const { genSessionID } = require('../utils');
|
|
2
|
-
|
|
3
|
-
const studyConstructor = require('./study');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @typedef {'HeikinAshi' | 'Renko' | 'LineBreak' | 'Kagi' | 'PointAndFigure'
|
|
7
|
-
* | 'Range'} ChartType Custom chart type
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const ChartTypes = {
|
|
11
|
-
HeikinAshi: 'BarSetHeikenAshi@tv-basicstudies-60!',
|
|
12
|
-
Renko: 'BarSetRenko@tv-prostudies-40!',
|
|
13
|
-
LineBreak: 'BarSetPriceBreak@tv-prostudies-34!',
|
|
14
|
-
Kagi: 'BarSetKagi@tv-prostudies-34!',
|
|
15
|
-
PointAndFigure: 'BarSetPnF@tv-prostudies-34!',
|
|
16
|
-
Range: 'BarSetRange@tv-basicstudies-72!',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @typedef {Object} ChartInputs Custom chart type
|
|
21
|
-
* @prop {number} [atrLength] Renko/Kagi/PointAndFigure ATR length
|
|
22
|
-
* @prop {'open' | 'high' | 'low' | 'close' | 'hl2'
|
|
23
|
-
* | 'hlc3' | 'ohlc4'} [source] Renko/LineBreak/Kagi source
|
|
24
|
-
* @prop {'ATR' | string} [style] Renko/Kagi/PointAndFigure style
|
|
25
|
-
* @prop {number} [boxSize] Renko/PointAndFigure box size
|
|
26
|
-
* @prop {number} [reversalAmount] Kagi/PointAndFigure reversal amount
|
|
27
|
-
* @prop {'Close'} [sources] Renko/PointAndFigure sources
|
|
28
|
-
* @prop {boolean} [wicks] Renko wicks
|
|
29
|
-
* @prop {number} [lb] LineBreak Line break
|
|
30
|
-
* @prop {boolean} [oneStepBackBuilding] PointAndFigure oneStepBackBuilding
|
|
31
|
-
* @prop {boolean} [phantomBars] Range phantom bars
|
|
32
|
-
* @prop {number} [range] Range range
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/** @typedef {Object<string, Function[]>} StudyListeners */
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @typedef {Object} ChartSessionBridge
|
|
39
|
-
* @prop {string} sessionID
|
|
40
|
-
* @prop {StudyListeners} studyListeners
|
|
41
|
-
* @prop {Object<number, number>} indexes
|
|
42
|
-
* @prop {import('../client').SendPacket} send
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @typedef {'seriesLoaded' | 'symbolLoaded' | 'update' | 'error'} ChartEvent
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @typedef {Object} PricePeriod
|
|
51
|
-
* @prop {number} time Period timestamp
|
|
52
|
-
* @prop {number} open Period open value
|
|
53
|
-
* @prop {number} close Period close value
|
|
54
|
-
* @prop {number} max Period max value
|
|
55
|
-
* @prop {number} min Period min value
|
|
56
|
-
* @prop {number} volume Period volume value
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @typedef {Object} Subsession
|
|
61
|
-
* @prop {string} id Subsession ID (ex: 'regular')
|
|
62
|
-
* @prop {string} description Subsession description (ex: 'Regular')
|
|
63
|
-
* @prop {boolean} private If private
|
|
64
|
-
* @prop {string} session Session (ex: '24x7')
|
|
65
|
-
* @prop {string} session-correction Session correction
|
|
66
|
-
* @prop {string} session-display Session display (ex: '24x7')
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @typedef {Object} MarketInfos
|
|
71
|
-
* @prop {string} series_id Used series (ex: 'ser_1')
|
|
72
|
-
* @prop {string} base_currency Base currency (ex: 'BTC')
|
|
73
|
-
* @prop {string} base_currency_id Base currency ID (ex: 'XTVCBTC')
|
|
74
|
-
* @prop {string} name Market short name (ex: 'BTCEUR')
|
|
75
|
-
* @prop {string} full_name Market full name (ex: 'COINBASE:BTCEUR')
|
|
76
|
-
* @prop {string} pro_name Market pro name (ex: 'COINBASE:BTCEUR')
|
|
77
|
-
* @prop {string} description Market symbol description (ex: 'BTC/EUR')
|
|
78
|
-
* @prop {string} short_description Market symbol short description (ex: 'BTC/EUR')
|
|
79
|
-
* @prop {string} exchange Market exchange (ex: 'COINBASE')
|
|
80
|
-
* @prop {string} listed_exchange Market exchange (ex: 'COINBASE')
|
|
81
|
-
* @prop {string} provider_id Values provider ID (ex: 'coinbase')
|
|
82
|
-
* @prop {string} currency_id Used currency ID (ex: 'EUR')
|
|
83
|
-
* @prop {string} currency_code Used currency code (ex: 'EUR')
|
|
84
|
-
* @prop {string} variable_tick_size Variable tick size
|
|
85
|
-
* @prop {number} pricescale Price scale
|
|
86
|
-
* @prop {number} pointvalue Point value
|
|
87
|
-
* @prop {string} session Session (ex: '24x7')
|
|
88
|
-
* @prop {string} session_display Session display (ex: '24x7')
|
|
89
|
-
* @prop {string} type Market type (ex: 'crypto')
|
|
90
|
-
* @prop {boolean} has_intraday If intraday values are available
|
|
91
|
-
* @prop {boolean} fractional If market is fractional
|
|
92
|
-
* @prop {boolean} is_tradable If the market is curently tradable
|
|
93
|
-
* @prop {number} minmov Minimum move value
|
|
94
|
-
* @prop {number} minmove2 Minimum move value 2
|
|
95
|
-
* @prop {string} timezone Used timezone
|
|
96
|
-
* @prop {boolean} is_replayable If the replay mode is available
|
|
97
|
-
* @prop {boolean} has_adjustment If the adjustment mode is enabled
|
|
98
|
-
* @prop {boolean} has_extended_hours Has extended hours
|
|
99
|
-
* @prop {string} bar_source Bar source
|
|
100
|
-
* @prop {string} bar_transform Bar transform
|
|
101
|
-
* @prop {boolean} bar_fillgaps Bar fill gaps
|
|
102
|
-
* @prop {string} allowed_adjustment Allowed adjustment (ex: 'none')
|
|
103
|
-
* @prop {string} subsession_id Subsession ID (ex: 'regular')
|
|
104
|
-
* @prop {string} pro_perm Pro permission (ex: '')
|
|
105
|
-
* @prop {[]} base_name Base name (ex: ['COINBASE:BTCEUR'])
|
|
106
|
-
* @prop {[]} legs Legs (ex: ['COINBASE:BTCEUR'])
|
|
107
|
-
* @prop {Subsession[]} subsessions Sub sessions
|
|
108
|
-
* @prop {[]} typespecs Typespecs (ex: [])
|
|
109
|
-
* @prop {[]} resolutions Resolutions (ex: [])
|
|
110
|
-
* @prop {[]} aliases Aliases (ex: [])
|
|
111
|
-
* @prop {[]} alternatives Alternatives (ex: [])
|
|
112
|
-
*/
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @param {import('../client').ClientBridge} client
|
|
116
|
-
*/
|
|
117
|
-
module.exports = (client) => class ChartSession {
|
|
118
|
-
#chartSessionID = genSessionID('cs');
|
|
119
|
-
|
|
120
|
-
#replaySessionID = genSessionID('rs');
|
|
121
|
-
|
|
122
|
-
#replayMode = false;
|
|
123
|
-
|
|
124
|
-
/** @type {Object<string, (): any>} */
|
|
125
|
-
#replayOKCB = {};
|
|
126
|
-
|
|
127
|
-
/** Parent client */
|
|
128
|
-
#client = client;
|
|
129
|
-
|
|
130
|
-
/** @type {StudyListeners} */
|
|
131
|
-
#studyListeners = {};
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Table of periods values indexed by timestamp
|
|
135
|
-
* @type {Object<number, PricePeriod[]>}
|
|
136
|
-
*/
|
|
137
|
-
#periods = {};
|
|
138
|
-
|
|
139
|
-
/** @return {PricePeriod[]} List of periods values */
|
|
140
|
-
get periods() {
|
|
141
|
-
return Object.values(this.#periods).sort((a, b) => b.time - a.time);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Current market infos
|
|
146
|
-
* @type {MarketInfos}
|
|
147
|
-
*/
|
|
148
|
-
#infos = {};
|
|
149
|
-
|
|
150
|
-
/** @return {MarketInfos} Current market infos */
|
|
151
|
-
get infos() {
|
|
152
|
-
return this.#infos;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
#callbacks = {
|
|
156
|
-
seriesLoaded: [],
|
|
157
|
-
symbolLoaded: [],
|
|
158
|
-
update: [],
|
|
159
|
-
|
|
160
|
-
replayLoaded: [],
|
|
161
|
-
replayPoint: [],
|
|
162
|
-
replayResolution: [],
|
|
163
|
-
replayEnd: [],
|
|
164
|
-
|
|
165
|
-
event: [],
|
|
166
|
-
error: [],
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @param {ChartEvent} ev Client event
|
|
171
|
-
* @param {...{}} data Packet data
|
|
172
|
-
*/
|
|
173
|
-
#handleEvent(ev, ...data) {
|
|
174
|
-
this.#callbacks[ev].forEach((e) => e(...data));
|
|
175
|
-
this.#callbacks.event.forEach((e) => e(ev, ...data));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
#handleError(...msgs) {
|
|
179
|
-
if (this.#callbacks.error.length === 0) console.error(...msgs);
|
|
180
|
-
else this.#handleEvent('error', ...msgs);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
constructor() {
|
|
184
|
-
this.#client.sessions[this.#chartSessionID] = {
|
|
185
|
-
type: 'chart',
|
|
186
|
-
onData: (packet) => {
|
|
187
|
-
if (global.TW_DEBUG) console.log('§90§30§106 CHART SESSION §0 DATA', packet);
|
|
188
|
-
|
|
189
|
-
if (typeof packet.data[1] === 'string' && this.#studyListeners[packet.data[1]]) {
|
|
190
|
-
this.#studyListeners[packet.data[1]](packet);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (packet.type === 'symbol_resolved') {
|
|
195
|
-
this.#infos = {
|
|
196
|
-
series_id: packet.data[1],
|
|
197
|
-
...packet.data[2],
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
this.#handleEvent('symbolLoaded');
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (['timescale_update', 'du'].includes(packet.type)) {
|
|
205
|
-
const changes = [];
|
|
206
|
-
|
|
207
|
-
Object.keys(packet.data[1]).forEach((k) => {
|
|
208
|
-
changes.push(k);
|
|
209
|
-
if (k === '$prices') {
|
|
210
|
-
const periods = packet.data[1].$prices;
|
|
211
|
-
if (!periods || !periods.s) return;
|
|
212
|
-
|
|
213
|
-
periods.s.forEach((p) => {
|
|
214
|
-
[this.#chartSession.indexes[p.i]] = p.v;
|
|
215
|
-
this.#periods[p.v[0]] = {
|
|
216
|
-
time: p.v[0],
|
|
217
|
-
open: p.v[1],
|
|
218
|
-
close: p.v[4],
|
|
219
|
-
max: p.v[2],
|
|
220
|
-
min: p.v[3],
|
|
221
|
-
volume: Math.round(p.v[5] * 100) / 100,
|
|
222
|
-
};
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (this.#studyListeners[k]) this.#studyListeners[k](packet);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
this.#handleEvent('update', changes);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (packet.type === 'symbol_error') {
|
|
236
|
-
this.#handleError(`(${packet.data[1]}) Symbol error:`, packet.data[2]);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (packet.type === 'series_error') {
|
|
241
|
-
this.#handleError('Series error:', packet.data[3]);
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (packet.type === 'critical_error') {
|
|
246
|
-
const [, name, description] = packet.data;
|
|
247
|
-
this.#handleError('Critical error:', name, description);
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
this.#client.sessions[this.#replaySessionID] = {
|
|
253
|
-
type: 'replay',
|
|
254
|
-
onData: (packet) => {
|
|
255
|
-
if (global.TW_DEBUG) console.log('§90§30§106 REPLAY SESSION §0 DATA', packet);
|
|
256
|
-
|
|
257
|
-
if (packet.type === 'replay_ok') {
|
|
258
|
-
if (this.#replayOKCB[packet.data[1]]) {
|
|
259
|
-
this.#replayOKCB[packet.data[1]]();
|
|
260
|
-
delete this.#replayOKCB[packet.data[1]];
|
|
261
|
-
}
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (packet.type === 'replay_instance_id') {
|
|
266
|
-
this.#handleEvent('replayLoaded', packet.data[1]);
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (packet.type === 'replay_point') {
|
|
271
|
-
this.#handleEvent('replayPoint', packet.data[1]);
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (packet.type === 'replay_resolutions') {
|
|
276
|
-
this.#handleEvent('replayResolution', packet.data[1], packet.data[2]);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (packet.type === 'replay_data_end') {
|
|
281
|
-
this.#handleEvent('replayEnd');
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (packet.type === 'critical_error') {
|
|
286
|
-
const [, name, description] = packet.data;
|
|
287
|
-
this.#handleError('Critical error:', name, description);
|
|
288
|
-
}
|
|
289
|
-
},
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
this.#client.send('chart_create_session', [this.#chartSessionID]);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
#seriesCreated = false;
|
|
296
|
-
|
|
297
|
-
#currentSeries = 0;
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* @param {import('../types').TimeFrame} timeframe Chart period timeframe
|
|
301
|
-
* @param {number} [range] Number of loaded periods/candles (Default: 100)
|
|
302
|
-
* @param {number} [reference] Reference candle timestamp (Default is now)
|
|
303
|
-
*/
|
|
304
|
-
setSeries(timeframe = '240', range = 100, reference = null) {
|
|
305
|
-
if (!this.#currentSeries) {
|
|
306
|
-
this.#handleError('Please set the market before setting series');
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const calcRange = !reference ? range : ['bar_count', reference, range];
|
|
311
|
-
|
|
312
|
-
this.#periods = {};
|
|
313
|
-
|
|
314
|
-
this.#client.send(`${this.#seriesCreated ? 'modify' : 'create'}_series`, [
|
|
315
|
-
this.#chartSessionID,
|
|
316
|
-
'$prices',
|
|
317
|
-
's1',
|
|
318
|
-
`ser_${this.#currentSeries}`,
|
|
319
|
-
timeframe,
|
|
320
|
-
this.#seriesCreated ? '' : calcRange,
|
|
321
|
-
]);
|
|
322
|
-
|
|
323
|
-
this.#seriesCreated = true;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Set the chart market
|
|
328
|
-
* @param {string} symbol Market symbol
|
|
329
|
-
* @param {Object} [options] Chart options
|
|
330
|
-
* @param {import('../types').TimeFrame} [options.timeframe] Chart period timeframe
|
|
331
|
-
* @param {number} [options.range] Number of loaded periods/candles (Default: 100)
|
|
332
|
-
* @param {number} [options.to] Last candle timestamp (Default is now)
|
|
333
|
-
* @param {'splits' | 'dividends'} [options.adjustment] Market adjustment
|
|
334
|
-
* @param {boolean} [options.backadjustment] Market backadjustment of futures contracts
|
|
335
|
-
* @param {'regular' | 'extended'} [options.session] Chart session
|
|
336
|
-
* @param {'EUR' | 'USD' | string} [options.currency] Chart currency
|
|
337
|
-
* @param {ChartType} [options.type] Chart custom type
|
|
338
|
-
* @param {ChartInputs} [options.inputs] Chart custom inputs
|
|
339
|
-
* @param {number} [options.replay] Replay mode starting point (Timestamp)
|
|
340
|
-
*/
|
|
341
|
-
setMarket(symbol, options = {}) {
|
|
342
|
-
this.#periods = {};
|
|
343
|
-
|
|
344
|
-
if (this.#replayMode) {
|
|
345
|
-
this.#replayMode = false;
|
|
346
|
-
this.#client.send('replay_delete_session', [this.#replaySessionID]);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
const symbolInit = {
|
|
350
|
-
symbol: symbol || 'BTCEUR',
|
|
351
|
-
adjustment: options.adjustment || 'splits',
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
if (options.backadjustment) symbolInit.backadjustment = 'default';
|
|
355
|
-
if (options.session) symbolInit.session = options.session;
|
|
356
|
-
if (options.currency) symbolInit['currency-id'] = options.currency;
|
|
357
|
-
|
|
358
|
-
if (options.replay) {
|
|
359
|
-
if (!this.#replayMode) {
|
|
360
|
-
this.#replayMode = true;
|
|
361
|
-
this.#client.send('replay_create_session', [this.#replaySessionID]);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
this.#client.send('replay_add_series', [
|
|
365
|
-
this.#replaySessionID,
|
|
366
|
-
'req_replay_addseries',
|
|
367
|
-
`=${JSON.stringify(symbolInit)}`,
|
|
368
|
-
options.timeframe,
|
|
369
|
-
]);
|
|
370
|
-
|
|
371
|
-
this.#client.send('replay_reset', [
|
|
372
|
-
this.#replaySessionID,
|
|
373
|
-
'req_replay_reset',
|
|
374
|
-
options.replay,
|
|
375
|
-
]);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
const complex = options.type || options.replay;
|
|
379
|
-
const chartInit = complex ? {} : symbolInit;
|
|
380
|
-
|
|
381
|
-
if (complex) {
|
|
382
|
-
if (options.replay) chartInit.replay = this.#replaySessionID;
|
|
383
|
-
chartInit.symbol = symbolInit;
|
|
384
|
-
chartInit.type = ChartTypes[options.type];
|
|
385
|
-
if (options.type) chartInit.inputs = { ...options.inputs };
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
this.#currentSeries += 1;
|
|
389
|
-
|
|
390
|
-
this.#client.send('resolve_symbol', [
|
|
391
|
-
this.#chartSessionID,
|
|
392
|
-
`ser_${this.#currentSeries}`,
|
|
393
|
-
`=${JSON.stringify(chartInit)}`,
|
|
394
|
-
]);
|
|
395
|
-
|
|
396
|
-
this.setSeries(options.timeframe, options.range, options.to);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* Set the chart timezone
|
|
401
|
-
* @param {import('../types').Timezone} timezone New timezone
|
|
402
|
-
*/
|
|
403
|
-
setTimezone(timezone) {
|
|
404
|
-
this.#periods = {};
|
|
405
|
-
this.#client.send('switch_timezone', [this.#chartSessionID, timezone]);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Fetch x additional previous periods/candles values
|
|
410
|
-
* @param {number} number Number of additional periods/candles you want to fetch
|
|
411
|
-
*/
|
|
412
|
-
fetchMore(number = 1) {
|
|
413
|
-
this.#client.send('request_more_data', [this.#chartSessionID, '$prices', number]);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Fetch x additional previous periods/candles values
|
|
418
|
-
* @param {number} number Number of additional periods/candles you want to fetch
|
|
419
|
-
* @returns {Promise} Raise when the data has been fetched
|
|
420
|
-
*/
|
|
421
|
-
replayStep(number = 1) {
|
|
422
|
-
return new Promise((cb) => {
|
|
423
|
-
if (!this.#replayMode) {
|
|
424
|
-
this.#handleError('No replay session');
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
const reqID = genSessionID('rsq_step');
|
|
429
|
-
this.#client.send('replay_step', [this.#replaySessionID, reqID, number]);
|
|
430
|
-
this.#replayOKCB[reqID] = () => { cb(); };
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Start fetching a new period/candle every x ms
|
|
436
|
-
* @param {number} interval Number of additional periods/candles you want to fetch
|
|
437
|
-
* @returns {Promise} Raise when the replay mode starts
|
|
438
|
-
*/
|
|
439
|
-
replayStart(interval = 1000) {
|
|
440
|
-
return new Promise((cb) => {
|
|
441
|
-
if (!this.#replayMode) {
|
|
442
|
-
this.#handleError('No replay session');
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const reqID = genSessionID('rsq_start');
|
|
447
|
-
this.#client.send('replay_start', [this.#replaySessionID, reqID, interval]);
|
|
448
|
-
this.#replayOKCB[reqID] = () => { cb(); };
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Stop fetching a new period/candle every x ms
|
|
454
|
-
* @returns {Promise} Raise when the replay mode stops
|
|
455
|
-
*/
|
|
456
|
-
replayStop() {
|
|
457
|
-
return new Promise((cb) => {
|
|
458
|
-
if (!this.#replayMode) {
|
|
459
|
-
this.#handleError('No replay session');
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
const reqID = genSessionID('rsq_stop');
|
|
464
|
-
this.#client.send('replay_stop', [this.#replaySessionID, reqID]);
|
|
465
|
-
this.#replayOKCB[reqID] = () => { cb(); };
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* When a symbol is loaded
|
|
471
|
-
* @param {() => void} cb
|
|
472
|
-
* @event
|
|
473
|
-
*/
|
|
474
|
-
onSymbolLoaded(cb) {
|
|
475
|
-
this.#callbacks.symbolLoaded.push(cb);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* When a chart update happens
|
|
480
|
-
* @param {(changes: ('$prices' | string)[]) => void} cb
|
|
481
|
-
* @event
|
|
482
|
-
*/
|
|
483
|
-
onUpdate(cb) {
|
|
484
|
-
this.#callbacks.update.push(cb);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* When the replay session is ready
|
|
489
|
-
* @param {() => void} cb
|
|
490
|
-
* @event
|
|
491
|
-
*/
|
|
492
|
-
onReplayLoaded(cb) {
|
|
493
|
-
this.#callbacks.replayLoaded.push(cb);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* When the replay session has new resolution
|
|
498
|
-
* @param {(
|
|
499
|
-
* timeframe: import('../types').TimeFrame,
|
|
500
|
-
* index: number,
|
|
501
|
-
* ) => void} cb
|
|
502
|
-
* @event
|
|
503
|
-
*/
|
|
504
|
-
onReplayResolution(cb) {
|
|
505
|
-
this.#callbacks.replayResolution.push(cb);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
/**
|
|
509
|
-
* When the replay session ends
|
|
510
|
-
* @param {() => void} cb
|
|
511
|
-
* @event
|
|
512
|
-
*/
|
|
513
|
-
onReplayEnd(cb) {
|
|
514
|
-
this.#callbacks.replayEnd.push(cb);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
/**
|
|
518
|
-
* When the replay session cursor has moved
|
|
519
|
-
* @param {(index: number) => void} cb
|
|
520
|
-
* @event
|
|
521
|
-
*/
|
|
522
|
-
onReplayPoint(cb) {
|
|
523
|
-
this.#callbacks.replayPoint.push(cb);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* When chart error happens
|
|
528
|
-
* @param {(...any) => void} cb Callback
|
|
529
|
-
* @event
|
|
530
|
-
*/
|
|
531
|
-
onError(cb) {
|
|
532
|
-
this.#callbacks.error.push(cb);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
/** @type {ChartSessionBridge} */
|
|
536
|
-
#chartSession = {
|
|
537
|
-
sessionID: this.#chartSessionID,
|
|
538
|
-
studyListeners: this.#studyListeners,
|
|
539
|
-
indexes: {},
|
|
540
|
-
send: (t, p) => this.#client.send(t, p),
|
|
541
|
-
};
|
|
542
|
-
|
|
543
|
-
Study = studyConstructor(this.#chartSession);
|
|
544
|
-
|
|
545
|
-
/** Delete the chart session */
|
|
546
|
-
delete() {
|
|
547
|
-
if (this.#replayMode) this.#client.send('replay_delete_session', [this.#replaySessionID]);
|
|
548
|
-
this.#client.send('chart_delete_session', [this.#chartSessionID]);
|
|
549
|
-
delete this.#client.sessions[this.#chartSessionID];
|
|
550
|
-
delete this.#client.sessions[this.#replaySessionID];
|
|
551
|
-
this.#replayMode = false;
|
|
552
|
-
}
|
|
553
|
-
};
|