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:
Type Safety - Prevent nonsensical operations like adding dollars to percentages
Semantic Clarity - Make code self-documenting by encoding business meaning
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.