Metadata-Version: 2.4
Name: binomial-marks
Version: 0.1.1
Summary: Binomial's earnings-call NLP scorer — 23 structured signals per transcript.
Project-URL: Homepage, https://huggingface.co/BinomialTechnologies/binomial-marks-1
Project-URL: Repository, https://github.com/Binomial-Capital-Management/binomial-ai-research
Project-URL: Issues, https://github.com/Binomial-Capital-Management/binomial-ai-research/issues
Author: Binomial AI Research
License: Apache-2.0
Keywords: earnings-calls,finance,nlp,quantitative-finance,transformers
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: huggingface-hub>=0.25
Requires-Dist: safetensors>=0.4
Requires-Dist: tokenizers>=0.20
Requires-Dist: torch>=2.1
Requires-Dist: transformers>=4.48
Description-Content-Type: text/markdown

# binomial-marks

Binomial's earnings-call NLP scorer — 23 structured signals per transcript, in ~50ms on CPU.

Part of Binomial AI Research's *specialist zoo* — small, deployable models for quantitative
finance. Named after Howard Marks (Oaktree), whose memos parse market sentiment and tone.

Model card: [`BinomialTechnologies/binomial-marks-1`](https://huggingface.co/BinomialTechnologies/binomial-marks-1).

## Install

```bash
pip install binomial-marks
```

Pulls in `torch`, `transformers>=4.48`, `huggingface-hub`. Weights (~1.6 GB) are downloaded
from HuggingFace on first use.

## One-shot

```python
from binomial_marks import score

result = score(
    transcript="Operator: Welcome to NVIDIA's Q4 2025 earnings call...",
    ticker="NVDA", sector="Technology", country="US",
    year=2025, quarter=4,
)
```

Returns:

```python
{
  "topics": {
    "guidance":       {"mentioned": True, "mention_prob": 0.94, "score":  1.7},
    "revenue_growth": {"mentioned": True, "mention_prob": 0.97, "score":  1.5},
    "margins":        {"mentioned": True, "mention_prob": 0.91, "score":  0.8},
    # ... 7 more topics
  },
  "mgmt_confidence":    4.6,   # 1 = uncertain "we hope" → 5 = "we will deliver X"
  "mgmt_defensiveness": 1.4,   # 1 = open Q&A → 5 = pivots, refuses to commit
  "analyst_skepticism": 1.8,   # 1 = congratulatory → 5 = re-asking same question
}
```

## Batched

```python
from binomial_marks import MarksScorer

scorer = MarksScorer()                       # loads model once
results = scorer.score_batch([
    {"transcript": "...", "ticker": "NVDA", "sector": "Technology", "year": 2025, "quarter": 4},
    {"transcript": "...", "ticker": "AAPL", "sector": "Technology", "year": 2025, "quarter": 1},
])
```

## Configuration

```python
MarksScorer(
    model_id="BinomialTechnologies/binomial-marks-1",  # or local path / pinned version
    device="cuda",                # auto-detect: cuda > mps > cpu
    dtype=torch.bfloat16,         # default: bf16 on GPU, fp32 on CPU
    max_length=16384,             # tokenizer truncation cap
    mention_threshold=0.5,        # sigmoid threshold for the topic_mentioned heads
)
```

## What it returns

**10 topic-direction scores** (each: was the topic discussed? if so, what direction in
[-2, +2]?):

| Topic | What −2 / +2 mean |
|---|---|
| `guidance` | lowered hard / raised significantly |
| `revenue_growth` | decelerating / accelerating |
| `margins` | compressing / expanding |
| `demand` | softening / strong |
| `buybacks` | paused or reduced / new or upsized |
| `dividends` | cut or skipped / raised or initiated |
| `m_and_a` | divestiture / strategic acquisition |
| `headcount` | layoffs / aggressive hiring |
| `macro_exposure` | clear headwind / clear tailwind |
| `competition` | losing share / gaining share |

**3 tone scores** (1 to 5): `mgmt_confidence`, `mgmt_defensiveness`, `analyst_skepticism`.

When `mentioned=False`, `score` is forced to 0 — the topic wasn't discussed, so direction
is undefined.

## Hardware

- **CPU**: ~50ms/call on a modern laptop.
- **GPU**: ~10ms/call on A100/H100/B200, ~12 calls/sec batched.
- **Memory**: ~1.6 GB weights, ~3 GB peak with a 16k-token context.

## Limitations

The model card has the full picture. In short:

1. `headcount` is the weakest dimension (Spearman 0.39 vs. frontier — half the others).
2. Tone has rank-order signal but absolute levels drift; normalize cross-sectionally.
3. English transcripts only.
4. Truncates at 16,384 tokens (~50k characters; covers ~p99 of calls).
5. Pure NLP scorer — outputs are *features*, not trades. The trading rule is yours.

## License

Apache 2.0. If you build on this, a citation is appreciated.
