Tutorial lengkap menjalankan kontrak Cost Recovery (CR) menggunakan PySCnomics. Dua kasus: Oil Only dan Oil + Gas.
from datetime import date
import numpy as np
from pyscnomics.contracts.costrecovery import CostRecovery
from pyscnomics.contracts.project import BaseProject
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,
)
Catatan:
CostTypemenentukan klasifikasi biaya —SUNK_COST,PRE_ONSTREAM_COST, atauPOST_ONSTREAM_COST. Untuk contoh sederhana, kita gunakanNone(default).
Profil produksi minyak 2023–2039 (17 tahun), harga flat USD 75/bbl.
| Tahun | Produksi (MSTB) | Tangible (MUSD) | Intangible (MUSD) | OPEX (MUSD) |
|---|---|---|---|---|
| 2023 | 18.98 | 1,146.78 | 2,314.53 | 2,445.28 |
| 2024 | 158.30 | 4,397.02 | 1,033.87 | 10,178.35 |
| 2025 | 147.40 | 2,197.75 | 0 | 7,893.39 |
| 2026 | 122.07 | 0 | 0 | 4,325.13 |
| 2027 | 119.10 | 0 | 0 | 4,628.28 |
| 2028 | 103.22 | 0 | 0 | 4,653.15 |
| 2029 | 90.76 | 0 | 0 | 4,066.68 |
| 2030 | 78.09 | 0 | 0 | 4,574.12 |
| 2031 | 82.41 | 0 | 0 | 4,321.78 |
| 2032 | 70.12 | 0 | 0 | 3,896.28 |
| 2033 | 67.07 | 0 | 0 | 4,329.21 |
| 2034 | 64.98 | 0 | 0 | 4,176.23 |
| 2035 | 55.79 | 0 | 0 | 3,778.05 |
| 2036 | 48.93 | 0 | 0 | 3,578.76 |
| 2037 | 44.10 | 0 | 0 | 3,432.03 |
| 2038 | 43.15 | 0 | 0 | 3,320.07 |
| 2039 | 35.19 | 0 | 0 | 3,441.04 |
ASR: 23.86 MUSD/tahun (2024–2039). FTP 10% shared. Tax 37.6%. Pretax share 59.94%.
fluid = FluidType.OIL
years = np.arange(2023, 2040)
n = 17
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),)
tangible = np.array([555.3528, 248.4237] + [0.0]*15) + \
np.array([591.4287, 4148.5932, 2197.7461] + [0.0]*14)
cap = (CapitalCost(start_year=2023, end_year=2039, expense_year=years,
cost=tangible, cost_allocation=[fluid]*n,
cost_type=[None]*n, pis_year=np.full(n, 2023),
useful_life=np.full(n, 5)),)
itg = (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),)
opx = (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),)
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=cap, intangible_cost=itg,
opex=opx, asr_cost=asr, lbt_cost=lbt, cost_of_sales=cos,
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_type=TaxSplitTypeCR.CONVENTIONAL,
condition_dict=dict, indicator_rc_icp_sliding=None,
oil_ctr_pretax_share=0.599359, gas_ctr_pretax_share=0.599359,
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,
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,
oil_carry_forward_depreciation=0.0,
gas_carry_forward_depreciation=0.0,
)
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,
)
s = cr.get_summary()
| Metrik | Nilai |
|---|---|
| Gross Revenue | 101,224.28 MUSD |
| Cost Recovery | 86,172.80 MUSD |
| CTR Gross Share | 2,954.27 MUSD |
| Sunk Cost | 0.00 MUSD |
| CTR Net Share | 5,932.37 MUSD |
| CTR NPV | -15,997.79 MUSD |
| CTR IRR | 11.00% |
| Gov FTP Share | 4,055.46 MUSD |
| Gov Tax Income | 3,088.87 MUSD |
| Gov Take | 9,119.11 MUSD (9.01%) |
Proyek minyak dan gas 2023–2035 (13 tahun). Produksi dimulai 2024.
Produksi:
| Tahun | Oil (MSTB) | Gas (BSCF) | Oil Price | Gas Price |
|---|---|---|---|---|
| 2024 | 377.89 | 1.00 | 60 USD/bbl | 5.01 USD/MMBTU |
| 2025 | 786.25 | 1.97 | 60 | 5.01 |
| 2026 | 695.67 | 2.56 | 60 | 5.01 |
| 2027 | 831.79 | 4.77 | 60 | 5.01 |
| 2028 | 846.61 | 6.05 | 60 | 5.01 |
| 2029 | 876.79 | 6.25 | 60 | 5.01 |
| 2030 | 518.76 | 4.05 | 60 | 5.01 |
| 2031 | 632.35 | 4.58 | 60 | 5.01 |
| 2032 | 520.20 | 4.27 | 60 | 5.01 |
| 2033 | 359.67 | 2.46 | 60 | 5.01 |
| 2034 | 348.47 | 2.35 | 60 | 5.01 |
| 2035 | 240.09 | 2.11 | 60 | 5.01 |
Parameter fiskal: FTP 20% shared, pretax share 67.23%, effective tax 40.5%.
Perbedaan utama dengan Oil Only: dua objek Lifting (minyak + gas), biaya terpisah per fluida, dan tuple digabung.
fluid_oil = FluidType.OIL
fluid_gas = FluidType.GAS
years = np.arange(2023, 2036)
n = 13
# --- Lifting ---
oil_prod = np.array([0, 377.89, 786.25, 695.67, 831.79, 846.61,
876.79, 518.76, 632.35, 520.20, 359.67,
348.47, 240.09])
gas_prod = np.array([0, 1.0, 1.97, 2.56, 4.77, 6.05, 6.25,
4.05, 4.58, 4.27, 2.46, 2.35, 2.11])
oil_lft = (Lifting(start_year=2023, end_year=2035,
prod_year=years, lifting_rate=oil_prod,
price=np.full(n, 60.0), fluid_type=fluid_oil),)
gas_lft = (Lifting(start_year=2023, end_year=2035,
prod_year=years, lifting_rate=gas_prod,
price=np.full(n, 5.01), fluid_type=fluid_gas),)
# --- Biaya per fluida ---
oil_tangible = np.array([0, 24772.17, 21083.21, 18219.45, 14799.89,
7421.0, 188.74, 405.52, 258.08, 533.09,
379.89, 0, 0])
gas_tangible = np.array([0, 5555.88, 4446.61, 5650.24, 7153.06,
4475.88, 113.54, 266.70, 157.72, 368.80,
219.36, 0, 0])
oil_intangible = np.array([0, 45131.83, 40981.19, 21215.43, 22363.65,
21299.55, 698.62, 945.67, 815.24, 1784.84,
1489.62, 0, 0])
gas_intangible = np.array([0, 10122.12, 8643.24, 6579.35, 10808.76,
12846.55, 420.27, 621.93, 498.23, 1234.78,
860.16, 0, 0])
oil_opex = np.array([0, 756.92, 4252.0, 4515.7, 6129.69, 6207.5,
6390.04, 4284.2, 4846.83, 8001.08, 3066.32,
3067.71, 3133.0])
gas_opex = np.array([0, 169.76, 896.78, 1400.41, 2962.59, 3743.98,
3844.04, 2817.56, 2962.10, 5535.25, 1770.60,
1741.46, 2319.09])
oil_cap = (CapitalCost(start_year=2023, end_year=2035, expense_year=years,
cost=oil_tangible, cost_allocation=[fluid_oil]*n,
cost_type=[None]*n, pis_year=np.full(n, 2024),
useful_life=np.full(n, 5)),)
gas_cap = (CapitalCost(start_year=2023, end_year=2035, expense_year=years,
cost=gas_tangible, cost_allocation=[fluid_gas]*n,
cost_type=[None]*n, pis_year=np.full(n, 2024),
useful_life=np.full(n, 5)),)
oil_itg = (Intangible(start_year=2023, end_year=2035, expense_year=years,
cost=oil_intangible, cost_allocation=[fluid_oil]*n,
cost_type=[None]*n),)
gas_itg = (Intangible(start_year=2023, end_year=2035, expense_year=years,
cost=gas_intangible, cost_allocation=[fluid_gas]*n,
cost_type=[None]*n),)
oil_opx = (OPEX(start_year=2023, end_year=2035, expense_year=years,
fixed_cost=oil_opex, cost_allocation=[fluid_oil]*n,
cost_type=[None]*n),)
gas_opx = (OPEX(start_year=2023, end_year=2035, expense_year=years,
fixed_cost=gas_opex, cost_allocation=[fluid_gas]*n,
cost_type=[None]*n),)
oil_asr = (ASR(start_year=2023, end_year=2035, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid_oil]*n,
cost_type=[None]*n),)
gas_asr = (ASR(start_year=2023, end_year=2035, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid_gas]*n,
cost_type=[None]*n),)
oil_lbt = (LBT(start_year=2023, end_year=2035, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid_oil]*n,
cost_type=[None]*n),)
gas_lbt = (LBT(start_year=2023, end_year=2035, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid_gas]*n,
cost_type=[None]*n),)
oil_cos = (CostOfSales(start_year=2023, end_year=2035, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid_oil]*n,
cost_type=[None]*n),)
gas_cos = (CostOfSales(start_year=2023, end_year=2035, expense_year=years,
cost=np.zeros(n), cost_allocation=[fluid_gas]*n,
cost_type=[None]*n),)
# --- Gabungkan tuple per fluida ---
cr = CostRecovery(
start_date=date(2023, 1, 1), end_date=date(2035, 12, 31),
oil_onstream_date=date(2024, 1, 1),
gas_onstream_date=date(2024, 1, 1),
approval_year=2023, is_pod_1=True, is_strict=False,
lifting=oil_lft + gas_lft,
capital_cost=oil_cap + gas_cap,
intangible_cost=oil_itg + gas_itg,
opex=oil_opx + gas_opx,
asr_cost=oil_asr + gas_asr,
lbt_cost=oil_lbt + gas_lbt,
cost_of_sales=oil_cos + gas_cos,
oil_ftp_is_available=True, oil_ftp_is_shared=True,
oil_ftp_portion=0.2,
gas_ftp_is_available=True, gas_ftp_is_shared=True,
gas_ftp_portion=0.2,
tax_split_type=TaxSplitTypeCR.CONVENTIONAL,
condition_dict=dict, indicator_rc_icp_sliding=None,
oil_ctr_pretax_share=0.672269, gas_ctr_pretax_share=0.672269,
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,
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,
oil_carry_forward_depreciation=0.0,
gas_carry_forward_depreciation=0.0,
)
cr.run(
effective_tax_rate=0.405,
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,
)
s = cr.get_summary()
| Metrik | Nilai |
|---|---|
| Gross Revenue | 422,284.92 MUSD |
| Oil Revenue | 422,072.40 MUSD |
| Gas Revenue | 212.52 MUSD |
| Cost Recovery | 337,827.94 MUSD |
| Sunk Cost | 0.00 MUSD |
| CTR Net Share | 56,777.81 MUSD |
| CTR NPV | -69,792.16 MUSD |
| Gov FTP Share | 27,679.17 MUSD |
| Gov Take | 27,679.17 MUSD (6.55%) |
| Metrik | Oil Only | Oil + Gas |
|---|---|---|
| Gross Revenue | 101,224 MUSD | 422,285 MUSD |
| Cost Recovery | 86,173 MUSD | 337,828 MUSD |
| CTR Net Share | 5,932 MUSD | 56,778 MUSD |
| CTR NPV | -15,998 MUSD | -69,792 MUSD |
| Gov Take | 9,119 MUSD (9.01%) | 27,679 MUSD (6.55%) |
Kasus Oil + Gas memiliki revenue jauh lebih besar karena produksi gas menambah penerimaan, meskipun kontribusi gas kecil dibanding minyak.