Files
calminer-docs/specifications/price_calculation.md
zwitschi 29f16139a3 feat: documentation update
- Completed export workflow implementation (query builders, CSV/XLSX serializers, streaming API endpoints, UI modals, automated tests).
- Added export modal UI and client script to trigger downloads directly from dashboard.
- Documented import/export field mapping and usage guidelines in FR-008.
- Updated installation guide with export environment variables, dependencies, and CLI/CI usage instructions.
2025-11-11 18:34:02 +01:00

8.9 KiB
Raw Blame History

Product Price Calculation Specification

1. Purpose

Provide a detailed reference for calculating product sale prices across supported metals, including adjustments for ore grade, recovery rate, moisture, and impurities. This document extends the initial variable list with explicit formula definitions, validation rules, and example workflows.

2. Scope

  • Applies to primary commodity outputs (e.g., copper, gold, lithium) cited in scenario models.
  • Supports integration into scenario profitability pipelines and exportable reporting.
  • Covers penalties/credits based on quality metrics (water content, impurity assays) and market adjustments.

3. Inputs & Parameters

Symbol Name Description Units / Domain Validation
M Metal Commodity identifier (e.g., copper, gold) Enum MetalType Required
Q_{ore} Ore tonnage processed Total ore mass entering processing metric tonnes Q_{ore} > 0
G Head grade Percentage of target metal in ore (mass fraction) % (0100) 0 < G \leq 100
R Recovery rate Plant recovery efficiency % (0100) 0 < R \leq 100
T Treatment charge Base processing fee negotiated with smelter/refiner currency / tonne concentrate T \geq 0
S Smelting charge Additional fee tied to concentrate handling currency / tonne concentrate S \geq 0
M_{moist} Moisture content Percentage water in concentrate % (0100) 0 \leq M_{moist} < 40
M_{imp}^{i} Impurity content For impurity i (e.g., As, Pb, Zn) measure mass ppm ppm 0 \leq M_{imp}^{i}
F_{moist} Moisture penalty factor Currency impact per excess moisture percentage currency / % Optional
F_{imp}^{i} Impurity penalty factor Currency impact per ppm over threshold currency / ppm Optional
Adj_{prem} Premiums/credits Adders (e.g., gold credits in copper concentrate) currency Optional
FX FX rate Convert pricing currency to scenario currency currency conversion rate FX > 0

4. Derived Values

  1. Metal content (payable basis):

    Q*{metal} = Q*{ore} \times \frac{G}{100} \times \frac{R}{100}
  2. Payable mass after deductions (if contractual payable is <100%): Introduce payable percentage K_M (default 100%).

    Q*{pay} = Q*{metal} \times \frac{K_M}{100}
  3. Gross revenue in reference currency:

    Rev*{gross}^{ref} = Q*{pay} \times P\_{ref}
  4. Treatment and smelting charges:

    Charges = T + S
  5. Moisture penalty (if moisture exceeds threshold M_{moist}^{thr}):

    Pen*{moist} = \max(0, M*{moist} - M*{moist}^{thr}) \times F*{moist}
  6. Impurity penalty (sum over impurities with thresholds M_{imp}^{i,thr}):

    Pen*{imp} = \sum_i \max(0, M*{imp}^{i} - M*{imp}^{i,thr}) \times F*{imp}^{i}
  7. Net revenue before premiums:

    Rev*{net}^{ref} = Rev*{gross}^{ref} - Charges - Pen*{moist} - Pen*{imp}
  8. Apply premiums/credits:

    Rev*{adj}^{ref} = Rev*{net}^{ref} + Adj\_{prem}
  9. Convert to scenario currency:

    Rev*{adj} = Rev*{adj}^{ref} \times FX

5. Workflow Examples

5.1 Copper Concentrate

  • Ore feed Q_{ore} = 100,000 t, head grade G = 1.2\%, recovery R = 90\%.
  • Reference price $P_{ref} = $8,500$/t, payable percentage K_M = 96\%.
  • Treatment and smelting charges T+S = \$100/t concentrate equivalent.
  • Moisture threshold 8%, actual 10%, penalty factor F_{moist} = \$3,000 per %.
  • Arsenic impurity: threshold 0 ppm (premium for As-free), actual 100 ppm, penalty factor F_{imp}^{As} = \$2 per ppm.

