@discomedia/utils 1.0.59 → 1.0.61
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 +0 -2
- package/dist/index-frontend.cjs +215 -43
- package/dist/index-frontend.cjs.map +1 -1
- package/dist/index-frontend.mjs +215 -43
- package/dist/index-frontend.mjs.map +1 -1
- package/dist/index.cjs +215 -1421
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +215 -1421
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +4 -4
- package/dist/test.js +215 -268
- package/dist/test.js.map +1 -1
- package/dist/types/index.d.ts +0 -82
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/misc-utils.d.ts +0 -6
- package/dist/types/misc-utils.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +0 -2
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types-frontend/index.d.ts +0 -82
- package/dist/types-frontend/index.d.ts.map +1 -1
- package/dist/types-frontend/misc-utils.d.ts +0 -6
- package/dist/types-frontend/misc-utils.d.ts.map +1 -1
- package/dist/types-frontend/types/index.d.ts +0 -2
- package/dist/types-frontend/types/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/types/polygon-indices.d.ts +0 -85
- package/dist/types/polygon-indices.d.ts.map +0 -1
- package/dist/types/polygon.d.ts +0 -126
- package/dist/types/polygon.d.ts.map +0 -1
- package/dist/types/technical-analysis.d.ts +0 -90
- package/dist/types/technical-analysis.d.ts.map +0 -1
- package/dist/types/types/polygon-indices-types.d.ts +0 -190
- package/dist/types/types/polygon-indices-types.d.ts.map +0 -1
- package/dist/types/types/polygon-types.d.ts +0 -204
- package/dist/types/types/polygon-types.d.ts.map +0 -1
- package/dist/types-frontend/polygon-indices.d.ts +0 -85
- package/dist/types-frontend/polygon-indices.d.ts.map +0 -1
- package/dist/types-frontend/polygon.d.ts +0 -126
- package/dist/types-frontend/polygon.d.ts.map +0 -1
- package/dist/types-frontend/technical-analysis.d.ts +0 -90
- package/dist/types-frontend/technical-analysis.d.ts.map +0 -1
- package/dist/types-frontend/types/polygon-indices-types.d.ts +0 -190
- package/dist/types-frontend/types/polygon-indices-types.d.ts.map +0 -1
- package/dist/types-frontend/types/polygon-types.d.ts +0 -204
- package/dist/types-frontend/types/polygon-types.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1382,933 +1382,6 @@ async function fetchWithRetry(url, options = {}, retries = 3, initialBackoff = 1
|
|
|
1382
1382
|
}
|
|
1383
1383
|
throw new Error('Failed to fetch after multiple attempts');
|
|
1384
1384
|
}
|
|
1385
|
-
/**
|
|
1386
|
-
* Validates a Polygon.io API key by making a test request.
|
|
1387
|
-
* @param apiKey - The API key to validate.
|
|
1388
|
-
* @returns Promise that resolves to true if valid, false otherwise.
|
|
1389
|
-
*/
|
|
1390
|
-
async function validatePolygonApiKey(apiKey) {
|
|
1391
|
-
try {
|
|
1392
|
-
const response = await fetch(`https://api.polygon.io/v1/meta/symbols?apikey=${apiKey}&limit=1`);
|
|
1393
|
-
if (response.status === 401) {
|
|
1394
|
-
throw new Error('Invalid or expired Polygon.io API key');
|
|
1395
|
-
}
|
|
1396
|
-
if (response.status === 403) {
|
|
1397
|
-
throw new Error('Polygon.io API key lacks required permissions');
|
|
1398
|
-
}
|
|
1399
|
-
return response.ok;
|
|
1400
|
-
}
|
|
1401
|
-
catch (error) {
|
|
1402
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
1403
|
-
console.error('Polygon.io API key validation failed:', errorMessage);
|
|
1404
|
-
return false;
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
/*
|
|
1409
|
-
How it works:
|
|
1410
|
-
`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.
|
|
1411
|
-
*/
|
|
1412
|
-
|
|
1413
|
-
class Node {
|
|
1414
|
-
value;
|
|
1415
|
-
next;
|
|
1416
|
-
|
|
1417
|
-
constructor(value) {
|
|
1418
|
-
this.value = value;
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
class Queue {
|
|
1423
|
-
#head;
|
|
1424
|
-
#tail;
|
|
1425
|
-
#size;
|
|
1426
|
-
|
|
1427
|
-
constructor() {
|
|
1428
|
-
this.clear();
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
enqueue(value) {
|
|
1432
|
-
const node = new Node(value);
|
|
1433
|
-
|
|
1434
|
-
if (this.#head) {
|
|
1435
|
-
this.#tail.next = node;
|
|
1436
|
-
this.#tail = node;
|
|
1437
|
-
} else {
|
|
1438
|
-
this.#head = node;
|
|
1439
|
-
this.#tail = node;
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1442
|
-
this.#size++;
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
dequeue() {
|
|
1446
|
-
const current = this.#head;
|
|
1447
|
-
if (!current) {
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
this.#head = this.#head.next;
|
|
1452
|
-
this.#size--;
|
|
1453
|
-
return current.value;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
peek() {
|
|
1457
|
-
if (!this.#head) {
|
|
1458
|
-
return;
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
return this.#head.value;
|
|
1462
|
-
|
|
1463
|
-
// TODO: Node.js 18.
|
|
1464
|
-
// return this.#head?.value;
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
clear() {
|
|
1468
|
-
this.#head = undefined;
|
|
1469
|
-
this.#tail = undefined;
|
|
1470
|
-
this.#size = 0;
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
get size() {
|
|
1474
|
-
return this.#size;
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
* [Symbol.iterator]() {
|
|
1478
|
-
let current = this.#head;
|
|
1479
|
-
|
|
1480
|
-
while (current) {
|
|
1481
|
-
yield current.value;
|
|
1482
|
-
current = current.next;
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
* drain() {
|
|
1487
|
-
while (this.#head) {
|
|
1488
|
-
yield this.dequeue();
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
function pLimit(concurrency) {
|
|
1494
|
-
let rejectOnClear = false;
|
|
1495
|
-
|
|
1496
|
-
if (typeof concurrency === 'object') {
|
|
1497
|
-
({concurrency, rejectOnClear = false} = concurrency);
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
validateConcurrency(concurrency);
|
|
1501
|
-
|
|
1502
|
-
if (typeof rejectOnClear !== 'boolean') {
|
|
1503
|
-
throw new TypeError('Expected `rejectOnClear` to be a boolean');
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
const queue = new Queue();
|
|
1507
|
-
let activeCount = 0;
|
|
1508
|
-
|
|
1509
|
-
const resumeNext = () => {
|
|
1510
|
-
// Process the next queued function if we're under the concurrency limit
|
|
1511
|
-
if (activeCount < concurrency && queue.size > 0) {
|
|
1512
|
-
activeCount++;
|
|
1513
|
-
queue.dequeue().run();
|
|
1514
|
-
}
|
|
1515
|
-
};
|
|
1516
|
-
|
|
1517
|
-
const next = () => {
|
|
1518
|
-
activeCount--;
|
|
1519
|
-
resumeNext();
|
|
1520
|
-
};
|
|
1521
|
-
|
|
1522
|
-
const run = async (function_, resolve, arguments_) => {
|
|
1523
|
-
// Execute the function and capture the result promise
|
|
1524
|
-
const result = (async () => function_(...arguments_))();
|
|
1525
|
-
|
|
1526
|
-
// Resolve immediately with the promise (don't wait for completion)
|
|
1527
|
-
resolve(result);
|
|
1528
|
-
|
|
1529
|
-
// Wait for the function to complete (success or failure)
|
|
1530
|
-
// We catch errors here to prevent unhandled rejections,
|
|
1531
|
-
// but the original promise rejection is preserved for the caller
|
|
1532
|
-
try {
|
|
1533
|
-
await result;
|
|
1534
|
-
} catch {}
|
|
1535
|
-
|
|
1536
|
-
// Decrement active count and process next queued function
|
|
1537
|
-
next();
|
|
1538
|
-
};
|
|
1539
|
-
|
|
1540
|
-
const enqueue = (function_, resolve, reject, arguments_) => {
|
|
1541
|
-
const queueItem = {reject};
|
|
1542
|
-
|
|
1543
|
-
// Queue the internal resolve function instead of the run function
|
|
1544
|
-
// to preserve the asynchronous execution context.
|
|
1545
|
-
new Promise(internalResolve => { // eslint-disable-line promise/param-names
|
|
1546
|
-
queueItem.run = internalResolve;
|
|
1547
|
-
queue.enqueue(queueItem);
|
|
1548
|
-
}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then
|
|
1549
|
-
|
|
1550
|
-
// Start processing immediately if we haven't reached the concurrency limit
|
|
1551
|
-
if (activeCount < concurrency) {
|
|
1552
|
-
resumeNext();
|
|
1553
|
-
}
|
|
1554
|
-
};
|
|
1555
|
-
|
|
1556
|
-
const generator = (function_, ...arguments_) => new Promise((resolve, reject) => {
|
|
1557
|
-
enqueue(function_, resolve, reject, arguments_);
|
|
1558
|
-
});
|
|
1559
|
-
|
|
1560
|
-
Object.defineProperties(generator, {
|
|
1561
|
-
activeCount: {
|
|
1562
|
-
get: () => activeCount,
|
|
1563
|
-
},
|
|
1564
|
-
pendingCount: {
|
|
1565
|
-
get: () => queue.size,
|
|
1566
|
-
},
|
|
1567
|
-
clearQueue: {
|
|
1568
|
-
value() {
|
|
1569
|
-
if (!rejectOnClear) {
|
|
1570
|
-
queue.clear();
|
|
1571
|
-
return;
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
const abortError = AbortSignal.abort().reason;
|
|
1575
|
-
|
|
1576
|
-
while (queue.size > 0) {
|
|
1577
|
-
queue.dequeue().reject(abortError);
|
|
1578
|
-
}
|
|
1579
|
-
},
|
|
1580
|
-
},
|
|
1581
|
-
concurrency: {
|
|
1582
|
-
get: () => concurrency,
|
|
1583
|
-
|
|
1584
|
-
set(newConcurrency) {
|
|
1585
|
-
validateConcurrency(newConcurrency);
|
|
1586
|
-
concurrency = newConcurrency;
|
|
1587
|
-
|
|
1588
|
-
queueMicrotask(() => {
|
|
1589
|
-
// eslint-disable-next-line no-unmodified-loop-condition
|
|
1590
|
-
while (activeCount < concurrency && queue.size > 0) {
|
|
1591
|
-
resumeNext();
|
|
1592
|
-
}
|
|
1593
|
-
});
|
|
1594
|
-
},
|
|
1595
|
-
},
|
|
1596
|
-
map: {
|
|
1597
|
-
async value(iterable, function_) {
|
|
1598
|
-
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
1599
|
-
return Promise.all(promises);
|
|
1600
|
-
},
|
|
1601
|
-
},
|
|
1602
|
-
});
|
|
1603
|
-
|
|
1604
|
-
return generator;
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
function validateConcurrency(concurrency) {
|
|
1608
|
-
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
1609
|
-
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
/**********************************************************************************
|
|
1614
|
-
* Polygon.io calls
|
|
1615
|
-
**********************************************************************************/
|
|
1616
|
-
// Constants from environment variables
|
|
1617
|
-
const POLYGON_API_KEY = process.env.POLYGON_API_KEY;
|
|
1618
|
-
// Define concurrency limits per API
|
|
1619
|
-
const POLYGON_CONCURRENCY_LIMIT = 100;
|
|
1620
|
-
const polygonLimit = pLimit(POLYGON_CONCURRENCY_LIMIT);
|
|
1621
|
-
// Use to update general information about stocks
|
|
1622
|
-
/**
|
|
1623
|
-
* Fetches general information about a stock ticker.
|
|
1624
|
-
* @param {string} symbol - The stock ticker symbol to fetch information for.
|
|
1625
|
-
* @param {Object} [options] - Optional parameters.
|
|
1626
|
-
* @param {string} [options.apiKey] - The API key to use for the request.
|
|
1627
|
-
* @returns {Promise<PolygonTickerInfo | null>} The ticker information or null if not found.
|
|
1628
|
-
*/
|
|
1629
|
-
const fetchTickerInfo = async (symbol, options) => {
|
|
1630
|
-
if (!options?.apiKey && !POLYGON_API_KEY) {
|
|
1631
|
-
throw new Error('Polygon API key is missing');
|
|
1632
|
-
}
|
|
1633
|
-
const baseUrl = `https://api.polygon.io/v3/reference/tickers/${encodeURIComponent(symbol)}`;
|
|
1634
|
-
const params = new URLSearchParams({
|
|
1635
|
-
apiKey: options?.apiKey || POLYGON_API_KEY,
|
|
1636
|
-
});
|
|
1637
|
-
return polygonLimit(async () => {
|
|
1638
|
-
try {
|
|
1639
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
1640
|
-
const data = await response.json();
|
|
1641
|
-
// Check for "NOT_FOUND" status and return null
|
|
1642
|
-
if (data.status === 'NOT_FOUND') {
|
|
1643
|
-
console.warn(`Ticker not found: ${symbol}`);
|
|
1644
|
-
return null;
|
|
1645
|
-
}
|
|
1646
|
-
// Map the results to the required structure
|
|
1647
|
-
const results = data.results;
|
|
1648
|
-
if (!results) {
|
|
1649
|
-
throw new Error('No results in Polygon API response');
|
|
1650
|
-
}
|
|
1651
|
-
// Validate required fields
|
|
1652
|
-
const requiredFields = [
|
|
1653
|
-
'active',
|
|
1654
|
-
'currency_name',
|
|
1655
|
-
'locale',
|
|
1656
|
-
'market',
|
|
1657
|
-
'name',
|
|
1658
|
-
'primary_exchange',
|
|
1659
|
-
'ticker',
|
|
1660
|
-
'type',
|
|
1661
|
-
];
|
|
1662
|
-
for (const field of requiredFields) {
|
|
1663
|
-
if (results[field] === undefined) {
|
|
1664
|
-
throw new Error(`Missing required field in Polygon API response: ${field}`);
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
// Handle optional share_class_shares_outstanding field
|
|
1668
|
-
if (results.share_class_shares_outstanding === undefined) {
|
|
1669
|
-
results.share_class_shares_outstanding = null;
|
|
1670
|
-
}
|
|
1671
|
-
return {
|
|
1672
|
-
ticker: results.ticker,
|
|
1673
|
-
type: results.type,
|
|
1674
|
-
active: results.active,
|
|
1675
|
-
currency_name: results.currency_name,
|
|
1676
|
-
description: results.description ?? 'No description available',
|
|
1677
|
-
locale: results.locale,
|
|
1678
|
-
market: results.market,
|
|
1679
|
-
market_cap: results.market_cap ?? 0,
|
|
1680
|
-
name: results.name,
|
|
1681
|
-
primary_exchange: results.primary_exchange,
|
|
1682
|
-
share_class_shares_outstanding: results.share_class_shares_outstanding,
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
|
-
catch (error) {
|
|
1686
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
1687
|
-
const contextualMessage = `Error fetching ticker info for ${symbol}`;
|
|
1688
|
-
console.error(`${contextualMessage}: ${errorMessage}`, {
|
|
1689
|
-
symbol,
|
|
1690
|
-
errorType: error instanceof Error && error.message.includes('AUTH_ERROR')
|
|
1691
|
-
? 'AUTH_ERROR'
|
|
1692
|
-
: error instanceof Error && error.message.includes('RATE_LIMIT')
|
|
1693
|
-
? 'RATE_LIMIT'
|
|
1694
|
-
: error instanceof Error && error.message.includes('NETWORK_ERROR')
|
|
1695
|
-
? 'NETWORK_ERROR'
|
|
1696
|
-
: 'UNKNOWN',
|
|
1697
|
-
url: hideApiKeyFromurl(`${baseUrl}?${params.toString()}`),
|
|
1698
|
-
source: 'PolygonAPI.fetchTickerInfo',
|
|
1699
|
-
timestamp: new Date().toISOString(),
|
|
1700
|
-
});
|
|
1701
|
-
throw new Error(`${contextualMessage}: ${errorMessage}`);
|
|
1702
|
-
}
|
|
1703
|
-
});
|
|
1704
|
-
};
|
|
1705
|
-
// Fetch last trade using Polygon.io
|
|
1706
|
-
/**
|
|
1707
|
-
* Fetches the last trade for a given stock ticker.
|
|
1708
|
-
* @param {string} symbol - The stock ticker symbol to fetch the last trade for.
|
|
1709
|
-
* @param {Object} [options] - Optional parameters.
|
|
1710
|
-
* @param {string} [options.apiKey] - The API key to use for the request.
|
|
1711
|
-
* @returns {Promise<PolygonQuote>} The last trade information.
|
|
1712
|
-
*/
|
|
1713
|
-
const fetchLastTrade = async (symbol, options) => {
|
|
1714
|
-
if (!options?.apiKey && !POLYGON_API_KEY) {
|
|
1715
|
-
throw new Error('Polygon API key is missing');
|
|
1716
|
-
}
|
|
1717
|
-
const baseUrl = `https://api.polygon.io/v2/last/trade/${encodeURIComponent(symbol)}`;
|
|
1718
|
-
const params = new URLSearchParams({
|
|
1719
|
-
apiKey: options?.apiKey || POLYGON_API_KEY,
|
|
1720
|
-
});
|
|
1721
|
-
return polygonLimit(async () => {
|
|
1722
|
-
try {
|
|
1723
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
1724
|
-
const data = await response.json();
|
|
1725
|
-
if (data.status !== 'OK' || !data.results) {
|
|
1726
|
-
throw new Error(`Polygon.io API error: ${data.status || 'No results'} ${data.error || ''}`);
|
|
1727
|
-
}
|
|
1728
|
-
const { p: price, s: vol, t: timestamp } = data.results;
|
|
1729
|
-
if (typeof price !== 'number' || typeof vol !== 'number' || typeof timestamp !== 'number') {
|
|
1730
|
-
throw new Error('Invalid trade data received from Polygon.io API');
|
|
1731
|
-
}
|
|
1732
|
-
return {
|
|
1733
|
-
price,
|
|
1734
|
-
vol,
|
|
1735
|
-
time: new Date(Math.floor(timestamp / 1000000)), // Convert nanoseconds to milliseconds
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
catch (error) {
|
|
1739
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
1740
|
-
const contextualMessage = `Error fetching last trade for ${symbol}`;
|
|
1741
|
-
console.error(`${contextualMessage}: ${errorMessage}`, {
|
|
1742
|
-
symbol,
|
|
1743
|
-
errorType: error instanceof Error && error.message.includes('AUTH_ERROR')
|
|
1744
|
-
? 'AUTH_ERROR'
|
|
1745
|
-
: error instanceof Error && error.message.includes('RATE_LIMIT')
|
|
1746
|
-
? 'RATE_LIMIT'
|
|
1747
|
-
: error instanceof Error && error.message.includes('NETWORK_ERROR')
|
|
1748
|
-
? 'NETWORK_ERROR'
|
|
1749
|
-
: 'UNKNOWN',
|
|
1750
|
-
url: hideApiKeyFromurl(`${baseUrl}?${params.toString()}`),
|
|
1751
|
-
source: 'PolygonAPI.fetchLastTrade',
|
|
1752
|
-
timestamp: new Date().toISOString(),
|
|
1753
|
-
});
|
|
1754
|
-
throw new Error(`${contextualMessage}: ${errorMessage}`);
|
|
1755
|
-
}
|
|
1756
|
-
});
|
|
1757
|
-
};
|
|
1758
|
-
// use Polygon for all price data fetching
|
|
1759
|
-
/**
|
|
1760
|
-
* Fetches price data for a given stock ticker.
|
|
1761
|
-
* @param {Object} params - The parameters for fetching price data.
|
|
1762
|
-
* @param {string} params.ticker - The stock ticker symbol.
|
|
1763
|
-
* @param {number} params.start - The start timestamp for fetching price data.
|
|
1764
|
-
* @param {number} [params.end] - The end timestamp for fetching price data.
|
|
1765
|
-
* @param {number} params.multiplier - The multiplier for the price data.
|
|
1766
|
-
* @param {string} params.timespan - The timespan for the price data.
|
|
1767
|
-
* @param {number} [params.limit] - The maximum number of price data points to fetch.
|
|
1768
|
-
* @param {Object} [options] - Optional parameters.
|
|
1769
|
-
* @param {string} [options.apiKey] - The API key to use for the request.
|
|
1770
|
-
* @returns {Promise<PolygonPriceData[]>} The fetched price data.
|
|
1771
|
-
*/
|
|
1772
|
-
const fetchPrices = async (params, options) => {
|
|
1773
|
-
if (!options?.apiKey && !POLYGON_API_KEY) {
|
|
1774
|
-
throw new Error('Polygon API key is missing');
|
|
1775
|
-
}
|
|
1776
|
-
const { ticker, start, end = Date.now().valueOf(), multiplier, timespan, limit = 1000 } = params;
|
|
1777
|
-
const baseUrl = `https://api.polygon.io/v2/aggs/ticker/${encodeURIComponent(ticker)}/range/${multiplier}/${timespan}/${start}/${end}`;
|
|
1778
|
-
const urlParams = new URLSearchParams({
|
|
1779
|
-
apiKey: options?.apiKey || POLYGON_API_KEY,
|
|
1780
|
-
adjusted: 'true',
|
|
1781
|
-
sort: 'asc',
|
|
1782
|
-
limit: limit.toString(),
|
|
1783
|
-
});
|
|
1784
|
-
return polygonLimit(async () => {
|
|
1785
|
-
try {
|
|
1786
|
-
let allResults = [];
|
|
1787
|
-
let nextUrl = `${baseUrl}?${urlParams.toString()}`;
|
|
1788
|
-
while (nextUrl) {
|
|
1789
|
-
//console.log(`Debug: Fetching ${nextUrl}`);
|
|
1790
|
-
const response = await fetchWithRetry(nextUrl, {}, 3, 1000);
|
|
1791
|
-
const data = await response.json();
|
|
1792
|
-
if (data.status !== 'OK') {
|
|
1793
|
-
throw new Error(`Polygon.io API responded with status: ${data.status}`);
|
|
1794
|
-
}
|
|
1795
|
-
if (data.results) {
|
|
1796
|
-
allResults = [...allResults, ...data.results];
|
|
1797
|
-
}
|
|
1798
|
-
// Check if there's a next page and append API key
|
|
1799
|
-
nextUrl = data.next_url ? `${data.next_url}&apiKey=${options?.apiKey || POLYGON_API_KEY}` : '';
|
|
1800
|
-
}
|
|
1801
|
-
return allResults.map((entry) => ({
|
|
1802
|
-
date: new Date(entry.t).toLocaleString('en-US', {
|
|
1803
|
-
year: 'numeric',
|
|
1804
|
-
month: 'short',
|
|
1805
|
-
day: '2-digit',
|
|
1806
|
-
hour: '2-digit',
|
|
1807
|
-
minute: '2-digit',
|
|
1808
|
-
second: '2-digit',
|
|
1809
|
-
timeZone: 'America/New_York',
|
|
1810
|
-
timeZoneName: 'short',
|
|
1811
|
-
hourCycle: 'h23',
|
|
1812
|
-
}),
|
|
1813
|
-
timeStamp: entry.t,
|
|
1814
|
-
open: entry.o,
|
|
1815
|
-
high: entry.h,
|
|
1816
|
-
low: entry.l,
|
|
1817
|
-
close: entry.c,
|
|
1818
|
-
vol: entry.v,
|
|
1819
|
-
vwap: entry.vw,
|
|
1820
|
-
trades: entry.n,
|
|
1821
|
-
}));
|
|
1822
|
-
}
|
|
1823
|
-
catch (error) {
|
|
1824
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
1825
|
-
const contextualMessage = `Error fetching price data for ${ticker}`;
|
|
1826
|
-
console.error(`${contextualMessage}: ${errorMessage}`, {
|
|
1827
|
-
ticker,
|
|
1828
|
-
errorType: error instanceof Error && error.message.includes('AUTH_ERROR')
|
|
1829
|
-
? 'AUTH_ERROR'
|
|
1830
|
-
: error instanceof Error && error.message.includes('RATE_LIMIT')
|
|
1831
|
-
? 'RATE_LIMIT'
|
|
1832
|
-
: error instanceof Error && error.message.includes('NETWORK_ERROR')
|
|
1833
|
-
? 'NETWORK_ERROR'
|
|
1834
|
-
: 'UNKNOWN',
|
|
1835
|
-
source: 'PolygonAPI.fetchPrices',
|
|
1836
|
-
timestamp: new Date().toISOString(),
|
|
1837
|
-
});
|
|
1838
|
-
throw new Error(`${contextualMessage}: ${errorMessage}`);
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1841
|
-
};
|
|
1842
|
-
/**
|
|
1843
|
-
* Analyzes the price data for a given stock.
|
|
1844
|
-
* @param {PolygonPriceData[]} priceData - The price data to analyze.
|
|
1845
|
-
* @returns {string} The analysis report.
|
|
1846
|
-
*/
|
|
1847
|
-
function analysePolygonPriceData(priceData) {
|
|
1848
|
-
if (!priceData || priceData.length === 0) {
|
|
1849
|
-
return 'No price data available for analysis.';
|
|
1850
|
-
}
|
|
1851
|
-
// Parse the dates into Date objects
|
|
1852
|
-
const parsedData = priceData.map((entry) => ({
|
|
1853
|
-
...entry,
|
|
1854
|
-
date: new Date(entry.date),
|
|
1855
|
-
}));
|
|
1856
|
-
// Sort the data by date
|
|
1857
|
-
parsedData.sort((a, b) => a.date.getTime() - b.date.getTime());
|
|
1858
|
-
// Extract start and end times
|
|
1859
|
-
const startTime = parsedData[0].date;
|
|
1860
|
-
const endTime = parsedData[parsedData.length - 1].date;
|
|
1861
|
-
// Calculate the total time in hours
|
|
1862
|
-
(endTime.getTime() - startTime.getTime()) / (1000 * 60 * 60);
|
|
1863
|
-
// Calculate the interval between data points
|
|
1864
|
-
const intervals = parsedData
|
|
1865
|
-
.slice(1)
|
|
1866
|
-
.map((_, i) => (parsedData[i + 1].date.getTime() - parsedData[i].date.getTime()) / 1000); // in seconds
|
|
1867
|
-
const avgInterval = intervals.length > 0 ? intervals.reduce((sum, interval) => sum + interval, 0) / intervals.length : 0;
|
|
1868
|
-
// Format the report
|
|
1869
|
-
const report = `
|
|
1870
|
-
Report:
|
|
1871
|
-
* Start time of data (US Eastern): ${startTime.toLocaleString('en-US', { timeZone: 'America/New_York' })}
|
|
1872
|
-
* End time of data (US Eastern): ${endTime.toLocaleString('en-US', { timeZone: 'America/New_York' })}
|
|
1873
|
-
* Number of data points: ${priceData.length}
|
|
1874
|
-
* Average interval between data points (seconds): ${avgInterval.toFixed(2)}
|
|
1875
|
-
`;
|
|
1876
|
-
return report.trim();
|
|
1877
|
-
}
|
|
1878
|
-
/**
|
|
1879
|
-
* Fetches grouped daily price data for a specific date.
|
|
1880
|
-
* @param {string} date - The date to fetch grouped daily data for.
|
|
1881
|
-
* @param {Object} [options] - Optional parameters.
|
|
1882
|
-
* @param {string} [options.apiKey] - The API key to use for the request.
|
|
1883
|
-
* @param {boolean} [options.adjusted] - Whether to adjust the data.
|
|
1884
|
-
* @param {boolean} [options.includeOTC] - Whether to include OTC data.
|
|
1885
|
-
* @returns {Promise<PolygonGroupedDailyResponse>} The grouped daily response.
|
|
1886
|
-
*/
|
|
1887
|
-
const fetchGroupedDaily = async (date, options) => {
|
|
1888
|
-
if (!options?.apiKey && !POLYGON_API_KEY) {
|
|
1889
|
-
throw new Error('Polygon API key is missing');
|
|
1890
|
-
}
|
|
1891
|
-
const baseUrl = `https://api.polygon.io/v2/aggs/grouped/locale/us/market/stocks/${date}`;
|
|
1892
|
-
const params = new URLSearchParams({
|
|
1893
|
-
apiKey: options?.apiKey || POLYGON_API_KEY,
|
|
1894
|
-
adjusted: options?.adjusted !== false ? 'true' : 'false',
|
|
1895
|
-
include_otc: options?.includeOTC ? 'true' : 'false',
|
|
1896
|
-
});
|
|
1897
|
-
return polygonLimit(async () => {
|
|
1898
|
-
try {
|
|
1899
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
1900
|
-
const data = await response.json();
|
|
1901
|
-
if (data.status !== 'OK') {
|
|
1902
|
-
throw new Error(`Polygon.io API responded with status: ${data.status}`);
|
|
1903
|
-
}
|
|
1904
|
-
return {
|
|
1905
|
-
adjusted: data.adjusted,
|
|
1906
|
-
queryCount: data.queryCount,
|
|
1907
|
-
request_id: data.request_id,
|
|
1908
|
-
resultsCount: data.resultsCount,
|
|
1909
|
-
status: data.status,
|
|
1910
|
-
results: data.results.map((result) => ({
|
|
1911
|
-
symbol: result.T,
|
|
1912
|
-
timeStamp: result.t,
|
|
1913
|
-
open: result.o,
|
|
1914
|
-
high: result.h,
|
|
1915
|
-
low: result.l,
|
|
1916
|
-
close: result.c,
|
|
1917
|
-
vol: result.v,
|
|
1918
|
-
vwap: result.vw,
|
|
1919
|
-
trades: result.n,
|
|
1920
|
-
})),
|
|
1921
|
-
};
|
|
1922
|
-
}
|
|
1923
|
-
catch (error) {
|
|
1924
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
1925
|
-
const contextualMessage = `Error fetching grouped daily data for ${date}`;
|
|
1926
|
-
console.error(`${contextualMessage}: ${errorMessage}`, {
|
|
1927
|
-
date,
|
|
1928
|
-
errorType: error instanceof Error && error.message.includes('AUTH_ERROR')
|
|
1929
|
-
? 'AUTH_ERROR'
|
|
1930
|
-
: error instanceof Error && error.message.includes('RATE_LIMIT')
|
|
1931
|
-
? 'RATE_LIMIT'
|
|
1932
|
-
: error instanceof Error && error.message.includes('NETWORK_ERROR')
|
|
1933
|
-
? 'NETWORK_ERROR'
|
|
1934
|
-
: 'UNKNOWN',
|
|
1935
|
-
url: hideApiKeyFromurl(`${baseUrl}?${params.toString()}`),
|
|
1936
|
-
source: 'PolygonAPI.fetchGroupedDaily',
|
|
1937
|
-
timestamp: new Date().toISOString(),
|
|
1938
|
-
});
|
|
1939
|
-
throw new Error(`${contextualMessage}: ${errorMessage}`);
|
|
1940
|
-
}
|
|
1941
|
-
});
|
|
1942
|
-
};
|
|
1943
|
-
/**
|
|
1944
|
-
* Formats the price data into a readable string.
|
|
1945
|
-
* @param {PolygonPriceData[]} priceData - The price data to format.
|
|
1946
|
-
* @returns {string} The formatted price data.
|
|
1947
|
-
*/
|
|
1948
|
-
function formatPriceData(priceData) {
|
|
1949
|
-
if (!priceData || priceData.length === 0)
|
|
1950
|
-
return 'No price data available';
|
|
1951
|
-
return priceData
|
|
1952
|
-
.map((d) => {
|
|
1953
|
-
// For daily data, remove the time portion if it's all zeros
|
|
1954
|
-
const dateStr = d.date.includes(', 00:00:00') ? d.date.split(', 00:00:00')[0] : d.date;
|
|
1955
|
-
return [
|
|
1956
|
-
dateStr,
|
|
1957
|
-
`O: ${formatCurrency(d.open)}`,
|
|
1958
|
-
`H: ${formatCurrency(d.high)}`,
|
|
1959
|
-
`L: ${formatCurrency(d.low)}`,
|
|
1960
|
-
`C: ${formatCurrency(d.close)}`,
|
|
1961
|
-
`Vol: ${d.vol}`,
|
|
1962
|
-
].join(' | ');
|
|
1963
|
-
})
|
|
1964
|
-
.join('\n');
|
|
1965
|
-
}
|
|
1966
|
-
const fetchDailyOpenClose = async (
|
|
1967
|
-
/**
|
|
1968
|
-
* Fetches the daily open and close data for a given stock ticker.
|
|
1969
|
-
* @param {string} symbol - The stock ticker symbol to fetch data for.
|
|
1970
|
-
* @param {Date} [date=new Date()] - The date to fetch data for.
|
|
1971
|
-
* @param {Object} [options] - Optional parameters.
|
|
1972
|
-
* @param {string} [options.apiKey] - The API key to use for the request.
|
|
1973
|
-
* @param {boolean} [options.adjusted] - Whether to adjust the data.
|
|
1974
|
-
* @returns {Promise<PolygonDailyOpenClose>} The daily open and close data.
|
|
1975
|
-
*/
|
|
1976
|
-
symbol, date = new Date(), options) => {
|
|
1977
|
-
if (!options?.apiKey && !POLYGON_API_KEY) {
|
|
1978
|
-
throw new Error('Polygon API key is missing');
|
|
1979
|
-
}
|
|
1980
|
-
const formattedDate = date.toISOString().split('T')[0]; // Format as YYYY-MM-DD
|
|
1981
|
-
const baseUrl = `https://api.polygon.io/v1/open-close/${encodeURIComponent(symbol)}/${formattedDate}`;
|
|
1982
|
-
const params = new URLSearchParams({
|
|
1983
|
-
apiKey: options?.apiKey || POLYGON_API_KEY,
|
|
1984
|
-
adjusted: (options?.adjusted ?? true).toString(),
|
|
1985
|
-
});
|
|
1986
|
-
return polygonLimit(async () => {
|
|
1987
|
-
const response = await fetchWithRetry(`${baseUrl}?${params.toString()}`, {}, 3, 1000);
|
|
1988
|
-
const data = await response.json();
|
|
1989
|
-
if (data.status !== 'OK') {
|
|
1990
|
-
throw new Error(`Failed to fetch daily open/close data for ${symbol}: ${data.status}`);
|
|
1991
|
-
}
|
|
1992
|
-
return data;
|
|
1993
|
-
});
|
|
1994
|
-
};
|
|
1995
|
-
/**
|
|
1996
|
-
* Gets the previous close price for a given stock ticker.
|
|
1997
|
-
* @param {string} symbol - The stock ticker symbol to fetch the previous close for.
|
|
1998
|
-
* @param {Date} [referenceDate] - The reference date to use for fetching the previous close.
|
|
1999
|
-
* @returns {Promise<{ close: number; date: Date }>} The previous close price and date.
|
|
2000
|
-
*/
|
|
2001
|
-
async function getPreviousClose(symbol, referenceDate, options) {
|
|
2002
|
-
const previousDate = getLastFullTradingDate(referenceDate);
|
|
2003
|
-
const lastOpenClose = await fetchDailyOpenClose(symbol, previousDate, options);
|
|
2004
|
-
if (!lastOpenClose) {
|
|
2005
|
-
throw new Error(`Could not fetch last trade price for ${symbol}`);
|
|
2006
|
-
}
|
|
2007
|
-
return {
|
|
2008
|
-
close: lastOpenClose.close,
|
|
2009
|
-
date: previousDate,
|
|
2010
|
-
};
|
|
2011
|
-
}
|
|
2012
|
-
/**
|
|
2013
|
-
* Fetches trade data for a given stock ticker.
|
|
2014
|
-
* @param {string} symbol - The stock ticker symbol to fetch trades for.
|
|
2015
|
-
* @param {Object} [options] - Optional parameters.
|
|
2016
|
-
* @param {string} [options.apiKey] - The API key to use for the request.
|
|
2017
|
-
* @param {string | number} [options.timestamp] - The timestamp for fetching trades.
|
|
2018
|
-
* @param {string | number} [options.timestampgt] - Greater than timestamp for fetching trades.
|
|
2019
|
-
* @param {string | number} [options.timestampgte] - Greater than or equal to timestamp for fetching trades.
|
|
2020
|
-
* @param {string | number} [options.timestamplt] - Less than timestamp for fetching trades.
|
|
2021
|
-
* @param {string | number} [options.timestamplte] - Less than or equal to timestamp for fetching trades.
|
|
2022
|
-
* @param {'asc' | 'desc'} [options.order] - The order of the trades.
|
|
2023
|
-
* @param {number} [options.limit] - The maximum number of trades to fetch.
|
|
2024
|
-
* @param {string} [options.sort] - The sort order for the trades.
|
|
2025
|
-
* @returns {Promise<PolygonTradesResponse>} The fetched trades response.
|
|
2026
|
-
*/
|
|
2027
|
-
const fetchTrades = async (symbol, options) => {
|
|
2028
|
-
if (!options?.apiKey && !POLYGON_API_KEY) {
|
|
2029
|
-
throw new Error('Polygon API key is missing');
|
|
2030
|
-
}
|
|
2031
|
-
const baseUrl = `https://api.polygon.io/v3/trades/${encodeURIComponent(symbol)}`;
|
|
2032
|
-
const params = new URLSearchParams({
|
|
2033
|
-
apiKey: options?.apiKey || POLYGON_API_KEY,
|
|
2034
|
-
});
|
|
2035
|
-
// Add optional parameters if they exist
|
|
2036
|
-
if (options?.timestamp)
|
|
2037
|
-
params.append('timestamp', options.timestamp.toString());
|
|
2038
|
-
if (options?.timestampgt)
|
|
2039
|
-
params.append('timestamp.gt', options.timestampgt.toString());
|
|
2040
|
-
if (options?.timestampgte)
|
|
2041
|
-
params.append('timestamp.gte', options.timestampgte.toString());
|
|
2042
|
-
if (options?.timestamplt)
|
|
2043
|
-
params.append('timestamp.lt', options.timestamplt.toString());
|
|
2044
|
-
if (options?.timestamplte)
|
|
2045
|
-
params.append('timestamp.lte', options.timestamplte.toString());
|
|
2046
|
-
if (options?.order)
|
|
2047
|
-
params.append('order', options.order);
|
|
2048
|
-
if (options?.limit)
|
|
2049
|
-
params.append('limit', options.limit.toString());
|
|
2050
|
-
if (options?.sort)
|
|
2051
|
-
params.append('sort', options.sort);
|
|
2052
|
-
return polygonLimit(async () => {
|
|
2053
|
-
const url = `${baseUrl}?${params.toString()}`;
|
|
2054
|
-
try {
|
|
2055
|
-
console.log(`[DEBUG] Fetching trades for ${symbol} from ${url}`);
|
|
2056
|
-
const response = await fetchWithRetry(url, {}, 3, 1000);
|
|
2057
|
-
const data = (await response.json());
|
|
2058
|
-
if ('message' in data) {
|
|
2059
|
-
// This is an error response
|
|
2060
|
-
throw new Error(`Polygon API Error: ${data.message}`);
|
|
2061
|
-
}
|
|
2062
|
-
return data;
|
|
2063
|
-
}
|
|
2064
|
-
catch (error) {
|
|
2065
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
2066
|
-
const contextualMessage = `Error fetching trades for ${symbol}`;
|
|
2067
|
-
console.error(`${contextualMessage}: ${errorMessage}`, {
|
|
2068
|
-
symbol,
|
|
2069
|
-
errorType: error instanceof Error && error.message.includes('AUTH_ERROR')
|
|
2070
|
-
? 'AUTH_ERROR'
|
|
2071
|
-
: error instanceof Error && error.message.includes('RATE_LIMIT')
|
|
2072
|
-
? 'RATE_LIMIT'
|
|
2073
|
-
: error instanceof Error && error.message.includes('NETWORK_ERROR')
|
|
2074
|
-
? 'NETWORK_ERROR'
|
|
2075
|
-
: 'UNKNOWN',
|
|
2076
|
-
url: hideApiKeyFromurl(url),
|
|
2077
|
-
source: 'PolygonAPI.fetchTrades',
|
|
2078
|
-
timestamp: new Date().toISOString(),
|
|
2079
|
-
});
|
|
2080
|
-
throw new Error(`${contextualMessage}: ${errorMessage}`);
|
|
2081
|
-
}
|
|
2082
|
-
});
|
|
2083
|
-
};
|
|
2084
|
-
|
|
2085
|
-
/**
|
|
2086
|
-
* Polygon Indices API Implementation
|
|
2087
|
-
*
|
|
2088
|
-
* This module provides functions to interact with the Polygon.io Indices API.
|
|
2089
|
-
*/
|
|
2090
|
-
// Constants from environment variables
|
|
2091
|
-
const { ALPACA_INDICES_API_KEY } = process.env;
|
|
2092
|
-
// Define concurrency limits for API
|
|
2093
|
-
const POLYGON_INDICES_CONCURRENCY_LIMIT = 5;
|
|
2094
|
-
const polygonIndicesLimit = pLimit(POLYGON_INDICES_CONCURRENCY_LIMIT);
|
|
2095
|
-
// Base URL for Polygon API
|
|
2096
|
-
const POLYGON_API_BASE_URL = 'https://api.polygon.io';
|
|
2097
|
-
/**
|
|
2098
|
-
* Validates that an API key is available
|
|
2099
|
-
* @param {string | undefined} apiKey - Optional API key to use
|
|
2100
|
-
* @throws {Error} If no API key is available
|
|
2101
|
-
*/
|
|
2102
|
-
const validateApiKey = (apiKey) => {
|
|
2103
|
-
const key = apiKey || ALPACA_INDICES_API_KEY;
|
|
2104
|
-
if (!key) {
|
|
2105
|
-
throw new Error('Polygon Indices API key is missing');
|
|
2106
|
-
}
|
|
2107
|
-
return key;
|
|
2108
|
-
};
|
|
2109
|
-
/**
|
|
2110
|
-
* Fetches aggregate bars for an index over a given date range in custom time window sizes.
|
|
2111
|
-
*
|
|
2112
|
-
* @param {PolygonIndicesAggregatesParams} params - Parameters for the aggregates request
|
|
2113
|
-
* @param {Object} [options] - Optional parameters
|
|
2114
|
-
* @param {string} [options.apiKey] - API key to use for the request
|
|
2115
|
-
* @returns {Promise<PolygonIndicesAggregatesResponse>} The aggregates response
|
|
2116
|
-
*/
|
|
2117
|
-
const fetchIndicesAggregates = async (params, options) => {
|
|
2118
|
-
const apiKey = validateApiKey(options?.apiKey);
|
|
2119
|
-
const { indicesTicker, multiplier, timespan, from, to, sort = 'asc', limit } = params;
|
|
2120
|
-
const url = new URL(`${POLYGON_API_BASE_URL}/v2/aggs/ticker/${encodeURIComponent(indicesTicker)}/range/${multiplier}/${timespan}/${from}/${to}`);
|
|
2121
|
-
const queryParams = new URLSearchParams();
|
|
2122
|
-
queryParams.append('apiKey', apiKey);
|
|
2123
|
-
if (sort) {
|
|
2124
|
-
queryParams.append('sort', sort);
|
|
2125
|
-
}
|
|
2126
|
-
if (limit) {
|
|
2127
|
-
queryParams.append('limit', limit.toString());
|
|
2128
|
-
}
|
|
2129
|
-
url.search = queryParams.toString();
|
|
2130
|
-
return polygonIndicesLimit(async () => {
|
|
2131
|
-
try {
|
|
2132
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
2133
|
-
const data = await response.json();
|
|
2134
|
-
if (data.status === 'ERROR') {
|
|
2135
|
-
throw new Error(`Polygon API Error: ${data.error}`);
|
|
2136
|
-
}
|
|
2137
|
-
return data;
|
|
2138
|
-
}
|
|
2139
|
-
catch (error) {
|
|
2140
|
-
console.error('Error fetching indices aggregates:', error);
|
|
2141
|
-
throw error;
|
|
2142
|
-
}
|
|
2143
|
-
});
|
|
2144
|
-
};
|
|
2145
|
-
/**
|
|
2146
|
-
* Gets the previous day's open, high, low, and close (OHLC) for the specified index.
|
|
2147
|
-
*
|
|
2148
|
-
* @param {string} indicesTicker - The ticker symbol of the index
|
|
2149
|
-
* @param {Object} [options] - Optional parameters
|
|
2150
|
-
* @param {string} [options.apiKey] - API key to use for the request
|
|
2151
|
-
* @returns {Promise<PolygonIndicesPrevCloseResponse>} The previous close response
|
|
2152
|
-
*/
|
|
2153
|
-
const fetchIndicesPreviousClose = async (indicesTicker, options) => {
|
|
2154
|
-
const apiKey = validateApiKey(options?.apiKey);
|
|
2155
|
-
const url = new URL(`${POLYGON_API_BASE_URL}/v2/aggs/ticker/${encodeURIComponent(indicesTicker)}/prev`);
|
|
2156
|
-
const queryParams = new URLSearchParams();
|
|
2157
|
-
queryParams.append('apiKey', apiKey);
|
|
2158
|
-
url.search = queryParams.toString();
|
|
2159
|
-
return polygonIndicesLimit(async () => {
|
|
2160
|
-
try {
|
|
2161
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
2162
|
-
const data = await response.json();
|
|
2163
|
-
if (data.status === 'ERROR') {
|
|
2164
|
-
throw new Error(`Polygon API Error: ${data.error}`);
|
|
2165
|
-
}
|
|
2166
|
-
return data;
|
|
2167
|
-
}
|
|
2168
|
-
catch (error) {
|
|
2169
|
-
console.error('Error fetching indices previous close:', error);
|
|
2170
|
-
throw error;
|
|
2171
|
-
}
|
|
2172
|
-
});
|
|
2173
|
-
};
|
|
2174
|
-
/**
|
|
2175
|
-
* Gets the open, close and afterhours values of an index symbol on a certain date.
|
|
2176
|
-
*
|
|
2177
|
-
* @param {string} indicesTicker - The ticker symbol of the index
|
|
2178
|
-
* @param {string} date - The date in YYYY-MM-DD format
|
|
2179
|
-
* @param {Object} [options] - Optional parameters
|
|
2180
|
-
* @param {string} [options.apiKey] - API key to use for the request
|
|
2181
|
-
* @returns {Promise<PolygonIndicesDailyOpenCloseResponse>} The daily open/close response
|
|
2182
|
-
*/
|
|
2183
|
-
const fetchIndicesDailyOpenClose = async (indicesTicker, date, options) => {
|
|
2184
|
-
const apiKey = validateApiKey(options?.apiKey);
|
|
2185
|
-
const url = new URL(`${POLYGON_API_BASE_URL}/v1/open-close/${encodeURIComponent(indicesTicker)}/${date}`);
|
|
2186
|
-
const queryParams = new URLSearchParams();
|
|
2187
|
-
queryParams.append('apiKey', apiKey);
|
|
2188
|
-
url.search = queryParams.toString();
|
|
2189
|
-
return polygonIndicesLimit(async () => {
|
|
2190
|
-
try {
|
|
2191
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
2192
|
-
const data = await response.json();
|
|
2193
|
-
if (data.status === 'ERROR') {
|
|
2194
|
-
throw new Error(`Polygon API Error: ${data.error}`);
|
|
2195
|
-
}
|
|
2196
|
-
return data;
|
|
2197
|
-
}
|
|
2198
|
-
catch (error) {
|
|
2199
|
-
console.error('Error fetching indices daily open/close:', error);
|
|
2200
|
-
throw error;
|
|
2201
|
-
}
|
|
2202
|
-
});
|
|
2203
|
-
};
|
|
2204
|
-
/**
|
|
2205
|
-
* Gets a snapshot of indices data for specified tickers.
|
|
2206
|
-
*
|
|
2207
|
-
* @param {PolygonIndicesSnapshotParams} [params] - Parameters for the snapshot request
|
|
2208
|
-
* @param {Object} [options] - Optional parameters
|
|
2209
|
-
* @param {string} [options.apiKey] - API key to use for the request
|
|
2210
|
-
* @returns {Promise<PolygonIndicesSnapshotResponse>} The indices snapshot response
|
|
2211
|
-
*/
|
|
2212
|
-
const fetchIndicesSnapshot = async (params, options) => {
|
|
2213
|
-
const apiKey = validateApiKey(options?.apiKey);
|
|
2214
|
-
const url = new URL(`${POLYGON_API_BASE_URL}/v3/snapshot/indices`);
|
|
2215
|
-
const queryParams = new URLSearchParams();
|
|
2216
|
-
queryParams.append('apiKey', apiKey);
|
|
2217
|
-
if (params?.tickers?.length) {
|
|
2218
|
-
queryParams.append('ticker.any_of', params.tickers.join(','));
|
|
2219
|
-
}
|
|
2220
|
-
if (params?.order) {
|
|
2221
|
-
queryParams.append('order', params.order);
|
|
2222
|
-
}
|
|
2223
|
-
if (params?.limit) {
|
|
2224
|
-
queryParams.append('limit', params.limit.toString());
|
|
2225
|
-
}
|
|
2226
|
-
if (params?.sort) {
|
|
2227
|
-
queryParams.append('sort', params.sort);
|
|
2228
|
-
}
|
|
2229
|
-
url.search = queryParams.toString();
|
|
2230
|
-
return polygonIndicesLimit(async () => {
|
|
2231
|
-
try {
|
|
2232
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
2233
|
-
const data = await response.json();
|
|
2234
|
-
if (data.status === 'ERROR') {
|
|
2235
|
-
throw new Error(`Polygon API Error: ${data.error}`);
|
|
2236
|
-
}
|
|
2237
|
-
return data;
|
|
2238
|
-
}
|
|
2239
|
-
catch (error) {
|
|
2240
|
-
console.error('Error fetching indices snapshot:', error);
|
|
2241
|
-
throw error;
|
|
2242
|
-
}
|
|
2243
|
-
});
|
|
2244
|
-
};
|
|
2245
|
-
/**
|
|
2246
|
-
* Gets snapshots for assets of all types, including indices.
|
|
2247
|
-
*
|
|
2248
|
-
* @param {string[]} tickers - Array of tickers to fetch snapshots for
|
|
2249
|
-
* @param {Object} [options] - Optional parameters
|
|
2250
|
-
* @param {string} [options.apiKey] - API key to use for the request
|
|
2251
|
-
* @param {string} [options.type] - Filter by asset type
|
|
2252
|
-
* @param {string} [options.order] - Order results
|
|
2253
|
-
* @param {number} [options.limit] - Limit the number of results
|
|
2254
|
-
* @param {string} [options.sort] - Sort field
|
|
2255
|
-
* @returns {Promise<any>} The universal snapshot response
|
|
2256
|
-
*/
|
|
2257
|
-
const fetchUniversalSnapshot = async (tickers, options) => {
|
|
2258
|
-
const apiKey = validateApiKey(options?.apiKey);
|
|
2259
|
-
const url = new URL(`${POLYGON_API_BASE_URL}/v3/snapshot`);
|
|
2260
|
-
const queryParams = new URLSearchParams();
|
|
2261
|
-
queryParams.append('apiKey', apiKey);
|
|
2262
|
-
if (tickers.length) {
|
|
2263
|
-
queryParams.append('ticker.any_of', tickers.join(','));
|
|
2264
|
-
}
|
|
2265
|
-
if (options?.type) {
|
|
2266
|
-
queryParams.append('type', options.type);
|
|
2267
|
-
}
|
|
2268
|
-
if (options?.order) {
|
|
2269
|
-
queryParams.append('order', options.order);
|
|
2270
|
-
}
|
|
2271
|
-
if (options?.limit) {
|
|
2272
|
-
queryParams.append('limit', options.limit.toString());
|
|
2273
|
-
}
|
|
2274
|
-
if (options?.sort) {
|
|
2275
|
-
queryParams.append('sort', options.sort);
|
|
2276
|
-
}
|
|
2277
|
-
url.search = queryParams.toString();
|
|
2278
|
-
return polygonIndicesLimit(async () => {
|
|
2279
|
-
try {
|
|
2280
|
-
const response = await fetchWithRetry(url.toString(), {}, 3, 300);
|
|
2281
|
-
const data = await response.json();
|
|
2282
|
-
if (data.status === 'ERROR') {
|
|
2283
|
-
throw new Error(`Polygon API Error: ${data.error}`);
|
|
2284
|
-
}
|
|
2285
|
-
return data;
|
|
2286
|
-
}
|
|
2287
|
-
catch (error) {
|
|
2288
|
-
console.error('Error fetching universal snapshot:', error);
|
|
2289
|
-
throw error;
|
|
2290
|
-
}
|
|
2291
|
-
});
|
|
2292
|
-
};
|
|
2293
|
-
/**
|
|
2294
|
-
* Converts Polygon Indices bar data to a more standardized format
|
|
2295
|
-
*
|
|
2296
|
-
* @param {PolygonIndicesAggregatesResponse} data - The raw aggregates response
|
|
2297
|
-
* @returns {Array<{date: string, open: number, high: number, low: number, close: number, timestamp: number}>} Formatted bar data
|
|
2298
|
-
*/
|
|
2299
|
-
const formatIndicesBarData = (data) => {
|
|
2300
|
-
return data.results.map((bar) => {
|
|
2301
|
-
const date = new Date(bar.t);
|
|
2302
|
-
return {
|
|
2303
|
-
date: date.toISOString().split('T')[0],
|
|
2304
|
-
open: bar.o,
|
|
2305
|
-
high: bar.h,
|
|
2306
|
-
low: bar.l,
|
|
2307
|
-
close: bar.c,
|
|
2308
|
-
timestamp: bar.t,
|
|
2309
|
-
};
|
|
2310
|
-
});
|
|
2311
|
-
};
|
|
2312
1385
|
|
|
2313
1386
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
2314
1387
|
if (typeof state === "function" ? receiver !== state || true : !state.has(receiver))
|
|
@@ -2541,7 +1614,7 @@ const safeJSON = (text) => {
|
|
|
2541
1614
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2542
1615
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2543
1616
|
|
|
2544
|
-
const VERSION = '6.
|
|
1617
|
+
const VERSION = '6.27.0'; // x-release-please-version
|
|
2545
1618
|
|
|
2546
1619
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2547
1620
|
const isRunningInBrowser = () => {
|
|
@@ -3161,6 +2234,11 @@ function stringify(object, opts = {}) {
|
|
|
3161
2234
|
return joined.length > 0 ? prefix + joined : '';
|
|
3162
2235
|
}
|
|
3163
2236
|
|
|
2237
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2238
|
+
function stringifyQuery(query) {
|
|
2239
|
+
return stringify(query, { arrayFormat: 'brackets' });
|
|
2240
|
+
}
|
|
2241
|
+
|
|
3164
2242
|
function concatBytes(buffers) {
|
|
3165
2243
|
let length = 0;
|
|
3166
2244
|
for (const buffer of buffers) {
|
|
@@ -3379,7 +2457,7 @@ class Stream {
|
|
|
3379
2457
|
this.controller = controller;
|
|
3380
2458
|
__classPrivateFieldSet(this, _Stream_client, client);
|
|
3381
2459
|
}
|
|
3382
|
-
static fromSSEResponse(response, controller, client) {
|
|
2460
|
+
static fromSSEResponse(response, controller, client, synthesizeEventData) {
|
|
3383
2461
|
let consumed = false;
|
|
3384
2462
|
const logger = client ? loggerFor(client) : console;
|
|
3385
2463
|
async function* iterator() {
|
|
@@ -3409,7 +2487,7 @@ class Stream {
|
|
|
3409
2487
|
if (data && data.error) {
|
|
3410
2488
|
throw new APIError(undefined, data.error, undefined, response.headers);
|
|
3411
2489
|
}
|
|
3412
|
-
yield data;
|
|
2490
|
+
yield synthesizeEventData ? { event: sse.event, data } : data;
|
|
3413
2491
|
}
|
|
3414
2492
|
else {
|
|
3415
2493
|
let data;
|
|
@@ -3659,9 +2737,9 @@ async function defaultParseResponse(client, props) {
|
|
|
3659
2737
|
// Note: there is an invariant here that isn't represented in the type system
|
|
3660
2738
|
// that if you set `stream: true` the response type must also be `Stream<T>`
|
|
3661
2739
|
if (props.options.__streamClass) {
|
|
3662
|
-
return props.options.__streamClass.fromSSEResponse(response, props.controller, client);
|
|
2740
|
+
return props.options.__streamClass.fromSSEResponse(response, props.controller, client, props.options.__synthesizeEventData);
|
|
3663
2741
|
}
|
|
3664
|
-
return Stream.fromSSEResponse(response, props.controller, client);
|
|
2742
|
+
return Stream.fromSSEResponse(response, props.controller, client, props.options.__synthesizeEventData);
|
|
3665
2743
|
}
|
|
3666
2744
|
// fetch refuses to read the body when the status code is 204.
|
|
3667
2745
|
if (response.status === 204) {
|
|
@@ -4214,6 +3292,9 @@ const createPathTagFunction = (pathEncoder = encodeURIPath) => function path(sta
|
|
|
4214
3292
|
const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
|
|
4215
3293
|
|
|
4216
3294
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
3295
|
+
/**
|
|
3296
|
+
* Given a list of messages comprising a conversation, the model will return a response.
|
|
3297
|
+
*/
|
|
4217
3298
|
let Messages$1 = class Messages extends APIResource {
|
|
4218
3299
|
/**
|
|
4219
3300
|
* Get the messages in a stored chat completion. Only Chat Completions that have
|
|
@@ -5576,6 +4657,9 @@ class ChatCompletionStreamingRunner extends ChatCompletionStream {
|
|
|
5576
4657
|
}
|
|
5577
4658
|
|
|
5578
4659
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4660
|
+
/**
|
|
4661
|
+
* Given a list of messages comprising a conversation, the model will return a response.
|
|
4662
|
+
*/
|
|
5579
4663
|
let Completions$1 = class Completions extends APIResource {
|
|
5580
4664
|
constructor() {
|
|
5581
4665
|
super(...arguments);
|
|
@@ -5746,10 +4830,15 @@ const buildHeaders = (newHeaders) => {
|
|
|
5746
4830
|
};
|
|
5747
4831
|
|
|
5748
4832
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4833
|
+
/**
|
|
4834
|
+
* Turn audio into text or text into audio.
|
|
4835
|
+
*/
|
|
5749
4836
|
class Speech extends APIResource {
|
|
5750
4837
|
/**
|
|
5751
4838
|
* Generates audio from the input text.
|
|
5752
4839
|
*
|
|
4840
|
+
* Returns the audio file content, or a stream of audio events.
|
|
4841
|
+
*
|
|
5753
4842
|
* @example
|
|
5754
4843
|
* ```ts
|
|
5755
4844
|
* const speech = await client.audio.speech.create({
|
|
@@ -5773,6 +4862,9 @@ class Speech extends APIResource {
|
|
|
5773
4862
|
}
|
|
5774
4863
|
|
|
5775
4864
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4865
|
+
/**
|
|
4866
|
+
* Turn audio into text or text into audio.
|
|
4867
|
+
*/
|
|
5776
4868
|
class Transcriptions extends APIResource {
|
|
5777
4869
|
create(body, options) {
|
|
5778
4870
|
return this._client.post('/audio/transcriptions', multipartFormRequestOptions({
|
|
@@ -5785,6 +4877,9 @@ class Transcriptions extends APIResource {
|
|
|
5785
4877
|
}
|
|
5786
4878
|
|
|
5787
4879
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4880
|
+
/**
|
|
4881
|
+
* Turn audio into text or text into audio.
|
|
4882
|
+
*/
|
|
5788
4883
|
class Translations extends APIResource {
|
|
5789
4884
|
create(body, options) {
|
|
5790
4885
|
return this._client.post('/audio/translations', multipartFormRequestOptions({ body, ...options, __metadata: { model: body.model } }, this._client));
|
|
@@ -5805,6 +4900,9 @@ Audio.Translations = Translations;
|
|
|
5805
4900
|
Audio.Speech = Speech;
|
|
5806
4901
|
|
|
5807
4902
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4903
|
+
/**
|
|
4904
|
+
* Create large batches of API requests to run asynchronously.
|
|
4905
|
+
*/
|
|
5808
4906
|
class Batches extends APIResource {
|
|
5809
4907
|
/**
|
|
5810
4908
|
* Creates and executes a batch from an uploaded file of requests
|
|
@@ -5835,6 +4933,9 @@ class Batches extends APIResource {
|
|
|
5835
4933
|
}
|
|
5836
4934
|
|
|
5837
4935
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4936
|
+
/**
|
|
4937
|
+
* Build Assistants that can call models and use tools.
|
|
4938
|
+
*/
|
|
5838
4939
|
class Assistants extends APIResource {
|
|
5839
4940
|
/**
|
|
5840
4941
|
* Create an assistant with a model and instructions.
|
|
@@ -5965,7 +5066,7 @@ Realtime$1.TranscriptionSessions = TranscriptionSessions;
|
|
|
5965
5066
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
5966
5067
|
class Sessions extends APIResource {
|
|
5967
5068
|
/**
|
|
5968
|
-
* Create a ChatKit session
|
|
5069
|
+
* Create a ChatKit session.
|
|
5969
5070
|
*
|
|
5970
5071
|
* @example
|
|
5971
5072
|
* ```ts
|
|
@@ -5984,7 +5085,9 @@ class Sessions extends APIResource {
|
|
|
5984
5085
|
});
|
|
5985
5086
|
}
|
|
5986
5087
|
/**
|
|
5987
|
-
* Cancel
|
|
5088
|
+
* Cancel an active ChatKit session and return its most recent metadata.
|
|
5089
|
+
*
|
|
5090
|
+
* Cancelling prevents new requests from using the issued client secret.
|
|
5988
5091
|
*
|
|
5989
5092
|
* @example
|
|
5990
5093
|
* ```ts
|
|
@@ -6003,7 +5106,7 @@ class Sessions extends APIResource {
|
|
|
6003
5106
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6004
5107
|
let Threads$1 = class Threads extends APIResource {
|
|
6005
5108
|
/**
|
|
6006
|
-
* Retrieve a ChatKit thread
|
|
5109
|
+
* Retrieve a ChatKit thread by its identifier.
|
|
6007
5110
|
*
|
|
6008
5111
|
* @example
|
|
6009
5112
|
* ```ts
|
|
@@ -6018,7 +5121,7 @@ let Threads$1 = class Threads extends APIResource {
|
|
|
6018
5121
|
});
|
|
6019
5122
|
}
|
|
6020
5123
|
/**
|
|
6021
|
-
* List ChatKit threads
|
|
5124
|
+
* List ChatKit threads with optional pagination and user filters.
|
|
6022
5125
|
*
|
|
6023
5126
|
* @example
|
|
6024
5127
|
* ```ts
|
|
@@ -6036,7 +5139,7 @@ let Threads$1 = class Threads extends APIResource {
|
|
|
6036
5139
|
});
|
|
6037
5140
|
}
|
|
6038
5141
|
/**
|
|
6039
|
-
* Delete a ChatKit thread
|
|
5142
|
+
* Delete a ChatKit thread along with its items and stored attachments.
|
|
6040
5143
|
*
|
|
6041
5144
|
* @example
|
|
6042
5145
|
* ```ts
|
|
@@ -6052,7 +5155,7 @@ let Threads$1 = class Threads extends APIResource {
|
|
|
6052
5155
|
});
|
|
6053
5156
|
}
|
|
6054
5157
|
/**
|
|
6055
|
-
* List ChatKit thread
|
|
5158
|
+
* List items that belong to a ChatKit thread.
|
|
6056
5159
|
*
|
|
6057
5160
|
* @example
|
|
6058
5161
|
* ```ts
|
|
@@ -6082,6 +5185,8 @@ ChatKit.Threads = Threads$1;
|
|
|
6082
5185
|
|
|
6083
5186
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6084
5187
|
/**
|
|
5188
|
+
* Build Assistants that can call models and use tools.
|
|
5189
|
+
*
|
|
6085
5190
|
* @deprecated The Assistants API is deprecated in favor of the Responses API
|
|
6086
5191
|
*/
|
|
6087
5192
|
class Messages extends APIResource {
|
|
@@ -6150,6 +5255,8 @@ class Messages extends APIResource {
|
|
|
6150
5255
|
|
|
6151
5256
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6152
5257
|
/**
|
|
5258
|
+
* Build Assistants that can call models and use tools.
|
|
5259
|
+
*
|
|
6153
5260
|
* @deprecated The Assistants API is deprecated in favor of the Responses API
|
|
6154
5261
|
*/
|
|
6155
5262
|
class Steps extends APIResource {
|
|
@@ -6762,6 +5869,8 @@ _a$1 = AssistantStream, _AssistantStream_addEvent = function _AssistantStream_ad
|
|
|
6762
5869
|
|
|
6763
5870
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6764
5871
|
/**
|
|
5872
|
+
* Build Assistants that can call models and use tools.
|
|
5873
|
+
*
|
|
6765
5874
|
* @deprecated The Assistants API is deprecated in favor of the Responses API
|
|
6766
5875
|
*/
|
|
6767
5876
|
let Runs$1 = class Runs extends APIResource {
|
|
@@ -6777,6 +5886,7 @@ let Runs$1 = class Runs extends APIResource {
|
|
|
6777
5886
|
...options,
|
|
6778
5887
|
headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
|
|
6779
5888
|
stream: params.stream ?? false,
|
|
5889
|
+
__synthesizeEventData: true,
|
|
6780
5890
|
});
|
|
6781
5891
|
}
|
|
6782
5892
|
/**
|
|
@@ -6907,6 +6017,7 @@ let Runs$1 = class Runs extends APIResource {
|
|
|
6907
6017
|
...options,
|
|
6908
6018
|
headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
|
|
6909
6019
|
stream: params.stream ?? false,
|
|
6020
|
+
__synthesizeEventData: true,
|
|
6910
6021
|
});
|
|
6911
6022
|
}
|
|
6912
6023
|
/**
|
|
@@ -6931,6 +6042,8 @@ Runs$1.Steps = Steps;
|
|
|
6931
6042
|
|
|
6932
6043
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6933
6044
|
/**
|
|
6045
|
+
* Build Assistants that can call models and use tools.
|
|
6046
|
+
*
|
|
6934
6047
|
* @deprecated The Assistants API is deprecated in favor of the Responses API
|
|
6935
6048
|
*/
|
|
6936
6049
|
class Threads extends APIResource {
|
|
@@ -6991,6 +6104,7 @@ class Threads extends APIResource {
|
|
|
6991
6104
|
...options,
|
|
6992
6105
|
headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
|
|
6993
6106
|
stream: body.stream ?? false,
|
|
6107
|
+
__synthesizeEventData: true,
|
|
6994
6108
|
});
|
|
6995
6109
|
}
|
|
6996
6110
|
/**
|
|
@@ -7028,6 +6142,9 @@ Beta.Assistants = Assistants;
|
|
|
7028
6142
|
Beta.Threads = Threads;
|
|
7029
6143
|
|
|
7030
6144
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6145
|
+
/**
|
|
6146
|
+
* Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
|
|
6147
|
+
*/
|
|
7031
6148
|
class Completions extends APIResource {
|
|
7032
6149
|
create(body, options) {
|
|
7033
6150
|
return this._client.post('/completions', { body, ...options, stream: body.stream ?? false });
|
|
@@ -7130,6 +6247,9 @@ class Containers extends APIResource {
|
|
|
7130
6247
|
Containers.Files = Files$2;
|
|
7131
6248
|
|
|
7132
6249
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6250
|
+
/**
|
|
6251
|
+
* Manage conversations and conversation items.
|
|
6252
|
+
*/
|
|
7133
6253
|
class Items extends APIResource {
|
|
7134
6254
|
/**
|
|
7135
6255
|
* Create items in a conversation with the given ID.
|
|
@@ -7165,6 +6285,9 @@ class Items extends APIResource {
|
|
|
7165
6285
|
}
|
|
7166
6286
|
|
|
7167
6287
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6288
|
+
/**
|
|
6289
|
+
* Manage conversations and conversation items.
|
|
6290
|
+
*/
|
|
7168
6291
|
class Conversations extends APIResource {
|
|
7169
6292
|
constructor() {
|
|
7170
6293
|
super(...arguments);
|
|
@@ -7198,6 +6321,9 @@ class Conversations extends APIResource {
|
|
|
7198
6321
|
Conversations.Items = Items;
|
|
7199
6322
|
|
|
7200
6323
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6324
|
+
/**
|
|
6325
|
+
* Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.
|
|
6326
|
+
*/
|
|
7201
6327
|
class Embeddings extends APIResource {
|
|
7202
6328
|
/**
|
|
7203
6329
|
* Creates an embedding vector representing the input text.
|
|
@@ -7248,6 +6374,9 @@ class Embeddings extends APIResource {
|
|
|
7248
6374
|
}
|
|
7249
6375
|
|
|
7250
6376
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6377
|
+
/**
|
|
6378
|
+
* Manage and run evals in the OpenAI platform.
|
|
6379
|
+
*/
|
|
7251
6380
|
class OutputItems extends APIResource {
|
|
7252
6381
|
/**
|
|
7253
6382
|
* Get an evaluation run output item by ID.
|
|
@@ -7266,6 +6395,9 @@ class OutputItems extends APIResource {
|
|
|
7266
6395
|
}
|
|
7267
6396
|
|
|
7268
6397
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6398
|
+
/**
|
|
6399
|
+
* Manage and run evals in the OpenAI platform.
|
|
6400
|
+
*/
|
|
7269
6401
|
class Runs extends APIResource {
|
|
7270
6402
|
constructor() {
|
|
7271
6403
|
super(...arguments);
|
|
@@ -7313,6 +6445,9 @@ class Runs extends APIResource {
|
|
|
7313
6445
|
Runs.OutputItems = OutputItems;
|
|
7314
6446
|
|
|
7315
6447
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6448
|
+
/**
|
|
6449
|
+
* Manage and run evals in the OpenAI platform.
|
|
6450
|
+
*/
|
|
7316
6451
|
class Evals extends APIResource {
|
|
7317
6452
|
constructor() {
|
|
7318
6453
|
super(...arguments);
|
|
@@ -7357,6 +6492,9 @@ class Evals extends APIResource {
|
|
|
7357
6492
|
Evals.Runs = Runs;
|
|
7358
6493
|
|
|
7359
6494
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6495
|
+
/**
|
|
6496
|
+
* Files are used to upload documents that can be used with features like Assistants and Fine-tuning.
|
|
6497
|
+
*/
|
|
7360
6498
|
let Files$1 = class Files extends APIResource {
|
|
7361
6499
|
/**
|
|
7362
6500
|
* Upload a file that can be used across various endpoints. Individual files can be
|
|
@@ -7436,6 +6574,9 @@ class Methods extends APIResource {
|
|
|
7436
6574
|
}
|
|
7437
6575
|
|
|
7438
6576
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6577
|
+
/**
|
|
6578
|
+
* Manage fine-tuning jobs to tailor a model to your specific training data.
|
|
6579
|
+
*/
|
|
7439
6580
|
let Graders$1 = class Graders extends APIResource {
|
|
7440
6581
|
/**
|
|
7441
6582
|
* Run a grader.
|
|
@@ -7489,6 +6630,9 @@ class Alpha extends APIResource {
|
|
|
7489
6630
|
Alpha.Graders = Graders$1;
|
|
7490
6631
|
|
|
7491
6632
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6633
|
+
/**
|
|
6634
|
+
* Manage fine-tuning jobs to tailor a model to your specific training data.
|
|
6635
|
+
*/
|
|
7492
6636
|
class Permissions extends APIResource {
|
|
7493
6637
|
/**
|
|
7494
6638
|
* **NOTE:** Calling this endpoint requires an [admin API key](../admin-api-keys).
|
|
@@ -7516,13 +6660,7 @@ class Permissions extends APIResource {
|
|
|
7516
6660
|
* Organization owners can use this endpoint to view all permissions for a
|
|
7517
6661
|
* fine-tuned model checkpoint.
|
|
7518
6662
|
*
|
|
7519
|
-
* @
|
|
7520
|
-
* ```ts
|
|
7521
|
-
* const permission =
|
|
7522
|
-
* await client.fineTuning.checkpoints.permissions.retrieve(
|
|
7523
|
-
* 'ft-AF1WoRqd3aJAHsqc9NY7iL8F',
|
|
7524
|
-
* );
|
|
7525
|
-
* ```
|
|
6663
|
+
* @deprecated Retrieve is deprecated. Please swap to the paginated list method instead.
|
|
7526
6664
|
*/
|
|
7527
6665
|
retrieve(fineTunedModelCheckpoint, query = {}, options) {
|
|
7528
6666
|
return this._client.get(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, {
|
|
@@ -7530,6 +6668,25 @@ class Permissions extends APIResource {
|
|
|
7530
6668
|
...options,
|
|
7531
6669
|
});
|
|
7532
6670
|
}
|
|
6671
|
+
/**
|
|
6672
|
+
* **NOTE:** This endpoint requires an [admin API key](../admin-api-keys).
|
|
6673
|
+
*
|
|
6674
|
+
* Organization owners can use this endpoint to view all permissions for a
|
|
6675
|
+
* fine-tuned model checkpoint.
|
|
6676
|
+
*
|
|
6677
|
+
* @example
|
|
6678
|
+
* ```ts
|
|
6679
|
+
* // Automatically fetches more pages as needed.
|
|
6680
|
+
* for await (const permissionListResponse of client.fineTuning.checkpoints.permissions.list(
|
|
6681
|
+
* 'ft-AF1WoRqd3aJAHsqc9NY7iL8F',
|
|
6682
|
+
* )) {
|
|
6683
|
+
* // ...
|
|
6684
|
+
* }
|
|
6685
|
+
* ```
|
|
6686
|
+
*/
|
|
6687
|
+
list(fineTunedModelCheckpoint, query = {}, options) {
|
|
6688
|
+
return this._client.getAPIList(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, (ConversationCursorPage), { query, ...options });
|
|
6689
|
+
}
|
|
7533
6690
|
/**
|
|
7534
6691
|
* **NOTE:** This endpoint requires an [admin API key](../admin-api-keys).
|
|
7535
6692
|
*
|
|
@@ -7564,6 +6721,9 @@ let Checkpoints$1 = class Checkpoints extends APIResource {
|
|
|
7564
6721
|
Checkpoints$1.Permissions = Permissions;
|
|
7565
6722
|
|
|
7566
6723
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6724
|
+
/**
|
|
6725
|
+
* Manage fine-tuning jobs to tailor a model to your specific training data.
|
|
6726
|
+
*/
|
|
7567
6727
|
class Checkpoints extends APIResource {
|
|
7568
6728
|
/**
|
|
7569
6729
|
* List checkpoints for a fine-tuning job.
|
|
@@ -7584,6 +6744,9 @@ class Checkpoints extends APIResource {
|
|
|
7584
6744
|
}
|
|
7585
6745
|
|
|
7586
6746
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6747
|
+
/**
|
|
6748
|
+
* Manage fine-tuning jobs to tailor a model to your specific training data.
|
|
6749
|
+
*/
|
|
7587
6750
|
class Jobs extends APIResource {
|
|
7588
6751
|
constructor() {
|
|
7589
6752
|
super(...arguments);
|
|
@@ -7725,6 +6888,9 @@ class Graders extends APIResource {
|
|
|
7725
6888
|
Graders.GraderModels = GraderModels;
|
|
7726
6889
|
|
|
7727
6890
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6891
|
+
/**
|
|
6892
|
+
* Given a prompt and/or an input image, the model will generate a new image.
|
|
6893
|
+
*/
|
|
7728
6894
|
class Images extends APIResource {
|
|
7729
6895
|
/**
|
|
7730
6896
|
* Creates a variation of a given image. This endpoint only supports `dall-e-2`.
|
|
@@ -7748,6 +6914,9 @@ class Images extends APIResource {
|
|
|
7748
6914
|
}
|
|
7749
6915
|
|
|
7750
6916
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6917
|
+
/**
|
|
6918
|
+
* List and describe the various models available in the API.
|
|
6919
|
+
*/
|
|
7751
6920
|
class Models extends APIResource {
|
|
7752
6921
|
/**
|
|
7753
6922
|
* Retrieves a model instance, providing basic information about the model such as
|
|
@@ -7773,6 +6942,9 @@ class Models extends APIResource {
|
|
|
7773
6942
|
}
|
|
7774
6943
|
|
|
7775
6944
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6945
|
+
/**
|
|
6946
|
+
* Given text and/or image inputs, classifies if those inputs are potentially harmful.
|
|
6947
|
+
*/
|
|
7776
6948
|
class Moderations extends APIResource {
|
|
7777
6949
|
/**
|
|
7778
6950
|
* Classifies if text and/or image inputs are potentially harmful. Learn more in
|
|
@@ -7856,6 +7028,20 @@ class ClientSecrets extends APIResource {
|
|
|
7856
7028
|
/**
|
|
7857
7029
|
* Create a Realtime client secret with an associated session configuration.
|
|
7858
7030
|
*
|
|
7031
|
+
* Client secrets are short-lived tokens that can be passed to a client app, such
|
|
7032
|
+
* as a web frontend or mobile client, which grants access to the Realtime API
|
|
7033
|
+
* without leaking your main API key. You can configure a custom TTL for each
|
|
7034
|
+
* client secret.
|
|
7035
|
+
*
|
|
7036
|
+
* You can also attach session configuration options to the client secret, which
|
|
7037
|
+
* will be applied to any sessions created using that client secret, but these can
|
|
7038
|
+
* also be overridden by the client connection.
|
|
7039
|
+
*
|
|
7040
|
+
* [Learn more about authentication with client secrets over WebRTC](https://platform.openai.com/docs/guides/realtime-webrtc).
|
|
7041
|
+
*
|
|
7042
|
+
* Returns the created client secret and the effective session object. The client
|
|
7043
|
+
* secret is a string that looks like `ek_1234`.
|
|
7044
|
+
*
|
|
7859
7045
|
* @example
|
|
7860
7046
|
* ```ts
|
|
7861
7047
|
* const clientSecret =
|
|
@@ -8281,7 +7467,10 @@ class InputItems extends APIResource {
|
|
|
8281
7467
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
8282
7468
|
class InputTokens extends APIResource {
|
|
8283
7469
|
/**
|
|
8284
|
-
*
|
|
7470
|
+
* Returns input token counts of the request.
|
|
7471
|
+
*
|
|
7472
|
+
* Returns an object with `object` set to `response.input_tokens` and an
|
|
7473
|
+
* `input_tokens` count.
|
|
8285
7474
|
*
|
|
8286
7475
|
* @example
|
|
8287
7476
|
* ```ts
|
|
@@ -8363,12 +7552,17 @@ class Responses extends APIResource {
|
|
|
8363
7552
|
return this._client.post(path `/responses/${responseID}/cancel`, options);
|
|
8364
7553
|
}
|
|
8365
7554
|
/**
|
|
8366
|
-
* Compact conversation
|
|
7555
|
+
* Compact a conversation. Returns a compacted response object.
|
|
7556
|
+
*
|
|
7557
|
+
* Learn when and how to compact long-running conversations in the
|
|
7558
|
+
* [conversation state guide](https://platform.openai.com/docs/guides/conversation-state#managing-the-context-window).
|
|
7559
|
+
* For ZDR-compatible compaction details, see
|
|
7560
|
+
* [Compaction (advanced)](https://platform.openai.com/docs/guides/conversation-state#compaction-advanced).
|
|
8367
7561
|
*
|
|
8368
7562
|
* @example
|
|
8369
7563
|
* ```ts
|
|
8370
7564
|
* const compactedResponse = await client.responses.compact({
|
|
8371
|
-
* model: 'gpt-5.
|
|
7565
|
+
* model: 'gpt-5.4',
|
|
8372
7566
|
* });
|
|
8373
7567
|
* ```
|
|
8374
7568
|
*/
|
|
@@ -8382,7 +7576,7 @@ Responses.InputTokens = InputTokens;
|
|
|
8382
7576
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
8383
7577
|
let Content$1 = class Content extends APIResource {
|
|
8384
7578
|
/**
|
|
8385
|
-
*
|
|
7579
|
+
* Download a skill zip bundle by its ID.
|
|
8386
7580
|
*/
|
|
8387
7581
|
retrieve(skillID, options) {
|
|
8388
7582
|
return this._client.get(path `/skills/${skillID}/content`, {
|
|
@@ -8396,7 +7590,7 @@ let Content$1 = class Content extends APIResource {
|
|
|
8396
7590
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
8397
7591
|
class Content extends APIResource {
|
|
8398
7592
|
/**
|
|
8399
|
-
*
|
|
7593
|
+
* Download a skill version zip bundle.
|
|
8400
7594
|
*/
|
|
8401
7595
|
retrieve(version, params, options) {
|
|
8402
7596
|
const { skill_id } = params;
|
|
@@ -8415,20 +7609,20 @@ class Versions extends APIResource {
|
|
|
8415
7609
|
this.content = new Content(this._client);
|
|
8416
7610
|
}
|
|
8417
7611
|
/**
|
|
8418
|
-
* Create
|
|
7612
|
+
* Create a new immutable skill version.
|
|
8419
7613
|
*/
|
|
8420
7614
|
create(skillID, body = {}, options) {
|
|
8421
7615
|
return this._client.post(path `/skills/${skillID}/versions`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
|
|
8422
7616
|
}
|
|
8423
7617
|
/**
|
|
8424
|
-
* Get
|
|
7618
|
+
* Get a specific skill version.
|
|
8425
7619
|
*/
|
|
8426
7620
|
retrieve(version, params, options) {
|
|
8427
7621
|
const { skill_id } = params;
|
|
8428
7622
|
return this._client.get(path `/skills/${skill_id}/versions/${version}`, options);
|
|
8429
7623
|
}
|
|
8430
7624
|
/**
|
|
8431
|
-
* List
|
|
7625
|
+
* List skill versions for a skill.
|
|
8432
7626
|
*/
|
|
8433
7627
|
list(skillID, query = {}, options) {
|
|
8434
7628
|
return this._client.getAPIList(path `/skills/${skillID}/versions`, (CursorPage), {
|
|
@@ -8437,7 +7631,7 @@ class Versions extends APIResource {
|
|
|
8437
7631
|
});
|
|
8438
7632
|
}
|
|
8439
7633
|
/**
|
|
8440
|
-
* Delete
|
|
7634
|
+
* Delete a skill version.
|
|
8441
7635
|
*/
|
|
8442
7636
|
delete(version, params, options) {
|
|
8443
7637
|
const { skill_id } = params;
|
|
@@ -8454,31 +7648,31 @@ class Skills extends APIResource {
|
|
|
8454
7648
|
this.versions = new Versions(this._client);
|
|
8455
7649
|
}
|
|
8456
7650
|
/**
|
|
8457
|
-
* Create
|
|
7651
|
+
* Create a new skill.
|
|
8458
7652
|
*/
|
|
8459
7653
|
create(body = {}, options) {
|
|
8460
7654
|
return this._client.post('/skills', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
|
|
8461
7655
|
}
|
|
8462
7656
|
/**
|
|
8463
|
-
* Get
|
|
7657
|
+
* Get a skill by its ID.
|
|
8464
7658
|
*/
|
|
8465
7659
|
retrieve(skillID, options) {
|
|
8466
7660
|
return this._client.get(path `/skills/${skillID}`, options);
|
|
8467
7661
|
}
|
|
8468
7662
|
/**
|
|
8469
|
-
* Update
|
|
7663
|
+
* Update the default version pointer for a skill.
|
|
8470
7664
|
*/
|
|
8471
7665
|
update(skillID, body, options) {
|
|
8472
7666
|
return this._client.post(path `/skills/${skillID}`, { body, ...options });
|
|
8473
7667
|
}
|
|
8474
7668
|
/**
|
|
8475
|
-
* List
|
|
7669
|
+
* List all skills for the current project.
|
|
8476
7670
|
*/
|
|
8477
7671
|
list(query = {}, options) {
|
|
8478
7672
|
return this._client.getAPIList('/skills', (CursorPage), { query, ...options });
|
|
8479
7673
|
}
|
|
8480
7674
|
/**
|
|
8481
|
-
* Delete
|
|
7675
|
+
* Delete a skill by its ID.
|
|
8482
7676
|
*/
|
|
8483
7677
|
delete(skillID, options) {
|
|
8484
7678
|
return this._client.delete(path `/skills/${skillID}`, options);
|
|
@@ -8488,6 +7682,9 @@ Skills.Content = Content$1;
|
|
|
8488
7682
|
Skills.Versions = Versions;
|
|
8489
7683
|
|
|
8490
7684
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
7685
|
+
/**
|
|
7686
|
+
* Use Uploads to upload large files in multiple parts.
|
|
7687
|
+
*/
|
|
8491
7688
|
class Parts extends APIResource {
|
|
8492
7689
|
/**
|
|
8493
7690
|
* Adds a
|
|
@@ -8508,6 +7705,9 @@ class Parts extends APIResource {
|
|
|
8508
7705
|
}
|
|
8509
7706
|
|
|
8510
7707
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
7708
|
+
/**
|
|
7709
|
+
* Use Uploads to upload large files in multiple parts.
|
|
7710
|
+
*/
|
|
8511
7711
|
class Uploads extends APIResource {
|
|
8512
7712
|
constructor() {
|
|
8513
7713
|
super(...arguments);
|
|
@@ -8533,12 +7733,16 @@ class Uploads extends APIResource {
|
|
|
8533
7733
|
* For guidance on the proper filename extensions for each purpose, please follow
|
|
8534
7734
|
* the documentation on
|
|
8535
7735
|
* [creating a File](https://platform.openai.com/docs/api-reference/files/create).
|
|
7736
|
+
*
|
|
7737
|
+
* Returns the Upload object with status `pending`.
|
|
8536
7738
|
*/
|
|
8537
7739
|
create(body, options) {
|
|
8538
7740
|
return this._client.post('/uploads', { body, ...options });
|
|
8539
7741
|
}
|
|
8540
7742
|
/**
|
|
8541
7743
|
* Cancels the Upload. No Parts may be added after an Upload is cancelled.
|
|
7744
|
+
*
|
|
7745
|
+
* Returns the Upload object with status `cancelled`.
|
|
8542
7746
|
*/
|
|
8543
7747
|
cancel(uploadID, options) {
|
|
8544
7748
|
return this._client.post(path `/uploads/${uploadID}/cancel`, options);
|
|
@@ -8556,7 +7760,9 @@ class Uploads extends APIResource {
|
|
|
8556
7760
|
*
|
|
8557
7761
|
* The number of bytes uploaded upon completion must match the number of bytes
|
|
8558
7762
|
* initially specified when creating the Upload object. No Parts may be added after
|
|
8559
|
-
* an Upload is completed.
|
|
7763
|
+
* an Upload is completed. Returns the Upload object with status `completed`,
|
|
7764
|
+
* including an additional `file` property containing the created usable File
|
|
7765
|
+
* object.
|
|
8560
7766
|
*/
|
|
8561
7767
|
complete(uploadID, body, options) {
|
|
8562
7768
|
return this._client.post(path `/uploads/${uploadID}/complete`, { body, ...options });
|
|
@@ -8916,31 +8122,33 @@ VectorStores.FileBatches = FileBatches;
|
|
|
8916
8122
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
8917
8123
|
class Videos extends APIResource {
|
|
8918
8124
|
/**
|
|
8919
|
-
* Create a video
|
|
8125
|
+
* Create a new video generation job from a prompt and optional reference assets.
|
|
8920
8126
|
*/
|
|
8921
8127
|
create(body, options) {
|
|
8922
8128
|
return this._client.post('/videos', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
|
|
8923
8129
|
}
|
|
8924
8130
|
/**
|
|
8925
|
-
*
|
|
8131
|
+
* Fetch the latest metadata for a generated video.
|
|
8926
8132
|
*/
|
|
8927
8133
|
retrieve(videoID, options) {
|
|
8928
8134
|
return this._client.get(path `/videos/${videoID}`, options);
|
|
8929
8135
|
}
|
|
8930
8136
|
/**
|
|
8931
|
-
* List videos
|
|
8137
|
+
* List recently generated videos for the current project.
|
|
8932
8138
|
*/
|
|
8933
8139
|
list(query = {}, options) {
|
|
8934
8140
|
return this._client.getAPIList('/videos', (ConversationCursorPage), { query, ...options });
|
|
8935
8141
|
}
|
|
8936
8142
|
/**
|
|
8937
|
-
*
|
|
8143
|
+
* Permanently delete a completed or failed video and its stored assets.
|
|
8938
8144
|
*/
|
|
8939
8145
|
delete(videoID, options) {
|
|
8940
8146
|
return this._client.delete(path `/videos/${videoID}`, options);
|
|
8941
8147
|
}
|
|
8942
8148
|
/**
|
|
8943
|
-
* Download video
|
|
8149
|
+
* Download the generated video bytes or a derived preview asset.
|
|
8150
|
+
*
|
|
8151
|
+
* Streams the rendered video content for the specified video job.
|
|
8944
8152
|
*/
|
|
8945
8153
|
downloadContent(videoID, query = {}, options) {
|
|
8946
8154
|
return this._client.get(path `/videos/${videoID}/content`, {
|
|
@@ -8951,7 +8159,7 @@ class Videos extends APIResource {
|
|
|
8951
8159
|
});
|
|
8952
8160
|
}
|
|
8953
8161
|
/**
|
|
8954
|
-
* Create a video
|
|
8162
|
+
* Create a remix of a completed video using a refreshed prompt.
|
|
8955
8163
|
*/
|
|
8956
8164
|
remix(videoID, body, options) {
|
|
8957
8165
|
return this._client.post(path `/videos/${videoID}/remix`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
|
|
@@ -9076,24 +8284,54 @@ class OpenAI {
|
|
|
9076
8284
|
constructor({ baseURL = readEnv('OPENAI_BASE_URL'), apiKey = readEnv('OPENAI_API_KEY'), organization = readEnv('OPENAI_ORG_ID') ?? null, project = readEnv('OPENAI_PROJECT_ID') ?? null, webhookSecret = readEnv('OPENAI_WEBHOOK_SECRET') ?? null, ...opts } = {}) {
|
|
9077
8285
|
_OpenAI_instances.add(this);
|
|
9078
8286
|
_OpenAI_encoder.set(this, void 0);
|
|
8287
|
+
/**
|
|
8288
|
+
* Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
|
|
8289
|
+
*/
|
|
9079
8290
|
this.completions = new Completions(this);
|
|
9080
8291
|
this.chat = new Chat(this);
|
|
8292
|
+
/**
|
|
8293
|
+
* Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.
|
|
8294
|
+
*/
|
|
9081
8295
|
this.embeddings = new Embeddings(this);
|
|
8296
|
+
/**
|
|
8297
|
+
* Files are used to upload documents that can be used with features like Assistants and Fine-tuning.
|
|
8298
|
+
*/
|
|
9082
8299
|
this.files = new Files$1(this);
|
|
8300
|
+
/**
|
|
8301
|
+
* Given a prompt and/or an input image, the model will generate a new image.
|
|
8302
|
+
*/
|
|
9083
8303
|
this.images = new Images(this);
|
|
9084
8304
|
this.audio = new Audio(this);
|
|
8305
|
+
/**
|
|
8306
|
+
* Given text and/or image inputs, classifies if those inputs are potentially harmful.
|
|
8307
|
+
*/
|
|
9085
8308
|
this.moderations = new Moderations(this);
|
|
8309
|
+
/**
|
|
8310
|
+
* List and describe the various models available in the API.
|
|
8311
|
+
*/
|
|
9086
8312
|
this.models = new Models(this);
|
|
9087
8313
|
this.fineTuning = new FineTuning(this);
|
|
9088
8314
|
this.graders = new Graders(this);
|
|
9089
8315
|
this.vectorStores = new VectorStores(this);
|
|
9090
8316
|
this.webhooks = new Webhooks(this);
|
|
9091
8317
|
this.beta = new Beta(this);
|
|
8318
|
+
/**
|
|
8319
|
+
* Create large batches of API requests to run asynchronously.
|
|
8320
|
+
*/
|
|
9092
8321
|
this.batches = new Batches(this);
|
|
8322
|
+
/**
|
|
8323
|
+
* Use Uploads to upload large files in multiple parts.
|
|
8324
|
+
*/
|
|
9093
8325
|
this.uploads = new Uploads(this);
|
|
9094
8326
|
this.responses = new Responses(this);
|
|
9095
8327
|
this.realtime = new Realtime(this);
|
|
8328
|
+
/**
|
|
8329
|
+
* Manage conversations and conversation items.
|
|
8330
|
+
*/
|
|
9096
8331
|
this.conversations = new Conversations(this);
|
|
8332
|
+
/**
|
|
8333
|
+
* Manage and run evals in the OpenAI platform.
|
|
8334
|
+
*/
|
|
9097
8335
|
this.evals = new Evals(this);
|
|
9098
8336
|
this.containers = new Containers(this);
|
|
9099
8337
|
this.skills = new Skills(this);
|
|
@@ -9163,7 +8401,7 @@ class OpenAI {
|
|
|
9163
8401
|
return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
|
|
9164
8402
|
}
|
|
9165
8403
|
stringifyQuery(query) {
|
|
9166
|
-
return
|
|
8404
|
+
return stringifyQuery(query);
|
|
9167
8405
|
}
|
|
9168
8406
|
getUserAgent() {
|
|
9169
8407
|
return `${this.constructor.name}/JS ${VERSION}`;
|
|
@@ -9432,9 +8670,9 @@ class OpenAI {
|
|
|
9432
8670
|
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
|
|
9433
8671
|
}
|
|
9434
8672
|
}
|
|
9435
|
-
// If the API asks us to wait a certain amount of time
|
|
9436
|
-
//
|
|
9437
|
-
if (
|
|
8673
|
+
// If the API asks us to wait a certain amount of time, just do what it
|
|
8674
|
+
// says, but otherwise calculate a default
|
|
8675
|
+
if (timeoutMillis === undefined) {
|
|
9438
8676
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
9439
8677
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
9440
8678
|
}
|
|
@@ -9531,6 +8769,13 @@ class OpenAI {
|
|
|
9531
8769
|
(Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
|
|
9532
8770
|
return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
|
|
9533
8771
|
}
|
|
8772
|
+
else if (typeof body === 'object' &&
|
|
8773
|
+
headers.values.get('content-type') === 'application/x-www-form-urlencoded') {
|
|
8774
|
+
return {
|
|
8775
|
+
bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
8776
|
+
body: this.stringifyQuery(body),
|
|
8777
|
+
};
|
|
8778
|
+
}
|
|
9534
8779
|
else {
|
|
9535
8780
|
return __classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers });
|
|
9536
8781
|
}
|
|
@@ -11061,428 +10306,6 @@ class PerformanceTimer {
|
|
|
11061
10306
|
}
|
|
11062
10307
|
}
|
|
11063
10308
|
|
|
11064
|
-
/**
|
|
11065
|
-
* Calculates Bollinger Bands for a given set of price data.
|
|
11066
|
-
* Bollinger Bands consist of a middle band (SMA) and two outer bands
|
|
11067
|
-
* that are standard deviations away from the middle band.
|
|
11068
|
-
*
|
|
11069
|
-
* @param priceData - An array of price data objects containing closing prices.
|
|
11070
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11071
|
-
* @param params.period - The number of periods to use for the SMA (default is 20).
|
|
11072
|
-
* @param params.standardDeviations - The number of standard deviations for the outer bands (default is 2).
|
|
11073
|
-
* @returns An array of BollingerBandsData objects containing the calculated bands.
|
|
11074
|
-
*/
|
|
11075
|
-
function calculateBollingerBands(priceData, { period = 20, standardDeviations = 2 } = {}) {
|
|
11076
|
-
if (priceData.length < period) {
|
|
11077
|
-
logIfDebug(`Insufficient data for Bollinger Bands calculation: required periods: ${period}, but only received ${priceData.length} periods of data`);
|
|
11078
|
-
return [];
|
|
11079
|
-
}
|
|
11080
|
-
const result = [];
|
|
11081
|
-
for (let i = period - 1; i < priceData.length; i++) {
|
|
11082
|
-
const periodSlice = priceData.slice(i - period + 1, i + 1);
|
|
11083
|
-
const prices = periodSlice.map((d) => d.close);
|
|
11084
|
-
// Calculate middle band (SMA)
|
|
11085
|
-
const sum = prices.reduce((acc, price) => acc + price, 0);
|
|
11086
|
-
const sma = sum / period;
|
|
11087
|
-
// Calculate standard deviation
|
|
11088
|
-
const squaredDifferences = prices.map((price) => Math.pow(price - sma, 2));
|
|
11089
|
-
const variance = squaredDifferences.reduce((acc, val) => acc + val, 0) / period;
|
|
11090
|
-
const standardDeviation = Math.sqrt(variance);
|
|
11091
|
-
// Calculate bands
|
|
11092
|
-
const upperBand = sma + standardDeviation * standardDeviations;
|
|
11093
|
-
const lowerBand = sma - standardDeviation * standardDeviations;
|
|
11094
|
-
result.push({
|
|
11095
|
-
date: priceData[i].date,
|
|
11096
|
-
middle: parseFloat(sma.toFixed(2)),
|
|
11097
|
-
upper: parseFloat(upperBand.toFixed(2)),
|
|
11098
|
-
lower: parseFloat(lowerBand.toFixed(2)),
|
|
11099
|
-
close: priceData[i].close,
|
|
11100
|
-
});
|
|
11101
|
-
}
|
|
11102
|
-
// logIfDebug(`Calculated Bollinger Bands for ${result.length} periods`);
|
|
11103
|
-
return result;
|
|
11104
|
-
}
|
|
11105
|
-
/**
|
|
11106
|
-
* Calculates the Exponential Moving Average (EMA) for a given set of price data.
|
|
11107
|
-
* The EMA gives more weight to recent prices, making it more responsive to new information.
|
|
11108
|
-
*
|
|
11109
|
-
* @param priceData - An array of price data objects containing closing prices.
|
|
11110
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11111
|
-
* @param params.period - The number of periods to use for the EMA (default is 20).
|
|
11112
|
-
* @param params.period2 - An optional second period for a second EMA (default is 9).
|
|
11113
|
-
* @returns An array of EMAData objects containing the calculated EMA values.
|
|
11114
|
-
*/
|
|
11115
|
-
function calculateEMA(priceData, { period = 20, period2 = 9 } = {}) {
|
|
11116
|
-
if (priceData.length < period || (period2 && priceData.length < period2)) {
|
|
11117
|
-
logIfDebug(`Insufficient data for EMA calculation: required periods: ${period}, ${period2}, but only received ${priceData.length} periods of data`);
|
|
11118
|
-
return [];
|
|
11119
|
-
}
|
|
11120
|
-
const result = [];
|
|
11121
|
-
const multiplier = 2 / (period + 1);
|
|
11122
|
-
const multiplier2 = period2 ? 2 / (period2 + 1) : 0;
|
|
11123
|
-
// Calculate initial SMA for first period
|
|
11124
|
-
let sum = 0;
|
|
11125
|
-
for (let i = 0; i < period; i++) {
|
|
11126
|
-
sum += priceData[i].close;
|
|
11127
|
-
}
|
|
11128
|
-
let prevEMA = sum / period;
|
|
11129
|
-
// Calculate initial SMA for second period if needed
|
|
11130
|
-
let prevEMA2;
|
|
11131
|
-
if (period2) {
|
|
11132
|
-
sum = 0;
|
|
11133
|
-
for (let i = 0; i < period2; i++) {
|
|
11134
|
-
sum += priceData[i].close;
|
|
11135
|
-
}
|
|
11136
|
-
prevEMA2 = sum / period2;
|
|
11137
|
-
}
|
|
11138
|
-
// Add first EMA(s)
|
|
11139
|
-
const firstEntry = {
|
|
11140
|
-
date: priceData[Math.max(period, period2 || 0) - 1].date,
|
|
11141
|
-
ema: parseFloat(prevEMA.toFixed(2)),
|
|
11142
|
-
close: priceData[Math.max(period, period2 || 0) - 1].close,
|
|
11143
|
-
};
|
|
11144
|
-
if (period2) {
|
|
11145
|
-
firstEntry.ema2 = parseFloat(prevEMA2.toFixed(2));
|
|
11146
|
-
}
|
|
11147
|
-
result.push(firstEntry);
|
|
11148
|
-
// Calculate EMA for remaining periods
|
|
11149
|
-
for (let i = Math.max(period, period2 || 0); i < priceData.length; i++) {
|
|
11150
|
-
const currentClose = priceData[i].close;
|
|
11151
|
-
const currentEMA = (currentClose - prevEMA) * multiplier + prevEMA;
|
|
11152
|
-
prevEMA = currentEMA;
|
|
11153
|
-
const entry = {
|
|
11154
|
-
date: priceData[i].date,
|
|
11155
|
-
ema: parseFloat(currentEMA.toFixed(2)),
|
|
11156
|
-
close: currentClose,
|
|
11157
|
-
};
|
|
11158
|
-
if (period2) {
|
|
11159
|
-
const currentEMA2 = (currentClose - prevEMA2) * multiplier2 + prevEMA2;
|
|
11160
|
-
prevEMA2 = currentEMA2;
|
|
11161
|
-
entry.ema2 = parseFloat(currentEMA2.toFixed(2));
|
|
11162
|
-
}
|
|
11163
|
-
result.push(entry);
|
|
11164
|
-
}
|
|
11165
|
-
// logIfDebug(`Calculated EMA for ${result.length} periods`);
|
|
11166
|
-
return result;
|
|
11167
|
-
}
|
|
11168
|
-
/**
|
|
11169
|
-
* Calculates Fibonacci retracement and extension levels based on price data.
|
|
11170
|
-
* Fibonacci levels are used to identify potential support and resistance levels.
|
|
11171
|
-
*
|
|
11172
|
-
* @param priceData - An array of price data objects containing high and low prices.
|
|
11173
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11174
|
-
* @param params.lookbackPeriod - The number of periods to look back for swing high/low (default is 20).
|
|
11175
|
-
* @param params.retracementLevels - An array of retracement levels to calculate (default is [0.236, 0.382, 0.5, 0.618, 0.786]).
|
|
11176
|
-
* @param params.extensionLevels - An array of extension levels to calculate (default is [1.272, 1.618, 2.618]).
|
|
11177
|
-
* @param params.reverseDirection - A boolean indicating if the trend is reversed (default is false).
|
|
11178
|
-
* @returns An array of FibonacciData objects containing the calculated levels.
|
|
11179
|
-
*/
|
|
11180
|
-
function calculateFibonacciLevels(priceData, { lookbackPeriod = 20, retracementLevels = [0.236, 0.382, 0.5, 0.618, 0.786], extensionLevels = [1.272, 1.618, 2.618], reverseDirection = false, } = {}) {
|
|
11181
|
-
const result = [];
|
|
11182
|
-
for (let i = 0; i < priceData.length; i++) {
|
|
11183
|
-
const periodSlice = priceData.slice(Math.max(0, i - lookbackPeriod + 1), i + 1);
|
|
11184
|
-
const swingHigh = Math.max(...periodSlice.map((d) => d.high));
|
|
11185
|
-
const swingLow = Math.min(...periodSlice.map((d) => d.low));
|
|
11186
|
-
const priceRange = swingHigh - swingLow;
|
|
11187
|
-
const trend = reverseDirection ? 'downtrend' : 'uptrend';
|
|
11188
|
-
let levels = [];
|
|
11189
|
-
if (priceRange > 0) {
|
|
11190
|
-
// Calculate retracement levels
|
|
11191
|
-
retracementLevels.forEach((level) => {
|
|
11192
|
-
const price = reverseDirection ? swingLow + priceRange * level : swingHigh - priceRange * level;
|
|
11193
|
-
levels.push({
|
|
11194
|
-
level,
|
|
11195
|
-
price: parseFloat(price.toFixed(2)),
|
|
11196
|
-
type: 'retracement',
|
|
11197
|
-
});
|
|
11198
|
-
});
|
|
11199
|
-
// Calculate extension levels
|
|
11200
|
-
extensionLevels.forEach((level) => {
|
|
11201
|
-
const price = reverseDirection
|
|
11202
|
-
? swingHigh - priceRange * (level - 1) // For downtrend
|
|
11203
|
-
: swingHigh + priceRange * (level - 1); // For uptrend
|
|
11204
|
-
levels.push({
|
|
11205
|
-
level,
|
|
11206
|
-
price: parseFloat(price.toFixed(2)),
|
|
11207
|
-
type: 'extension',
|
|
11208
|
-
});
|
|
11209
|
-
});
|
|
11210
|
-
// Sort levels by price
|
|
11211
|
-
levels.sort((a, b) => (reverseDirection ? b.price - a.price : a.price - b.price));
|
|
11212
|
-
}
|
|
11213
|
-
else {
|
|
11214
|
-
logIfDebug(`Price range is zero on date ${priceData[i].date}; no levels calculated.`);
|
|
11215
|
-
}
|
|
11216
|
-
result.push({
|
|
11217
|
-
date: priceData[i].date,
|
|
11218
|
-
levels,
|
|
11219
|
-
swingHigh,
|
|
11220
|
-
swingLow,
|
|
11221
|
-
trend,
|
|
11222
|
-
close: priceData[i].close,
|
|
11223
|
-
});
|
|
11224
|
-
}
|
|
11225
|
-
// logIfDebug(`Calculated Fibonacci levels for ${result.length} periods`);
|
|
11226
|
-
return result;
|
|
11227
|
-
}
|
|
11228
|
-
/**
|
|
11229
|
-
* Calculates the Moving Average Convergence Divergence (MACD) for a given set of price data.
|
|
11230
|
-
* MACD is a trend-following momentum indicator that shows the relationship between two EMAs.
|
|
11231
|
-
*
|
|
11232
|
-
* @param priceData - An array of price data objects containing closing prices.
|
|
11233
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11234
|
-
* @param params.shortPeriod - The short EMA period (default is 12).
|
|
11235
|
-
* @param params.longPeriod - The long EMA period (default is 26).
|
|
11236
|
-
* @param params.signalPeriod - The signal line period (default is 9).
|
|
11237
|
-
* @returns An array of MACDData objects containing the calculated MACD values.
|
|
11238
|
-
*/
|
|
11239
|
-
function calculateMACD(priceData, { shortPeriod = 12, longPeriod = 26, signalPeriod = 9 } = {}) {
|
|
11240
|
-
if (priceData.length < longPeriod + signalPeriod) {
|
|
11241
|
-
logIfDebug(`Insufficient data for MACD calculation: required periods: ${longPeriod + signalPeriod}, but only received ${priceData.length} periods of data`);
|
|
11242
|
-
return [];
|
|
11243
|
-
}
|
|
11244
|
-
const emaShort = calculateEMA(priceData, { period: shortPeriod });
|
|
11245
|
-
const emaLong = calculateEMA(priceData, { period: longPeriod });
|
|
11246
|
-
// Align EMAs by trimming the beginning of emaShort to match emaLong length
|
|
11247
|
-
if (emaShort.length < emaLong.length) {
|
|
11248
|
-
logIfDebug('Short EMA length is less than Long EMA length for MACD calculation');
|
|
11249
|
-
return [];
|
|
11250
|
-
}
|
|
11251
|
-
const emaShortAligned = emaShort.slice(emaShort.length - emaLong.length);
|
|
11252
|
-
const macdLine = emaShortAligned.map((short, i) => short.ema - emaLong[i].ema);
|
|
11253
|
-
const result = [];
|
|
11254
|
-
if (macdLine.length < signalPeriod) {
|
|
11255
|
-
logIfDebug(`Insufficient MACD data for Signal Line calculation: required periods: ${signalPeriod}, but only received ${macdLine.length} periods of data`);
|
|
11256
|
-
return [];
|
|
11257
|
-
}
|
|
11258
|
-
const signalMultiplier = 2 / (signalPeriod + 1);
|
|
11259
|
-
let signalEMA = macdLine.slice(0, signalPeriod).reduce((sum, val) => sum + val, 0) / signalPeriod;
|
|
11260
|
-
for (let i = signalPeriod; i < macdLine.length; i++) {
|
|
11261
|
-
const macdValue = macdLine[i];
|
|
11262
|
-
signalEMA = (macdValue - signalEMA) * signalMultiplier + signalEMA;
|
|
11263
|
-
const hist = macdValue - signalEMA;
|
|
11264
|
-
result.push({
|
|
11265
|
-
date: emaLong[i].date, // Use emaLong's date for alignment
|
|
11266
|
-
macd: parseFloat(macdValue.toFixed(2)),
|
|
11267
|
-
signal: parseFloat(signalEMA.toFixed(2)),
|
|
11268
|
-
histogram: parseFloat(hist.toFixed(2)),
|
|
11269
|
-
close: emaLong[i].close,
|
|
11270
|
-
});
|
|
11271
|
-
}
|
|
11272
|
-
// logIfDebug(`Calculated MACD for ${result.length} periods`);
|
|
11273
|
-
return result;
|
|
11274
|
-
}
|
|
11275
|
-
/**
|
|
11276
|
-
* Calculates the Relative Strength Index (RSI) for a given set of price data.
|
|
11277
|
-
* RSI is a momentum oscillator that measures the speed and change of price movements.
|
|
11278
|
-
*
|
|
11279
|
-
* @param priceData - An array of price data objects containing closing prices.
|
|
11280
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11281
|
-
* @param params.period - The number of periods to use for the RSI (default is 14).
|
|
11282
|
-
* @returns An array of RSIData objects containing the calculated RSI values.
|
|
11283
|
-
*/
|
|
11284
|
-
function calculateRSI(priceData, { period = 14 } = {}) {
|
|
11285
|
-
if (priceData.length < period + 1) {
|
|
11286
|
-
logIfDebug(`Insufficient data for RSI calculation: required periods: ${period + 1}, but only received ${priceData.length} periods of data`);
|
|
11287
|
-
return [];
|
|
11288
|
-
}
|
|
11289
|
-
const result = [];
|
|
11290
|
-
let avgGain = 0;
|
|
11291
|
-
let avgLoss = 0;
|
|
11292
|
-
// Calculate first average gain and loss
|
|
11293
|
-
for (let i = 1; i <= period; i++) {
|
|
11294
|
-
const change = priceData[i].close - priceData[i - 1].close;
|
|
11295
|
-
if (change >= 0) {
|
|
11296
|
-
avgGain += change;
|
|
11297
|
-
}
|
|
11298
|
-
else {
|
|
11299
|
-
avgLoss += Math.abs(change);
|
|
11300
|
-
}
|
|
11301
|
-
}
|
|
11302
|
-
avgGain = avgGain / period;
|
|
11303
|
-
avgLoss = avgLoss / period;
|
|
11304
|
-
// Calculate RSI for the first period
|
|
11305
|
-
let rs = avgGain / avgLoss;
|
|
11306
|
-
let rsi = 100 - 100 / (1 + rs);
|
|
11307
|
-
result.push({
|
|
11308
|
-
date: priceData[period].date,
|
|
11309
|
-
rsi: parseFloat(rsi.toFixed(2)),
|
|
11310
|
-
close: priceData[period].close,
|
|
11311
|
-
});
|
|
11312
|
-
// Calculate subsequent periods using smoothed averages
|
|
11313
|
-
for (let i = period + 1; i < priceData.length; i++) {
|
|
11314
|
-
const change = priceData[i].close - priceData[i - 1].close;
|
|
11315
|
-
const gain = change >= 0 ? change : 0;
|
|
11316
|
-
const loss = change < 0 ? Math.abs(change) : 0;
|
|
11317
|
-
// Use smoothed averages
|
|
11318
|
-
avgGain = (avgGain * (period - 1) + gain) / period;
|
|
11319
|
-
avgLoss = (avgLoss * (period - 1) + loss) / period;
|
|
11320
|
-
rs = avgGain / avgLoss;
|
|
11321
|
-
rsi = 100 - 100 / (1 + rs);
|
|
11322
|
-
result.push({
|
|
11323
|
-
date: priceData[i].date,
|
|
11324
|
-
rsi: parseFloat(rsi.toFixed(2)),
|
|
11325
|
-
close: priceData[i].close,
|
|
11326
|
-
});
|
|
11327
|
-
}
|
|
11328
|
-
// logIfDebug(`Calculated RSI for ${result.length} periods`);
|
|
11329
|
-
return result;
|
|
11330
|
-
}
|
|
11331
|
-
/**
|
|
11332
|
-
* Calculates the Stochastic Oscillator for a given set of price data.
|
|
11333
|
-
* The Stochastic Oscillator compares a particular closing price of a security to a range of its prices over a certain period of time.
|
|
11334
|
-
*
|
|
11335
|
-
* @param priceData - An array of price data objects containing high, low, and closing prices.
|
|
11336
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11337
|
-
* @param params.lookbackPeriod - The number of periods to look back for the calculation of %K (default is 5).
|
|
11338
|
-
* @param params.signalPeriod - The number of periods for the %D signal line (default is 3).
|
|
11339
|
-
* @param params.smoothingFactor - The smoothing factor for %K (default is 3).
|
|
11340
|
-
* @returns An array of StochData objects containing the calculated %K and %D values.
|
|
11341
|
-
*/
|
|
11342
|
-
function calculateStochasticOscillator(priceData, { lookbackPeriod = 5, signalPeriod = 3, smoothingFactor = 3 } = {}) {
|
|
11343
|
-
if (priceData.length < lookbackPeriod) {
|
|
11344
|
-
logIfDebug(`Insufficient data for Stochastic Oscillator calculation: required periods: ${lookbackPeriod}, but only received ${priceData.length} periods of data`);
|
|
11345
|
-
return [];
|
|
11346
|
-
}
|
|
11347
|
-
const kValues = [];
|
|
11348
|
-
const result = [];
|
|
11349
|
-
let kSum = 0;
|
|
11350
|
-
let dSum = 0;
|
|
11351
|
-
for (let i = lookbackPeriod - 1; i < priceData.length; i++) {
|
|
11352
|
-
const periodSlice = priceData.slice(i - lookbackPeriod + 1, i + 1);
|
|
11353
|
-
const currentClose = periodSlice[periodSlice.length - 1].close;
|
|
11354
|
-
const highPrices = periodSlice.map((d) => d.high);
|
|
11355
|
-
const lowPrices = periodSlice.map((d) => d.low);
|
|
11356
|
-
const highestHigh = Math.max(...highPrices);
|
|
11357
|
-
const lowestLow = Math.min(...lowPrices);
|
|
11358
|
-
const k = highestHigh === lowestLow ? 0 : ((currentClose - lowestLow) / (highestHigh - lowestLow)) * 100;
|
|
11359
|
-
kValues.push(k);
|
|
11360
|
-
kSum += k;
|
|
11361
|
-
if (kValues.length > smoothingFactor)
|
|
11362
|
-
kSum -= kValues[kValues.length - smoothingFactor - 1];
|
|
11363
|
-
const smoothedK = kSum / Math.min(kValues.length, smoothingFactor);
|
|
11364
|
-
dSum += smoothedK;
|
|
11365
|
-
if (kValues.length > smoothingFactor + signalPeriod - 1)
|
|
11366
|
-
dSum -= kValues[kValues.length - smoothingFactor - signalPeriod];
|
|
11367
|
-
const smoothedD = dSum / Math.min(kValues.length - smoothingFactor + 1, signalPeriod);
|
|
11368
|
-
if (kValues.length >= smoothingFactor + signalPeriod - 1) {
|
|
11369
|
-
result.push({
|
|
11370
|
-
date: priceData[i].date,
|
|
11371
|
-
slowK: parseFloat(smoothedK.toFixed(2)),
|
|
11372
|
-
slowD: parseFloat(smoothedD.toFixed(2)),
|
|
11373
|
-
close: currentClose,
|
|
11374
|
-
});
|
|
11375
|
-
}
|
|
11376
|
-
}
|
|
11377
|
-
// logIfDebug(`Calculated Stochastic Oscillator for ${result.length} periods`);
|
|
11378
|
-
return result;
|
|
11379
|
-
}
|
|
11380
|
-
/**
|
|
11381
|
-
* Calculates support and resistance levels based on price data.
|
|
11382
|
-
* Support and resistance levels are price levels at which a stock tends to stop and reverse.
|
|
11383
|
-
*
|
|
11384
|
-
* @param priceData - An array of price data objects containing high, low, and closing prices.
|
|
11385
|
-
* @param params - An object containing optional parameters for the calculation.
|
|
11386
|
-
* @param params.maxLevels - The maximum number of support/resistance levels to return (default is 5).
|
|
11387
|
-
* @param params.lookbackPeriod - The number of periods to look back for pivot points (default is 10).
|
|
11388
|
-
* @returns An array of SupportResistanceData objects containing the calculated levels.
|
|
11389
|
-
*/
|
|
11390
|
-
function calculateSupportAndResistance(priceData, { maxLevels = 5, lookbackPeriod = 10 } = {}) {
|
|
11391
|
-
const result = [];
|
|
11392
|
-
for (let i = 0; i < priceData.length; i++) {
|
|
11393
|
-
const startIdx = Math.max(0, i - lookbackPeriod);
|
|
11394
|
-
const analysisWindow = priceData.slice(startIdx, i + 1);
|
|
11395
|
-
const pivotPoints = [];
|
|
11396
|
-
// **Compute Volatility Metrics**
|
|
11397
|
-
const priceChanges = analysisWindow.slice(1).map((bar, idx) => Math.abs(bar.close - analysisWindow[idx].close));
|
|
11398
|
-
const avgPriceChange = priceChanges.reduce((sum, change) => sum + change, 0) / priceChanges.length;
|
|
11399
|
-
const volatility = avgPriceChange / analysisWindow[0].close; // Relative volatility
|
|
11400
|
-
// **Adjust Sensitivity and minGapBetweenLevels Dynamically**
|
|
11401
|
-
const sensitivity = volatility * 2; // Adjust the multiplier as needed
|
|
11402
|
-
const minGapBetweenLevels = volatility * 100; // Convert to percentage
|
|
11403
|
-
// Analyze each point in window for pivot status
|
|
11404
|
-
for (let j = 1; j < analysisWindow.length - 1; j++) {
|
|
11405
|
-
const curr = analysisWindow[j];
|
|
11406
|
-
const prevBar = analysisWindow[j - 1];
|
|
11407
|
-
const nextBar = analysisWindow[j + 1];
|
|
11408
|
-
// Check for high pivot
|
|
11409
|
-
if (curr.high > prevBar.high && curr.high > nextBar.high) {
|
|
11410
|
-
const existingPivot = pivotPoints.find((p) => Math.abs(p.price - curr.high) / curr.high < sensitivity);
|
|
11411
|
-
if (existingPivot) {
|
|
11412
|
-
existingPivot.count++;
|
|
11413
|
-
existingPivot.volume += curr.vol; // **Include Volume**
|
|
11414
|
-
}
|
|
11415
|
-
else {
|
|
11416
|
-
pivotPoints.push({ price: curr.high, count: 1, volume: curr.vol });
|
|
11417
|
-
}
|
|
11418
|
-
}
|
|
11419
|
-
// Check for low pivot
|
|
11420
|
-
if (curr.low < prevBar.low && curr.low < nextBar.low) {
|
|
11421
|
-
const existingPivot = pivotPoints.find((p) => Math.abs(p.price - curr.low) / curr.low < sensitivity);
|
|
11422
|
-
if (existingPivot) {
|
|
11423
|
-
existingPivot.count++;
|
|
11424
|
-
existingPivot.volume += curr.vol; // **Include Volume**
|
|
11425
|
-
}
|
|
11426
|
-
else {
|
|
11427
|
-
pivotPoints.push({ price: curr.low, count: 1, volume: curr.vol });
|
|
11428
|
-
}
|
|
11429
|
-
}
|
|
11430
|
-
}
|
|
11431
|
-
// Group nearby levels
|
|
11432
|
-
const currentPrice = priceData[i].close;
|
|
11433
|
-
const levels = [];
|
|
11434
|
-
// Sort pivots by price
|
|
11435
|
-
pivotPoints.sort((a, b) => a.price - b.price);
|
|
11436
|
-
// Group close pivots
|
|
11437
|
-
let currentGroup = [];
|
|
11438
|
-
for (let j = 0; j < pivotPoints.length; j++) {
|
|
11439
|
-
if (currentGroup.length === 0) {
|
|
11440
|
-
currentGroup.push(pivotPoints[j]);
|
|
11441
|
-
}
|
|
11442
|
-
else {
|
|
11443
|
-
const lastPrice = currentGroup[currentGroup.length - 1].price;
|
|
11444
|
-
if ((Math.abs(pivotPoints[j].price - lastPrice) / lastPrice) * 100 <= minGapBetweenLevels) {
|
|
11445
|
-
currentGroup.push(pivotPoints[j]);
|
|
11446
|
-
}
|
|
11447
|
-
else {
|
|
11448
|
-
// Process current group
|
|
11449
|
-
if (currentGroup.length > 0) {
|
|
11450
|
-
const totalVolume = currentGroup.reduce((sum, p) => sum + p.volume, 0);
|
|
11451
|
-
const avgPrice = currentGroup.reduce((sum, p) => sum + p.price * p.volume, 0) / totalVolume;
|
|
11452
|
-
const totalStrength = currentGroup.reduce((sum, p) => sum + p.count * (p.volume / totalVolume), 0);
|
|
11453
|
-
levels.push({
|
|
11454
|
-
price: parseFloat(avgPrice.toFixed(2)),
|
|
11455
|
-
strength: parseFloat(totalStrength.toFixed(2)),
|
|
11456
|
-
type: avgPrice > currentPrice ? 'resistance' : 'support',
|
|
11457
|
-
});
|
|
11458
|
-
}
|
|
11459
|
-
currentGroup = [pivotPoints[j]];
|
|
11460
|
-
}
|
|
11461
|
-
}
|
|
11462
|
-
}
|
|
11463
|
-
// Process final group
|
|
11464
|
-
if (currentGroup.length > 0) {
|
|
11465
|
-
const totalVolume = currentGroup.reduce((sum, p) => sum + p.volume, 0);
|
|
11466
|
-
const avgPrice = currentGroup.reduce((sum, p) => sum + p.price * p.volume, 0) / totalVolume;
|
|
11467
|
-
const totalStrength = currentGroup.reduce((sum, p) => sum + p.count * (p.volume / totalVolume), 0);
|
|
11468
|
-
levels.push({
|
|
11469
|
-
price: parseFloat(avgPrice.toFixed(2)),
|
|
11470
|
-
strength: parseFloat(totalStrength.toFixed(2)),
|
|
11471
|
-
type: avgPrice > currentPrice ? 'resistance' : 'support',
|
|
11472
|
-
});
|
|
11473
|
-
}
|
|
11474
|
-
// Sort by strength and limit
|
|
11475
|
-
const finalLevels = levels.sort((a, b) => b.strength - a.strength).slice(0, maxLevels);
|
|
11476
|
-
result.push({
|
|
11477
|
-
date: priceData[i].date,
|
|
11478
|
-
levels: finalLevels,
|
|
11479
|
-
close: currentPrice,
|
|
11480
|
-
});
|
|
11481
|
-
}
|
|
11482
|
-
logIfDebug(`Found ${result.reduce((sum, r) => sum + r.levels.length, 0)} support/resistance levels across ${result.length} periods`);
|
|
11483
|
-
return result;
|
|
11484
|
-
}
|
|
11485
|
-
|
|
11486
10309
|
function getDefaultExportFromCjs (x) {
|
|
11487
10310
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
11488
10311
|
}
|
|
@@ -19888,40 +18711,12 @@ const disco = {
|
|
|
19888
18711
|
pct: formatPercentage,
|
|
19889
18712
|
dateTimeForGS: dateTimeForGS,
|
|
19890
18713
|
},
|
|
19891
|
-
indices: {
|
|
19892
|
-
fetchAggregates: fetchIndicesAggregates,
|
|
19893
|
-
fetchPreviousClose: fetchIndicesPreviousClose,
|
|
19894
|
-
fetchDailyOpenClose: fetchIndicesDailyOpenClose,
|
|
19895
|
-
fetchSnapshot: fetchIndicesSnapshot,
|
|
19896
|
-
fetchUniversalSnapshot: fetchUniversalSnapshot,
|
|
19897
|
-
formatBarData: formatIndicesBarData,
|
|
19898
|
-
},
|
|
19899
18714
|
llm: {
|
|
19900
18715
|
call: makeLLMCall,
|
|
19901
18716
|
seek: makeDeepseekCall,
|
|
19902
18717
|
images: makeImagesCall,
|
|
19903
18718
|
open: makeOpenRouterCall,
|
|
19904
18719
|
},
|
|
19905
|
-
polygon: {
|
|
19906
|
-
fetchTickerInfo: fetchTickerInfo,
|
|
19907
|
-
fetchGroupedDaily: fetchGroupedDaily,
|
|
19908
|
-
fetchLastTrade: fetchLastTrade,
|
|
19909
|
-
fetchTrades: fetchTrades,
|
|
19910
|
-
fetchPrices: fetchPrices,
|
|
19911
|
-
analysePolygonPriceData: analysePolygonPriceData,
|
|
19912
|
-
formatPriceData: formatPriceData,
|
|
19913
|
-
fetchDailyOpenClose: fetchDailyOpenClose,
|
|
19914
|
-
getPreviousClose: getPreviousClose,
|
|
19915
|
-
},
|
|
19916
|
-
ta: {
|
|
19917
|
-
calculateEMA: calculateEMA,
|
|
19918
|
-
calculateMACD: calculateMACD,
|
|
19919
|
-
calculateRSI: calculateRSI,
|
|
19920
|
-
calculateStochasticOscillator: calculateStochasticOscillator,
|
|
19921
|
-
calculateBollingerBands: calculateBollingerBands,
|
|
19922
|
-
calculateSupportAndResistance: calculateSupportAndResistance,
|
|
19923
|
-
calculateFibonacciLevels: calculateFibonacciLevels,
|
|
19924
|
-
},
|
|
19925
18720
|
time: {
|
|
19926
18721
|
convertDateToMarketTimeZone: convertDateToMarketTimeZone,
|
|
19927
18722
|
getStartAndEndDates: getStartAndEndDates,
|
|
@@ -19944,7 +18739,6 @@ const disco = {
|
|
|
19944
18739
|
utils: {
|
|
19945
18740
|
logIfDebug: logIfDebug,
|
|
19946
18741
|
fetchWithRetry: fetchWithRetry,
|
|
19947
|
-
validatePolygonApiKey: validatePolygonApiKey,
|
|
19948
18742
|
Timer: PerformanceTimer,
|
|
19949
18743
|
},
|
|
19950
18744
|
};
|