@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.
185 lines (180 loc) • 6.46 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/smartapi_utils.ts
var smartapi_utils_exports = {};
__export(smartapi_utils_exports, {
default: () => getManyScripLtpMap,
getIndexHistoricalData: () => getIndexHistoricalData,
getIndexLatestHistoricalData: () => getIndexLatestHistoricalData,
getIndexScripLtpMap: () => getIndexScripLtpMap,
getManyScripLtpMap: () => getManyScripLtpMap,
getManyScripLtpMapCache: () => getManyScripLtpMapCache
});
module.exports = __toCommonJS(smartapi_utils_exports);
var import_date_fns = require("date-fns");
var import_utils_core = require("@thoshpathi/utils-core");
var import_utils_core2 = require("@thoshpathi/utils-core");
// src/configs.ts
var candleMaxDayConfigs = {
ONE_MINUTE: 30,
THREE_MINUTE: 60,
FIVE_MINUTE: 100,
TEN_MINUTE: 100,
FIFTEEN_MINUTE: 200,
THIRTY_MINUTE: 200,
ONE_HOUR: 400,
ONE_DAY: 2e3
};
var candleFetchDayConfigs = Object.fromEntries(
Object.entries(candleMaxDayConfigs).map(([key, value]) => [
key,
Math.floor(value / 5)
])
);
var intervalMinuteConfigs = {
ONE_MINUTE: 1,
THREE_MINUTE: 3,
FIVE_MINUTE: 5,
TEN_MINUTE: 10,
FIFTEEN_MINUTE: 15,
THIRTY_MINUTE: 30,
ONE_HOUR: 60,
ONE_DAY: 24 * 60
};
// src/candle_utils.ts
function getLastCompletedMarketCandle(interval, marketOpenTime = "09:15:00") {
const [openHour, openMinute] = marketOpenTime.split(":").map((s) => +s.trim());
const marketOpen = /* @__PURE__ */ new Date();
marketOpen.setHours(openHour, openMinute, 0, 0);
const diffMs = +/* @__PURE__ */ new Date() - +marketOpen;
if (diffMs < 0) return null;
const diffMinutes = Math.floor(diffMs / 6e4);
const intervalMinutes = intervalMinuteConfigs[interval];
let completedCandles = Math.floor(diffMinutes / intervalMinutes);
const minutesSinceLastCandle = diffMinutes % intervalMinutes;
if (minutesSinceLastCandle === 0 && diffMinutes !== 0) {
completedCandles -= 1;
}
const lastCandleMinutes = completedCandles * intervalMinutes;
const lastCandleTime = new Date(marketOpen);
lastCandleTime.setMinutes(marketOpen.getMinutes() + lastCandleMinutes);
return lastCandleTime;
}
// src/smartapi_utils.ts
async function getTokensLtpMap(exchangeTokens, smartapi) {
const ltpDataArray = await smartapi.fetchTokensLtp(exchangeTokens);
const ltpDataMap = (0, import_utils_core2.groupByLatestMap)(ltpDataArray, "tradingSymbol");
import_utils_core2.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 = (0, import_utils_core2.groupByKeyObject)(
instrumentDumps,
"exchange",
"symbolToken"
);
const ltpDataMap = await getTokensLtpMap(exchangeTokens, smartapi);
const createdAt = (0, import_utils_core.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) {
import_utils_core2.logger.w(
"candleDataArray is empty",
JSON.stringify((0, import_utils_core.convertDatesToStrings)(params))
);
return;
}
try {
const lastCompletedCandle = getLastCompletedMarketCandle(params.interval);
if (lastCompletedCandle != null) {
const lastCandle = candleDataArray[candleDataArray.length - 1];
const lastCandleDate = lastCandle.date;
if ((0, import_date_fns.isAfter)(lastCandleDate, lastCompletedCandle)) {
import_utils_core2.logger.d(
"not completed candle present. remove it",
(0, import_utils_core.toDatetimeString)(lastCandle.date)
);
candleDataArray.pop();
}
}
} catch (error) {
import_utils_core2.logger.e("error in removing not completed candle", error);
}
return candleDataArray;
}
async function getIndexLatestHistoricalData(args, smartapi) {
const days = candleFetchDayConfigs[args.interval];
const todate = (0, import_date_fns.endOfToday)();
const fromdate = (0, import_date_fns.startOfDay)((0, import_date_fns.subDays)(todate, days));
const params = { ...args, fromdate, todate };
return await getIndexHistoricalData(params, smartapi);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getIndexHistoricalData,
getIndexLatestHistoricalData,
getIndexScripLtpMap,
getManyScripLtpMap,
getManyScripLtpMapCache
});