metricengine.value
FinancialValue wrapper for immutable financial data with policy-aware formatting.
This module provides the core FinancialValue class that wraps financial data with immutable, policy-aware behavior. FinancialValue instances support safe arithmetic operations, automatic formatting, and None propagation through calculations.
- Key Features:
Immutable financial data wrapper with automatic Decimal conversion
Policy-aware formatting and rounding (decimal places, rounding mode)
Safe arithmetic operations (division by zero returns None)
None propagation through calculations
Percentage formatting and ratio conversion
Type-flexible input (int, float, str, Decimal, FinancialValue)
Hashable and comparable instances
Example
>>> from metricengine import FinancialValue as FV
>>> price = FV(100.50)
>>> quantity = FV(3)
>>> total = price * quantity
>>> print(total.as_str()) # "301.50"
>>> print(total.as_decimal()) # Decimal('301.50')
>>> # Safe operations
>>> result = FV(100) / FV(0) # Returns FV(None), not error
>>> print(result.is_none()) # True
>>> # Percentage handling
>>> margin = FV(0.15).as_percentage()
>>> print(margin.as_str()) # "15%"
>>> print(margin.ratio()) # FV(0.15)
>>> # Policy inheritance
>>> custom_policy = Policy(decimal_places=4)
>>> value = FV(123.4567, policy=custom_policy)
>>> result = value + 50 # Inherits custom_policy
>>> print(result.as_str()) # "173.4567"
See README.md for comprehensive usage examples and best practices.
- class metricengine.value.EqualityMode(value)[source]
Bases:
Enum- VALUE_ONLY = 1
- VALUE_AND_UNIT = 2
- VALUE_UNIT_AND_POLICY = 3
- class metricengine.value.FinancialValue(_value, policy=None, unit=<class 'metricengine.units.Dimensionless'>, _is_percentage=False, _prov=None)[source]
Bases:
Generic[U]- unit
alias of
Dimensionless
- render(fmt='text', **context)[source]
Render this FinancialValue using a registered renderer.
- Parameters:
fmt (
str) – Name of the renderer to use (default: “text”)**context – Additional context passed to the renderer
- Return type:
- Returns:
Rendered string representation
- Raises:
KeyError – If the specified renderer is not registered
Example
>>> amount = money(1234.56) >>> amount.render("html") # '<span class="fv positive">$1,234.56</span>' >>> amount.render("html", css_classes="highlight")
- to(unit, *, at=None, meta=None)[source]
Convert this FinancialValue to a different unit.
This method performs explicit unit conversion using the registered conversion functions. It creates a new FinancialValue with the target unit and converted value, preserving the original policy and percentage flag.
- Parameters:
- Return type:
- Returns:
New FinancialValue with the target unit and converted value
- Raises:
KeyError – If no conversion is registered between the units
ValueError – If this FinancialValue has a None value
TypeError – If this FinancialValue doesn’t use the new unit system
Example
>>> from metricengine import FinancialValue as FV >>> from metricengine.units import MoneyUnit >>> >>> usd = MoneyUnit("USD") >>> gbp = MoneyUnit("GBP") >>> amount = FV(100, unit=usd) >>> >>> # Convert with default context >>> converted = amount.to(gbp) >>> >>> # Convert with specific rate and timestamp >>> converted = amount.to(gbp, at="2025-09-06T10:30:00Z", ... meta={"rate": "0.79", "source": "ECB"})
- get_provenance()[source]
Get the provenance record for this FinancialValue.
- Return type:
- Returns:
Provenance record if available, None otherwise
- has_provenance()[source]
Check if this FinancialValue has provenance information.
- Return type:
- Returns:
True if provenance is available, False otherwise
- get_operation()[source]
Get the operation that created this FinancialValue.
Example
>>> a = FinancialValue(10) >>> b = FinancialValue(5) >>> result = a + b >>> print(result.get_operation()) # "+"
- get_inputs()[source]
Get the input provenance IDs that contributed to this FinancialValue.
- Return type:
- Returns:
Tuple of provenance IDs for inputs, empty tuple if no provenance
Example
>>> a = FinancialValue(10) >>> b = FinancialValue(5) >>> result = a + b >>> inputs = result.get_inputs() >>> print(len(inputs)) # 2
- get_provenance_metadata()[source]
Get the metadata associated with this FinancialValue’s provenance.
Example
>>> with calc_span("analysis"): ... result = FinancialValue(10) + FinancialValue(5) >>> meta = result.get_provenance_metadata() >>> print(meta.get("span")) # "analysis"
- get_provenance_id()[source]
Get the unique provenance ID for this FinancialValue.
Example
>>> value = FinancialValue(100) >>> prov_id = value.get_provenance_id() >>> print(prov_id[:8]) # First 8 chars of hash
- trace_calculation(max_depth=10)[source]
Generate a human-readable trace of how this value was calculated.
This method provides a detailed explanation of the calculation chain that led to this FinancialValue, useful for debugging and auditing.
- Parameters:
max_depth (
int) – Maximum depth to traverse in the calculation tree- Return type:
- Returns:
Formatted string showing the calculation trace
Example
>>> revenue = FinancialValue(1000) >>> cost = FinancialValue(600) >>> profit = revenue - cost >>> print(profit.trace_calculation())
- get_calculation_summary()[source]
Get a brief summary of how this value was calculated.
- Return type:
- Returns:
Brief string summary of the calculation
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> print(result.get_calculation_summary()) # "Op: + | Inputs: 2"
- export_provenance_graph()[source]
Export the complete provenance graph for this FinancialValue.
- Return type:
- Returns:
Dictionary containing the provenance graph in JSON-serializable format
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> graph = result.export_provenance_graph() >>> print(graph['root']) # Root provenance ID
- has_operation(operation)[source]
Check if this FinancialValue was created by a specific operation.
- Parameters:
operation (
str) – Operation string to check for (e.g., “+”, “literal”, “calc:margin”)- Return type:
- Returns:
True if the operation matches, False otherwise
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> print(result.has_operation("+")) # True >>> print(result.has_operation("*")) # False
- is_literal()[source]
Check if this FinancialValue is a literal (not computed from other values).
- Return type:
- Returns:
True if this is a literal value, False if computed
Example
>>> literal = FinancialValue(100) >>> computed = FinancialValue(50) + FinancialValue(50) >>> print(literal.is_literal()) # True >>> print(computed.is_literal()) # False
- is_computed()[source]
Check if this FinancialValue was computed from other values.
- Return type:
- Returns:
True if this value was computed, False if it’s a literal
Example
>>> literal = FinancialValue(100) >>> computed = FinancialValue(50) + FinancialValue(50) >>> print(literal.is_computed()) # False >>> print(computed.is_computed()) # True
- get_input_count()[source]
Get the number of inputs that contributed to this FinancialValue.
- Return type:
- Returns:
Number of input values, 0 for literals or values without provenance
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> print(result.get_input_count()) # 2
- as_percentage()[source]
Convert this FinancialValue to percentage representation with provenance tracking.
- Return type:
- ratio()[source]
Convert this FinancialValue to ratio representation with provenance tracking.
- Return type:
- with_policy(policy)[source]
Create a new FinancialValue with a different policy, maintaining provenance.
- Return type:
- classmethod zero(policy=None, unit=<class 'metricengine.units.Dimensionless'>)[source]
Create a zero FinancialValue with appropriate provenance.
- classmethod none(policy=None)[source]
Create a None FinancialValue with appropriate provenance.
- Return type:
- metricengine.value.FV
alias of
FinancialValue
Core Value Types
- class metricengine.value.FinancialValue(_value, policy=None, unit=<class 'metricengine.units.Dimensionless'>, _is_percentage=False, _prov=None)[source]
Bases:
Generic[U]- unit
alias of
Dimensionless
- render(fmt='text', **context)[source]
Render this FinancialValue using a registered renderer.
- Parameters:
fmt (
str) – Name of the renderer to use (default: “text”)**context – Additional context passed to the renderer
- Return type:
- Returns:
Rendered string representation
- Raises:
KeyError – If the specified renderer is not registered
Example
>>> amount = money(1234.56) >>> amount.render("html") # '<span class="fv positive">$1,234.56</span>' >>> amount.render("html", css_classes="highlight")
- to(unit, *, at=None, meta=None)[source]
Convert this FinancialValue to a different unit.
This method performs explicit unit conversion using the registered conversion functions. It creates a new FinancialValue with the target unit and converted value, preserving the original policy and percentage flag.
- Parameters:
- Return type:
- Returns:
New FinancialValue with the target unit and converted value
- Raises:
KeyError – If no conversion is registered between the units
ValueError – If this FinancialValue has a None value
TypeError – If this FinancialValue doesn’t use the new unit system
Example
>>> from metricengine import FinancialValue as FV >>> from metricengine.units import MoneyUnit >>> >>> usd = MoneyUnit("USD") >>> gbp = MoneyUnit("GBP") >>> amount = FV(100, unit=usd) >>> >>> # Convert with default context >>> converted = amount.to(gbp) >>> >>> # Convert with specific rate and timestamp >>> converted = amount.to(gbp, at="2025-09-06T10:30:00Z", ... meta={"rate": "0.79", "source": "ECB"})
- get_provenance()[source]
Get the provenance record for this FinancialValue.
- Return type:
- Returns:
Provenance record if available, None otherwise
- has_provenance()[source]
Check if this FinancialValue has provenance information.
- Return type:
- Returns:
True if provenance is available, False otherwise
- get_operation()[source]
Get the operation that created this FinancialValue.
Example
>>> a = FinancialValue(10) >>> b = FinancialValue(5) >>> result = a + b >>> print(result.get_operation()) # "+"
- get_inputs()[source]
Get the input provenance IDs that contributed to this FinancialValue.
- Return type:
- Returns:
Tuple of provenance IDs for inputs, empty tuple if no provenance
Example
>>> a = FinancialValue(10) >>> b = FinancialValue(5) >>> result = a + b >>> inputs = result.get_inputs() >>> print(len(inputs)) # 2
- get_provenance_metadata()[source]
Get the metadata associated with this FinancialValue’s provenance.
Example
>>> with calc_span("analysis"): ... result = FinancialValue(10) + FinancialValue(5) >>> meta = result.get_provenance_metadata() >>> print(meta.get("span")) # "analysis"
- get_provenance_id()[source]
Get the unique provenance ID for this FinancialValue.
Example
>>> value = FinancialValue(100) >>> prov_id = value.get_provenance_id() >>> print(prov_id[:8]) # First 8 chars of hash
- trace_calculation(max_depth=10)[source]
Generate a human-readable trace of how this value was calculated.
This method provides a detailed explanation of the calculation chain that led to this FinancialValue, useful for debugging and auditing.
- Parameters:
max_depth (
int) – Maximum depth to traverse in the calculation tree- Return type:
- Returns:
Formatted string showing the calculation trace
Example
>>> revenue = FinancialValue(1000) >>> cost = FinancialValue(600) >>> profit = revenue - cost >>> print(profit.trace_calculation())
- get_calculation_summary()[source]
Get a brief summary of how this value was calculated.
- Return type:
- Returns:
Brief string summary of the calculation
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> print(result.get_calculation_summary()) # "Op: + | Inputs: 2"
- export_provenance_graph()[source]
Export the complete provenance graph for this FinancialValue.
- Return type:
- Returns:
Dictionary containing the provenance graph in JSON-serializable format
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> graph = result.export_provenance_graph() >>> print(graph['root']) # Root provenance ID
- has_operation(operation)[source]
Check if this FinancialValue was created by a specific operation.
- Parameters:
operation (
str) – Operation string to check for (e.g., “+”, “literal”, “calc:margin”)- Return type:
- Returns:
True if the operation matches, False otherwise
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> print(result.has_operation("+")) # True >>> print(result.has_operation("*")) # False
- is_literal()[source]
Check if this FinancialValue is a literal (not computed from other values).
- Return type:
- Returns:
True if this is a literal value, False if computed
Example
>>> literal = FinancialValue(100) >>> computed = FinancialValue(50) + FinancialValue(50) >>> print(literal.is_literal()) # True >>> print(computed.is_literal()) # False
- is_computed()[source]
Check if this FinancialValue was computed from other values.
- Return type:
- Returns:
True if this value was computed, False if it’s a literal
Example
>>> literal = FinancialValue(100) >>> computed = FinancialValue(50) + FinancialValue(50) >>> print(literal.is_computed()) # False >>> print(computed.is_computed()) # True
- get_input_count()[source]
Get the number of inputs that contributed to this FinancialValue.
- Return type:
- Returns:
Number of input values, 0 for literals or values without provenance
Example
>>> result = FinancialValue(10) + FinancialValue(5) >>> print(result.get_input_count()) # 2
- as_percentage()[source]
Convert this FinancialValue to percentage representation with provenance tracking.
- Return type:
- ratio()[source]
Convert this FinancialValue to ratio representation with provenance tracking.
- Return type:
- with_policy(policy)[source]
Create a new FinancialValue with a different policy, maintaining provenance.
- Return type:
- classmethod zero(policy=None, unit=<class 'metricengine.units.Dimensionless'>)[source]
Create a zero FinancialValue with appropriate provenance.
- classmethod none(policy=None)[source]
Create a None FinancialValue with appropriate provenance.
- Return type:
- classmethod none_with_unit(unit, policy=None)[source]
Create a None FinancialValue with specific unit and appropriate provenance.
- Return type:
- classmethod constant(value, policy=None, unit=<class 'metricengine.units.Dimensionless'>)[source]
Create a constant FinancialValue with appropriate provenance.
- __init__(_value, policy=None, unit=<class 'metricengine.units.Dimensionless'>, _is_percentage=False, _prov=None)