@ganaka/sdk 1.0.1 → 1.0.3
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.d.ts +20 -10
- package/dist/index.js +125 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +125 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -79,7 +79,7 @@ declare const fetchCandles: ({ developerToken, apiDomain, runId, currentTimestam
|
|
|
79
79
|
developerToken: string;
|
|
80
80
|
apiDomain: string;
|
|
81
81
|
runId: string | null;
|
|
82
|
-
currentTimestamp:
|
|
82
|
+
currentTimestamp: string;
|
|
83
83
|
currentTimezone?: string;
|
|
84
84
|
}) => (params: default_2.infer<typeof v1_developer_groww_schemas.getGrowwHistoricalCandles.query>) => Promise<default_2.infer<typeof v1_developer_groww_schemas.getGrowwHistoricalCandles.response>["data"]>;
|
|
85
85
|
|
|
@@ -89,7 +89,7 @@ declare const fetchQuote: ({ developerToken, apiDomain, runId, currentTimestamp,
|
|
|
89
89
|
developerToken: string;
|
|
90
90
|
apiDomain: string;
|
|
91
91
|
runId: string | null;
|
|
92
|
-
currentTimestamp:
|
|
92
|
+
currentTimestamp: string;
|
|
93
93
|
currentTimezone?: string;
|
|
94
94
|
}) => (params: default_2.infer<typeof v1_developer_groww_schemas.getGrowwQuote.query>) => Promise<default_2.infer<typeof v1_developer_groww_schemas.getGrowwQuote.response>["data"] | null>;
|
|
95
95
|
|
|
@@ -99,9 +99,13 @@ declare const fetchQuoteTimeline: ({ developerToken, apiDomain, runId, currentTi
|
|
|
99
99
|
developerToken: string;
|
|
100
100
|
apiDomain: string;
|
|
101
101
|
runId: string | null;
|
|
102
|
-
currentTimestamp:
|
|
102
|
+
currentTimestamp: string;
|
|
103
103
|
currentTimezone?: string;
|
|
104
|
-
}) => (symbol: string,
|
|
104
|
+
}) => (symbol: string,
|
|
105
|
+
/**
|
|
106
|
+
* Date in IST string format (YYYY-MM-DD)
|
|
107
|
+
*/
|
|
108
|
+
date: string) => Promise<default_2.infer<typeof v1_developer_groww_schemas.getGrowwQuoteTimeline.response>["data"]["quoteTimeline"]>;
|
|
105
109
|
|
|
106
110
|
export declare type FetchQuoteTimelineResponse = Awaited<ReturnType<ReturnType<typeof fetchQuoteTimeline>>>;
|
|
107
111
|
|
|
@@ -109,7 +113,7 @@ declare const fetchShortlist: ({ developerToken, apiDomain, runId, currentTimest
|
|
|
109
113
|
developerToken: string;
|
|
110
114
|
apiDomain: string;
|
|
111
115
|
runId: string | null;
|
|
112
|
-
currentTimestamp:
|
|
116
|
+
currentTimestamp: string;
|
|
113
117
|
currentTimezone?: string;
|
|
114
118
|
}) => (queryParams: default_2.infer<typeof v1_developer_lists_schemas.getLists.query>) => Promise<default_2.infer<typeof v1_developer_lists_schemas.getLists.response>["data"] | null>;
|
|
115
119
|
|
|
@@ -117,8 +121,10 @@ export declare type FetchShortlistResponse = Awaited<ReturnType<ReturnType<typeo
|
|
|
117
121
|
|
|
118
122
|
export declare function ganaka<T>({ fn, startTime, endTime, intervalMinutes, deleteRunAfterCompletion, }: {
|
|
119
123
|
fn: (context: RunContext) => Promise<T>;
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
/** Start time in IST string format (YYYY-MM-DDTHH:mm:ss) */
|
|
125
|
+
startTime: string;
|
|
126
|
+
/** End time in IST string format (YYYY-MM-DDTHH:mm:ss) */
|
|
127
|
+
endTime: string;
|
|
122
128
|
intervalMinutes: number;
|
|
123
129
|
/**
|
|
124
130
|
* Delete run after completion.
|
|
@@ -172,8 +178,8 @@ declare const getCandles: {
|
|
|
172
178
|
low: z.ZodNumber;
|
|
173
179
|
close: z.ZodNumber;
|
|
174
180
|
}, z.core.$strip>>;
|
|
175
|
-
start_time: z.ZodString
|
|
176
|
-
end_time: z.ZodString
|
|
181
|
+
start_time: z.ZodNullable<z.ZodString>;
|
|
182
|
+
end_time: z.ZodNullable<z.ZodString>;
|
|
177
183
|
interval_in_minutes: z.ZodNumber;
|
|
178
184
|
}, z.core.$strip>;
|
|
179
185
|
}, z.core.$strip>;
|
|
@@ -752,7 +758,11 @@ export declare interface RunContext {
|
|
|
752
758
|
fetchQuote: ReturnType<typeof fetchQuote>;
|
|
753
759
|
fetchQuoteTimeline: ReturnType<typeof fetchQuoteTimeline>;
|
|
754
760
|
fetchShortlist: ReturnType<typeof fetchShortlist>;
|
|
755
|
-
|
|
761
|
+
/**
|
|
762
|
+
* Current timestamp in IST string format (YYYY-MM-DDTHH:mm:ss)
|
|
763
|
+
* for every loop iteration
|
|
764
|
+
*/
|
|
765
|
+
currentTimestamp: string;
|
|
756
766
|
}
|
|
757
767
|
|
|
758
768
|
declare const signIn: {
|
package/dist/index.js
CHANGED
|
@@ -4402,8 +4402,8 @@ const p = object({
|
|
|
4402
4402
|
close: number$1()
|
|
4403
4403
|
})
|
|
4404
4404
|
),
|
|
4405
|
-
start_time: string(),
|
|
4406
|
-
end_time: string(),
|
|
4405
|
+
start_time: string().nullable(),
|
|
4406
|
+
end_time: string().nullable(),
|
|
4407
4407
|
interval_in_minutes: number$1()
|
|
4408
4408
|
})
|
|
4409
4409
|
})
|
|
@@ -7924,8 +7924,7 @@ const fetchCandles = ({
|
|
|
7924
7924
|
headers["X-Run-Id"] = runId;
|
|
7925
7925
|
}
|
|
7926
7926
|
if (currentTimestamp) {
|
|
7927
|
-
|
|
7928
|
-
headers["X-Current-Timestamp"] = timestampStr;
|
|
7927
|
+
headers["X-Current-Timestamp"] = currentTimestamp;
|
|
7929
7928
|
}
|
|
7930
7929
|
if (currentTimezone) {
|
|
7931
7930
|
headers["X-Current-Timezone"] = currentTimezone;
|
|
@@ -7969,8 +7968,7 @@ const fetchQuote = ({
|
|
|
7969
7968
|
headers["X-Run-Id"] = runId;
|
|
7970
7969
|
}
|
|
7971
7970
|
if (currentTimestamp) {
|
|
7972
|
-
|
|
7973
|
-
headers["X-Current-Timestamp"] = timestampStr;
|
|
7971
|
+
headers["X-Current-Timestamp"] = currentTimestamp;
|
|
7974
7972
|
}
|
|
7975
7973
|
if (currentTimezone) {
|
|
7976
7974
|
headers["X-Current-Timezone"] = currentTimezone;
|
|
@@ -8002,10 +8000,9 @@ const fetchQuoteTimeline = ({
|
|
|
8002
8000
|
throw new Error("Developer token not found. Please set DEVELOPER_KEY environment variable.");
|
|
8003
8001
|
}
|
|
8004
8002
|
try {
|
|
8005
|
-
const dateStr = dayjs.tz(date2, currentTimezone).format("YYYY-MM-DD");
|
|
8006
8003
|
const validatedParams = _e.getGrowwQuoteTimeline.query.parse({
|
|
8007
8004
|
symbol,
|
|
8008
|
-
date:
|
|
8005
|
+
date: date2
|
|
8009
8006
|
});
|
|
8010
8007
|
const headers = {
|
|
8011
8008
|
Authorization: `Bearer ${developerToken}`
|
|
@@ -8014,8 +8011,7 @@ const fetchQuoteTimeline = ({
|
|
|
8014
8011
|
headers["X-Run-Id"] = runId;
|
|
8015
8012
|
}
|
|
8016
8013
|
if (currentTimestamp) {
|
|
8017
|
-
|
|
8018
|
-
headers["X-Current-Timestamp"] = timestampStr;
|
|
8014
|
+
headers["X-Current-Timestamp"] = currentTimestamp;
|
|
8019
8015
|
}
|
|
8020
8016
|
if (currentTimezone) {
|
|
8021
8017
|
headers["X-Current-Timezone"] = currentTimezone;
|
|
@@ -8059,8 +8055,7 @@ const fetchShortlist = ({
|
|
|
8059
8055
|
headers["X-Run-Id"] = runId;
|
|
8060
8056
|
}
|
|
8061
8057
|
if (currentTimestamp) {
|
|
8062
|
-
|
|
8063
|
-
headers["X-Current-Timestamp"] = timestampStr;
|
|
8058
|
+
headers["X-Current-Timestamp"] = currentTimestamp;
|
|
8064
8059
|
}
|
|
8065
8060
|
if (currentTimezone) {
|
|
8066
8061
|
headers["X-Current-Timezone"] = currentTimezone;
|
|
@@ -8154,7 +8149,7 @@ async function retryWithBackoff(fn, maxRetries = 3, baseDelayMs = 1e3) {
|
|
|
8154
8149
|
throw lastError;
|
|
8155
8150
|
}
|
|
8156
8151
|
const placeOrder = ({ runId, apiClient }) => async (data) => {
|
|
8157
|
-
|
|
8152
|
+
logger.debug(`data: ${JSON.stringify(data)}`);
|
|
8158
8153
|
if (runId) {
|
|
8159
8154
|
try {
|
|
8160
8155
|
await retryWithBackoff(
|
|
@@ -8270,73 +8265,144 @@ class ApiClient {
|
|
|
8270
8265
|
}
|
|
8271
8266
|
}
|
|
8272
8267
|
}
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
}
|
|
8268
|
+
var calendar$1 = { exports: {} };
|
|
8269
|
+
(function(module2, exports$1) {
|
|
8270
|
+
!function(e, t2) {
|
|
8271
|
+
module2.exports = t2();
|
|
8272
|
+
}(commonjsGlobal, function() {
|
|
8273
|
+
return function(e, t2, a) {
|
|
8274
|
+
var n2 = "h:mm A", d2 = { lastDay: "[Yesterday at] " + n2, sameDay: "[Today at] " + n2, nextDay: "[Tomorrow at] " + n2, nextWeek: "dddd [at] " + n2, lastWeek: "[Last] dddd [at] " + n2, sameElse: "MM/DD/YYYY" };
|
|
8275
|
+
t2.prototype.calendar = function(e2, t3) {
|
|
8276
|
+
var n3 = t3 || this.$locale().calendar || d2, o2 = a(e2 || void 0).startOf("d"), s = this.diff(o2, "d", true), i2 = "sameElse", f2 = s < -6 ? i2 : s < -1 ? "lastWeek" : s < 0 ? "lastDay" : s < 1 ? "sameDay" : s < 2 ? "nextDay" : s < 7 ? "nextWeek" : i2, l2 = n3[f2] || d2[f2];
|
|
8277
|
+
return "function" == typeof l2 ? l2.call(this, a()) : this.format(l2);
|
|
8278
|
+
};
|
|
8279
|
+
};
|
|
8280
|
+
});
|
|
8281
|
+
})(calendar$1);
|
|
8282
|
+
var calendarExports = calendar$1.exports;
|
|
8283
|
+
const calendar = /* @__PURE__ */ getDefaultExportFromCjs(calendarExports);
|
|
8284
|
+
var relativeTime$1 = { exports: {} };
|
|
8285
|
+
(function(module2, exports$1) {
|
|
8286
|
+
!function(r2, e) {
|
|
8287
|
+
module2.exports = e();
|
|
8288
|
+
}(commonjsGlobal, function() {
|
|
8289
|
+
return function(r2, e, t2) {
|
|
8290
|
+
r2 = r2 || {};
|
|
8291
|
+
var n2 = e.prototype, o2 = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" };
|
|
8292
|
+
function i2(r3, e2, t3, o3) {
|
|
8293
|
+
return n2.fromToBase(r3, e2, t3, o3);
|
|
8294
|
+
}
|
|
8295
|
+
t2.en.relativeTime = o2, n2.fromToBase = function(e2, n3, i3, d3, u) {
|
|
8296
|
+
for (var f2, a, s, l2 = i3.$locale().relativeTime || o2, h = r2.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m2 = h.length, c2 = 0; c2 < m2; c2 += 1) {
|
|
8297
|
+
var y2 = h[c2];
|
|
8298
|
+
y2.d && (f2 = d3 ? t2(e2).diff(i3, y2.d, true) : i3.diff(e2, y2.d, true));
|
|
8299
|
+
var p2 = (r2.rounding || Math.round)(Math.abs(f2));
|
|
8300
|
+
if (s = f2 > 0, p2 <= y2.r || !y2.r) {
|
|
8301
|
+
p2 <= 1 && c2 > 0 && (y2 = h[c2 - 1]);
|
|
8302
|
+
var v2 = l2[y2.l];
|
|
8303
|
+
u && (p2 = u("" + p2)), a = "string" == typeof v2 ? v2.replace("%d", p2) : v2(p2, n3, y2.l, s);
|
|
8304
|
+
break;
|
|
8305
|
+
}
|
|
8306
|
+
}
|
|
8307
|
+
if (n3) return a;
|
|
8308
|
+
var M2 = s ? l2.future : l2.past;
|
|
8309
|
+
return "function" == typeof M2 ? M2(a) : M2.replace("%s", a);
|
|
8310
|
+
}, n2.to = function(r3, e2) {
|
|
8311
|
+
return i2(r3, e2, this, true);
|
|
8312
|
+
}, n2.from = function(r3, e2) {
|
|
8313
|
+
return i2(r3, e2, this);
|
|
8314
|
+
};
|
|
8315
|
+
var d2 = function(r3) {
|
|
8316
|
+
return r3.$u ? t2.utc() : t2();
|
|
8317
|
+
};
|
|
8318
|
+
n2.toNow = function(r3) {
|
|
8319
|
+
return this.to(d2(this), r3);
|
|
8320
|
+
}, n2.fromNow = function(r3) {
|
|
8321
|
+
return this.from(d2(this), r3);
|
|
8322
|
+
};
|
|
8323
|
+
};
|
|
8324
|
+
});
|
|
8325
|
+
})(relativeTime$1);
|
|
8326
|
+
var relativeTimeExports = relativeTime$1.exports;
|
|
8327
|
+
const relativeTime = /* @__PURE__ */ getDefaultExportFromCjs(relativeTimeExports);
|
|
8328
|
+
dayjs.extend(utc);
|
|
8329
|
+
dayjs.extend(timezone);
|
|
8330
|
+
dayjs.extend(calendar);
|
|
8331
|
+
dayjs.extend(relativeTime);
|
|
8285
8332
|
function sleep(ms) {
|
|
8286
8333
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8287
8334
|
}
|
|
8288
8335
|
async function runMinuteLoop({
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8336
|
+
startTimeDayJS,
|
|
8337
|
+
endTimeDayJS,
|
|
8338
|
+
intervalMinutes,
|
|
8339
|
+
callback
|
|
8293
8340
|
}) {
|
|
8294
|
-
|
|
8295
|
-
|
|
8341
|
+
let currentISTDayJS = dayjs.utc().tz("Asia/Kolkata");
|
|
8342
|
+
logger.debug(`currentIST: ${currentISTDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
|
|
8343
|
+
logger.debug(`startTime: ${startTimeDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
|
|
8344
|
+
logger.debug(`endTime: ${endTimeDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
|
|
8345
|
+
const isSimulationMode = currentISTDayJS.isAfter(endTimeDayJS);
|
|
8296
8346
|
if (isSimulationMode) {
|
|
8297
|
-
|
|
8347
|
+
logger.info("Current time is after endTime, simulating loop");
|
|
8348
|
+
}
|
|
8349
|
+
if (currentISTDayJS.isBefore(startTimeDayJS)) {
|
|
8350
|
+
const delayUntilStart = startTimeDayJS.diff(currentISTDayJS, "millisecond");
|
|
8351
|
+
logger.info(
|
|
8352
|
+
`Starting loop ${startTimeDayJS.from(currentISTDayJS)} at ${startTimeDayJS.format(
|
|
8353
|
+
"YYYY-MM-DD HH:mm"
|
|
8354
|
+
)}`
|
|
8355
|
+
);
|
|
8356
|
+
await sleep(delayUntilStart);
|
|
8357
|
+
currentISTDayJS = currentISTDayJS.add(delayUntilStart, "millisecond");
|
|
8358
|
+
}
|
|
8359
|
+
if (currentISTDayJS.isAfter(startTimeDayJS) && currentISTDayJS.isBefore(endTimeDayJS)) {
|
|
8360
|
+
startTimeDayJS = currentISTDayJS;
|
|
8298
8361
|
}
|
|
8299
|
-
const
|
|
8300
|
-
const startMinute = startDate.minute();
|
|
8362
|
+
const startMinute = startTimeDayJS.minute();
|
|
8301
8363
|
const minutesToFirstBoundary = intervalMinutes - startMinute % intervalMinutes;
|
|
8302
|
-
const isOnBoundary = startMinute % intervalMinutes === 0 &&
|
|
8303
|
-
let
|
|
8364
|
+
const isOnBoundary = startMinute % intervalMinutes === 0 && startTimeDayJS.second() === 0 && startTimeDayJS.millisecond() === 0;
|
|
8365
|
+
let nextBoundaryDayJS;
|
|
8304
8366
|
if (isOnBoundary) {
|
|
8305
|
-
|
|
8367
|
+
nextBoundaryDayJS = startTimeDayJS;
|
|
8306
8368
|
} else {
|
|
8307
|
-
|
|
8369
|
+
nextBoundaryDayJS = startTimeDayJS.add(minutesToFirstBoundary, "minute").second(0).millisecond(0);
|
|
8308
8370
|
}
|
|
8371
|
+
logger.debug(`nextBoundary: ${nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
|
|
8309
8372
|
if (isSimulationMode) {
|
|
8310
|
-
while (
|
|
8373
|
+
while (nextBoundaryDayJS.isBefore(endTimeDayJS) || nextBoundaryDayJS.isSame(endTimeDayJS)) {
|
|
8311
8374
|
try {
|
|
8312
|
-
await callback(
|
|
8375
|
+
await callback(nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss"));
|
|
8313
8376
|
} catch (error) {
|
|
8314
8377
|
console.error(
|
|
8315
|
-
`Error executing callback at ${
|
|
8378
|
+
`Error executing callback at ${nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss")}:`,
|
|
8316
8379
|
error
|
|
8317
8380
|
);
|
|
8318
8381
|
}
|
|
8319
|
-
|
|
8382
|
+
nextBoundaryDayJS = nextBoundaryDayJS.add(intervalMinutes, "minute");
|
|
8320
8383
|
}
|
|
8321
8384
|
return;
|
|
8322
8385
|
}
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
}
|
|
8326
|
-
while (nextBoundary <= endTime) {
|
|
8327
|
-
const delay = nextBoundary.getTime() - Date.now();
|
|
8386
|
+
while (nextBoundaryDayJS.isBefore(endTimeDayJS) || nextBoundaryDayJS.isSame(endTimeDayJS)) {
|
|
8387
|
+
const delay = nextBoundaryDayJS.diff(currentISTDayJS, "millisecond");
|
|
8328
8388
|
if (delay > 0) {
|
|
8389
|
+
logger.info(
|
|
8390
|
+
`Waiting for ${nextBoundaryDayJS.from(
|
|
8391
|
+
currentISTDayJS,
|
|
8392
|
+
true
|
|
8393
|
+
)} to reach next execution time: ${nextBoundaryDayJS.format("YYYY-MM-DD HH:mm:ss")}`
|
|
8394
|
+
);
|
|
8329
8395
|
await sleep(delay);
|
|
8330
8396
|
}
|
|
8331
8397
|
try {
|
|
8332
|
-
await callback(
|
|
8398
|
+
await callback(nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss"));
|
|
8333
8399
|
} catch (error) {
|
|
8334
8400
|
console.error(
|
|
8335
|
-
`Error executing callback at ${
|
|
8401
|
+
`Error executing callback at ${nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss")}:`,
|
|
8336
8402
|
error
|
|
8337
8403
|
);
|
|
8338
8404
|
}
|
|
8339
|
-
|
|
8405
|
+
nextBoundaryDayJS = nextBoundaryDayJS.add(intervalMinutes, "minute");
|
|
8340
8406
|
}
|
|
8341
8407
|
}
|
|
8342
8408
|
dotenv.config();
|
|
@@ -8357,10 +8423,15 @@ async function ganaka({
|
|
|
8357
8423
|
);
|
|
8358
8424
|
}
|
|
8359
8425
|
const apiClient = new ApiClient({ developerToken, apiDomain });
|
|
8426
|
+
const startTimeDayJS = dayjs.tz(startTime, "Asia/Kolkata");
|
|
8427
|
+
const endTimeDayJS = dayjs.tz(endTime, "Asia/Kolkata");
|
|
8428
|
+
if (startTimeDayJS.isAfter(endTimeDayJS)) {
|
|
8429
|
+
throw new Error("Start time cannot be after end time");
|
|
8430
|
+
}
|
|
8360
8431
|
let runId = null;
|
|
8361
8432
|
const createRunBody = {
|
|
8362
|
-
start_datetime:
|
|
8363
|
-
end_datetime:
|
|
8433
|
+
start_datetime: startTime,
|
|
8434
|
+
end_datetime: endTime,
|
|
8364
8435
|
timezone: "Asia/Kolkata"
|
|
8365
8436
|
};
|
|
8366
8437
|
try {
|
|
@@ -8384,8 +8455,8 @@ async function ganaka({
|
|
|
8384
8455
|
}
|
|
8385
8456
|
try {
|
|
8386
8457
|
await runMinuteLoop({
|
|
8387
|
-
|
|
8388
|
-
|
|
8458
|
+
startTimeDayJS,
|
|
8459
|
+
endTimeDayJS,
|
|
8389
8460
|
intervalMinutes,
|
|
8390
8461
|
callback: async (currentTimestamp) => {
|
|
8391
8462
|
await fn({
|