tickatlas 0.1.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/dist/index.mjs ADDED
@@ -0,0 +1,768 @@
1
+ // src/errors.ts
2
+ var TickAtlasError = class extends Error {
3
+ constructor(message, options) {
4
+ super(message);
5
+ this.name = "TickAtlasError";
6
+ Object.setPrototypeOf(this, new.target.prototype);
7
+ if (options && "cause" in options) {
8
+ this.cause = options.cause;
9
+ }
10
+ }
11
+ };
12
+ var TickAtlasAPIError = class extends TickAtlasError {
13
+ constructor(opts) {
14
+ super(opts.message);
15
+ this.name = "TickAtlasAPIError";
16
+ this.statusCode = opts.statusCode;
17
+ this.code = opts.code;
18
+ this.details = opts.details;
19
+ this.requestId = opts.requestId ?? null;
20
+ this.raw = opts.raw ?? null;
21
+ Object.setPrototypeOf(this, new.target.prototype);
22
+ }
23
+ };
24
+ var AuthenticationError = class extends TickAtlasAPIError {
25
+ constructor(opts) {
26
+ super(opts);
27
+ this.name = "AuthenticationError";
28
+ Object.setPrototypeOf(this, new.target.prototype);
29
+ }
30
+ };
31
+ var PermissionDeniedError = class extends TickAtlasAPIError {
32
+ constructor(opts) {
33
+ super(opts);
34
+ this.name = "PermissionDeniedError";
35
+ Object.setPrototypeOf(this, new.target.prototype);
36
+ }
37
+ };
38
+ var NotFoundError = class extends TickAtlasAPIError {
39
+ constructor(opts) {
40
+ super(opts);
41
+ this.name = "NotFoundError";
42
+ Object.setPrototypeOf(this, new.target.prototype);
43
+ }
44
+ };
45
+ var ValidationError = class extends TickAtlasAPIError {
46
+ constructor(opts) {
47
+ super(opts);
48
+ this.name = "ValidationError";
49
+ Object.setPrototypeOf(this, new.target.prototype);
50
+ }
51
+ };
52
+ var RateLimitError = class extends TickAtlasAPIError {
53
+ constructor(opts) {
54
+ super(opts);
55
+ this.name = "RateLimitError";
56
+ this.retryAfter = opts.retryAfter ?? null;
57
+ Object.setPrototypeOf(this, new.target.prototype);
58
+ }
59
+ };
60
+ var ServerError = class extends TickAtlasAPIError {
61
+ constructor(opts) {
62
+ super(opts);
63
+ this.name = "ServerError";
64
+ Object.setPrototypeOf(this, new.target.prototype);
65
+ }
66
+ };
67
+ var TickAtlasNetworkError = class extends TickAtlasError {
68
+ constructor(message, options) {
69
+ super(message, options);
70
+ this.name = "TickAtlasNetworkError";
71
+ this.isTimeout = options?.isTimeout ?? false;
72
+ Object.setPrototypeOf(this, new.target.prototype);
73
+ }
74
+ };
75
+ var TickAtlasConfigError = class extends TickAtlasError {
76
+ constructor(message) {
77
+ super(message);
78
+ this.name = "TickAtlasConfigError";
79
+ Object.setPrototypeOf(this, new.target.prototype);
80
+ }
81
+ };
82
+ function createApiError(statusCode, body, requestId, retryAfter) {
83
+ const code = body.code ?? `HTTP_${statusCode}`;
84
+ const message = body.message ?? `TickAtlas API error (HTTP ${statusCode}, code ${code})`;
85
+ const base = {
86
+ statusCode,
87
+ code,
88
+ message,
89
+ details: body.details,
90
+ requestId,
91
+ raw: body
92
+ };
93
+ if (code === "RATE_LIMIT_EXCEEDED" || code === "QUOTA_EXCEEDED" || code === "RATE_LIMITED") {
94
+ return new RateLimitError({ ...base, retryAfter });
95
+ }
96
+ switch (statusCode) {
97
+ case 401:
98
+ return new AuthenticationError(base);
99
+ case 403:
100
+ return new PermissionDeniedError(base);
101
+ case 404:
102
+ return new NotFoundError(base);
103
+ case 400:
104
+ case 422:
105
+ return new ValidationError(base);
106
+ case 429:
107
+ return new RateLimitError({ ...base, retryAfter });
108
+ default:
109
+ if (statusCode >= 500) return new ServerError(base);
110
+ if (statusCode >= 400) return new ValidationError(base);
111
+ return new TickAtlasAPIError(base);
112
+ }
113
+ }
114
+
115
+ // src/http.ts
116
+ var SDK_VERSION = "0.1.0";
117
+ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
118
+ var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
119
+ var defaultJitter = () => Math.random();
120
+ function buildQueryString(query) {
121
+ if (!query) return "";
122
+ const sp = new URLSearchParams();
123
+ for (const [key, value] of Object.entries(query)) {
124
+ if (value === void 0 || value === null) continue;
125
+ if (Array.isArray(value)) {
126
+ if (value.length === 0) continue;
127
+ sp.append(key, value.join(","));
128
+ } else {
129
+ sp.append(key, String(value));
130
+ }
131
+ }
132
+ const qs = sp.toString();
133
+ return qs ? `?${qs}` : "";
134
+ }
135
+ function parseIntHeader(headers, name) {
136
+ const raw = headers.get(name);
137
+ if (raw === null) return null;
138
+ const n = Number.parseInt(raw, 10);
139
+ return Number.isNaN(n) ? null : n;
140
+ }
141
+ function retryAfterMs(headers, body) {
142
+ const ra = parseIntHeader(headers, "Retry-After");
143
+ if (ra !== null) return ra * 1e3;
144
+ const reset = parseIntHeader(headers, "X-RateLimit-Reset");
145
+ if (reset !== null) return reset * 1e3;
146
+ const bodyReset = body?.["reset_in_seconds"];
147
+ if (typeof bodyReset === "number") return bodyReset * 1e3;
148
+ return null;
149
+ }
150
+ function backoffMs(config, attempt) {
151
+ const exp = config.backoffBase * Math.pow(2, attempt);
152
+ const capped = Math.min(config.backoffCap, exp);
153
+ return capped * config.jitter();
154
+ }
155
+ async function request(config, opts) {
156
+ const base = opts.root ? new URL(config.baseURL).origin : config.baseURL.replace(/\/+$/, "");
157
+ const url = base + opts.path + buildQueryString(opts.query);
158
+ const maxAttempts = config.maxRetries + 1;
159
+ let lastError;
160
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
161
+ const isLastAttempt = attempt === maxAttempts - 1;
162
+ const headers = {
163
+ "X-API-Key": config.apiKey,
164
+ Accept: "application/json"
165
+ };
166
+ if (config.sendUserAgent) {
167
+ headers["User-Agent"] = `tickatlas-js/${SDK_VERSION}`;
168
+ }
169
+ let bodyInit;
170
+ if (opts.body !== void 0) {
171
+ headers["Content-Type"] = "application/json";
172
+ bodyInit = JSON.stringify(opts.body);
173
+ }
174
+ const controller = new AbortController();
175
+ const timeoutMs = opts.timeout ?? config.timeout;
176
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
177
+ let timedOut = false;
178
+ const onTimeout = () => {
179
+ timedOut = true;
180
+ };
181
+ controller.signal.addEventListener("abort", onTimeout, { once: true });
182
+ let abortListener;
183
+ if (opts.signal) {
184
+ if (opts.signal.aborted) controller.abort();
185
+ else {
186
+ abortListener = () => controller.abort();
187
+ opts.signal.addEventListener("abort", abortListener, { once: true });
188
+ }
189
+ }
190
+ let response;
191
+ try {
192
+ response = await config.fetch(url, {
193
+ method: opts.method,
194
+ headers,
195
+ body: bodyInit,
196
+ signal: controller.signal
197
+ });
198
+ } catch (err) {
199
+ clearTimeout(timer);
200
+ if (abortListener && opts.signal) {
201
+ opts.signal.removeEventListener("abort", abortListener);
202
+ }
203
+ if (opts.signal?.aborted && !timedOut) {
204
+ throw new TickAtlasNetworkError("Request aborted by caller", {
205
+ cause: err
206
+ });
207
+ }
208
+ const netErr = new TickAtlasNetworkError(
209
+ timedOut ? `Request timed out after ${timeoutMs}ms` : `Network request failed: ${err?.message ?? String(err)}`,
210
+ { cause: err, isTimeout: timedOut }
211
+ );
212
+ lastError = netErr;
213
+ if (isLastAttempt) throw netErr;
214
+ await config.sleep(backoffMs(config, attempt));
215
+ continue;
216
+ } finally {
217
+ clearTimeout(timer);
218
+ if (abortListener && opts.signal) {
219
+ opts.signal.removeEventListener("abort", abortListener);
220
+ }
221
+ }
222
+ const requestId = response.headers.get("X-Request-ID");
223
+ const text = await response.text();
224
+ let parsed = void 0;
225
+ if (text.length > 0) {
226
+ try {
227
+ parsed = JSON.parse(text);
228
+ } catch {
229
+ parsed = void 0;
230
+ }
231
+ }
232
+ if (response.ok) {
233
+ const env2 = parsed;
234
+ if (env2 && typeof env2 === "object" && "data" in env2) {
235
+ return env2.data;
236
+ }
237
+ return parsed;
238
+ }
239
+ const env = parsed;
240
+ const errorBody = env && typeof env === "object" && env.error && typeof env.error === "object" ? env.error : {
241
+ code: `HTTP_${response.status}`,
242
+ message: text.length > 0 ? text : `TickAtlas API returned HTTP ${response.status}`
243
+ };
244
+ const retryMs = response.status === 429 ? retryAfterMs(response.headers, errorBody) : null;
245
+ const apiError = createApiError(
246
+ response.status,
247
+ errorBody,
248
+ requestId,
249
+ retryMs !== null ? Math.round(retryMs / 1e3) : null
250
+ );
251
+ const retryable = RETRYABLE_STATUSES.has(response.status);
252
+ if (!retryable || isLastAttempt) {
253
+ throw apiError;
254
+ }
255
+ lastError = apiError;
256
+ const delay = response.status === 429 && retryMs !== null ? retryMs : backoffMs(config, attempt);
257
+ await config.sleep(delay);
258
+ }
259
+ throw lastError ?? new TickAtlasNetworkError("Request failed after all retries");
260
+ }
261
+
262
+ // src/client.ts
263
+ var DEFAULT_BASE_URL = "https://tickatlas.com/v1";
264
+ function readEnv(name) {
265
+ if (typeof process !== "undefined" && process?.env) {
266
+ return process.env[name];
267
+ }
268
+ return void 0;
269
+ }
270
+ function isNodeLike() {
271
+ return typeof process !== "undefined" && !!process?.versions?.node;
272
+ }
273
+ function csv(value) {
274
+ if (value === void 0) return void 0;
275
+ return Array.isArray(value) ? value.join(",") : value;
276
+ }
277
+ var TickAtlas = class {
278
+ constructor(options = {}) {
279
+ const apiKey = options.apiKey ?? readEnv("TICKATLAS_API_KEY");
280
+ if (!apiKey) {
281
+ throw new TickAtlasConfigError(
282
+ "No TickAtlas API key provided. Pass { apiKey } to the constructor or set the TICKATLAS_API_KEY environment variable."
283
+ );
284
+ }
285
+ const baseURL = options.baseURL ?? readEnv("TICKATLAS_BASE_URL") ?? DEFAULT_BASE_URL;
286
+ const fetchImpl = options.fetch ?? globalThis.fetch;
287
+ if (typeof fetchImpl !== "function") {
288
+ throw new TickAtlasConfigError(
289
+ "Global `fetch` is not available in this runtime. Use Node 18+ or a modern browser, or pass a `fetch` implementation in the options."
290
+ );
291
+ }
292
+ this.config = {
293
+ apiKey,
294
+ baseURL,
295
+ timeout: options.timeout ?? 3e4,
296
+ maxRetries: options.maxRetries ?? 3,
297
+ backoffBase: options.backoffBase ?? 500,
298
+ backoffCap: options.backoffCap ?? 3e4,
299
+ fetch: fetchImpl,
300
+ sleep: options.sleep ?? defaultSleep,
301
+ jitter: options.jitter ?? defaultJitter,
302
+ sendUserAgent: isNodeLike()
303
+ };
304
+ }
305
+ // =========================================================================
306
+ // Symbols
307
+ // =========================================================================
308
+ /** 7.1 `GET /symbols` — list symbols (paginated). */
309
+ getSymbols(opts = {}) {
310
+ const query = {
311
+ category: opts.category,
312
+ search: opts.search,
313
+ offset: opts.offset,
314
+ limit: opts.limit
315
+ };
316
+ return request(this.config, {
317
+ method: "GET",
318
+ path: "/symbols",
319
+ query
320
+ });
321
+ }
322
+ /** 7.2 `GET /symbols/{symbol}` — symbol contract spec. */
323
+ getSymbol(symbol) {
324
+ return request(this.config, {
325
+ method: "GET",
326
+ path: `/symbols/${encodeURIComponent(symbol)}`
327
+ });
328
+ }
329
+ // =========================================================================
330
+ // Quotes
331
+ // =========================================================================
332
+ /** 7.3 `GET /quote` — single real-time quote. */
333
+ getQuote(symbol, opts = {}) {
334
+ const query = {
335
+ symbol,
336
+ include_sources: opts.includeSources,
337
+ source: opts.source
338
+ };
339
+ return request(this.config, {
340
+ method: "GET",
341
+ path: "/quote",
342
+ query
343
+ });
344
+ }
345
+ /**
346
+ * 7.4 `POST /quotes` — batch quotes (1..100 symbols).
347
+ * `fields` ⊆ ["bid","ask","spread","spread_pips","timestamp"] (default all).
348
+ */
349
+ getQuotes(symbols, fields) {
350
+ const body = { symbols };
351
+ if (fields) body.fields = fields;
352
+ return request(this.config, {
353
+ method: "POST",
354
+ path: "/quotes",
355
+ body
356
+ });
357
+ }
358
+ // =========================================================================
359
+ // OHLC / Ticks
360
+ // =========================================================================
361
+ /** 7.5 `GET /ohlc` — OHLC candles. */
362
+ getOhlc(symbol, opts = {}) {
363
+ const query = {
364
+ symbol,
365
+ timeframe: opts.timeframe,
366
+ from: opts.from,
367
+ to: opts.to,
368
+ limit: opts.limit
369
+ };
370
+ return request(this.config, {
371
+ method: "GET",
372
+ path: "/ohlc",
373
+ query
374
+ });
375
+ }
376
+ /**
377
+ * 7.6 `GET /ticks` — tick data (plan: pro/enterprise).
378
+ * `from`/`to` are required ISO 8601; range must be ≤ 1 hour.
379
+ */
380
+ getTicks(symbol, from, to) {
381
+ return request(this.config, {
382
+ method: "GET",
383
+ path: "/ticks",
384
+ query: { symbol, from, to }
385
+ });
386
+ }
387
+ // =========================================================================
388
+ // Indicators
389
+ // =========================================================================
390
+ /** 7.7 `GET /indicator` — single indicator value. */
391
+ getIndicator(symbol, indicator, opts = {}) {
392
+ const query = {
393
+ symbol,
394
+ indicator,
395
+ timeframe: opts.timeframe,
396
+ source: opts.source
397
+ };
398
+ return request(this.config, {
399
+ method: "GET",
400
+ path: "/indicator",
401
+ query
402
+ });
403
+ }
404
+ /** 7.8 `GET /indicators` — all indicators for a symbol. */
405
+ getIndicators(symbol, opts = {}) {
406
+ const query = {
407
+ symbol,
408
+ timeframe: opts.timeframe,
409
+ category: opts.category
410
+ };
411
+ return request(this.config, {
412
+ method: "GET",
413
+ path: "/indicators",
414
+ query
415
+ });
416
+ }
417
+ /** 7.9 `GET /indicators/list` — indicator catalogue. */
418
+ listIndicators() {
419
+ return request(this.config, {
420
+ method: "GET",
421
+ path: "/indicators/list"
422
+ });
423
+ }
424
+ /**
425
+ * 7.10 `GET /indicator/history` — indicator series (plan: starter+).
426
+ */
427
+ getIndicatorHistory(symbol, indicator, opts = {}) {
428
+ const query = {
429
+ symbol,
430
+ indicator,
431
+ timeframe: opts.timeframe,
432
+ from: opts.from,
433
+ to: opts.to,
434
+ limit: opts.limit
435
+ };
436
+ return request(this.config, {
437
+ method: "GET",
438
+ path: "/indicator/history",
439
+ query
440
+ });
441
+ }
442
+ /**
443
+ * 7.11 `GET /multi` — batch indicators across symbols. Supplying `from`
444
+ * switches the server into historical mode (plan: starter+).
445
+ */
446
+ getMulti(symbols, indicators, opts = {}) {
447
+ const query = {
448
+ symbols: symbols.join(","),
449
+ indicators: indicators.join(","),
450
+ timeframe: opts.timeframe,
451
+ from: opts.from,
452
+ to: opts.to
453
+ };
454
+ return request(this.config, {
455
+ method: "GET",
456
+ path: "/multi",
457
+ query
458
+ });
459
+ }
460
+ // =========================================================================
461
+ // Screener
462
+ // =========================================================================
463
+ /**
464
+ * 7.12 `GET /screener` — scan symbols by indicator.
465
+ * Note: `minVal`/`maxVal` serialise to `min_val`/`max_val` (the docs' `min`/
466
+ * `max` are silently ignored by the API — see SPEC §12 F2).
467
+ */
468
+ screen(indicator, opts = {}) {
469
+ const query = {
470
+ indicator,
471
+ timeframe: opts.timeframe,
472
+ min_val: opts.minVal,
473
+ max_val: opts.maxVal,
474
+ sort: opts.sort,
475
+ offset: opts.offset,
476
+ limit: opts.limit
477
+ };
478
+ return request(this.config, {
479
+ method: "GET",
480
+ path: "/screener",
481
+ query
482
+ });
483
+ }
484
+ // =========================================================================
485
+ // Summary
486
+ // =========================================================================
487
+ /** 7.13 `GET /summary` — market-bias summary. */
488
+ getSummary(symbol, timeframe) {
489
+ return request(this.config, {
490
+ method: "GET",
491
+ path: "/summary",
492
+ query: { symbol, timeframe }
493
+ });
494
+ }
495
+ // =========================================================================
496
+ // Spread
497
+ // =========================================================================
498
+ /** 7.14 `GET /spread` — spread statistics. */
499
+ getSpread(symbol, period) {
500
+ return request(this.config, {
501
+ method: "GET",
502
+ path: "/spread",
503
+ query: { symbol, period }
504
+ });
505
+ }
506
+ /** 7.15 `GET /spread/compare` — compare spread across symbols (≤20). */
507
+ compareSpread(symbols, period) {
508
+ return request(this.config, {
509
+ method: "GET",
510
+ path: "/spread/compare",
511
+ query: { symbols: symbols.join(","), period }
512
+ });
513
+ }
514
+ // =========================================================================
515
+ // Sessions / Heatmap / Calendar
516
+ // =========================================================================
517
+ /** 7.16 `GET /sessions` — market session clock. */
518
+ getSessions() {
519
+ return request(this.config, { method: "GET", path: "/sessions" });
520
+ }
521
+ /** 7.17 `GET /heatmap` — currency strength / correlation. */
522
+ getHeatmap(opts = {}) {
523
+ const query = {
524
+ type: opts.type,
525
+ timeframe: opts.timeframe,
526
+ correlations: opts.correlations
527
+ };
528
+ return request(this.config, {
529
+ method: "GET",
530
+ path: "/heatmap",
531
+ query
532
+ });
533
+ }
534
+ /** 7.18 `GET /calendar` — economic calendar. */
535
+ getCalendar(opts = {}) {
536
+ const query = {
537
+ from: opts.from,
538
+ to: opts.to,
539
+ currencies: csv(opts.currencies),
540
+ country: csv(opts.country),
541
+ impact: opts.impact,
542
+ q: opts.q,
543
+ next_hours: opts.nextHours,
544
+ offset: opts.offset,
545
+ limit: opts.limit
546
+ };
547
+ return request(this.config, {
548
+ method: "GET",
549
+ path: "/calendar",
550
+ query
551
+ });
552
+ }
553
+ // =========================================================================
554
+ // Monitor (account / layout)
555
+ // =========================================================================
556
+ /** 7.19 `GET /monitor/account` — account identity & quota. */
557
+ getAccount() {
558
+ return request(this.config, {
559
+ method: "GET",
560
+ path: "/monitor/account"
561
+ });
562
+ }
563
+ /** 7.20 `GET /monitor/layout` — saved dashboard layout. */
564
+ getLayout() {
565
+ return request(this.config, {
566
+ method: "GET",
567
+ path: "/monitor/layout"
568
+ });
569
+ }
570
+ /**
571
+ * 7.21 `PUT /monitor/layout` — save dashboard layout (≤60 widgets).
572
+ *
573
+ * ADVANCED / WRITE: this is the only mutating endpoint in the SDK. It
574
+ * overwrites the user's saved dashboard layout for this API key. Use with care.
575
+ */
576
+ saveLayout(layout) {
577
+ return request(this.config, {
578
+ method: "PUT",
579
+ path: "/monitor/layout",
580
+ body: { layout }
581
+ });
582
+ }
583
+ // =========================================================================
584
+ // Infra probe
585
+ // =========================================================================
586
+ /** `GET /health` — service health probe (no API key required server-side). */
587
+ health() {
588
+ return request(this.config, {
589
+ method: "GET",
590
+ path: "/health",
591
+ root: true
592
+ });
593
+ }
594
+ };
595
+ /** SDK version (e.g. for diagnostics). */
596
+ TickAtlas.version = SDK_VERSION;
597
+
598
+ // src/constants.ts
599
+ var Timeframes = {
600
+ M1: "M1",
601
+ M5: "M5",
602
+ M15: "M15",
603
+ M30: "M30",
604
+ H1: "H1",
605
+ H4: "H4",
606
+ D1: "D1"
607
+ };
608
+ var HeatmapTimeframes = {
609
+ H1: "H1",
610
+ H4: "H4",
611
+ D1: "D1",
612
+ W1: "W1"
613
+ };
614
+ var SymbolCategories = {
615
+ forex: "forex",
616
+ metals: "metals",
617
+ commodities: "commodities",
618
+ indices: "indices",
619
+ crypto: "crypto",
620
+ stocks: "stocks"
621
+ };
622
+ var SpreadPeriods = {
623
+ "1h": "1h",
624
+ "24h": "24h",
625
+ "7d": "7d",
626
+ "30d": "30d"
627
+ };
628
+ var CalendarImpacts = {
629
+ high: "high",
630
+ medium: "medium",
631
+ low: "low"
632
+ };
633
+ var Bias = {
634
+ bullish: "bullish",
635
+ bearish: "bearish",
636
+ neutral: "neutral"
637
+ };
638
+ var BiasStrengths = {
639
+ normal: "normal",
640
+ strong: "strong"
641
+ };
642
+ var HeatmapTypes = {
643
+ strength: "strength",
644
+ correlation: "correlation"
645
+ };
646
+ var IndicatorCategories = {
647
+ trend: "trend",
648
+ oscillator: "oscillator",
649
+ volatility: "volatility",
650
+ volume: "volume"
651
+ };
652
+ var Plans = {
653
+ free: "free",
654
+ trial: "trial",
655
+ starter: "starter",
656
+ pro: "pro",
657
+ enterprise: "enterprise",
658
+ payg: "payg"
659
+ };
660
+ var SortDirections = {
661
+ asc: "asc",
662
+ desc: "desc"
663
+ };
664
+ var Indicators = {
665
+ // --- Trend (23) ---
666
+ SMA_10: "SMA_10",
667
+ SMA_20: "SMA_20",
668
+ SMA_50: "SMA_50",
669
+ SMA_100: "SMA_100",
670
+ SMA_200: "SMA_200",
671
+ EMA_10: "EMA_10",
672
+ EMA_20: "EMA_20",
673
+ EMA_50: "EMA_50",
674
+ MACD_main: "MACD_main",
675
+ MACD_signal: "MACD_signal",
676
+ MACD_hist: "MACD_hist",
677
+ ADX: "ADX",
678
+ ADX_plusDI: "ADX_plusDI",
679
+ ADX_minusDI: "ADX_minusDI",
680
+ Ichimoku_tenkan: "Ichimoku_tenkan",
681
+ Ichimoku_kijun: "Ichimoku_kijun",
682
+ Ichimoku_senkou_a: "Ichimoku_senkou_a",
683
+ Alligator_jaw: "Alligator_jaw",
684
+ Alligator_teeth: "Alligator_teeth",
685
+ Alligator_lips: "Alligator_lips",
686
+ SAR: "SAR",
687
+ TEMA_20: "TEMA_20",
688
+ DEMA_20: "DEMA_20",
689
+ // --- Oscillator (8) ---
690
+ RSI_14: "RSI_14",
691
+ Stochastic_K: "Stochastic_K",
692
+ Stochastic_D: "Stochastic_D",
693
+ CCI_14: "CCI_14",
694
+ CCI_20: "CCI_20",
695
+ WilliamsR_14: "WilliamsR_14",
696
+ Momentum_14: "Momentum_14",
697
+ DeMarker_14: "DeMarker_14",
698
+ // --- Volatility (7) ---
699
+ BB_upper: "BB_upper",
700
+ BB_middle: "BB_middle",
701
+ BB_lower: "BB_lower",
702
+ BB_width: "BB_width",
703
+ ATR_14: "ATR_14",
704
+ ATR_7: "ATR_7",
705
+ StdDev_20: "StdDev_20",
706
+ // --- Volume (4) ---
707
+ OBV: "OBV",
708
+ MFI_14: "MFI_14",
709
+ AD: "AD",
710
+ Volumes: "Volumes"
711
+ };
712
+ var IndicatorsByCategory = {
713
+ trend: [
714
+ "SMA_10",
715
+ "SMA_20",
716
+ "SMA_50",
717
+ "SMA_100",
718
+ "SMA_200",
719
+ "EMA_10",
720
+ "EMA_20",
721
+ "EMA_50",
722
+ "MACD_main",
723
+ "MACD_signal",
724
+ "MACD_hist",
725
+ "ADX",
726
+ "ADX_plusDI",
727
+ "ADX_minusDI",
728
+ "Ichimoku_tenkan",
729
+ "Ichimoku_kijun",
730
+ "Ichimoku_senkou_a",
731
+ "Alligator_jaw",
732
+ "Alligator_teeth",
733
+ "Alligator_lips",
734
+ "SAR",
735
+ "TEMA_20",
736
+ "DEMA_20"
737
+ ],
738
+ oscillator: [
739
+ "RSI_14",
740
+ "Stochastic_K",
741
+ "Stochastic_D",
742
+ "CCI_14",
743
+ "CCI_20",
744
+ "WilliamsR_14",
745
+ "Momentum_14",
746
+ "DeMarker_14"
747
+ ],
748
+ volatility: [
749
+ "BB_upper",
750
+ "BB_middle",
751
+ "BB_lower",
752
+ "BB_width",
753
+ "ATR_14",
754
+ "ATR_7",
755
+ "StdDev_20"
756
+ ],
757
+ volume: ["OBV", "MFI_14", "AD", "Volumes"]
758
+ };
759
+ var ALL_INDICATORS = [
760
+ ...IndicatorsByCategory.trend,
761
+ ...IndicatorsByCategory.oscillator,
762
+ ...IndicatorsByCategory.volatility,
763
+ ...IndicatorsByCategory.volume
764
+ ];
765
+
766
+ export { ALL_INDICATORS, AuthenticationError, Bias, BiasStrengths, CalendarImpacts, HeatmapTimeframes, HeatmapTypes, IndicatorCategories, Indicators, IndicatorsByCategory, NotFoundError, PermissionDeniedError, Plans, RateLimitError, SDK_VERSION, ServerError, SortDirections, SpreadPeriods, SymbolCategories, TickAtlas, TickAtlasAPIError, TickAtlasConfigError, TickAtlasError, TickAtlasNetworkError, Timeframes, ValidationError };
767
+ //# sourceMappingURL=index.mjs.map
768
+ //# sourceMappingURL=index.mjs.map