sentisense 0.50.0 → 0.51.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/README.md CHANGED
@@ -212,7 +212,7 @@ client.stocks.getFundamentals("AAPL") // Financial data
212
212
  client.stocks.getShortInterest("GME") // Short interest
213
213
  client.stocks.getOptionsSummary("NVDA") // End-of-day options dossier
214
214
  client.stocks.getOptionsHistory("NVDA", { window: "2y" }) // Daily options aggregates over time
215
- client.stocks.getRating("AAPL") // SentiSense Rating: letter, percentile, dimensions
215
+ client.stocks.getRating("AAPL") // SentiSense Rating: score, letter, percentile, dimensions
216
216
  client.stocks.getAISummary("AAPL", { depth: "deep" }) // AI report (PRO)
217
217
  ```
218
218
 
@@ -426,7 +426,7 @@ client.entityMetrics.getDistribution("AAPL", "sentiment")
426
426
  client.entityMetrics.getDistribution("AAPL", "mentions", { dimension: "source" })
427
427
  ```
428
428
 
429
- Available metric types: `mentions`, `sentiment`, `sentisense_score`, `sentisense_rating`, `social_dominance`, `creators`. `sentisense_rating` is the SentiSense Rating percentile and is a time series only: it has no source breakdown, so `getDistribution` answers with an empty distribution for it.
429
+ Available metric types: `mentions`, `sentiment`, `sentisense_score`, `sentisense_rating`, `social_dominance`, `creators`. `sentisense_rating` is the SentiSense Rating score and is a time series only: it has no source breakdown, so `getDistribution` answers with an empty distribution for it.
430
430
 
431
431
  ### Options
432
432
 
@@ -444,12 +444,13 @@ A row whose baseline is still building carries its raw readings with the percent
444
444
 
445
445
  ### SentiSense Rating
446
446
 
