@adaptic/utils 0.0.926 → 0.0.927
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +43 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +43 -53
- package/dist/index.mjs.map +1 -1
- package/dist/test.js +11 -14
- package/dist/test.js.map +1 -1
- package/dist/types/alpaca/client.d.ts.map +1 -1
- package/dist/types/alpaca/crypto/data.d.ts.map +1 -1
- package/dist/types/alpaca/crypto/orders.d.ts.map +1 -1
- package/dist/types/alpaca/index.d.ts.map +1 -1
- package/dist/types/alpaca/legacy/account.d.ts.map +1 -1
- package/dist/types/alpaca/legacy/positions.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/bars.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/news.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/quotes.d.ts.map +1 -1
- package/dist/types/alpaca/market-data/trades.d.ts.map +1 -1
- package/dist/types/alpaca/options/data.d.ts +1 -1
- package/dist/types/alpaca/options/data.d.ts.map +1 -1
- package/dist/types/alpaca/options/orders.d.ts.map +1 -1
- package/dist/types/alpaca/streams/crypto-stream.d.ts.map +1 -1
- package/dist/types/alpaca/streams/option-stream.d.ts +2 -2
- package/dist/types/alpaca/streams/option-stream.d.ts.map +1 -1
- package/dist/types/alpaca/streams/stock-stream.d.ts.map +1 -1
- package/dist/types/alpaca/streams/stream-manager.d.ts.map +1 -1
- package/dist/types/alpaca/trading/smart-orders.d.ts.map +1 -1
- package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types/asset-allocation-algorithm.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/market-time.d.ts.map +1 -1
- package/dist/types/massive.d.ts.map +1 -1
- package/dist/types/metrics-calcs.d.ts.map +1 -1
- package/dist/types/misc-utils.d.ts +2 -2
- package/dist/types/misc-utils.d.ts.map +1 -1
- package/dist/types/performance-metrics.d.ts.map +1 -1
- package/dist/types/price-utils.d.ts.map +1 -1
- package/dist/types/schemas/massive-schemas.d.ts +6 -6
- package/dist/types/utils/retry.d.ts +1 -10
- package/dist/types/utils/retry.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -785,13 +785,11 @@ let fs;
|
|
|
785
785
|
let path;
|
|
786
786
|
if (isNode) {
|
|
787
787
|
try {
|
|
788
|
-
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
789
788
|
const readline = require("readline");
|
|
790
789
|
clearLine = readline.clearLine;
|
|
791
790
|
cursorTo = readline.cursorTo;
|
|
792
791
|
fs = require("fs");
|
|
793
792
|
path = require("path");
|
|
794
|
-
/* eslint-enable @typescript-eslint/no-require-imports */
|
|
795
793
|
}
|
|
796
794
|
catch {
|
|
797
795
|
// Silently degrade — all operations will be no-ops.
|
|
@@ -862,7 +860,7 @@ class DisplayManager {
|
|
|
862
860
|
/**
|
|
863
861
|
* Writes a log entry to a symbol-specific log file
|
|
864
862
|
*/
|
|
865
|
-
writeSymbolLog(symbol, date, logMessage,
|
|
863
|
+
writeSymbolLog(symbol, date, logMessage, _options) {
|
|
866
864
|
if (!fs || !path)
|
|
867
865
|
return;
|
|
868
866
|
try {
|
|
@@ -878,7 +876,7 @@ class DisplayManager {
|
|
|
878
876
|
const filename = `${symbol}-${year}-${month}-${day}.log`;
|
|
879
877
|
const filePath = path.join("logs", filename);
|
|
880
878
|
// Strip ANSI color codes from log message
|
|
881
|
-
const plainLogMessage = logMessage.replace(
|
|
879
|
+
const plainLogMessage = logMessage.replace(new RegExp(String.fromCharCode(27) + "\\[\\d+m", "g"), "");
|
|
882
880
|
// Write to file (append if exists, create if not)
|
|
883
881
|
fs.appendFileSync(filePath, plainLogMessage + "\n");
|
|
884
882
|
}
|
|
@@ -907,7 +905,7 @@ class DisplayManager {
|
|
|
907
905
|
const filename = `${source}-${year}-${month}-${day}.log`;
|
|
908
906
|
const filePath = path.join("logs", filename);
|
|
909
907
|
// Strip ANSI color codes from log message
|
|
910
|
-
const plainLogMessage = logMessage.replace(
|
|
908
|
+
const plainLogMessage = logMessage.replace(new RegExp(String.fromCharCode(27) + "\\[\\d+m", "g"), "");
|
|
911
909
|
// Write to file (append if exists, create if not)
|
|
912
910
|
fs.appendFileSync(filePath, plainLogMessage + "\n");
|
|
913
911
|
}
|
|
@@ -1463,7 +1461,7 @@ class MarketTimeUtil {
|
|
|
1463
1461
|
}
|
|
1464
1462
|
// In all other cases (during trading hours, before market open, holidays, weekends),
|
|
1465
1463
|
// we want the last completed trading day
|
|
1466
|
-
|
|
1464
|
+
const lastFullDate = this.getLastMarketDay(nowET);
|
|
1467
1465
|
// Set to midnight ET while preserving the date
|
|
1468
1466
|
return dateFnsTz.fromZonedTime(dateFns.set(lastFullDate, { hours: 0, minutes: 0, seconds: 0, milliseconds: 0 }), this.timezone);
|
|
1469
1467
|
}
|
|
@@ -1603,7 +1601,6 @@ class MarketTimeUtil {
|
|
|
1603
1601
|
}
|
|
1604
1602
|
// Convert end date to specified timezone
|
|
1605
1603
|
const zonedEndDate = dateFnsTz.toZonedTime(end, this.timezone);
|
|
1606
|
-
let startDate;
|
|
1607
1604
|
let endDate;
|
|
1608
1605
|
const isCurrentMarketDay = this.isMarketDayZoned(zonedEndDate);
|
|
1609
1606
|
const isWithinHours = this.isWithinMarketHoursZoned(zonedEndDate);
|
|
@@ -1635,7 +1632,7 @@ class MarketTimeUtil {
|
|
|
1635
1632
|
// Now calculate the start date based on the period
|
|
1636
1633
|
const periodStartDate = this.calculatePeriodStartDate(endDate, period);
|
|
1637
1634
|
const { start: dayStart } = this.getDayBoundaries(periodStartDate);
|
|
1638
|
-
startDate = dayStart;
|
|
1635
|
+
const startDate = dayStart;
|
|
1639
1636
|
// Convert boundaries back to UTC for final output
|
|
1640
1637
|
const utcStart = dateFnsTz.fromZonedTime(startDate, this.timezone);
|
|
1641
1638
|
const utcEnd = dateFnsTz.fromZonedTime(endDate, this.timezone);
|
|
@@ -2502,7 +2499,7 @@ class AlpacaMarketDataAPI extends require$$0$1.EventEmitter {
|
|
|
2502
2499
|
async getHistoricalBars(params) {
|
|
2503
2500
|
const symbols = params.symbols;
|
|
2504
2501
|
const symbolsStr = symbols.join(",");
|
|
2505
|
-
|
|
2502
|
+
const allBars = {};
|
|
2506
2503
|
let pageToken = null;
|
|
2507
2504
|
let hasMorePages = true;
|
|
2508
2505
|
let totalBarsCount = 0;
|
|
@@ -2816,7 +2813,7 @@ class AlpacaMarketDataAPI extends require$$0$1.EventEmitter {
|
|
|
2816
2813
|
*/
|
|
2817
2814
|
async getLatestOptionsTrades(params) {
|
|
2818
2815
|
// Remove limit and page_token as they're not supported by this endpoint
|
|
2819
|
-
const { limit, page_token, ...requestParams } = params;
|
|
2816
|
+
const { limit: _limit, page_token: _page_token, ...requestParams } = params;
|
|
2820
2817
|
return this.makeRequest("/options/trades/latest", "GET", requestParams, "v1beta1");
|
|
2821
2818
|
}
|
|
2822
2819
|
/**
|
|
@@ -2828,7 +2825,7 @@ class AlpacaMarketDataAPI extends require$$0$1.EventEmitter {
|
|
|
2828
2825
|
*/
|
|
2829
2826
|
async getLatestOptionsQuotes(params) {
|
|
2830
2827
|
// Remove limit and page_token as they're not supported by this endpoint
|
|
2831
|
-
const { limit, page_token, ...requestParams } = params;
|
|
2828
|
+
const { limit: _limit, page_token: _page_token, ...requestParams } = params;
|
|
2832
2829
|
return this.makeRequest("/options/quotes/latest", "GET", requestParams, "v1beta1");
|
|
2833
2830
|
}
|
|
2834
2831
|
/**
|
|
@@ -2842,7 +2839,7 @@ class AlpacaMarketDataAPI extends require$$0$1.EventEmitter {
|
|
|
2842
2839
|
async getHistoricalOptionsBars(params) {
|
|
2843
2840
|
const symbols = params.symbols;
|
|
2844
2841
|
const symbolsStr = symbols.join(",");
|
|
2845
|
-
|
|
2842
|
+
const allBars = {};
|
|
2846
2843
|
let pageToken = null;
|
|
2847
2844
|
let hasMorePages = true;
|
|
2848
2845
|
let totalBarsCount = 0;
|
|
@@ -2926,7 +2923,7 @@ class AlpacaMarketDataAPI extends require$$0$1.EventEmitter {
|
|
|
2926
2923
|
async getHistoricalOptionsTrades(params) {
|
|
2927
2924
|
const symbols = params.symbols;
|
|
2928
2925
|
const symbolsStr = symbols.join(",");
|
|
2929
|
-
|
|
2926
|
+
const allTrades = {};
|
|
2930
2927
|
let pageToken = null;
|
|
2931
2928
|
let hasMorePages = true;
|
|
2932
2929
|
let totalTradesCount = 0;
|
|
@@ -3009,7 +3006,7 @@ class AlpacaMarketDataAPI extends require$$0$1.EventEmitter {
|
|
|
3009
3006
|
*/
|
|
3010
3007
|
async getOptionsSnapshot(params) {
|
|
3011
3008
|
// Remove limit and page_token as they may not be supported by this endpoint
|
|
3012
|
-
const { limit, page_token, ...requestParams } = params;
|
|
3009
|
+
const { limit: _limit, page_token: _page_token, ...requestParams } = params;
|
|
3013
3010
|
return this.makeRequest("/options/snapshots", "GET", requestParams, "v1beta1");
|
|
3014
3011
|
}
|
|
3015
3012
|
/**
|
|
@@ -5706,11 +5703,12 @@ async function closePosition$1(auth, symbolOrAssetId, params) {
|
|
|
5706
5703
|
throw new Error(`Position not found for ${symbolOrAssetId}`);
|
|
5707
5704
|
}
|
|
5708
5705
|
// Construct global Alpaca Auth for quote fetching
|
|
5709
|
-
const
|
|
5706
|
+
const alpacaAuthData = {
|
|
5710
5707
|
type: "LIVE",
|
|
5711
5708
|
alpacaApiKey: process.env.ALPACA_API_KEY,
|
|
5712
5709
|
alpacaApiSecret: process.env.ALPACA_API_SECRET || process.env.ALPACA_SECRET_KEY,
|
|
5713
5710
|
};
|
|
5711
|
+
const alpacaAuth = alpacaAuthData;
|
|
5714
5712
|
const quotesResponse = await getLatestQuotes$1(alpacaAuth, {
|
|
5715
5713
|
symbols: [symbolOrAssetId],
|
|
5716
5714
|
});
|
|
@@ -5913,11 +5911,12 @@ async function closeAllPositionsAfterHours$1(auth, params = { cancel_orders: tru
|
|
|
5913
5911
|
account: auth.adapticAccountId || "direct",
|
|
5914
5912
|
});
|
|
5915
5913
|
}
|
|
5916
|
-
const
|
|
5914
|
+
const alpacaAuthObj = {
|
|
5917
5915
|
type: "LIVE",
|
|
5918
5916
|
alpacaApiKey: process.env.ALPACA_API_KEY,
|
|
5919
5917
|
alpacaApiSecret: process.env.ALPACA_SECRET_KEY,
|
|
5920
5918
|
};
|
|
5919
|
+
const alpacaAuth = alpacaAuthObj;
|
|
5921
5920
|
const symbols = positions.map((position) => position.symbol);
|
|
5922
5921
|
const quotesResponse = await getLatestQuotes$1(alpacaAuth, { symbols });
|
|
5923
5922
|
for (const position of positions) {
|
|
@@ -5973,11 +5972,12 @@ async function fetchAccountDetails({ accountId, client, alpacaAccount, auth, })
|
|
|
5973
5972
|
let alpacaAccountObj = alpacaAccount ? alpacaAccount : null;
|
|
5974
5973
|
if (!alpacaAccountObj && auth) {
|
|
5975
5974
|
const validatedAuth = await validateAuth(auth);
|
|
5976
|
-
|
|
5975
|
+
const accountFromAuth = {
|
|
5977
5976
|
APIKey: validatedAuth.APIKey,
|
|
5978
5977
|
APISecret: validatedAuth.APISecret,
|
|
5979
5978
|
type: validatedAuth.type,
|
|
5980
5979
|
};
|
|
5980
|
+
alpacaAccountObj = accountFromAuth;
|
|
5981
5981
|
}
|
|
5982
5982
|
if (!alpacaAccountObj) {
|
|
5983
5983
|
try {
|
|
@@ -6222,7 +6222,7 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
6222
6222
|
throw new Error(`Allocation percentages must sum to 100%. Current total: ${totalAllocation}%`);
|
|
6223
6223
|
}
|
|
6224
6224
|
if (account.allocation) {
|
|
6225
|
-
|
|
6225
|
+
const allocUpdateData = {
|
|
6226
6226
|
id: account.allocation.id,
|
|
6227
6227
|
alpacaAccount: {
|
|
6228
6228
|
id: account.id,
|
|
@@ -6234,10 +6234,11 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
6234
6234
|
etfs: updatedConfig.allocation.etfs ?? 0,
|
|
6235
6235
|
forex: updatedConfig.allocation.forex ?? 0,
|
|
6236
6236
|
crypto: updatedConfig.allocation.crypto ?? 0,
|
|
6237
|
-
}
|
|
6237
|
+
};
|
|
6238
|
+
allocUpdatePromise = adaptic$1.allocation.update(allocUpdateData, client);
|
|
6238
6239
|
}
|
|
6239
6240
|
else {
|
|
6240
|
-
|
|
6241
|
+
const allocCreateData = {
|
|
6241
6242
|
stocks: updatedConfig.allocation.stocks ?? 0,
|
|
6242
6243
|
options: updatedConfig.allocation.options ?? 0,
|
|
6243
6244
|
futures: updatedConfig.allocation.futures ?? 0,
|
|
@@ -6248,10 +6249,11 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
6248
6249
|
id: account.id,
|
|
6249
6250
|
},
|
|
6250
6251
|
alpacaAccountId: account.id,
|
|
6251
|
-
}
|
|
6252
|
+
};
|
|
6253
|
+
allocUpdatePromise = adaptic$1.allocation.create(allocCreateData, client);
|
|
6252
6254
|
}
|
|
6253
6255
|
}
|
|
6254
|
-
const
|
|
6256
|
+
const accountUpdateData = {
|
|
6255
6257
|
id: account.id,
|
|
6256
6258
|
user: {
|
|
6257
6259
|
id: user.id,
|
|
@@ -6277,7 +6279,8 @@ async function updateConfiguration(user, account, updatedConfig) {
|
|
|
6277
6279
|
firstReducedTrailPercentage100: updatedConfig.firstReducedTrailPercentage100 ?? 0,
|
|
6278
6280
|
secondReducedTrailPercentage100: updatedConfig.secondReducedTrailPercentage100 ?? 0,
|
|
6279
6281
|
minimumPriceChangePercent100: updatedConfig.minimumPriceChangePercent100 ?? 0,
|
|
6280
|
-
}
|
|
6282
|
+
};
|
|
6283
|
+
const adapticUpdatePromise = adaptic$1.alpacaAccount.update(accountUpdateData, client);
|
|
6281
6284
|
const [alpacaResponse, updatedAlpacaAccount, updatedAllocation] = await Promise.all([
|
|
6282
6285
|
alpacaUpdatePromise,
|
|
6283
6286
|
adapticUpdatePromise,
|
|
@@ -7588,7 +7591,7 @@ const fetchTickerInfo = async (symbol, options) => {
|
|
|
7588
7591
|
if (results.share_class_shares_outstanding === undefined) {
|
|
7589
7592
|
results.share_class_shares_outstanding = null;
|
|
7590
7593
|
}
|
|
7591
|
-
|
|
7594
|
+
const tickerInfo = {
|
|
7592
7595
|
ticker: results.ticker,
|
|
7593
7596
|
type: results.type,
|
|
7594
7597
|
active: results.active,
|
|
@@ -7601,6 +7604,7 @@ const fetchTickerInfo = async (symbol, options) => {
|
|
|
7601
7604
|
primary_exchange: results.primary_exchange,
|
|
7602
7605
|
share_class_shares_outstanding: results.share_class_shares_outstanding,
|
|
7603
7606
|
};
|
|
7607
|
+
return tickerInfo;
|
|
7604
7608
|
}
|
|
7605
7609
|
catch (error) {
|
|
7606
7610
|
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
@@ -7925,7 +7929,7 @@ const fetchGroupedDaily = async (date, options) => {
|
|
|
7925
7929
|
if (!MASSIVE_VALID_STATUSES.has(data.status)) {
|
|
7926
7930
|
throw new Error(`Massive.com API responded with status: ${data.status}`);
|
|
7927
7931
|
}
|
|
7928
|
-
|
|
7932
|
+
const groupedDaily = {
|
|
7929
7933
|
adjusted: data.adjusted,
|
|
7930
7934
|
queryCount: data.queryCount,
|
|
7931
7935
|
request_id: data.request_id,
|
|
@@ -7943,6 +7947,7 @@ const fetchGroupedDaily = async (date, options) => {
|
|
|
7943
7947
|
trades: result.n,
|
|
7944
7948
|
})),
|
|
7945
7949
|
};
|
|
7950
|
+
return groupedDaily;
|
|
7946
7951
|
}
|
|
7947
7952
|
catch (error) {
|
|
7948
7953
|
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
@@ -8358,25 +8363,9 @@ const calculateFees = async (action, trade, alpacaAccount) => {
|
|
|
8358
8363
|
0;
|
|
8359
8364
|
switch (assetType) {
|
|
8360
8365
|
case "STOCK":
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
// regulatoryFee =
|
|
8365
|
-
// (tradeValue * FEE_CONFIG.REGULATORY_FEES_PERCENTAGE) / 100;
|
|
8366
|
-
// fee = commissionFee + regulatoryFee;
|
|
8367
|
-
// break;
|
|
8368
|
-
// case "OPTION" as enums.AssetType.OPTION:
|
|
8369
|
-
// perContractFee = qty * FEE_CONFIG.OPTIONS_PER_CONTRACT_FEE;
|
|
8370
|
-
// baseCommission = FEE_CONFIG.OPTIONS_BASE_COMMISSION;
|
|
8371
|
-
// fee = perContractFee + baseCommission;
|
|
8372
|
-
// break;
|
|
8373
|
-
// case "CRYPTOCURRENCY" as enums.AssetType.CRYPTOCURRENCY:
|
|
8374
|
-
// fee = (tradeValue * FEE_CONFIG.CRYPTO_TRANSACTION_PERCENTAGE) / 100;
|
|
8375
|
-
// break;
|
|
8376
|
-
// case "FUTURE" as enums.AssetType.FUTURE:
|
|
8377
|
-
// // Sum of all futures fees
|
|
8378
|
-
// fee = 0.85 + 0.85 + 0.25 + 0.02 + 0.01 + 0.3 + 0.01;
|
|
8379
|
-
// break;
|
|
8366
|
+
// Currently zero fees for stocks via Alpaca
|
|
8367
|
+
fee = 0;
|
|
8368
|
+
break;
|
|
8380
8369
|
default:
|
|
8381
8370
|
fee = 0;
|
|
8382
8371
|
break;
|
|
@@ -8950,7 +8939,7 @@ async function calculateExpenseRatio({ accountId, client, alpacaAccount, }) {
|
|
|
8950
8939
|
getLogger().warn("Missing account ID or client to calculate expense ratio.");
|
|
8951
8940
|
return "N/A";
|
|
8952
8941
|
}
|
|
8953
|
-
|
|
8942
|
+
const alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
|
|
8954
8943
|
let accountDetails;
|
|
8955
8944
|
if (!alpacaAccountId) {
|
|
8956
8945
|
getLogger().warn("Invalid account ID.");
|
|
@@ -8990,7 +8979,7 @@ async function calculateExpenseRatio({ accountId, client, alpacaAccount, }) {
|
|
|
8990
8979
|
return `${expenseRatio.toFixed(2)}%`;
|
|
8991
8980
|
}
|
|
8992
8981
|
// Mock function to represent fetching expenses from your system
|
|
8993
|
-
async function getPortfolioExpensesFromYourSystem(
|
|
8982
|
+
async function getPortfolioExpensesFromYourSystem(_accountId) {
|
|
8994
8983
|
// Implement this function based on your data storage
|
|
8995
8984
|
return 0; // Placeholder
|
|
8996
8985
|
}
|
|
@@ -9006,7 +8995,7 @@ async function calculateLiquidityRatio({ accountId, client, alpacaAccount, }) {
|
|
|
9006
8995
|
getLogger().warn("Missing account ID or client to calculateLiquidityRatio.");
|
|
9007
8996
|
return "N/A";
|
|
9008
8997
|
}
|
|
9009
|
-
|
|
8998
|
+
const alpacaAccountId = accountId || (alpacaAccount && alpacaAccount.id) || "";
|
|
9010
8999
|
let accountDetails;
|
|
9011
9000
|
if (!alpacaAccountId) {
|
|
9012
9001
|
getLogger().warn("Invalid account ID.");
|
|
@@ -9706,7 +9695,7 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
|
|
|
9706
9695
|
const benchmarkSymbol = "SPY";
|
|
9707
9696
|
let benchmarkBars = [];
|
|
9708
9697
|
try {
|
|
9709
|
-
const { start, end } =
|
|
9698
|
+
const { start, end } = getStartAndEndTimestamps({
|
|
9710
9699
|
timezone: "America/New_York",
|
|
9711
9700
|
period: params?.period === "YTD" || params?.period === "1A"
|
|
9712
9701
|
? "1Y"
|
|
@@ -9751,7 +9740,7 @@ async function fetchPerformanceMetrics({ params, client, accountId, alpacaAccoun
|
|
|
9751
9740
|
alpacaAccount: alpacaAccountObj,
|
|
9752
9741
|
}),
|
|
9753
9742
|
getDividendYield(),
|
|
9754
|
-
calculateMaxDrawdown(portfolioHistory.equity),
|
|
9743
|
+
Promise.resolve(calculateMaxDrawdown(portfolioHistory.equity)),
|
|
9755
9744
|
]);
|
|
9756
9745
|
// Extract results with error handling for each metric
|
|
9757
9746
|
const result = { ...defaultMetrics };
|
|
@@ -9906,7 +9895,7 @@ function calculateFibonacciLevels(priceData, { lookbackPeriod = 20, retracementL
|
|
|
9906
9895
|
const swingLow = Math.min(...periodSlice.map((d) => d.low));
|
|
9907
9896
|
const priceRange = swingHigh - swingLow;
|
|
9908
9897
|
const trend = reverseDirection ? "downtrend" : "uptrend";
|
|
9909
|
-
|
|
9898
|
+
const levels = [];
|
|
9910
9899
|
if (priceRange > 0) {
|
|
9911
9900
|
// Calculate retracement levels
|
|
9912
9901
|
retracementLevels.forEach((level) => {
|
|
@@ -48579,7 +48568,8 @@ class AlpacaClient {
|
|
|
48579
48568
|
// Handle empty responses (e.g., DELETE requests)
|
|
48580
48569
|
const contentType = response.headers.get("content-type");
|
|
48581
48570
|
if (!contentType || !contentType.includes("application/json")) {
|
|
48582
|
-
|
|
48571
|
+
const emptyObj = {};
|
|
48572
|
+
return emptyObj;
|
|
48583
48573
|
}
|
|
48584
48574
|
return (await response.json());
|
|
48585
48575
|
}
|
|
@@ -56065,7 +56055,7 @@ async function getHistoricalOptionsBars(client, params) {
|
|
|
56065
56055
|
* Calculate implied volatility from option price (simplified approximation)
|
|
56066
56056
|
* For production use, consider using a proper Black-Scholes solver
|
|
56067
56057
|
*/
|
|
56068
|
-
function approximateImpliedVolatility(optionPrice, underlyingPrice, strike, daysToExpiration,
|
|
56058
|
+
function approximateImpliedVolatility(optionPrice, underlyingPrice, strike, daysToExpiration, _riskFreeRate = 0.05, isCall = true) {
|
|
56069
56059
|
// Simplified IV approximation using Brenner-Subrahmanyam formula
|
|
56070
56060
|
// IV ~ (optionPrice / underlyingPrice) * sqrt(2 * pi / T)
|
|
56071
56061
|
const T = daysToExpiration / 365;
|
|
@@ -61336,7 +61326,7 @@ class AssetAllocationEngine {
|
|
|
61336
61326
|
/**
|
|
61337
61327
|
* Apply user constraints and preferences
|
|
61338
61328
|
*/
|
|
61339
|
-
applyConstraints(allocations, preferences, constraints,
|
|
61329
|
+
applyConstraints(allocations, preferences, constraints, _characteristics) {
|
|
61340
61330
|
const constrained = new Map(allocations);
|
|
61341
61331
|
// Apply exclusions
|
|
61342
61332
|
if (preferences?.excludedAssetClasses) {
|