Oil & gas deal valuation toolkit for Crude Code inner agents — forecast, cashflow, NPV.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crudecode_valuation-0.2.0.tar.gz.
File metadata
- Download URL: crudecode_valuation-0.2.0.tar.gz
- Upload date:
- Size: 21.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9870e305b59b6a3baf8148d79bebf22fe7503af446e75c4bb9a9736757289f8a
|
|
| MD5 |
253edf26153bd85f09d892f913abbe60
|
|
| BLAKE2b-256 |
db0dd32fab1ff01ed1fe31e5e693742aa773e86b263002fc961bed6e1d0f4d42
|
File details
Details for the file crudecode_valuation-0.2.0-py3-none-any.whl.
File metadata
- Download URL: crudecode_valuation-0.2.0-py3-none-any.whl
- Upload date:
- Size: 31.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52aa5a579fe67c40295d1f123abff9ab731206f66c63142b85a491a1b6ccf285
|
|
| MD5 |
fc5b079ca1e357e91ac24715b34b8576
|
|
| BLAKE2b-256 |
7824d4ec6594c2424390e8145f3129b70be038bbb1edc364037adc4854751ea4
|