Units

Metric Engine’s unit system provides type-safe dimensional analysis for financial calculations, preventing meaningless operations and ensuring mathematical correctness. Units act as compile-time and runtime guards that encode the semantic meaning of financial values, making calculations more robust and self-documenting.

What are Units?

Units in Metric Engine are type markers that encode the dimensional meaning of financial values. They serve three critical purposes:

  1. Type Safety - Prevent nonsensical operations like adding dollars to percentages

  2. Semantic Clarity - Make code self-documenting by encoding business meaning

  3. Mathematical Correctness - Ensure operations follow proper financial mathematics

Unlike traditional unit systems that focus on physical dimensions, Metric Engine’s units are designed specifically for financial semantics and business logic.

Core Unit Types

Metric Engine provides four fundamental unit types, each designed for specific financial use cases:

Money

Represents monetary amounts and currency values:

from metricengine import money, Policy

# Create monetary values
revenue = money(100_000)
cost = money(75_000)
profit = revenue - cost

print(revenue)  # "$100,000.00"
print(cost)     # "$75,000.00"
print(profit)   # "$25,000.00"

# Type safety: Money operations are validated
valid_total = revenue + cost      # ✓ Money + Money = Money
# invalid_mix = revenue + 0.25    # Would return None - no units to guide operation

Money Unit Properties:

  • Represents currency amounts (dollars, euros, etc.)

  • Supports addition, subtraction with other Money values

  • Multiplication/division with dimensionless values and ratios

  • Cannot be directly added to percentages or non-monetary units

  • Formatted with currency symbols and thousands separators

Percent

Represents percentage values with automatic display formatting:

from metricengine import percent

# Input as percentage (15.5% -> stored as 0.155)
tax_rate = percent(15.5, input="percent")
print(tax_rate)  # "15.50%"

# Input as ratio (0.155 -> displayed as 15.5%)
growth_rate = percent(0.155, input="ratio")
print(growth_rate)  # "15.50%"

# Both methods store the same internal value
assert tax_rate.as_decimal() == growth_rate.as_decimal()  # Both are 0.155

# Type safety in action
revenue = money(100_000)
taxable_income = revenue * tax_rate  # ✓ Money * Percent = Money
print(taxable_income)  # "$15,500.00"

Percent Unit Properties:

  • Stores values as ratios (0.155 for 15.5%) internally

  • Displays with percentage formatting (15.50%)

  • Inherits from Ratio for mathematical operations

  • Automatically handles ratio/percentage conversion

  • Used for rates, margins, growth percentages

Ratio

Represents pure ratios and multipliers without percentage formatting:

from metricengine import ratio

# Pure ratios for calculations
multiplier = ratio(1.25)        # 25% increase multiplier
efficiency = ratio(0.85)        # 85% efficiency
exchange_rate = ratio(1.18)     # Currency exchange rate

print(multiplier)    # "1.25" (not "125%")
print(efficiency)    # "0.85" (not "85%")
print(exchange_rate) # "1.18" (not "118%")

# Mathematical operations
base_amount = money(1000)
adjusted_amount = base_amount * multiplier
print(adjusted_amount)  # "$1,250.00"

# Convert to percentage for display if needed
efficiency_percent = efficiency.as_percentage()
print(efficiency_percent)  # "85.00%"

Ratio Unit Properties:

  • Stores and displays as decimal values (not percentages)

  • Used for multipliers, scaling factors, exchange rates

  • Parent class for Percent unit

  • No automatic percentage formatting

  • Ideal for pure mathematical relationships

Dimensionless

Represents quantities without specific units - counts, indices, pure numbers:

from metricengine import dimensionless

# Quantities and counts
shares_outstanding = dimensionless(1_000_000)
employee_count = dimensionless(250)
quarter_number = dimensionless(3)

print(shares_outstanding)  # "1,000,000.00"
print(employee_count)      # "250.00"
print(quarter_number)      # "3.00"

