New paste Repaste Download
spec_name = 'manual_generic'
fields = {'account': 'cuixia', 'action': 'trim', 'dip_n': 1, 'dip_variant': '', ...}
spec = CoidSpec(name='manual_generic', strategy_label='manual', prefix='manual-', regex=re.compile('^manual-', re.IGNORECASE)...ID (any `manual-*` prefix). Protected from auto-trim by buying_power_trim._manual_protected_symbols.', is_legacy=False)
norm_fields = {'account': 'cuixia', 'action': 'trim', 'dip_n': 1, 'dip_variant': '', ...}
k = 'dip_variant', v = ''
e = ValueError("format_coid: spec='manual_generic' template requires field 'tag' (template='manual-{tag}-{symbol}-{account...b_id', 'entry_count', 'mmdd', 'hold_days', 'action', 'side', 'ts', 'uniq', 'kind', 'source', 'dip_n', 'dip_variant'])")
    def format_coid(spec_name: str, **fields: Any) -> str:
        """Format and return a COID per the named spec.
    
        The template's required fields are derived from the f-string's
        `{name}` placeholders. Missing fields raise ValueError (loud
        failure) — never silently substitute an empty string, because that
        produces malformed coids that parse to wrong specs.
    
        Strings are lowercased before substitution. `uniq` is auto-filled
        with a 6-char uuid hex when not provided (matches the ovf-* pattern
        and avoids collisions on repeated calls).
    
        The result is truncated to the spec's max_len (default 48 = Alpaca's
        client_order_id cap). Truncation preserves the prefix — if the
        template would exceed max_len the trailing fields are clipped.
    
        Raises:
          ValueError if `spec_name` is not in the registry, the spec is
          flagged is_legacy (read-only), or a required field is missing.
        """
        spec = _BY_NAME.get(spec_name)
        if spec is None:
            raise ValueError(
                f"format_coid: unknown spec_name={spec_name!r}. "
                f"Add a CoidSpec to rtrader/utils/coid_registry.REGISTRY."
            )
        if spec.is_legacy or not spec.format_template:
            raise ValueError(
                f"format_coid: spec={spec_name!r} is legacy/read-only. "
                f"New emit sites must use a non-legacy spec."
            )
    
        # Lowercase string fields; pass through ints/floats unchanged.
        norm_fields: Dict[str, Any] = {}
        for k, v in fields.items():
            if isinstance(v, str):
                norm_fields[k] = v.lower()
            else:
                norm_fields[k] = v
    
        # Auto-fill uniq when the template needs it but caller didn't supply.
        if "{uniq}" in spec.format_template and "uniq" not in norm_fields:
            norm_fields["uniq"] = uuid.uuid4().hex[:6]
    
        try:
>           coid = spec.format_template.format(**norm_fields)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E           KeyError: 'tag'
rtrader/utils/coid_registry.py:1253: KeyError
The above exception was the direct cause of the following exception:
spec = CoidSpec(name='manual_generic', strategy_label='manual', prefix='manual-', regex=re.compile('^manual-', re.IGNORECASE)...ID (any `manual-*` prefix). Protected from auto-trim by buying_power_trim._manual_protected_symbols.', is_legacy=False)
    @pytest.mark.parametrize(
        "spec",
        [s for s in REGISTRY if not s.is_legacy],
        ids=lambda s: s.name,
    )
    def test_each_spec_round_trips(spec):
        """format_coid(name, ...) → parse_coid(...) → same spec."""
>       coid = format_coid(spec.name, **_SAMPLE_FIELDS)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/utils/test_coid_registry.py:66:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
spec_name = 'manual_generic'
fields = {'account': 'cuixia', 'action': 'trim', 'dip_n': 1, 'dip_variant': '', ...}
spec = CoidSpec(name='manual_generic', strategy_label='manual', prefix='manual-', regex=re.compile('^manual-', re.IGNORECASE)...ID (any `manual-*` prefix). Protected from auto-trim by buying_power_trim._manual_protected_symbols.', is_legacy=False)
norm_fields = {'account': 'cuixia', 'action': 'trim', 'dip_n': 1, 'dip_variant': '', ...}
k = 'dip_variant', v = ''
e = ValueError("format_coid: spec='manual_generic' template requires field 'tag' (template='manual-{tag}-{symbol}-{account...b_id', 'entry_count', 'mmdd', 'hold_days', 'action', 'side', 'ts', 'uniq', 'kind', 'source', 'dip_n', 'dip_variant'])")
    def format_coid(spec_name: str, **fields: Any) -> str:
        """Format and return a COID per the named spec.
    
        The template's required fields are derived from the f-string's
        `{name}` placeholders. Missing fields raise ValueError (loud
        failure) — never silently substitute an empty string, because that
        produces malformed coids that parse to wrong specs.
    
        Strings are lowercased before substitution. `uniq` is auto-filled
        with a 6-char uuid hex when not provided (matches the ovf-* pattern
        and avoids collisions on repeated calls).
    
        The result is truncated to the spec's max_len (default 48 = Alpaca's
        client_order_id cap). Truncation preserves the prefix — if the
        template would exceed max_len the trailing fields are clipped.
    
        Raises:
          ValueError if `spec_name` is not in the registry, the spec is
          flagged is_legacy (read-only), or a required field is missing.
        """
        spec = _BY_NAME.get(spec_name)
        if spec is None:
            raise ValueError(
                f"format_coid: unknown spec_name={spec_name!r}. "
                f"Add a CoidSpec to rtrader/utils/coid_registry.REGISTRY."
            )
        if spec.is_legacy or not spec.format_template:
            raise ValueError(
                f"format_coid: spec={spec_name!r} is legacy/read-only. "
                f"New emit sites must use a non-legacy spec."
            )
    
        # Lowercase string fields; pass through ints/floats unchanged.
        norm_fields: Dict[str, Any] = {}
        for k, v in fields.items():
            if isinstance(v, str):
                norm_fields[k] = v.lower()
            else:
                norm_fields[k] = v
    
        # Auto-fill uniq when the template needs it but caller didn't supply.
        if "{uniq}" in spec.format_template and "uniq" not in norm_fields:
            norm_fields["uniq"] = uuid.uuid4().hex[:6]
    
        try:
            coid = spec.format_template.format(**norm_fields)
        except KeyError as exc:
            # Missing required template field — surface to Sentry then raise.
            e = ValueError(
                f"format_coid: spec={spec_name!r} template requires field "
                f"{exc!s} (template={spec.format_template!r}, "
                f"provided={list(fields.keys())})"
            )
            sentry_sdk.capture_exception(e)
>           raise e from exc
E           ValueError: format_coid: spec='manual_generic' template requires field 'tag' (template='manual-{tag}-{symbol}-{account}-{uniq}', provided=['symbol', 'account', 'plan_id', 'job_id', 'entry_count', 'mmdd', 'hold_days', 'action', 'side', 'ts', 'uniq', 'kind', 'source', 'dip_n', 'dip_variant'])
rtrader/utils/coid_registry.py:1262: ValueError
Filename: None. Size: 7kb. View raw, , hex, or download this file.

This paste expires on 2026-06-29 23:16:04.893396+00:00. Pasted through deprecated-web.