447
- Where a stock ranks against the other stocks rated that day, as a letter and a percentile, plus the six dimensions the rank is blended from. It is a relative research signal for informational and educational purposes, not financial, investment or trading advice, and not a recommendation about any security. Every response carries the wording to display alongside a grade in `disclaimer`. [Methodology](https://sentisense.ai/methodology/#sentisense-rating).
447
+ Where a stock ranks against the other stocks rated that day, as a score, a letter and a percentile, plus the six dimensions the rank is blended from. It is a relative research signal for informational and educational purposes, not financial, investment or trading advice, and not a recommendation about any security. Every response carries the wording to display alongside a grade in `disclaimer`. [Methodology](https://sentisense.ai/methodology/#sentisense-rating).
448
448
 
449
449
  ```typescript
450
450
  const rating = await client.stocks.getRating("AAPL");
451
451
  if (rating.rated) {
452
- console.log(rating.letter, rating.percentile, "of", rating.ratedCount, "rated stocks");
452
+ console.log(rating.letter, rating.score, "percentile", rating.percentile, "of", rating.ratedCount);
453
+ for (const adj of rating.riskAdjustments ?? []) console.log(" ", adj.condition, -adj.points);
453
454
  for (const dim of rating.dimensions.filter((d) => d.present)) {
454
455
  console.log(" ", dim.label, dim.percentile);
455
456
  }
@@ -458,11 +459,15 @@ if (rating.rated) {
458
459
  }
459
460
  ```
460
461
 
461
- `StockRating` is a discriminated union on `rated`, so the `if` narrows to `letter`, `percentile`, `composite`, `ratedCount` and `methodologyVersion`, and the `else` narrows to `reason`, `dimensionsPresent` and `presentDimensions`. Branch on that flag rather than testing a field for `undefined`.
462
+ `getRating` returns `StockRatingResponse`, a discriminated union on `rated` of `StockRating` (graded) and `StockNotRated`. The `if` narrows to `score`, `letter`, `percentile`, `composite`, `ratedCount` and `methodologyVersion`, the `else` to `reason`, `dimensionsPresent` and `presentDimensions`. Branch on that flag rather than testing a field for `undefined`.
462
463
 
463
464
  Having no grade is a normal 200, not a 404: ETFs and tickers outside the swept universe answer that way, and `reason` is one of `stale`, `not_rated_today`, `insufficient_dimensions` or `insufficient_coverage_weight`. Only a ticker that resolves to nothing we track rejects with `NotFoundError`.
464
465
 
465
- `dimensions` always holds all six rows in a fixed order, including the ones with no data, which arrive with `present` false and a `null` percentile. Read `present` first and never substitute zero for a missing percentile: zero is the bottom of the cross-section, absence is not a position on it. Only the smart-money dimension carries `subLegs`. `letter` is served as stored rather than derived from `percentile`, so read it instead of computing your own bucket edges. For the daily history of a stock's percentile, ask `entityMetrics.getMetrics` for the `sentisense_rating` metric.
466
+ `dimensions` always holds all six rows in a fixed order, including the ones with no data, which arrive with `present` false and a `null` percentile. Read `present` first and never substitute zero for a missing percentile: zero is the bottom of the cross-section, absence is not a position on it. Only the smart-money dimension carries `subLegs`.
467
+
468
+ **`score` is not `percentile`.** `percentile` is the rank of the blended signals against the day's rated set. `score = percentile - sum(riskAdjustments.map((a) => a.points))`, floored at 10 when fewer than five dimensions are available, and it is the number `letter` bands (A 90, B 70, C 30, D 10). `bucketLetter` is the band the percentile alone would give, so the two letters differ by exactly what the conditions cost. `riskAdjustments` itemises that cost, `penaltyPoints` totals it, and `riskConditions` names the active ones from the `RiskCondition` union: `thin_coverage`, `weak_dimension`, `unprofitable`, `no_fundamentals`, `high_leverage`, `unseasoned_listing`, `small_market_cap`, `thin_liquidity`, `extended_price`, `insider_selling` and `institutional_outflow`.
469
+
470
+ All five are optional: a response served before they shipped omits them. For the daily history of a stock's score, ask `entityMetrics.getMetrics` for the `sentisense_rating` metric.
466
471
 
467
472
  ### Market mood & knowledge base
468
473
 
package/dist/cli.cjs CHANGED
@@ -1037,7 +1037,7 @@ var flowsCommand = {
1037
1037
  };
1038
1038
 
1039
1039
  // src/version.ts
1040
- var VERSION = "0.50.0";
1040
+ var VERSION = "0.51.0";
1041
1041
 
1042
1042
  // src/resources/analyst.ts
1043
1043
  var Analyst = class {
@@ -2079,10 +2079,10 @@ var Stocks = class {
2079
2079
  * security. `disclaimer` carries the wording to display alongside a grade. Methodology:
2080
2080
  * https://sentisense.ai/methodology/#sentisense-rating
2081
2081
  *
2082
- * **A discriminated union on `rated`.** `if (rating.rated)` narrows to `letter`,
2083
- * `percentile`, `composite`, `ratedCount` and `methodologyVersion`; the `else` branch
2084
- * narrows to `reason`, `dimensionsPresent` and `presentDimensions`. Branch on the flag
2085
- * rather than testing a field for `undefined`.
2082
+ * **A discriminated union on `rated`.** `if (rating.rated)` narrows to `score`,
2083
+ * `letter`, `percentile`, `composite`, `ratedCount` and `methodologyVersion`; the
2084
+ * `else` branch narrows to `reason`, `dimensionsPresent` and `presentDimensions`.
2085
+ * Branch on the flag rather than testing a field for `undefined`.
2086
2086
  *
2087
2087
  * **Having no grade is a normal 200, not a 404.** ETFs and tickers outside the swept
2088
2088
  * universe answer with `rated` false, and the composition still arrives so a card can
@@ -2092,11 +2092,22 @@ var Stocks = class {
2092
2092
  *
2093
2093
  * `dimensions` always holds all six rows in a fixed order, including the ones with no
2094
2094
  * data, which arrive with `present` false and a `null` percentile. Read `present` first
2095
- * and never read a missing percentile as zero. `letter` is served as stored rather than
2096
- * derived from `percentile`, so read it instead of computing your own bucket edges.
2095
+ * and never read a missing percentile as zero.
2097
2096
  *
2098
- * For the daily history of a stock's percentile, ask `client.entityMetrics.getMetrics`
2099
- * for the `sentisense_rating` metric.
2097
+ * **`score` and `percentile` are different numbers.** `percentile` is the rank of the
2098
+ * blended signals against the day's rated set, and
2099
+ * `score = percentile - sum(riskAdjustments.map((a) => a.points))`, floored at 10 when
2100
+ * fewer than five dimensions are available and at 0 otherwise. `letter` is the band
2101
+ * `score` falls in, at edges 90, 70, 30 and 10, while `bucketLetter` is the band the
2102
+ * percentile alone would fall in, so a difference between the two letters is exactly
2103
+ * what the conditions cost. `riskConditions` names the active ones, `riskAdjustments`
2104
+ * gives the points each cost (graded, up to 12 apiece), and `penaltyPoints` is their
2105
+ * sum. `letter` is served as stored, so read it instead of computing your own bucket
2106
+ * edges. The five fields arrive from the next API deploy onward and are optional, so a
2107
+ * response served before then still parses.
2108
+ *
2109
+ * For the daily history of a stock's score, ask `client.entityMetrics.getMetrics` for
2110
+ * the `sentisense_rating` metric.
2100
2111
  */
2101
2112
  async getRating(ticker) {
2102
2113
  return this.client.get(`/api/v1/rating/${encodeURIComponent(ticker.toUpperCase())}`);
package/dist/index.cjs CHANGED
@@ -1114,10 +1114,10 @@ var Stocks = class {
1114
1114
  * security. `disclaimer` carries the wording to display alongside a grade. Methodology:
1115
1115
  * https://sentisense.ai/methodology/#sentisense-rating
1116
1116
  *
1117
- * **A discriminated union on `rated`.** `if (rating.rated)` narrows to `letter`,
1118
- * `percentile`, `composite`, `ratedCount` and `methodologyVersion`; the `else` branch
1119
- * narrows to `reason`, `dimensionsPresent` and `presentDimensions`. Branch on the flag
1120
- * rather than testing a field for `undefined`.
1117
+ * **A discriminated union on `rated`.** `if (rating.rated)` narrows to `score`,
1118
+ * `letter`, `percentile`, `composite`, `ratedCount` and `methodologyVersion`; the
1119
+ * `else` branch narrows to `reason`, `dimensionsPresent` and `presentDimensions`.
1120
+ * Branch on the flag rather than testing a field for `undefined`.
1121
1121
  *
1122
1122
  * **Having no grade is a normal 200, not a 404.** ETFs and tickers outside the swept
1123
1123
  * universe answer with `rated` false, and the composition still arrives so a card can
@@ -1127,11 +1127,22 @@ var Stocks = class {
1127
1127
  *
1128
1128
  * `dimensions` always holds all six rows in a fixed order, including the ones with no
1129
1129
  * data, which arrive with `present` false and a `null` percentile. Read `present` first
1130
- * and never read a missing percentile as zero. `letter` is served as stored rather than
1131
- * derived from `percentile`, so read it instead of computing your own bucket edges.
1132
- *
1133
- * For the daily history of a stock's percentile, ask `client.entityMetrics.getMetrics`
1134
- * for the `sentisense_rating` metric.
1130
+ * and never read a missing percentile as zero.
1131
+ *
1132
+ * **`score` and `percentile` are different numbers.** `percentile` is the rank of the
1133
+ * blended signals against the day's rated set, and
1134
+ * `score = percentile - sum(riskAdjustments.map((a) => a.points))`, floored at 10 when
1135
+ * fewer than five dimensions are available and at 0 otherwise. `letter` is the band
1136
+ * `score` falls in, at edges 90, 70, 30 and 10, while `bucketLetter` is the band the
1137
+ * percentile alone would fall in, so a difference between the two letters is exactly
1138
+ * what the conditions cost. `riskConditions` names the active ones, `riskAdjustments`
1139
+ * gives the points each cost (graded, up to 12 apiece), and `penaltyPoints` is their
1140
+ * sum. `letter` is served as stored, so read it instead of computing your own bucket
1141
+ * edges. The five fields arrive from the next API deploy onward and are optional, so a
1142
+ * response served before then still parses.
1143
+ *
1144
+ * For the daily history of a stock's score, ask `client.entityMetrics.getMetrics` for
1145
+ * the `sentisense_rating` metric.
1135
1146
  */
1136
1147
  async getRating(ticker) {
1137
1148
  return this.client.get(`/api/v1/rating/${encodeURIComponent(ticker.toUpperCase())}`);
@@ -1215,7 +1226,7 @@ var Trackers = class {
1215
1226
  };
1216
1227
 
1217
1228
  // src/version.ts
1218
- var VERSION = "0.50.0";
1229
+ var VERSION = "0.51.0";
1219
1230
 
1220
1231
  // src/client.ts
1221
1232
  var DEFAULT_BASE_URL = "https://app.sentisense.ai";