# Pure mathematical operations
revenue_per_employee = money(500_000) / employee_count
print(revenue_per_employee)  # "$2,000.00" (Money ÷ Dimensionless = Money)

# Scaling operations
total_compensation = money(75_000) * employee_count
print(total_compensation)  # "$18,750,000.00"

Dimensionless Unit Properties:

  • No specific semantic meaning - pure quantities

  • Acts as mathematical “unit-less” multiplier

  • Used for counts, indices, scaling factors

  • Default fallback unit for operations

  • Preserves other units in multiplication/division

Unit Algebra and Type Safety

Metric Engine implements sophisticated unit algebra that prevents meaningless operations while enabling valid financial mathematics:

Addition and Subtraction Rules

from metricengine import money, percent, ratio, dimensionless

# Valid same-unit operations
revenue_q1 = money(100_000)
revenue_q2 = money(120_000)
total_revenue = revenue_q1 + revenue_q2  # ✓ Money + Money = Money

# Valid ratio/percent combinations
base_rate = ratio(0.05)
adjustment = percent(2, input="percent")  # 2% -> 0.02
combined_rate = base_rate + adjustment    # ✓ Ratio + Percent = Ratio (both are ratioish)

# Invalid cross-unit operations
try:
    invalid = revenue_q1 + base_rate      # Money + Ratio = None (invalid)
    print(f"Invalid result: {invalid.is_none()}")  # True
except:
    print("Operation blocked by type system")

# Dimensionless operations
count_a = dimensionless(100)
count_b = dimensionless(50)
total_count = count_a + count_b          # ✓ Dimensionless + Dimensionless = Dimensionless

Multiplication Rules

# Money multiplication rules
principal = money(10_000)
interest_rate = percent(5, input="percent")
multiplier = ratio(1.25)
years = dimensionless(3)

# Valid multiplications
interest = principal * interest_rate     # ✓ Money × Percent = Money
scaled_amount = principal * multiplier   # ✓ Money × Ratio = Money
compound_growth = principal * years      # ✓ Money × Dimensionless = Money

# Invalid multiplications
try:
    invalid = principal * money(5000)    # Money × Money = None (invalid - no unit²)
    print(f"Invalid: {invalid.is_none()}")
except:
    print("Invalid operation blocked")

# Ratio multiplication
efficiency = ratio(0.9)
utilization = percent(80, input="percent")
combined_factor = efficiency * utilization  # ✓ Ratio × Percent = Ratio

Division Rules

# Money division rules
total_revenue = money(1_000_000)
total_costs = money(750_000)
employee_count = dimensionless(100)

# Valid divisions
profit_margin = total_revenue / total_costs    # ✓ Money ÷ Money = Ratio
revenue_per_employee = total_revenue / employee_count  # ✓ Money ÷ Dimensionless = Money

# Ratio divisions
rate_a = percent(10, input="percent")
rate_b = percent(5, input="percent")
rate_ratio = rate_a / rate_b              # ✓ Percent ÷ Percent = Ratio

# Invalid divisions
try:
    invalid = rate_a / total_revenue      # Percent ÷ Money = None (invalid)
    print(f"Invalid: {invalid.is_none()}")
except:
    print("Invalid operation blocked")

Unit Conversion and Display

Automatic Unit Inference

Financial values automatically determine appropriate result units:

# Result units follow mathematical logic
revenue = money(100_000)
margin_ratio = ratio(0.15)
margin_percent = percent(15, input="percent")

# Both produce the same result (Money), different input representations
profit_from_ratio = revenue * margin_ratio    # Money × Ratio = Money
profit_from_percent = revenue * margin_percent # Money × Percent = Money

assert profit_from_ratio.as_decimal() == profit_from_percent.as_decimal()  # Same value
assert profit_from_ratio.unit == profit_from_percent.unit  # Same unit (Money)

Unit Conversion Methods

Convert between related unit types when semantically appropriate:

