Skip to main content

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). Plus notes flagging 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crudecode_valuation-0.2.0.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crudecode_valuation-0.2.0-py3-none-any.whl (31.2 kB view details)

Uploaded Python 3

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

Hashes for crudecode_valuation-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9870e305b59b6a3baf8148d79bebf22fe7503af446e75c4bb9a9736757289f8a
MD5 253edf26153bd85f09d892f913abbe60
BLAKE2b-256 db0dd32fab1ff01ed1fe31e5e693742aa773e86b263002fc961bed6e1d0f4d42

See more details on using hashes here.

File details

Details for the file crudecode_valuation-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for crudecode_valuation-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 52aa5a579fe67c40295d1f123abff9ab731206f66c63142b85a491a1b6ccf285
MD5 fc5b079ca1e357e91ac24715b34b8576
BLAKE2b-256 7824d4ec6594c2424390e8145f3129b70be038bbb1edc364037adc4854751ea4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page