Registry Collections

Organize, extend, and manage financial calculations by domain.

What Are Registry Collections?

A Registry Collection is a namespace for grouping related financial calculations in Metric Engine. Collections help you:

  • Organize calculations by domain (e.g., profitability, growth, inventory)

  • Register functions with explicit names and dependencies

  • Build extensible, maintainable calculation libraries

  • Avoid naming collisions and enable modularity

Think of a collection as a toolbox for a specific domain—each with its own set of calculation tools.

Why Use Collections?

  • Clarity: Group related calculations for easier discovery and maintenance

  • Extensibility: Add or override calculations in your own domain packages

  • Dependency Management: Explicitly declare calculation dependencies for safe, automatic resolution

  • Isolation: Prevent accidental name clashes between unrelated calculations

How Collections Work

A collection is created by instantiating the Collection class with a namespace. You then use the .calc() decorator to register functions under that namespace, optionally specifying dependencies.

Example: Defining a Collection

from metricengine.registry_collections import Collection

profitability = Collection("profitability")

@profitability.calc("gross_profit", depends_on=("sales", "cost"))
def gross_profit(sales, cost):
    return sales - cost

@profitability.calc("net_profit", depends_on=("gross_profit", "expenses"))
def net_profit(gross_profit, expenses):
    return gross_profit - expenses
  • Each calculation is registered with a unique name (e.g., gross_profit)

  • Dependencies are declared by name, enabling automatic resolution

Built-in Collections

Metric Engine provides several built-in collections:

  • growth: Growth rate calculations

  • profitability: Margin and profitability metrics

  • ratios: Financial ratio calculations

  • inventory: Inventory management calculations

  • pricing: Price-related calculations

  • variance: Variance and volatility metrics

  • utilities: Miscellaneous helpers

You can import and use these collections directly:

from metricengine.calculations import growth

cagr = growth.compound_annual_growth_rate(start_value, end_value, years)

Dependency Management

Each calculation can declare dependencies on other calculations by name. The registry engine:

  • Resolves dependencies automatically when evaluating calculations

  • Detects and prevents circular dependencies

  • Allows you to build complex calculation graphs safely

Example: Dependency Graph

@profitability.calc("operating_margin", depends_on=("operating_income", "sales"))
def operating_margin(operating_income, sales):
    return operating_income / sales
  • When you request operating_margin, the engine ensures operating_income and sales are computed first.

Extending with Custom Collections

You can define your own collections for domain-specific logic:

from metricengine.registry_collections import Collection

my_metrics = Collection("my_metrics")

@my_metrics.calc("custom_kpi", depends_on=("input1", "input2"))
def custom_kpi(input1, input2):
    # Your custom calculation
    return (input1 + input2) / 2
  • Use a unique namespace to avoid conflicts

  • Register as many calculations as needed

Best Practices

  • Use clear, descriptive names for calculations

  • Declare all dependencies explicitly for safety and traceability

  • Group related calculations in the same collection

  • Avoid circular dependencies—the engine will detect and prevent them

  • Document your collections for maintainability

Common Pitfalls

  • Registering two calculations with the same name in the same collection will raise an error

  • Forgetting to declare a dependency may result in missing or incorrect results

  • Circular dependencies are not allowed and will be detected at registration

Real-World Example: Custom Domain Package

Suppose you want to add a set of KPIs for your business domain:

from metricengine.registry_collections import Collection

kpi = Collection("my_kpi")

@kpi.calc("customer_lifetime_value", depends_on=("avg_purchase_value", "purchase_frequency", "customer_lifespan"))
def customer_lifetime_value(avg_purchase_value, purchase_frequency, customer_lifespan):
    return avg_purchase_value * purchase_frequency * customer_lifespan

Now you can use customer_lifetime_value as part of your calculation engine, with all dependencies resolved automatically.


Registry Collections are the foundation for building robust, modular, and maintainable financial calculation libraries in Metric Engine. Use them to organize your logic, manage dependencies, and extend the metric engine for your own domain needs.