PySCnomics merupakan library Python untuk analisis keekonomian kontrak Production Sharing Contract (PSC) di sektor hulu minyak dan gas bumi Indonesia. Halaman ini memandu pengguna menjalankan perhitungan pertama — mulai dari menyiapkan data, membangun objek kontrak, hingga memperoleh indikator keekonomian seperti NPV dan IRR.
Contoh berikut menggunakan data dummy lapangan minyak pada rezim Cost Recovery (CR), yang merupakan kontrak PSC paling umum di Indonesia.
Perhitungan keekonomian PSC mengikuti alur berikut:
Lifting + Costs → Kontrak → .run() → .get_summary() → Indikator (NPV/IRR)
Data berikut merepresentasikan lapangan minyak dengan produksi 17 tahun (2023–2039), harga konstan USD 75/bbl, dan struktur biaya yang mencakup capital cost, intangible cost, OPEX, dan ASR.
| Tahun | Produksi (MSTB) | Harga (USD/bbl) |
|---|---|---|
| 2023 | 18.98 | 75 |
| 2024 | 158.30 | 75 |
| 2025 | 147.40 | 75 |
| 2026 | 122.07 | 75 |
| 2027 | 119.10 | 75 |
| 2028 | 103.22 | 75 |
| 2029 | 90.76 | 75 |
| 2030 | 78.09 | 75 |
| 2031 | 82.41 | 75 |
| 2032 | 70.12 | 75 |
| 2033 | 67.07 | 75 |
| 2034 | 64.98 | 75 |
| 2035 | 55.79 | 75 |
| 2036 | 48.93 | 75 |
| 2037 | 44.10 | 75 |
| 2038 | 43.15 | 75 |
| 2039 | 35.19 | 75 |
Total produksi kumulatif: 1.349,66 MSTB; harga konstan USD 75/bbl.
| Komponen | Tahun Aktif | Total |
|---|---|---|
| Tangible (DWO + PF) | 2023–2025 | 7.741,54 |
| Intangible (DWO) | 2023–2024 | 3.348,40 |
| OPEX | 2023–2039 | 77.037,82 |
| ASR | 2024–2039 | 381,78 |
Parameter fiskal berikut mengatur distribusi hasil antara kontraktor dan pemerintah:
Semua kelas dan enumerasi yang dibutuhkan diimpor dari pyscnomics. Enumerasi (FluidType, TaxRegime, DeprMethod, dll.) digunakan untuk memilih opsi perhitungan secara eksplisit, menghindari kesalahan akibat penggunaan string atau angka magic.
from datetime import date
import numpy as np
from pyscnomics.contracts.costrecovery import CostRecovery
from pyscnomics.econ.revenue import Lifting
from pyscnomics.econ.costs import CapitalCost, Intangible, OPEX, ASR, LBT, CostOfSales
from pyscnomics.econ.selection import (
FluidType, CostType, TaxSplitTypeCR, TaxRegime,
FTPTaxRegime, DeprMethod, OtherRevenue,
)
fluid = FluidType.OIL
years = np.arange(2023, 2040)
n = 17
Variabel fluid, years, dan n digunakan berulang kali di tahap berikutnya, sehingga didefinisikan sekali di awal.
Lifting mendefinisikan profil produksi dan harga per tahun. Parameter utamanya adalah laju produksi (lifting_rate), harga (price), dan jenis fluida (fluid_type). Semua array harus berukuran sama, yaitu sebanyak jumlah tahun kontrak.
oil_prod = np.array([18.98, 158.3033, 147.4048, 122.0714, 119.1029,
103.224, 90.7603, 78.0871, 82.4073, 70.117,
67.0701, 64.9807, 55.7928, 48.9258, 44.0986,
43.1454, 35.1856])
lifting = (Lifting(
start_year=2023, end_year=2039,
prod_year=years, lifting_rate=oil_prod,
price=np.full(n, 75.0), fluid_type=fluid,
),)
Catatan: objek Lifting dibungkus tuple dengan tanda koma trailing (Lifting(...),) — ini konvensi PySCnomics karena parameter lifting pada konstruktor kontrak menerima tuple objek, bukan objek tunggal.
Biaya diklasifikasikan menjadi lima komponen. Setiap komponen adalah objek yang menerima array biaya per tahun, alokasi fluida, dan tipe biaya.
Capital cost mencakup biaya tangible yang didepresiasi sepanjang masa manfaat aset (useful_life). Dalam contoh ini, tangible terdiri dari DWO (Drilling & Well Operations) dan PF (Platform Facility), masing-masing didefinisikan terpisah lalu dijumlahkan.
tangible_dwo = np.array([555.3528, 248.4237] + [0.0]*15)
tangible_pf = np.array([591.4287, 4148.5932, 2197.7461] + [0.0]*14)
total_tangible = tangible_dwo + tangible_pf
capital_cost = (CapitalCost(
start_year=2023, end_year=2039, expense_year=years,
cost=total_tangible, cost_allocation=[fluid]*n,
cost_type=[None]*n, pis_year=np.full(n, 2023),
useful_life=np.full(n, 5),
),)
Parameter pis_year (placed-in-service year) menentukan kapan aset mulai didepresiasi. Dengan cost_type=[None]*n, seluruh biaya berwujud diklasifikasikan sebagai biaya operasional default — bukan sunk cost maupun pre-onstream cost.
Intangible cost tidak didepresiasi; pada rezim Cost Recovery, biaya ini langsung masuk ke cost recovery pool pada tahun pengeluaran.
intangible_cost = (Intangible(
start_year=2023, end_year=2039, expense_year=years,
cost=np.array([2314.5267, 1033.8725] + [0.0]*15),
cost_allocation=[fluid]*n, cost_type=[None]*n,
),)
OPEX merupakan biaya operasional tahunan yang paling besar (77.037,82 MUSD total). ASR (Abandonment and Site Restoration) dan LBT (Land and Building Tax) termasuk komponen pendukung. Cost of Sales dalam contoh ini bernilai nol.
opex = (OPEX(
start_year=2023, end_year=2039, expense_year=years,
fixed_cost=np.array([2445.2836, 10178.3519, 7893.3926, 4325.1296,
4628.2841, 4653.1457, 4066.6783, 4574.1198,
4321.782, 3896.2821, 4329.2056, 4176.2252,
3778.0459, 3578.7603, 3432.025, 3320.0657,
3441.0413]),
cost_allocation=[fluid]*n, cost_type=[None]*n,
),)
asr = (ASR(
start_year=2023, end_year=2039, expense_year=years,
cost=np.array([0.0] + [23.8613]*16),
cost_allocation=[fluid]*n, cost_type=[None]*n,
),)
lbt = (LBT(
start_year=2023, end_year=2039, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid]*n, cost_type=[None]*n,
),)
cos = (CostOfSales(
start_year=2023, end_year=2039, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid]*n, cost_type=[None]*n,
),)
Objek CostRecovery dibangun dengan seluruh data produksi dan biaya, beserta parameter fiskal struktural (FTP, DMO, tax split, investment credit). Parameter ini ditetapkan dalam konstruktor karena tidak berubah antar eksekusi.
cr = CostRecovery(
start_date=date(2023, 1, 1), end_date=date(2039, 12, 31),
oil_onstream_date=date(2023, 1, 1), gas_onstream_date=None,
approval_year=2023, is_pod_1=True, is_strict=False,
lifting=lifting, capital_cost=capital_cost,
intangible_cost=intangible_cost, opex=opex,
asr_cost=asr, lbt_cost=lbt, cost_of_sales=cos,
# FTP
oil_ftp_is_available=True, oil_ftp_is_shared=True,
oil_ftp_portion=0.1,
gas_ftp_is_available=False, gas_ftp_is_shared=True,
gas_ftp_portion=0.0,
# Tax split
tax_split_type=TaxSplitTypeCR.CONVENTIONAL,
condition_dict=dict, indicator_rc_icp_sliding=None,
oil_ctr_pretax_share=0.599359, gas_ctr_pretax_share=0.599359,
# Investment credit
oil_ic_rate=0.0, gas_ic_rate=0.0, ic_is_available=False,
oil_cr_cap_rate=1.0, gas_cr_cap_rate=1.0,
# DMO
oil_dmo_volume_portion=0.25, oil_dmo_fee_portion=1.0,
oil_dmo_holiday_duration=0,
gas_dmo_volume_portion=1.0, gas_dmo_fee_portion=1.0,
gas_dmo_holiday_duration=0,
# Carry forward
oil_carry_forward_depreciation=0.0,
gas_carry_forward_depreciation=0.0,
)
Beberapa parameter penting yang diperhatikan:
is_pod_1=True — mengaktifkan amortisasi pada rezim Gross Split (tidak berpengaruh di CR, tapi relevan saat berpindah kontrak).oil_ftp_is_shared=True — FTP dibagi antara pemerintah dan kontraktor, bukan sepenuhnya milik pemerintah.oil_cr_cap_rate=1.0 — tidak ada pembatasan (cap) pada cost recovery.Parameter fiskal operasional dikirim ke metode .run(), bukan ke konstruktor. Pemisahan ini memungkinkan pemanggilan ulang .run() dengan parameter berbeda — misalnya skenario tarif pajak alternatif — tanpa membuat objek kontrak baru.
cr.run(
effective_tax_rate=0.376,
is_dmo_end_weighted=False,
tax_regime=TaxRegime.NAILED_DOWN,
ftp_tax_regime=FTPTaxRegime.PDJP_20_2017,
depr_method=DeprMethod.PSC_DB,
decline_factor=2,
post_uu_22_year2001=True,
oil_cost_of_sales_applied=False,
gas_cost_of_sales_applied=False,
sum_undepreciated_cost=False,
sulfur_revenue=OtherRevenue.ADDITION_TO_GAS_REVENUE,
electricity_revenue=OtherRevenue.ADDITION_TO_GAS_REVENUE,
co2_revenue=OtherRevenue.ADDITION_TO_GAS_REVENUE,
vat_rate=0.0,
)
Parameter kunci:
TaxRegime.NAILED_DOWN — tarif pajak tunggal, bukan progresif.DeprMethod.PSC_DB — depresiasi declining balance sesuai PSC Exhibit "C".decline_factor=2 — faktor penurunan ganda (double declining).FTPTaxRegime.PDJP_20_2017 — perlakuan pajak FTP mengacu pada Permen 20/2017.s = cr.get_summary()
Metode get_summary() mengembalikan dictionary flat yang berisi seluruh indikator keekonomian utama:
| Kunci | Nilai | Keterangan |
|---|---|---|
gross_revenue |
101.224,28 MUSD | Pendapatan kotor dari penjualan minyak |
cost_recovery |
86.172,80 MUSD | Total biaya yang dikembalikan ke kontraktor |
ctr_gross_share |
2.954,27 MUSD | Bagian kontraktor sebelum pajak |
ctr_net_share |
5.932,37 MUSD | Bagian kontraktor setelah pajak |
ctr_npv |
−15.997,79 MUSD | Net present value kontraktor (diskonto 10%) |
gov_take |
9.119,11 MUSD (9,01%) | Total penerimaan pemerintah |
NPV kontraktor negatif (−15.997,79 MUSD) karena capital expenditure (CAPEX) yang besar di awal kontrak (7.741,54 MUSD tangible + 3.348,40 MUSD intangible) belum tertutup oleh contractor share dalam horizon waktu proyek. Hal ini menunjukkan bahwa proyek tidak layak secara keekonomian dari perspektif kontraktor pada parameter fiskal yang diberikan.
Beberapa konvensi API yang perlu diperhatikan:
date(), bukan string — misalnya date(2023, 1, 1).lifting, capital_cost, opex, dll.) harus tuple, bukan list. Perhatikan tanda koma trailing: (Lifting(...),).pyscnomics.econ.selection: FluidType.OIL, TaxSplitTypeCR.CONVENTIONAL, TaxRegime.NAILED_DOWN, DeprMethod.PSC_DB.CostType menentukan klasifikasi biaya: SUNK_COST, PRE_ONSTREAM_COST, POST_ONSTREAM_COST. Gunakan None untuk default.effective_tax_rate, tax_regime, depr_method, dll.) dikirim ke .run(), bukan ke konstruktor.get_summary() mengembalikan dictionary flat — akses nilai via s['ctr_npv'], s['gov_take'], dll.