@thoshpathi/utils-smartapi
Version:
Extended utilities for Angel One's smartapi-javascript SDK, including custom methods and helpers for market data like candles, P&L, and more.
121 lines (118 loc) • 3.62 kB
JavaScript
import {
getLastCompletedMarketCandle
} from "./chunk-RAMYA6SI.mjs";
import {
candleFetchDayConfigs
} from "./chunk-K6S6WDGB.mjs";
// src/smartapi_utils.ts
import { subDays, endOfToday, startOfDay, isAfter } from "date-fns";
import {
convertDatesToStrings,
toDatetimeString,
toDbDatetimeString
} from "@thoshpathi/utils-core";
import {
logger,
groupByLatestMap,
groupByKeyObject
} from "@thoshpathi/utils-core";
async function getTokensLtpMap(exchangeTokens, smartapi) {
const ltpDataArray = await smartapi.fetchTokensLtp(exchangeTokens);
const ltpDataMap = groupByLatestMap(ltpDataArray, "tradingSymbol");
logger.i("fetching ltp from smartapi", ltpDataMap.size);
return ltpDataMap;
}
async function getManyScripLtpMap(params, instrumentDumps, cacheObject) {
const { symbols, smartapi } = params;
const scripLtpMap = /* @__PURE__ */ new Map();
if (!symbols.length || !instrumentDumps.length) return scripLtpMap;
const exchangeTokens = groupByKeyObject(
instrumentDumps,
"exchange",
"symbolToken"
);
const ltpDataMap = await getTokensLtpMap(exchangeTokens, smartapi);
const createdAt = toDbDatetimeString();
instrumentDumps.forEach((dumpScrip) => {
const ltpData = ltpDataMap.get(dumpScrip.symbol);
if (ltpData == null) return;
const { name, symbol, symbolToken, exchange } = dumpScrip;
scripLtpMap.set(symbol, {
id: 0n,
name,
symbol,
symbolToken,
exchange,
ltp: ltpData.ltp,
createdAt
});
});
cacheObject?.set(scripLtpMap);
return scripLtpMap;
}
async function getManyScripLtpMapCache(params, instrumentDumps, cacheObject) {
let scripLtpMap = cacheObject?.get();
if (scripLtpMap == null)
return await getManyScripLtpMap(params, instrumentDumps, cacheObject);
const someSymbolsExist = params.symbols.some(
(symbol) => scripLtpMap?.has(symbol)
);
if (!someSymbolsExist)
scripLtpMap = await getManyScripLtpMap(
params,
instrumentDumps,
cacheObject
);
return scripLtpMap;
}
async function getIndexScripLtpMap(indexScrips, smartapi, cacheObject) {
return await getManyScripLtpMap(
{
symbols: indexScrips.map((v) => v.symbol),
smartapi
},
indexScrips,
cacheObject
);
}
async function getIndexHistoricalData(params, smartapi) {
const candleDataArray = await smartapi.fetchCandleData(params);
if (!Array.isArray(candleDataArray) || candleDataArray.length == 0) {
logger.w(
"candleDataArray is empty",
JSON.stringify(convertDatesToStrings(params))
);
return;
}
try {
const lastCompletedCandle = getLastCompletedMarketCandle(params.interval);
if (lastCompletedCandle != null) {
const lastCandle = candleDataArray[candleDataArray.length - 1];
const lastCandleDate = lastCandle.date;
if (isAfter(lastCandleDate, lastCompletedCandle)) {
logger.d(
"not completed candle present. remove it",
toDatetimeString(lastCandle.date)
);
candleDataArray.pop();
}
}
} catch (error) {
logger.e("error in removing not completed candle", error);
}
return candleDataArray;
}
async function getIndexLatestHistoricalData(args, smartapi) {
const days = candleFetchDayConfigs[args.interval];
const todate = endOfToday();
const fromdate = startOfDay(subDays(todate, days));
const params = { ...args, fromdate, todate };
return await getIndexHistoricalData(params, smartapi);
}
export {
getManyScripLtpMap,
getManyScripLtpMapCache,
getIndexScripLtpMap,
getIndexHistoricalData,
getIndexLatestHistoricalData
};