# Ratio ↔ Percentage conversion
efficiency_ratio = ratio(0.85)
efficiency_percent = efficiency_ratio.as_percentage()

print(efficiency_ratio)    # "0.85"
print(efficiency_percent)  # "85.00%"

# Back to ratio
converted_back = efficiency_percent.ratio()
print(converted_back)      # "0.85"

# Maintain mathematical equivalence
revenue = money(1000)
result1 = revenue * efficiency_ratio
result2 = revenue * efficiency_percent
assert result1.as_decimal() == result2.as_decimal()  # Same mathematical result

Policy-Aware Unit Formatting

Units respect policy settings for consistent display:

from metricengine import Policy

# Currency-specific formatting
usd_policy = Policy(currency_symbol="$", currency_position="prefix")
eur_policy = Policy(currency_symbol="€", currency_position="suffix")

amount = 1234.56

usd_amount = money(amount, policy=usd_policy)
eur_amount = money(amount, policy=eur_policy)

print(usd_amount)  # "$1,234.56"
print(eur_amount)  # "1,234.56€"

# Percentage formatting
percent_policy = Policy(decimal_places=1, percent_display="percent")
ratio_policy = Policy(decimal_places=3, percent_display="ratio")

rate_value = 0.155

rate_as_percent = percent(rate_value, input="ratio", policy=percent_policy)
rate_as_ratio = ratio(rate_value, policy=ratio_policy)

print(rate_as_percent)  # "15.5%"
print(rate_as_ratio)    # "0.155"

Real-World Applications

Financial Statement Analysis

# Income statement calculations with proper units
revenue = money(1_000_000)
cost_of_goods_sold = money(600_000)
operating_expenses = money(250_000)

# Financial calculations with type safety
gross_profit = revenue - cost_of_goods_sold        # Money - Money = Money
operating_income = gross_profit - operating_expenses # Money - Money = Money

# Ratio calculations
gross_margin = (gross_profit / revenue).as_percentage()     # (Money ÷ Money).as_percentage() = Percent
operating_margin = (operating_income / revenue).as_percentage()  # Same pattern

print(f"Revenue: {revenue}")                # "$1,000,000.00"
print(f"Gross Profit: {gross_profit}")     # "$400,000.00"
print(f"Operating Income: {operating_income}")  # "$150,000.00"
print(f"Gross Margin: {gross_margin}")     # "40.00%"
print(f"Operating Margin: {operating_margin}")  # "15.00%"

Portfolio Analysis

# Portfolio performance with mixed units
initial_value = money(100_000)
final_value = money(125_000)
time_period = dimensionless(2)  # 2 years

# Calculate returns with proper unit handling
absolute_return = final_value - initial_value     # Money - Money = Money
return_ratio = final_value / initial_value        # Money ÷ Money = Ratio
return_percent = (return_ratio - ratio(1)).as_percentage()  # (Ratio - Ratio).as_percentage() = Percent

# Annualized calculations
annualized_ratio = return_ratio ** (dimensionless(1) / time_period)  # Ratio^(Dimensionless÷Dimensionless) = Ratio
annualized_percent = (annualized_ratio - ratio(1)).as_percentage()

print(f"Initial Value: {initial_value}")       # "$100,000.00"
print(f"Final Value: {final_value}")           # "$125,000.00"
print(f"Absolute Return: {absolute_return}")   # "$25,000.00"
print(f"Total Return: {return_percent}")       # "25.00%"
print(f"Annualized Return: {annualized_percent}") # "11.80%"

Pricing and Margin Analysis

# Product pricing with unit validation
cost_per_unit = money(50.00)
target_margin = percent(40, input="percent")  # 40% margin
markup_multiplier = ratio(1) / (ratio(1) - target_margin.ratio())

# Calculate selling price
selling_price = cost_per_unit * markup_multiplier

# Validate the margin
actual_margin = ((selling_price - cost_per_unit) / selling_price).as_percentage()

