crudecode-valuation
Domain package for oil & gas deal valuation. Used by the valuation_agent
inner agent in the EI Plugins MCP server.
What you get
Two subsystems:
forecast— primitives + diagnostic helpers for building production forecasts from analogs, own history, or blends.econ— revenue → cashflow → NPV given a forecast tuple, interest type, and economic assumptions.
You compose them yourself. No fused valuate() entry point.
Agent workflow — EXPLORE → DECIDE → EXECUTE
Every /tmp/valuation.py follows three phases marked by comment headers.
EXPLORE
Load production, find analogs, fit them, and inspect with the three diagnostic helpers:
from crude_valuation import (
load_production, find_analogs, fit_curve,
cohort_summary, fit_quality, target_vs_cohort,
)
prod = load_production(WELL_APIS, run_sql)
analog_apis = find_analogs(ANALOG_FILTER, run_sql, exclude=WELL_APIS)
analog_curves = []
for a in analog_apis:
try:
analog_prod = load_production([a], run_sql)
q = np.array(analog_prod["oil_bbl"])
months = np.arange(len(q), dtype=float)
meta = peek_well(a, run_sql)
analog_curves.append(
fit_curve(months, q, stream="oil", lateral_norm_ft=meta.lateral_ft, b_fixed=0.8)
)
except ValueError:
continue # skip thin / un-fittable analogs
print(cohort_summary(analog_curves))
cohort_median = percentile_curves(analog_curves, pct=0.5, norm_to_lateral_ft=10_000.0)
for api in WELL_APIS:
meta = peek_well(api, run_sql)
target_prod = load_production([api], run_sql)
target_q = np.array(target_prod["oil_bbl"])
target_months = np.arange(len(target_q), dtype=float)
print(api, target_vs_cohort(cohort_median, target_months, target_q, meta.lateral_ft))
DECIDE
A free-form comment block. Document the call per well in plain English:
# === DECIDE ===
# Cohort: 15 analogs after dropping 3 bound-riders. b median 0.92, IQR 0.31.
# Target 42-329-12345 (Wolfcamp A, 9,400 ft):
# 36 months observed, qi_ratio 1.04 -> in line with cohort
# Choice: pdp; fit own decline with b=0.9 (cohort median, dropped outliers)
# Target 42-329-12999 (PERMITTED, 10,200 ft):
# no history; planned spud 2026-08
# Choice: pure_analog with cohort curve at target lateral
EXECUTE
Build Forecasts inline per-well — no router, no module constants:
# === EXECUTE ===
forecasts_oil = []
forecasts_gas = []
for api, choice in CHOICES.items():
if choice["strategy"] == "pdp":
forecasts_oil.append(_build_pdp(api, b=choice["b"], stream="oil", ...))
elif choice["strategy"] == "thin_blend":
forecasts_oil.append(_build_thin(api, cohort_median_oil, ...))
else: # pure_analog
forecasts_oil.append(_build_pure_analog(api, cohort_median_oil, ...))
# same for gas
# Econ + persist
revenue = compute_gross_revenue(forecasts_oil, forecasts_gas, price_deck=...)
cashflow = compute_net_cashflow(revenue, interest_type=INTEREST_TYPE, ...)
npv_dict = npv(cashflow, discount_rates=[0.08, 0.10, 0.12, 0.15])
spec = build_minimal_briefing(headline=..., commentary=..., npv=npv_dict, ...)
persist(spec, persist_url="$persist_url")
Commentary must reference at least one concrete diagnostic you looked at.
Playbooks
crude_valuation/forecast/examples/ ships annotated playbooks showing the
EXPLORE → DECIDE → EXECUTE pattern end-to-end. Today only forecast_mixed.py
is in the new playbook form; the other two are still recipe-style.
Diagnostic helpers in detail
cohort_summary(curves)— distribution stats per fitted parameter (qi, di, b, terminal, lateral). Plusnotesflagging fits that rode the b bound.fit_quality(curve, months, q)— R^2, RMSE, bound-riding flags, max residual %, early/late signed-% bias windows for a single fit.target_vs_cohort(cohort, target_months, target_q, target_lateral_ft)— qi_ratio of target to cohort, peak detection, per-month signed-% residual vs cohort placed at target lateral.
None of these decide anything. The agent reads them and chooses.
Metadata
Release files for crudecode-valuation 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| crudecode_valuation-0.2.1.tar.gz | 22.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| crudecode_valuation-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.4 kB
Release files / crudecode_valuation-0.2.1.tar.gz
| Download URL | crudecode_valuation-0.2.1.tar.gz |
|---|---|
| Size | 22.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
92af92fbd5459ea0f2bfe41d5aae24df73e82d2e4848c5f305559cfa380c801e
|
|
BLAKE2b-256 checksum How to use checksums |
f73e084d8a4c436e01aee6e8f34b9e3a300ee64effbf88e0c9e7b6cff18f1da3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / crudecode_valuation-0.2.1-py3-none-any.whl
| Download URL | crudecode_valuation-0.2.1-py3-none-any.whl |
|---|---|
| Size | 31.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b2c6b6a0f50a8fb78bb059ad68e103683c5a5df6181b7d7d3b3f9c740481110
|
|
BLAKE2b-256 checksum How to use checksums |
de6b7fb15d01cd9745666fd0c1aab86cb4e9e03e30afe46ead1afdcd21cddf90
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|