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