bharosa 0.3.3 → 0.5.0
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/ANALYTICS-CONTRACT-SHA256 +1 -0
- package/CHANGELOG.md +2 -2
- package/MONTHLY-MARKET-CONTRACT-SHA256 +1 -1
- package/README.md +18 -7
- package/dist/analytics-contract.cjs +665 -0
- package/dist/analytics-contract.d.cts +2 -0
- package/dist/analytics-contract.d.ts +2 -0
- package/dist/analytics-types.cjs +2 -0
- package/dist/analytics-types.d.cts +103 -0
- package/dist/analytics-types.d.ts +103 -0
- package/dist/client-types.d.cts +17 -1
- package/dist/client-types.d.ts +17 -1
- package/dist/index.cjs +74 -19
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/monthly-market-data.cjs +3 -2
- package/dist/monthly-types.d.cts +1 -1
- package/dist/monthly-types.d.ts +1 -1
- package/dist/operation-types.d.cts +3 -0
- package/dist/operation-types.d.ts +3 -0
- package/dist/response-checks.cjs +68 -1
- package/dist/transport.cjs +18 -9
- package/dist/transport.d.cts +1 -1
- package/dist/transport.d.ts +1 -1
- package/dist/validate.cjs +3 -1
- package/docs/analytics.md +26 -0
- package/docs/getting-started.md +2 -2
- package/package.json +6 -3
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { RequestOptions } from "./client-types.cjs";
|
|
2
|
+
export type AnalyticsPeriod = "1y" | "3y" | "5y" | "since_inception";
|
|
3
|
+
export type AnalyticsMetric = {
|
|
4
|
+
status: "available";
|
|
5
|
+
value: string;
|
|
6
|
+
reason: null;
|
|
7
|
+
} | {
|
|
8
|
+
status: "unavailable";
|
|
9
|
+
value: null;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
export interface PerformanceSelection {
|
|
13
|
+
asOf: string;
|
|
14
|
+
periods?: AnalyticsPeriod[];
|
|
15
|
+
}
|
|
16
|
+
export interface AnalyticsEnvelope {
|
|
17
|
+
methodology_version: "ts-analytics-v1";
|
|
18
|
+
requested_as_of: string;
|
|
19
|
+
currency: "INR";
|
|
20
|
+
source_cutoff: string;
|
|
21
|
+
source_version: string;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface PerformancePeriod {
|
|
25
|
+
period: AnalyticsPeriod;
|
|
26
|
+
requested_start: string | null;
|
|
27
|
+
requested_end: string;
|
|
28
|
+
status: "available" | "unavailable";
|
|
29
|
+
reason: string | null;
|
|
30
|
+
total_return_pct: AnalyticsMetric;
|
|
31
|
+
cagr_pct: AnalyticsMetric;
|
|
32
|
+
}
|
|
33
|
+
export interface AnalyticsFreshnessPolicy {
|
|
34
|
+
nav_days: number;
|
|
35
|
+
aum_days: number;
|
|
36
|
+
ter_days: number;
|
|
37
|
+
category_min_funds: number;
|
|
38
|
+
category_min_coverage_pct: number;
|
|
39
|
+
}
|
|
40
|
+
export interface SchemePerformance extends AnalyticsEnvelope {
|
|
41
|
+
calculation_precision: "decimal_inputs_float64_returns";
|
|
42
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
43
|
+
available_history_start: string | null;
|
|
44
|
+
inception_basis: "verified_first_scheme_nav" | null;
|
|
45
|
+
scheme_nav_inception_date: string | null;
|
|
46
|
+
object: "scheme_performance";
|
|
47
|
+
scheme_id: string;
|
|
48
|
+
fund_id: string;
|
|
49
|
+
plan: string;
|
|
50
|
+
option: string;
|
|
51
|
+
basis: string;
|
|
52
|
+
periods: (PerformancePeriod & {
|
|
53
|
+
start_observation_date: string | null;
|
|
54
|
+
end_observation_date: string | null;
|
|
55
|
+
start_nav: string | null;
|
|
56
|
+
end_nav: string | null;
|
|
57
|
+
start_lag_days: number | null;
|
|
58
|
+
end_lag_days: number | null;
|
|
59
|
+
elapsed_days: number | null;
|
|
60
|
+
annualization_basis: "observed_nav_dates_365_25";
|
|
61
|
+
})[];
|
|
62
|
+
}
|
|
63
|
+
export interface CategorySelection {
|
|
64
|
+
asOf: string;
|
|
65
|
+
periods?: Exclude<AnalyticsPeriod, "since_inception">[];
|
|
66
|
+
metrics?: "return"[];
|
|
67
|
+
plan?: "direct" | "regular";
|
|
68
|
+
option?: "growth";
|
|
69
|
+
}
|
|
70
|
+
export interface CategoryStatistics extends AnalyticsEnvelope {
|
|
71
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
72
|
+
object: "category_statistics";
|
|
73
|
+
category: string;
|
|
74
|
+
cohort: {
|
|
75
|
+
policy: "current_classification_as_of_prices";
|
|
76
|
+
plan: "direct" | "regular";
|
|
77
|
+
option: "growth";
|
|
78
|
+
fund_count: number;
|
|
79
|
+
selected_scheme_count: number;
|
|
80
|
+
classification_date: string | null;
|
|
81
|
+
};
|
|
82
|
+
metrics: Record<string, AnalyticsMetric & {
|
|
83
|
+
method: "equal_weighted_arithmetic_mean";
|
|
84
|
+
return_type: "total_return" | "cagr" | null;
|
|
85
|
+
observation_date_min: string | null;
|
|
86
|
+
observation_date_max: string | null;
|
|
87
|
+
observed_elapsed_days_min: number | null;
|
|
88
|
+
observed_elapsed_days_max: number | null;
|
|
89
|
+
start_lag_days_max: number | null;
|
|
90
|
+
end_lag_days_max: number | null;
|
|
91
|
+
unit: string;
|
|
92
|
+
eligible_count: number;
|
|
93
|
+
valid_count: number;
|
|
94
|
+
missing_count: number;
|
|
95
|
+
stale_count: number;
|
|
96
|
+
invalid_count: number;
|
|
97
|
+
coverage_pct: string;
|
|
98
|
+
exclusions: Record<string, number>;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
export interface AnalyticsResource<P, R> {
|
|
102
|
+
retrieve(id: string, params: P, options?: RequestOptions): Promise<R>;
|
|
103
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { RequestOptions } from "./client-types.js";
|
|
2
|
+
export type AnalyticsPeriod = "1y" | "3y" | "5y" | "since_inception";
|
|
3
|
+
export type AnalyticsMetric = {
|
|
4
|
+
status: "available";
|
|
5
|
+
value: string;
|
|
6
|
+
reason: null;
|
|
7
|
+
} | {
|
|
8
|
+
status: "unavailable";
|
|
9
|
+
value: null;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
export interface PerformanceSelection {
|
|
13
|
+
asOf: string;
|
|
14
|
+
periods?: AnalyticsPeriod[];
|
|
15
|
+
}
|
|
16
|
+
export interface AnalyticsEnvelope {
|
|
17
|
+
methodology_version: "ts-analytics-v1";
|
|
18
|
+
requested_as_of: string;
|
|
19
|
+
currency: "INR";
|
|
20
|
+
source_cutoff: string;
|
|
21
|
+
source_version: string;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface PerformancePeriod {
|
|
25
|
+
period: AnalyticsPeriod;
|
|
26
|
+
requested_start: string | null;
|
|
27
|
+
requested_end: string;
|
|
28
|
+
status: "available" | "unavailable";
|
|
29
|
+
reason: string | null;
|
|
30
|
+
total_return_pct: AnalyticsMetric;
|
|
31
|
+
cagr_pct: AnalyticsMetric;
|
|
32
|
+
}
|
|
33
|
+
export interface AnalyticsFreshnessPolicy {
|
|
34
|
+
nav_days: number;
|
|
35
|
+
aum_days: number;
|
|
36
|
+
ter_days: number;
|
|
37
|
+
category_min_funds: number;
|
|
38
|
+
category_min_coverage_pct: number;
|
|
39
|
+
}
|
|
40
|
+
export interface SchemePerformance extends AnalyticsEnvelope {
|
|
41
|
+
calculation_precision: "decimal_inputs_float64_returns";
|
|
42
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
43
|
+
available_history_start: string | null;
|
|
44
|
+
inception_basis: "verified_first_scheme_nav" | null;
|
|
45
|
+
scheme_nav_inception_date: string | null;
|
|
46
|
+
object: "scheme_performance";
|
|
47
|
+
scheme_id: string;
|
|
48
|
+
fund_id: string;
|
|
49
|
+
plan: string;
|
|
50
|
+
option: string;
|
|
51
|
+
basis: string;
|
|
52
|
+
periods: (PerformancePeriod & {
|
|
53
|
+
start_observation_date: string | null;
|
|
54
|
+
end_observation_date: string | null;
|
|
55
|
+
start_nav: string | null;
|
|
56
|
+
end_nav: string | null;
|
|
57
|
+
start_lag_days: number | null;
|
|
58
|
+
end_lag_days: number | null;
|
|
59
|
+
elapsed_days: number | null;
|
|
60
|
+
annualization_basis: "observed_nav_dates_365_25";
|
|
61
|
+
})[];
|
|
62
|
+
}
|
|
63
|
+
export interface CategorySelection {
|
|
64
|
+
asOf: string;
|
|
65
|
+
periods?: Exclude<AnalyticsPeriod, "since_inception">[];
|
|
66
|
+
metrics?: "return"[];
|
|
67
|
+
plan?: "direct" | "regular";
|
|
68
|
+
option?: "growth";
|
|
69
|
+
}
|
|
70
|
+
export interface CategoryStatistics extends AnalyticsEnvelope {
|
|
71
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
72
|
+
object: "category_statistics";
|
|
73
|
+
category: string;
|
|
74
|
+
cohort: {
|
|
75
|
+
policy: "current_classification_as_of_prices";
|
|
76
|
+
plan: "direct" | "regular";
|
|
77
|
+
option: "growth";
|
|
78
|
+
fund_count: number;
|
|
79
|
+
selected_scheme_count: number;
|
|
80
|
+
classification_date: string | null;
|
|
81
|
+
};
|
|
82
|
+
metrics: Record<string, AnalyticsMetric & {
|
|
83
|
+
method: "equal_weighted_arithmetic_mean";
|
|
84
|
+
return_type: "total_return" | "cagr" | null;
|
|
85
|
+
observation_date_min: string | null;
|
|
86
|
+
observation_date_max: string | null;
|
|
87
|
+
observed_elapsed_days_min: number | null;
|
|
88
|
+
observed_elapsed_days_max: number | null;
|
|
89
|
+
start_lag_days_max: number | null;
|
|
90
|
+
end_lag_days_max: number | null;
|
|
91
|
+
unit: string;
|
|
92
|
+
eligible_count: number;
|
|
93
|
+
valid_count: number;
|
|
94
|
+
missing_count: number;
|
|
95
|
+
stale_count: number;
|
|
96
|
+
invalid_count: number;
|
|
97
|
+
coverage_pct: string;
|
|
98
|
+
exclusions: Record<string, number>;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
export interface AnalyticsResource<P, R> {
|
|
102
|
+
retrieve(id: string, params: P, options?: RequestOptions): Promise<R>;
|
|
103
|
+
}
|
package/dist/client-types.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.cjs";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.cjs";
|
|
2
3
|
import type { MarketDataClient, CurrentHoldingsInput, CurrentHoldingsResult } from "./market-types.cjs";
|
|
3
4
|
export type * from "./market-types.cjs";
|
|
@@ -23,7 +24,7 @@ interface BharosaBaseConfig {
|
|
|
23
24
|
readonly allowLocalhostHttp?: boolean;
|
|
24
25
|
readonly maxResponseBytes?: number;
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
+
type LegacyBharosaConfig = BharosaBaseConfig & ({
|
|
27
28
|
readonly auth: Auth;
|
|
28
29
|
readonly fetch?: typeof globalThis.fetch;
|
|
29
30
|
readonly transport?: never;
|
|
@@ -32,6 +33,17 @@ export type BharosaConfig = BharosaBaseConfig & ({
|
|
|
32
33
|
readonly auth?: never;
|
|
33
34
|
readonly fetch?: never;
|
|
34
35
|
});
|
|
36
|
+
/** Simple server-side API-key configuration. Account access remains server-authorized. */
|
|
37
|
+
export type BharosaConfig = LegacyBharosaConfig | {
|
|
38
|
+
readonly apiKey: string;
|
|
39
|
+
readonly account?: string;
|
|
40
|
+
readonly baseUrl?: string;
|
|
41
|
+
readonly allowLocalhostHttp?: boolean;
|
|
42
|
+
readonly maxResponseBytes?: number;
|
|
43
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
44
|
+
readonly auth?: never;
|
|
45
|
+
readonly transport?: never;
|
|
46
|
+
};
|
|
35
47
|
export interface RequestOptions {
|
|
36
48
|
idempotencyKey?: string;
|
|
37
49
|
signal?: AbortSignal;
|
|
@@ -175,7 +187,11 @@ export type FundObjectReferences = Omit<Fields<FundReferences>, "data"> & {
|
|
|
175
187
|
};
|
|
176
188
|
export interface ClientSurface {
|
|
177
189
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
190
|
+
readonly fundCategories: {
|
|
191
|
+
readonly statistics: A.AnalyticsResource<A.CategorySelection, A.CategoryStatistics>;
|
|
192
|
+
};
|
|
178
193
|
readonly mutualFundSchemes: {
|
|
194
|
+
readonly performance: A.AnalyticsResource<A.PerformanceSelection, A.SchemePerformance>;
|
|
179
195
|
readonly navs: {
|
|
180
196
|
readonly retrieve: MonthlyMarketClient["schemes"]["nav"];
|
|
181
197
|
};
|
package/dist/client-types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.js";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.js";
|
|
2
3
|
import type { MarketDataClient, CurrentHoldingsInput, CurrentHoldingsResult } from "./market-types.js";
|
|
3
4
|
export type * from "./market-types.js";
|
|
@@ -23,7 +24,7 @@ interface BharosaBaseConfig {
|
|
|
23
24
|
readonly allowLocalhostHttp?: boolean;
|
|
24
25
|
readonly maxResponseBytes?: number;
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
+
type LegacyBharosaConfig = BharosaBaseConfig & ({
|
|
27
28
|
readonly auth: Auth;
|
|
28
29
|
readonly fetch?: typeof globalThis.fetch;
|
|
29
30
|
readonly transport?: never;
|
|
@@ -32,6 +33,17 @@ export type BharosaConfig = BharosaBaseConfig & ({
|
|
|
32
33
|
readonly auth?: never;
|
|
33
34
|
readonly fetch?: never;
|
|
34
35
|
});
|
|
36
|
+
/** Simple server-side API-key configuration. Account access remains server-authorized. */
|
|
37
|
+
export type BharosaConfig = LegacyBharosaConfig | {
|
|
38
|
+
readonly apiKey: string;
|
|
39
|
+
readonly account?: string;
|
|
40
|
+
readonly baseUrl?: string;
|
|
41
|
+
readonly allowLocalhostHttp?: boolean;
|
|
42
|
+
readonly maxResponseBytes?: number;
|
|
43
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
44
|
+
readonly auth?: never;
|
|
45
|
+
readonly transport?: never;
|
|
46
|
+
};
|
|
35
47
|
export interface RequestOptions {
|
|
36
48
|
idempotencyKey?: string;
|
|
37
49
|
signal?: AbortSignal;
|
|
@@ -175,7 +187,11 @@ export type FundObjectReferences = Omit<Fields<FundReferences>, "data"> & {
|
|
|
175
187
|
};
|
|
176
188
|
export interface ClientSurface {
|
|
177
189
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
190
|
+
readonly fundCategories: {
|
|
191
|
+
readonly statistics: A.AnalyticsResource<A.CategorySelection, A.CategoryStatistics>;
|
|
192
|
+
};
|
|
178
193
|
readonly mutualFundSchemes: {
|
|
194
|
+
readonly performance: A.AnalyticsResource<A.PerformanceSelection, A.SchemePerformance>;
|
|
179
195
|
readonly navs: {
|
|
180
196
|
readonly retrieve: MonthlyMarketClient["schemes"]["nav"];
|
|
181
197
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -42,12 +42,52 @@ class Bharosa {
|
|
|
42
42
|
clients;
|
|
43
43
|
investors;
|
|
44
44
|
portfolios;
|
|
45
|
+
fundCategories;
|
|
45
46
|
mutualFunds;
|
|
46
47
|
mutualFundSchemes;
|
|
48
|
+
markets;
|
|
47
49
|
marketSnapshots;
|
|
48
50
|
marketData;
|
|
49
51
|
constructor(config) {
|
|
52
|
+
this.markets = baselineMarkets((0, transport_cjs_1.createTransport)(config, true));
|
|
50
53
|
const call = (0, transport_cjs_1.createTransport)(config);
|
|
54
|
+
const analyticsQuery = (q, extra = []) => {
|
|
55
|
+
(0, transport_cjs_1.keys)(q, ["asOf", "periods", ...extra]);
|
|
56
|
+
checkedDate(q.asOf);
|
|
57
|
+
(0, transport_cjs_1.check)(q.asOf.endsWith("-01"));
|
|
58
|
+
if (q.periods !== undefined)
|
|
59
|
+
(0, transport_cjs_1.check)(Array.isArray(q.periods) &&
|
|
60
|
+
q.periods.length > 0 &&
|
|
61
|
+
q.periods.length <= 4 &&
|
|
62
|
+
new Set(q.periods).size === q.periods.length &&
|
|
63
|
+
q.periods.every((p) => ["1y", "3y", "5y", "since_inception"].includes(p)));
|
|
64
|
+
return {
|
|
65
|
+
as_of: q.asOf,
|
|
66
|
+
...(q.periods === undefined ? {} : { periods: q.periods.join(",") }),
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
this.fundCategories = Object.freeze({
|
|
70
|
+
statistics: Object.freeze({
|
|
71
|
+
retrieve: (id, q, o) => {
|
|
72
|
+
const query = analyticsQuery(q, ["metrics", "plan", "option"]);
|
|
73
|
+
if (q.metrics !== undefined)
|
|
74
|
+
(0, transport_cjs_1.check)(Array.isArray(q.metrics) &&
|
|
75
|
+
q.metrics.length > 0 &&
|
|
76
|
+
q.metrics.length <= 3 &&
|
|
77
|
+
new Set(q.metrics).size === q.metrics.length &&
|
|
78
|
+
q.metrics.every((m) => m === "return"));
|
|
79
|
+
(0, transport_cjs_1.check)(!q.periods?.includes("since_inception"));
|
|
80
|
+
(0, transport_cjs_1.check)(!(q.metrics && !q.metrics.includes("return") && q.periods));
|
|
81
|
+
return call("analytics_category", {
|
|
82
|
+
id,
|
|
83
|
+
...query,
|
|
84
|
+
...(q.metrics ? { metrics: q.metrics.join(",") } : {}),
|
|
85
|
+
...(q.plan ? { plan: q.plan } : {}),
|
|
86
|
+
...(q.option ? { option: q.option } : {}),
|
|
87
|
+
}, undefined, o);
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
51
91
|
const list = (p) => {
|
|
52
92
|
(0, transport_cjs_1.keys)(p, ["limit", "startingAfter", "client"]);
|
|
53
93
|
return Object.fromEntries(Object.entries(p)
|
|
@@ -276,7 +316,10 @@ class Bharosa {
|
|
|
276
316
|
};
|
|
277
317
|
this.marketSnapshots = {
|
|
278
318
|
schemes: {
|
|
279
|
-
nav: (id, q, o) =>
|
|
319
|
+
nav: (id, q = {}, o) => {
|
|
320
|
+
(0, transport_cjs_1.keys)(q, ["asOf"]);
|
|
321
|
+
return call("monthly_nav", { id, ...(q.asOf === undefined ? {} : { as_of: q.asOf }) }, undefined, o);
|
|
322
|
+
},
|
|
280
323
|
expenseRatio: (id, q, o) => call("monthly_expense", { id, ...monthlyQuery(q) }, undefined, o),
|
|
281
324
|
valuation: (id, input = {}, o) => {
|
|
282
325
|
(0, transport_cjs_1.keys)(input, ["units", "asOf", "positionDate", "observedValue"]);
|
|
@@ -299,6 +342,9 @@ class Bharosa {
|
|
|
299
342
|
},
|
|
300
343
|
};
|
|
301
344
|
this.mutualFundSchemes = Object.freeze({
|
|
345
|
+
performance: Object.freeze({
|
|
346
|
+
retrieve: (id, q, o) => call("analytics_scheme", { id, ...analyticsQuery(q) }, undefined, o),
|
|
347
|
+
}),
|
|
302
348
|
navs: Object.freeze({ retrieve: this.marketSnapshots.schemes.nav }),
|
|
303
349
|
expenseRatios: Object.freeze({
|
|
304
350
|
retrieve: this.marketSnapshots.schemes.expenseRatio,
|
|
@@ -367,24 +413,33 @@ class BharosaMarket {
|
|
|
367
413
|
]);
|
|
368
414
|
const { apiKey, ...rest } = config;
|
|
369
415
|
const call = (0, transport_cjs_1.createTransport)({ ...rest, account: "me", auth: { type: "account_key", apiKey } }, true);
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
as_of: q.asOf,
|
|
374
|
-
...(q.limit === undefined ? {} : { limit: q.limit }),
|
|
375
|
-
...(q.startingAfter === undefined
|
|
376
|
-
? {}
|
|
377
|
-
: { starting_after: q.startingAfter }),
|
|
378
|
-
};
|
|
379
|
-
};
|
|
380
|
-
this.schemes = {
|
|
381
|
-
nav: (id, q, o) => call("monthly_nav", { id, ...query(q) }, undefined, o),
|
|
382
|
-
expenseRatio: (id, q, o) => call("monthly_expense", { id, ...query(q) }, undefined, o),
|
|
383
|
-
};
|
|
384
|
-
this.funds = {
|
|
385
|
-
portfolio: (id, q, o) => call("monthly_portfolio", { id, ...query(q) }, undefined, o),
|
|
386
|
-
holdings: (id, q, o) => call("monthly_holdings", { id, ...query(q, true) }, undefined, o),
|
|
387
|
-
};
|
|
416
|
+
const resources = baselineMarkets(call);
|
|
417
|
+
this.schemes = resources.schemes;
|
|
418
|
+
this.funds = resources.funds;
|
|
388
419
|
}
|
|
389
420
|
}
|
|
390
421
|
exports.BharosaMarket = BharosaMarket;
|
|
422
|
+
function baselineMarkets(call) {
|
|
423
|
+
const query = (q, paging = false) => {
|
|
424
|
+
(0, transport_cjs_1.keys)(q, paging ? ["asOf", "limit", "startingAfter"] : ["asOf"]);
|
|
425
|
+
return {
|
|
426
|
+
as_of: q.asOf,
|
|
427
|
+
...(q.limit === undefined ? {} : { limit: q.limit }),
|
|
428
|
+
...(q.startingAfter === undefined
|
|
429
|
+
? {}
|
|
430
|
+
: { starting_after: q.startingAfter }),
|
|
431
|
+
};
|
|
432
|
+
};
|
|
433
|
+
const schemes = {
|
|
434
|
+
nav: (id, q = {}, o) => {
|
|
435
|
+
(0, transport_cjs_1.keys)(q, ["asOf"]);
|
|
436
|
+
return call("monthly_nav", { id, ...(q.asOf === undefined ? {} : { as_of: q.asOf }) }, undefined, o);
|
|
437
|
+
},
|
|
438
|
+
expenseRatio: (id, q, o) => call("monthly_expense", { id, ...query(q) }, undefined, o),
|
|
439
|
+
};
|
|
440
|
+
const funds = {
|
|
441
|
+
portfolio: (id, q, o) => call("monthly_portfolio", { id, ...query(q) }, undefined, o),
|
|
442
|
+
holdings: (id, q, o) => call("monthly_holdings", { id, ...query(q, true) }, undefined, o),
|
|
443
|
+
};
|
|
444
|
+
return Object.freeze({ schemes: Object.freeze(schemes), funds: Object.freeze(funds) });
|
|
445
|
+
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type * from "./analytics-types.cjs";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.cjs";
|
|
2
3
|
export type * from "./monthly-types.cjs";
|
|
3
4
|
import type * as T from "./client-types.cjs";
|
|
@@ -9,8 +10,10 @@ export declare class Bharosa implements T.ClientSurface {
|
|
|
9
10
|
readonly clients: T.ClientSurface["clients"];
|
|
10
11
|
readonly investors: T.ClientSurface["investors"];
|
|
11
12
|
readonly portfolios: T.ClientSurface["portfolios"];
|
|
13
|
+
readonly fundCategories: T.ClientSurface["fundCategories"];
|
|
12
14
|
readonly mutualFunds: T.ClientSurface["mutualFunds"];
|
|
13
15
|
readonly mutualFundSchemes: T.ClientSurface["mutualFundSchemes"];
|
|
16
|
+
readonly markets: BaselineMarketClient;
|
|
14
17
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
15
18
|
readonly marketData: D.MarketDataClient;
|
|
16
19
|
constructor(config: T.BharosaConfig);
|
|
@@ -25,7 +28,16 @@ export interface BharosaMarketConfig {
|
|
|
25
28
|
}
|
|
26
29
|
/** Server-only registered-app monthly market access. No account or user token. */
|
|
27
30
|
export declare class BharosaMarket {
|
|
28
|
-
readonly schemes:
|
|
31
|
+
readonly schemes: BaselineMarketClient["schemes"];
|
|
29
32
|
readonly funds: MonthlyMarketClient["funds"];
|
|
30
33
|
constructor(config: BharosaMarketConfig);
|
|
31
34
|
}
|
|
35
|
+
export interface BaselineMarketClient {
|
|
36
|
+
readonly schemes: {
|
|
37
|
+
nav(id: string, selection?: {
|
|
38
|
+
asOf?: string;
|
|
39
|
+
}, options?: T.RequestOptions): ReturnType<MonthlyMarketClient["schemes"]["nav"]>;
|
|
40
|
+
expenseRatio: MonthlyMarketClient["schemes"]["expenseRatio"];
|
|
41
|
+
};
|
|
42
|
+
readonly funds: MonthlyMarketClient["funds"];
|
|
43
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type * from "./analytics-types.js";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.js";
|
|
2
3
|
export type * from "./monthly-types.js";
|
|
3
4
|
import type * as T from "./client-types.js";
|
|
@@ -9,8 +10,10 @@ export declare class Bharosa implements T.ClientSurface {
|
|
|
9
10
|
readonly clients: T.ClientSurface["clients"];
|
|
10
11
|
readonly investors: T.ClientSurface["investors"];
|
|
11
12
|
readonly portfolios: T.ClientSurface["portfolios"];
|
|
13
|
+
readonly fundCategories: T.ClientSurface["fundCategories"];
|
|
12
14
|
readonly mutualFunds: T.ClientSurface["mutualFunds"];
|
|
13
15
|
readonly mutualFundSchemes: T.ClientSurface["mutualFundSchemes"];
|
|
16
|
+
readonly markets: BaselineMarketClient;
|
|
14
17
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
15
18
|
readonly marketData: D.MarketDataClient;
|
|
16
19
|
constructor(config: T.BharosaConfig);
|
|
@@ -25,7 +28,16 @@ export interface BharosaMarketConfig {
|
|
|
25
28
|
}
|
|
26
29
|
/** Server-only registered-app monthly market access. No account or user token. */
|
|
27
30
|
export declare class BharosaMarket {
|
|
28
|
-
readonly schemes:
|
|
31
|
+
readonly schemes: BaselineMarketClient["schemes"];
|
|
29
32
|
readonly funds: MonthlyMarketClient["funds"];
|
|
30
33
|
constructor(config: BharosaMarketConfig);
|
|
31
34
|
}
|
|
35
|
+
export interface BaselineMarketClient {
|
|
36
|
+
readonly schemes: {
|
|
37
|
+
nav(id: string, selection?: {
|
|
38
|
+
asOf?: string;
|
|
39
|
+
}, options?: T.RequestOptions): ReturnType<MonthlyMarketClient["schemes"]["nav"]>;
|
|
40
|
+
expenseRatio: MonthlyMarketClient["schemes"]["expenseRatio"];
|
|
41
|
+
};
|
|
42
|
+
readonly funds: MonthlyMarketClient["funds"];
|
|
43
|
+
}
|
|
@@ -29,12 +29,13 @@ module.exports = {
|
|
|
29
29
|
{
|
|
30
30
|
"name": "as_of",
|
|
31
31
|
"in": "query",
|
|
32
|
-
"required":
|
|
32
|
+
"required": false,
|
|
33
33
|
"schema": {
|
|
34
34
|
"type": "string",
|
|
35
35
|
"format": "date",
|
|
36
36
|
"pattern": "^[0-9]{4}-[0-9]{2}-01$"
|
|
37
|
-
}
|
|
37
|
+
},
|
|
38
|
+
"description": "Omit for latest NAV on or before today in Asia/Kolkata. When supplied, must be the first of a month and not in the future. Actual observation date is returned separately."
|
|
38
39
|
}
|
|
39
40
|
],
|
|
40
41
|
"response": {
|
package/dist/monthly-types.d.cts
CHANGED
|
@@ -21,7 +21,7 @@ export interface MonthSelection {
|
|
|
21
21
|
}
|
|
22
22
|
export interface MonthlyMarketClient {
|
|
23
23
|
schemes: {
|
|
24
|
-
nav(id: string, query
|
|
24
|
+
nav(id: string, query?: Partial<MonthSelection>, options?: RequestOptions): Promise<MarketSnapshot<D.NavObservation>>;
|
|
25
25
|
expenseRatio(id: string, query: MonthSelection, options?: RequestOptions): Promise<MarketSnapshot<D.ExpenseObservation>>;
|
|
26
26
|
valuation(id: string, input?: D.ValuationInput, options?: RequestOptions): Promise<D.LatestNavValuation>;
|
|
27
27
|
};
|
package/dist/monthly-types.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface MonthSelection {
|
|
|
21
21
|
}
|
|
22
22
|
export interface MonthlyMarketClient {
|
|
23
23
|
schemes: {
|
|
24
|
-
nav(id: string, query
|
|
24
|
+
nav(id: string, query?: Partial<MonthSelection>, options?: RequestOptions): Promise<MarketSnapshot<D.NavObservation>>;
|
|
25
25
|
expenseRatio(id: string, query: MonthSelection, options?: RequestOptions): Promise<MarketSnapshot<D.ExpenseObservation>>;
|
|
26
26
|
valuation(id: string, input?: D.ValuationInput, options?: RequestOptions): Promise<D.LatestNavValuation>;
|
|
27
27
|
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.cjs";
|
|
1
2
|
import type * as S from "./monthly-types.cjs";
|
|
2
3
|
import type * as M from "./models.cjs";
|
|
3
4
|
import type * as D from "./market-types.cjs";
|
|
4
5
|
import type { CurrentMixEvidence } from "./client-types.cjs";
|
|
5
6
|
/** Each entry is the decoded response of the corresponding generated operation. */
|
|
6
7
|
export interface OperationResults {
|
|
8
|
+
analytics_scheme: A.SchemePerformance;
|
|
9
|
+
analytics_category: A.CategoryStatistics;
|
|
7
10
|
monthly_nav: S.MarketSnapshot<D.NavObservation>;
|
|
8
11
|
monthly_expense: S.MarketSnapshot<D.ExpenseObservation>;
|
|
9
12
|
monthly_portfolio: S.MarketSnapshot<D.FundPortfolio>;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.js";
|
|
1
2
|
import type * as S from "./monthly-types.js";
|
|
2
3
|
import type * as M from "./models.js";
|
|
3
4
|
import type * as D from "./market-types.js";
|
|
4
5
|
import type { CurrentMixEvidence } from "./client-types.js";
|
|
5
6
|
/** Each entry is the decoded response of the corresponding generated operation. */
|
|
6
7
|
export interface OperationResults {
|
|
8
|
+
analytics_scheme: A.SchemePerformance;
|
|
9
|
+
analytics_category: A.CategoryStatistics;
|
|
7
10
|
monthly_nav: S.MarketSnapshot<D.NavObservation>;
|
|
8
11
|
monthly_expense: S.MarketSnapshot<D.ExpenseObservation>;
|
|
9
12
|
monthly_portfolio: S.MarketSnapshot<D.FundPortfolio>;
|
package/dist/response-checks.cjs
CHANGED
|
@@ -121,9 +121,76 @@ function responseMatches(id, op, data, params, body, account) {
|
|
|
121
121
|
b("valuation_date") !== undefined &&
|
|
122
122
|
d("valuation_date") !== b("valuation_date")))
|
|
123
123
|
return false;
|
|
124
|
+
if (id.startsWith("analytics_")) {
|
|
125
|
+
if (id === "analytics_aum") {
|
|
126
|
+
if (d("requested_date") !== params.as_of ||
|
|
127
|
+
(d("observation_date") !== null &&
|
|
128
|
+
String(d("observation_date")) > String(params.as_of)))
|
|
129
|
+
return false;
|
|
130
|
+
if (d("status") === "available" &&
|
|
131
|
+
field(d("data"), "basis") === "reported_fund_total" &&
|
|
132
|
+
field(field(d("data"), "source"), "date") !== d("observation_date"))
|
|
133
|
+
return false;
|
|
134
|
+
if (d("status") === "available" &&
|
|
135
|
+
(field(d("data"), "fund_id") !== params.id ||
|
|
136
|
+
field(d("data"), "date") !== d("observation_date") ||
|
|
137
|
+
String(d("observation_date")) > String(params.as_of)))
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
if (d("requested_as_of") !== params.as_of)
|
|
142
|
+
return false;
|
|
143
|
+
const identity = id === "analytics_scheme"
|
|
144
|
+
? "scheme_id"
|
|
145
|
+
: id === "analytics_portfolio"
|
|
146
|
+
? "portfolio_id"
|
|
147
|
+
: "category";
|
|
148
|
+
if (d(identity) !== params.id)
|
|
149
|
+
return false;
|
|
150
|
+
if (id === "analytics_category") {
|
|
151
|
+
if (d("cohort", "plan") !== (params.plan ?? "direct") ||
|
|
152
|
+
d("cohort", "option") !== (params.option ?? "growth"))
|
|
153
|
+
return false;
|
|
154
|
+
const requested = String(params.metrics ?? "return").split(",");
|
|
155
|
+
const expected = requested.flatMap((m) => m === "return"
|
|
156
|
+
? String(params.periods ?? "1y,3y,5y")
|
|
157
|
+
.split(",")
|
|
158
|
+
.map((p) => "return_" + p)
|
|
159
|
+
: [m]);
|
|
160
|
+
for (const key of expected) {
|
|
161
|
+
const metric = d("metrics", key);
|
|
162
|
+
if (!(0, schema_cjs_1.record)(metric))
|
|
163
|
+
return false;
|
|
164
|
+
const eligible = Number(field(metric, "eligible_count")), valid = Number(field(metric, "valid_count"));
|
|
165
|
+
const excluded = [
|
|
166
|
+
"missing_count",
|
|
167
|
+
"stale_count",
|
|
168
|
+
"invalid_count",
|
|
169
|
+
].reduce((n, k) => n + Number(field(metric, k)), 0);
|
|
170
|
+
if (eligible !== d("cohort", "fund_count") ||
|
|
171
|
+
valid + excluded !== eligible)
|
|
172
|
+
return false;
|
|
173
|
+
if (field(metric, "status") === "available" &&
|
|
174
|
+
(valid < 3 || valid * 100 < eligible * 80))
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (id !== "analytics_category") {
|
|
179
|
+
const expected = String(params.periods ?? "1y,3y,5y").split(",");
|
|
180
|
+
const got = rows(d("periods"));
|
|
181
|
+
if (got.length !== expected.length ||
|
|
182
|
+
got.some((p, i) => field(p, "period") !== expected[i] ||
|
|
183
|
+
field(p, "requested_end") !== params.as_of ||
|
|
184
|
+
(id === "analytics_scheme" &&
|
|
185
|
+
(later(field(p, "start_observation_date"), field(p, "requested_start")) ||
|
|
186
|
+
later(field(p, "end_observation_date"), params.as_of)))))
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
124
191
|
if (id.startsWith("monthly_") && id !== "monthly_valuation") {
|
|
125
192
|
const observation = d("observation_date"), requested = d("requested_date"), data = d("data");
|
|
126
|
-
if (requested !== params.as_of)
|
|
193
|
+
if (!(id === "monthly_nav" && params.as_of === undefined) && requested !== params.as_of)
|
|
127
194
|
return false;
|
|
128
195
|
if (d("status") === "available") {
|
|
129
196
|
if (typeof observation !== "string" ||
|