print(f"Cost per Unit: {cost_per_unit}")       # "$50.00"
print(f"Target Margin: {target_margin}")       # "40.00%"
print(f"Markup Multiplier: {markup_multiplier}") # "1.67"
print(f"Selling Price: {selling_price}")       # "$83.33"
print(f"Actual Margin: {actual_margin}")       # "40.00%"

# Volume calculations
units_sold = dimensionless(1000)
total_revenue = selling_price * units_sold      # Money × Dimensionless = Money
total_cost = cost_per_unit * units_sold         # Money × Dimensionless = Money
total_profit = total_revenue - total_cost       # Money - Money = Money

print(f"Units Sold: {units_sold}")             # "1,000.00"
print(f"Total Revenue: {total_revenue}")       # "$83,333.33"
print(f"Total Profit: {total_profit}")         # "$33,333.33"

Multi-Currency Operations

# Currency operations with exchange rates
usd_amount = money(1000, policy=Policy(currency_symbol="$"))
eur_usd_rate = ratio(1.18)  # 1 EUR = 1.18 USD

# Convert currencies using ratios
eur_amount = usd_amount / eur_usd_rate
eur_amount = eur_amount.with_policy(Policy(currency_symbol="€", currency_position="suffix"))

print(f"USD Amount: {usd_amount}")    # "$1,000.00"
print(f"EUR/USD Rate: {eur_usd_rate}") # "1.18"
print(f"EUR Amount: {eur_amount}")     # "847.46€"

# Validate round-trip conversion
converted_back = eur_amount * eur_usd_rate
converted_back = converted_back.with_policy(Policy(currency_symbol="$"))
print(f"Converted Back: {converted_back}")  # "$1,000.00" (approximately)

Advanced Unit Patterns

Custom Unit Semantics

While Metric Engine provides core units, you can create semantic meaning through careful unit selection:

# Use Dimensionless for different semantic categories
shares_outstanding = dimensionless(1_000_000)  # Share count
days_in_period = dimensionless(365)            # Time periods
basis_points = dimensionless(100)              # 100 basis points = 1%

# Convert basis points to percentage
bps_to_percent = basis_points / dimensionless(10_000)  # 100/10000 = 0.01
interest_rate = bps_to_percent.as_percentage()
print(interest_rate)  # "1.00%"

# Market value calculations
share_price = money(45.50)
market_value = share_price * shares_outstanding
print(f"Market Value: {market_value}")  # "$45,500,000.00"

Unit-Safe Financial Formulas

def calculate_compound_interest(
    principal: money,
    annual_rate: percent,
    years: dimensionless,
    compounds_per_year: dimensionless = None
) -> money:
    """Calculate compound interest with unit validation."""

    if compounds_per_year is None:
        compounds_per_year = dimensionless(1)  # Annual compounding

    # Convert percentage to ratio for calculation
    rate = annual_rate.ratio()

    # Compound interest formula: A = P(1 + r/n)^(nt)
    rate_per_period = rate / compounds_per_year
    total_periods = compounds_per_year * years

    # (1 + rate_per_period) is dimensionless, so we can raise to a power
    compound_factor = (ratio(1) + rate_per_period) ** total_periods

    return principal * compound_factor

# Example usage
initial_investment = money(10_000)
annual_rate = percent(8, input="percent")  # 8%
investment_years = dimensionless(10)
quarterly_compounding = dimensionless(4)

final_amount = calculate_compound_interest(
    initial_investment,
    annual_rate,
    investment_years,
    quarterly_compounding
)

print(f"Initial Investment: {initial_investment}")    # "$10,000.00"
print(f"Annual Rate: {annual_rate}")                  # "8.00%"
print(f"Years: {investment_years}")                   # "10.00"
print(f"Final Amount: {final_amount}")                # "$22,080.40"

Error Prevention Through Units