Calculations:

  1. Q_{metal} = 100,000 \times 0.012 \times 0.9 = 1,080 t.
  2. Q_{pay} = 1,080 \times 0.96 = 1,036.8 t.
  3. Rev_{gross}^{ref} = 1,036.8 \times 8,500 = \$8,812,800.
  4. Pen_{moist} = (10 - 8) \times 3,000 = \$6,000.
  5. Pen_{imp} = (100 - 0) \times 2 = \$200.
  6. Rev_{net}^{ref} = 8,812,800 - 100,000 - 6,000 - 200 = \$8,706,600.
  7. Assume premiums Adj_{prem} = \$50,000, FX = 1.0 → final Rev_{adj} = \$8,756,600.

5.2 Gold Doré

  • Ore feed 50,000 t, head grade 2.5 g/t (convert to % mass: 0.00025%), recovery 92%.
  • Reference price $P_{ref} = $1,900$/oz, convert to per tonne of metal (1\ \text{oz} = 0.0311035 \text{kg}).
  • Treat Q_{metal} in kilograms or troy ounces as implementation convenience.
  • No moisture/impurity penalties; add refining charge 1.5% of revenue.

Implementation note: Provide conversion helpers for precious metals (grams per tonne to ounces, etc.).

6. Validation & Error Handling

  • Ensure required inputs are provided; raise descriptive validation errors per scenario when data missing.
  • Bound checks for percentage inputs; clamp or reject values outside (0,100].
  • Penalty factors default to zero if not configured; log warnings if impurities exceed supported list.
  • FX rate defaults to 1.0 when scenario currency matches reference currency; enforce positive values.

7. Data Sources & Configuration

  • Reference prices sourced from market data integration (e.g., LME, LBMA). Provide placeholder configuration until connectors exist.
  • Penalty thresholds and factors configurable per smelter contract; persisted in the pricing_settings tables (pricing_settings, pricing_metal_settings, pricing_impurity_settings).
  • The default configuration lives in the pricing_settings row with slug default. services.bootstrap.bootstrap_pricing_settings runs during FastAPI startup (and via scripts/initial_data.py) to ensure this row exists and mirrors the configured baseline metadata.
  • Runtime consumers obtain metadata through the FastAPI dependency dependencies.get_pricing_metadata, which loads the persisted defaults with impurity overrides. If the requested slug is missing, the dependency reseeds the table from Settings.pricing_metadata() before returning a fresh PricingMetadata instance.
  • Deployment environments can still influence the initial bootstrap by setting the following environment variables before the database is seeded. They are only read when creating or reseeding the default record:
Environment Variable Default Bootstrap Usage
CALMINER_PRICING_DEFAULT_PAYABLE_PCT 100.0 Initial payable percentage stored in the default pricing settings row.
CALMINER_PRICING_DEFAULT_CURRENCY USD Initial currency recorded in the persisted metadata (can be set to null).
CALMINER_PRICING_MOISTURE_THRESHOLD_PCT 8.0 Initial moisture threshold applied when seeding the database.
CALMINER_PRICING_MOISTURE_PENALTY_PER_PCT 0.0 Initial moisture penalty factor captured in the persisted configuration record.

Operators should update the database record (or project-specific overrides) after bootstrap to align with active smelter contracts. Subsequent application restarts reuse the stored values without re-reading environment variables.

8. Output Schema

Define structured result for integration:

{
  "metal": "copper",
  "ore_tonnage": 100000,
  "head_grade_pct": 1.2,
  "recovery_pct": 90,
  "payable_metal_tonnes": 1036.8,
  "reference_price": 8500,
  "gross_revenue": 8812800,
  "moisture_penalty": 6000,
  "impurity_penalty": 200,
  "treatment_smelt_charges": 100000,
  "premiums": 50000,
  "net_revenue": 8756600,
  "currency": "USD"
}

9. Dependencies & Next Steps

  • Align with FR-006 (performance monitoring) to collect calculation metrics.
  • Coordinate with reporting requirements to expose inputs/outputs in exports.
  • Next implementation steps: build pricing service module, integrate with scenario evaluation, and author unit tests using example data above.# Variables for Price Calculation

Variables

  • Base Percentage Ore Content
  • Increase per Percentage Ore Content
  • Price per Unit Weight

Penalties

  • Moisture
  • Impurities

Price Calculation Formula

The revenue from product sales can be modeled as:

Revenue = (Quantity Sold * Price per Unit) - Penalties