HKUDS/Vibe-Trading · error · ValueError

kind={self.kind!r} must have a {direction} amount under the

Error message

kind={self.kind!r} must have a {direction} amount under the holder-perspective sign convention, got {amount!r}. Flip the sign, or use a distinct kind if this flow is genuinely two-directional (e.g. 'recallable_distribution').

What it means

Each CashFlow kind has a fixed sign direction (holder perspective), e.g. dividends are cash in (positive) and purchases are cash out (negative). If the amount's sign contradicts KIND_DIRECTION for that kind, the entity refuses construction rather than silently misreporting direction.

Source

Thrown at agent/src/entities/cashflow.py:173

        try:
            amount = float(self.amount)
        except (TypeError, ValueError) as exc:
            raise ValueError(
                f"amount must be numeric, got {self.amount!r}"
            ) from exc
        if not math.isfinite(amount):
            raise ValueError(
                f"amount must be a finite number, got {self.amount!r}; a missing "
                "value must be fixed at the source, not carried as NaN"
            )
        object.__setattr__(self, "amount", amount)

        required_sign = KIND_DIRECTION.get(self.kind)
        if required_sign is not None and amount != 0.0:
            if (amount > 0) != (required_sign > 0):
                direction = "positive (cash in)" if required_sign > 0 else "negative (cash out)"
                raise ValueError(
                    f"kind={self.kind!r} must have a {direction} amount under the "
                    f"holder-perspective sign convention, got {amount!r}. Flip the "
                    "sign, or use a distinct kind if this flow is genuinely "
                    "two-directional (e.g. 'recallable_distribution')."
                )

        if not isinstance(self.metadata, Mapping):
            raise ValueError(
                f"metadata must be a mapping, got {type(self.metadata).__name__}"
            )
        object.__setattr__(self, "metadata", MappingProxyType(dict(self.metadata)))

    @property
    def is_valuation(self) -> bool:
        """Whether this record is a mark rather than a settled cash movement.

        Returns:
            True when ``kind`` is one of ``VALUATION_KINDS``.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Flip the amount's sign to match the kind's required direction (see the message text for which direction is expected)
  2. If the flow is genuinely two-directional (e.g. recallable distributions that can be clawed back), use a kind without a fixed direction such as 'recallable_distribution'
  3. Apply the sign at ingest: amount = abs(amount) * expected_sign based on the kind mapping

Example fix

# before
CashFlow(date=d, kind='purchase', amount=1000.0, currency='USD')
# after
CashFlow(date=d, kind='purchase', amount=-1000.0, currency='USD')
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED_SIGN = {'purchase': -1, 'dividend': 1}  # mirror KIND_DIRECTION
row['amount'] = abs(float(row['amount'])) * REQUIRED_SIGN.get(row['kind'], 1)

Try / catch

try:
    CashFlow(...)
except ValueError as e:
    if 'sign convention' in str(e):
        row['amount'] = -row['amount']  # only if direction metadata is trusted

Prevention

When it happens

Trigger: CashFlow(kind='purchase', amount=1000.0) when purchase requires a negative amount, or CashFlow(kind='dividend', amount=-50.0) when dividend must be positive; amount 0.0 is always allowed.

Common situations: Feeding raw unsigned magnitudes from a brokerage CSV where direction lives in a separate column; mixing conventions (inflow-positive vs outflow-positive) between data sources; genuinely two-directional flows modeled with the wrong kind.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/0609d95900d330ca. Report an issue: GitHub.