trader.news.aliases module

Turn a broker’s asset name into the names a headline would actually use.

Issue #6 measured that 4 of 26 ollama_news BUY decisions scored relevant=0/10 — ten fresh headlines, not one of which named the company — and that supplying plain company aliases moved all four to 5, 6, 7 and 4, with the median across all 26 BUYs going 2 -> 5 and no row left at 0. The gap was a missing config value, not a missing feature: company_aliases existed and was never set, so relevance matched on the bare ticker alone.

A static list in config/strategies.yaml would have closed it for fixed_tickers only. Two of the fifteen rows that improved (NNE, NVDA) were symbols discovery found, which arrive with no entry in any hand-written map — and a symbol nobody has written an alias for is exactly the 0/10 case. So the name is resolved per symbol instead, from a field the app already receives and was discarding: Alpaca’s asset payload carries name (“Apple Inc. Common Stock”), and every evaluated symbol already goes through get_asset.

This feeds `relevance_count` and nothing else. Aliases never reach the prompt, so nothing here can change a trading decision — it makes a recorded measurement honest, which is what issue #6 asked for. Filtering on relevance is a separate question and deliberately not answered here.

trader.news.aliases.derive_aliases(name)[source]

Company aliases implied by a broker asset name.

Returns the cleaned issuer name and, where it is safely separable, the leading word: “Palantir Technologies Inc. Class A Common Stock” yields (“Palantir Technologies”, “Palantir”).

Returns an empty tuple for None, for blank input, and whenever cleaning leaves nothing usable. An empty tuple is the honest answer — it degrades relevance to the bare-ticker matching that existed before this module, and never invents a needle.

What it cannot do: derive a name the asset record does not contain. Alpaca calls GOOG “Alphabet Inc. Class C Common Stock”, so “Google” is not derivable from it, and the measured GOOG improvement needed both. That is what the company_aliases config override remains for; the two are unioned rather than one replacing the other.

Parameters:

name (str | None)

Return type:

tuple[str, …]

class trader.news.aliases.CompanyAliasResolver(fetch_name)[source]

Bases: object

Resolves a symbol to company aliases, once per symbol per process.

Wraps a name lookup — in production, the broker’s get_asset — and caches the derived aliases, because relevance_count runs for every symbol every cycle and the answer does not change between cycles.

Never raises. A lookup failure yields no aliases and lets relevance fall back to bare-ticker matching, the same discipline the LLM path applies to everything else: a broker hiccup must degrade a recorded measurement, not abort a cycle that is about to place or ratchet protective orders.

Parameters:

fetch_name (Callable[[str], str | None])

trader.news.aliases.merge_aliases(configured, resolved)[source]

Configured aliases first, then resolved ones, de-duplicated.

Order is by specificity, not preference: both sets end up in the same alternation inside one regex, so the result is a union and the ordering matters only for readability of what gets recorded. Configured entries come first because an operator naming “Google” for GOOG is making a claim the asset record cannot.

De-duplication is case-insensitive, matching how relevance_count searches.

Parameters:
  • configured (Sequence[str])

  • resolved (Sequence[str])

Return type:

tuple[str, …]