Alpha Library: the 191 notes, 117 nicknames and 10 theme tags now switch
to Chinese with the rest of the site. wiki/alpha-library/i18n.zh.json keeps
each translation next to the English it came from; the generator puts the
Chinese in data-text-zh only while that English still matches the
registry, and tests/factors/test_alpha_library_translations.py fails on a
missing, stale or orphaned translation or an unnamed theme.
GTJA 191 post: the 2026-05-17 numbers came from Tushare prices that were
not split-adjusted and from today's CSI 300 roster applied to the whole
window, both fixed on 2026-08-04 (d52199ff). Re-ran the bench on the
current code (point-in-time membership, qfq prices): 8 alive, 14 reversed,
168 dead, gtja191_138 untested (99% NaN), where the first version said
10 / 15 / 165 and never accounted for the 191st. Both languages now carry
a revision note and the new counts, theme table, top 5 by IR and three
most-negative alphas, and fix what the translation surfaced or the code
contradicts: the top 5 are ranked by IR, not IC; the theme table counts
every tag an alpha carries; the reflection matches the table; the Method
universe matches the Caveats; Kakushadze's preprint came a year after the
report; forward returns are simple, not log; no GTJA formula needs sector
tags; the bench measures no turnover and draws no IC plot; five alphas use
a proxy input (named); the reproduce command covers 2018-2025. A new
caveat reports the bench's multiple-testing deflation: 3 of the 8 alive
alphas clear the IR expected from 190 null formulas.
53 lines
2.2 KiB
Python
53 lines
2.2 KiB
Python
"""The Alpha Library's Chinese notes, nicknames and theme names match the registry.
|
|
|
|
The wiki shows every alpha's ``notes`` and ``nickname`` in Chinese from
|
|
``wiki/alpha-library/i18n.zh.json``. Each entry keeps the English it was
|
|
translated from, and the page generator only uses a translation whose English
|
|
still equals the registry's, so an edited note silently falls back to English.
|
|
These tests make that visible: a new alpha with a note but no translation, an
|
|
edited note whose translation is now stale, a translation for an alpha that no
|
|
longer exists, or a theme tag with no Chinese name all fail here.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from src.factors.registry import Registry
|
|
|
|
STORE = Path(__file__).resolve().parents[3] / "wiki" / "alpha-library" / "i18n.zh.json"
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def registry_meta() -> dict[str, dict]:
|
|
manifest = Registry().export_manifest()
|
|
return {a["id"]: a["meta"] for zoo in manifest["zoos"] for a in zoo["alphas"]}
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def store() -> dict:
|
|
return json.loads(STORE.read_text(encoding="utf-8"))
|
|
|
|
|
|
@pytest.mark.parametrize(("field", "bucket"), [("notes", "notes"), ("nickname", "nicknames")])
|
|
def test_every_english_text_has_a_current_chinese_version(
|
|
registry_meta: dict[str, dict], store: dict, field: str, bucket: str
|
|
) -> None:
|
|
english = {aid: meta[field] for aid, meta in registry_meta.items() if (meta.get(field) or "").strip()}
|
|
translated = store[bucket]
|
|
|
|
assert not sorted(set(english) - set(translated)), "untranslated: add them to i18n.zh.json"
|
|
assert not sorted(set(translated) - set(english)), "translations for alphas that have no such text any more"
|
|
stale = sorted(aid for aid, text in english.items() if translated[aid]["en"] != text)
|
|
assert not stale, f"English changed since translation, update 'en' and 'zh': {stale}"
|
|
assert all(entry["zh"].strip() and entry["zh"] != entry["en"] for entry in translated.values())
|
|
|
|
|
|
def test_every_theme_tag_has_a_chinese_name(registry_meta: dict[str, dict], store: dict) -> None:
|
|
used = {tag for meta in registry_meta.values() for tag in meta.get("theme") or []}
|
|
|
|
assert used <= set(store["themes"]), sorted(used - set(store["themes"]))
|