fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

Sector-Specific Weight Calibration

Install and import#

bash
npm install fintech-algorithms
ts
import { sectorSpecificWeightCalibration } from "fintech-algorithms/fundamental-analysis-and-valuation/sector-specific-equity-scoring/sector-specific-weight-calibration";

Signature#

sectorSpecificWeightCalibration(data)

Fits component weights by projected gradient descent on a logistic model of the labelled outcome, keeping the weights nonnegative and summing to 1 at every step and pulling them back toward the declared base weights with a ridge term. Splits the history in time and keeps the fitted weights only when they beat the base weights on the held-out Brier score.

Parameters#

NameTypeNotes
dataRecordValueA plain object. framework must be the string sector-weight-calibration-teaching-v1. component_names is an array of at least two unique nonempty strings; base_weights is an object keyed by exactly those names, nonnegative and summing to 1. feature_rows is an array of at least twelve rows, each a numeric array aligned to component_names with every score in [0, 100]; labels and observation_dates must match it in length, labels being 0 or 1 and dates being strictly increasing YYYY-MM-DD strings. train_end_index splits the rows in time. learning_rate, logit_slope and iterations must be positive, ridge_penalty nonnegative.
min_rows: 12 · min_training_rows: 8 · min_validation_rows: 4 · max_iterations: 5000

Returns#

{ state: string; method: string; component_names: string[]; base_weights: Record<string, number>; candidate_weights: Record<string, number>; selected_weights: Record<string, number>; candidate_intercept: number; selected_intercept: number; base_train_brier: number; base_validation_brier: number; candidate_train_brier: number; candidate_validation_brier: number; selected_validation_brier: number; weight_shift_l1: number; train_rows: number; validation_rows: number; coverage_ratio: number; reason: string }

candidate_weights and candidate_intercept are the fitted values; selected_weights and selected_intercept are those same values when the candidate validation Brier score is at or below the base one, and otherwise the base weights with a zero intercept. The four Brier fields report train and validation loss for base and candidate, and selected_validation_brier repeats whichever was chosen. weight_shift_l1 is the summed absolute move from base to candidate, and train_rows and validation_rows record the split sizes. state is calibrated-improved or retain-base-weights. method is nonnegative-simplex-logloss-v1 and coverage_ratio is 1.

Errors#

  • When data is not a plain object, or a feature value is not a finite number — throws TypeError
  • When an observation date is not a YYYY-MM-DD string — throws TypeError
  • When framework is not sector-weight-calibration-teaching-v1 — throws RangeError
  • When component_names is not at least two unique nonempty strings — throws RangeError
  • When feature_rows holds fewer than 12 observations, or labels or observation_dates do not match its length — throws RangeError
  • When a feature row does not match component_names in length, or a score falls outside [0, 100] — throws RangeError
  • When a label is not 0 or 1, or observation_dates is not strictly increasing — throws RangeError
  • When train_end_index leaves fewer than 8 training or 4 validation rows — throws RangeError
  • When base_weights does not match component_names, is negative, or does not sum to 1 within 1e-9 — throws RangeError
  • When learning_rate, logit_slope or iterations is not positive, ridge_penalty is negative, or iterations exceeds 5000 — throws RangeError

Complexity: time O(i * n * k + i * k log k) for i iterations, n rows and k components, space O(n * k).

Worked example#

executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.

Input#

data
{
  "framework": "sector-weight-calibration-teaching-v1",
  "component_names": ["quality", "resilience", "cash_conversion"],
  "base_weights": {
    "quality": 0.4,
    "resilience": 0.35,
    "cash_conversion": 0.25
  },
  "feature_rows": [
    [82, 65, 78],
    [74, 60, 70],
    [45, 72, 55]
  ],
  "labels": [1, 1, 0, 1, 0, 1],
  "observation_dates": [
    "2024-01-01",
    "2024-02-01",
    "2024-03-01",
    "2024-04-01",
    "2024-05-01",
    "2024-06-01"
  ],
  "train_end_index": 12,
  "learning_rate": 0.08,
  "ridge_penalty": 0.2,
  "logit_slope": 5,
  "iterations": 600
}

Call#

sectorSpecificWeightCalibration(data)

Returns#

object with 18 fields: state, method, component_names, base_weights, candidate_weights, selected_weights, candidate_intercept, selected_intercept, …

{
  "state": "retain-base-weights",
  "method": "nonnegative-simplex-logloss-v1",
  "component_names": ["quality", "resilience", "cash_conversion"],
  "base_weights": {
    "quality": 0.4,
    "resilience": 0.35,
    "cash_conversion": 0.25
  },
  "candidate_weights": {
    "quality": 0.7551696860135335,
    "resilience": 0,
    "cash_conversion": 0.24483031398646643
  },
  "selected_weights": {
    "quality": 0.4,
    "resilience": 0.35,
    "cash_conversion": 0.25
  },
  "candidate_intercept": -0.40266157235699845,
  "selected_intercept": 0,
  "base_train_brier": 0.14500903499442555,
  "base_validation_brier": 0.10197248987791843,
  "candidate_train_brier": 0.10051624085395794,
  "candidate_validation_brier": 0.10310568321068389,
  "selected_validation_brier": 0.10197248987791843,
  "weight_shift_l1": 0.710339372027067
}

Showing 14 of 18 fields.

Other exports#

This module also exports calculate, bankFundamentalScore, insuranceFundamentalScore, reitFundamentalScore, utilityFundamentalScore, earlyStageLiquidityAndRunwayScore, cyclicalAndCommodityCycleNormalization, holdingCompanyLookThroughScore, unsupportedScopeAndCoverageDecision. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams#

Sector-Specific Weight Calibration — article hero
Sector-Specific Weight Calibration — component ledger
Sector-Specific Weight Calibration — decision boundary
Sector-Specific Weight Calibration — evidence clock
Sector-Specific Weight Calibration — model anatomy
Sector-Specific Weight Calibration — system map

How it works#

This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.

Read the article →

References#

The rest of the Sector-Specific Equity Scoring family#