def calculate_break_even_analysis(
    fixed_costs: money,
    variable_cost_per_unit: money,
    selling_price_per_unit: money
) -> dimensionless:
    """Calculate break-even units with type safety."""

    # Unit algebra prevents errors
    contribution_margin = selling_price_per_unit - variable_cost_per_unit  # Money - Money = Money

    # Break-even formula: Fixed Costs ÷ Contribution Margin per Unit
    break_even_units = fixed_costs / contribution_margin  # Money ÷ Money = Dimensionless (units)

    return break_even_units

# Example with type validation
monthly_fixed_costs = money(50_000)
variable_cost = money(25.00)
selling_price = money(45.00)

break_even = calculate_break_even_analysis(monthly_fixed_costs, variable_cost, selling_price)
print(f"Break-even Units: {break_even}")  # "2,500.00"

# Validation calculations
total_contribution = break_even * (selling_price - variable_cost)  # Dimensionless × Money = Money
print(f"Total Contribution at Break-even: {total_contribution}")   # "$50,000.00"

Best Practices

1. Choose Appropriate Units for Business Context

# Good: Units match business semantics
profit_margin = percent(15, input="percent")        # Display as percentage
exchange_rate = ratio(1.18)                         # Display as ratio
revenue = money(100_000)                            # Currency amount
employee_count = dimensionless(50)                  # Pure quantity

# Less clear: Units don't match semantics
# margin_as_ratio = ratio(0.15)                    # Confusing - is this 15% or 0.15%?
# count_as_money = money(50)                        # Nonsensical - employees aren't currency

2. Use Type Hints for Clarity

from metricengine import money, percent, ratio, dimensionless, MoneyFV, PercentFV

def calculate_tax_impact(
    gross_income: MoneyFV,
    tax_rate: PercentFV,
    deduction: MoneyFV
) -> tuple[MoneyFV, MoneyFV]:
    """Calculate tax with clear type signatures."""
    taxable_income = gross_income - deduction
    tax_amount = taxable_income * tax_rate
    net_income = taxable_income - tax_amount

    return tax_amount, net_income

3. Validate Unit Compatibility

def safe_financial_calculation(*values):
    """Safely handle mixed unit operations."""
    result = values[0]

    for value in values[1:]:
        operation_result = result + value
        if operation_result.is_none():
            print(f"Warning: Incompatible units {result.unit} and {value.unit}")
            continue
        result = operation_result

    return result

# Example usage
mixed_values = [
    money(1000),
    money(500),
    # percent(10, input="percent"),  # Would trigger warning
    # ratio(0.15),                   # Would trigger warning
]

total = safe_financial_calculation(*mixed_values)
print(f"Safe Total: {total}")  # "$1,500.00"

4. Document Unit Expectations

class FinancialMetrics:
    """Financial metrics calculator with documented unit requirements.

    All monetary amounts should use Money units.
    All rates and percentages should use Percent units.
    All ratios and multipliers should use Ratio units.
    All counts and quantities should use Dimensionless units.
    """

    def calculate_roe(
        self,
        net_income: MoneyFV,      # Annual net income in Money units
        equity: MoneyFV,          # Total shareholder equity in Money units
    ) -> PercentFV:
        """Calculate Return on Equity as a percentage.

        Returns: ROE as Percent unit (e.g., "15.5%" for 15.5% ROE)
        """
        roe_ratio = net_income / equity  # Money ÷ Money = Ratio
        return roe_ratio.as_percentage() # Convert to Percent for display

    def calculate_debt_to_equity(
        self,
        total_debt: MoneyFV,      # Total debt in Money units
        total_equity: MoneyFV,    # Total equity in Money units
    ) -> ratio:
        """Calculate Debt-to-Equity ratio.

        Returns: D/E ratio as Ratio unit (e.g., "1.25" for 1.25:1 ratio)
        """
        return total_debt / total_equity  # Money ÷ Money = Ratio

Metric Engine’s unit system provides robust type safety and semantic clarity for financial calculations. By encoding business meaning into the type system, units help prevent errors, improve code readability, and ensure mathematical correctness in financial applications.