Forecast Scheduling - Scenario Class¶
The scenario class is just a wrapper to group multiple periods in order to evaluate their production and optionally the economics.
It adds a feature of period dependency. You can set that one period could start its forecast once another ends.
A forecast can end mainly by three reasons.
By Date: When defining an
end_date
key argument the forecast will stop unless another condition makes it fishish earlier. In any case, the forecast won't go beyond that date.By Rate Limit: Set the rate limit of oil. If the oil rate reaches that rate limit it automatically will stop.
By Cumulative Limit: Set the Cumulative limit of oil. If the oil cum reaches that cumulative limit it automatically will stop.
import os
from dcapy import dca
from dcapy.schedule import Scenario, Period
from dcapy.cashflow import CashFlowParams
import numpy as np
import pandas as pd
from datetime import date
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import seaborn as sns
First. Define at least two periods, in this case using the dca.Wor
models. On each period is defined a cashflow parameter tageting the capex.
p1_dict = {
'name':'pdp',
'dca': {
'ti':'2021-01-01',
'bsw':0.3,
'slope':[2e-5,1e-5],
'fluid_rate':1000,
'gor':0.3
},
'start':'2021-01-01',
'end':'2022-01-01',
'freq_input':'M',
'freq_output':'M',
'cashflow_params':[
{
'name':'capex',
'value':{
'date':['2021-01-01'],
'value':[-5000000]
},
'target':'capex'
}
]
}
p1 = Period(**p1_dict)
p1
Period(name='pdp', cashflow_params=[CashFlowParams(name='capex', wi=1.0, periods=None, value=ChgPts(date=[datetime.date(2021, 1, 1)], value=[-5000000.0]), target=<TargetEnum.capex: 'capex'>, multiply=None, agg='mean', depends=False, iter=1, general=False, freq_value=None)], cashflow=None, forecast=None, seed=None, iter=1, ppf=None, description=None, id=None, dca=Wor(bsw=0.3, slope=[2e-05, 1e-05], fluid_rate=1000.0, ti=datetime.date(2021, 1, 1), seed=None, gor=0.3, glr=None), start=datetime.date(2021, 1, 1), end=datetime.date(2022, 1, 1), time_list=None, freq_input=<FreqEnum.M: 'M'>, freq_output=<FreqEnum.M: 'M'>, rate_limit=None, cum_limit=None, depends=None, type=<SchemasEnum.period: 'period'>)
p2_dict = {
'name':'pud',
'dca': {
'ti':'2022-01-01',
'bsw':0.3,
'slope':[2e-5],
'fluid_rate':1000,
'gor':0.3
},
'start':'2022-01-01',
'end':'2023-01-01',
'freq_input':'M',
'freq_output':'M',
'cashflow_params':[
{
'name':'capex',
'value':{
'date':['2022-01-01'],
'value':[-450000]},
'target':'capex'
}
]
}
p2 = Period(**p2_dict)
p2
Period(name='pud', cashflow_params=[CashFlowParams(name='capex', wi=1.0, periods=None, value=ChgPts(date=[datetime.date(2022, 1, 1)], value=[-450000.0]), target=<TargetEnum.capex: 'capex'>, multiply=None, agg='mean', depends=False, iter=1, general=False, freq_value=None)], cashflow=None, forecast=None, seed=None, iter=1, ppf=None, description=None, id=None, dca=Wor(bsw=0.3, slope=[2e-05], fluid_rate=1000.0, ti=datetime.date(2022, 1, 1), seed=None, gor=0.3, glr=None), start=datetime.date(2022, 1, 1), end=datetime.date(2023, 1, 1), time_list=None, freq_input=<FreqEnum.M: 'M'>, freq_output=<FreqEnum.M: 'M'>, rate_limit=None, cum_limit=None, depends=None, type=<SchemasEnum.period: 'period'>)
If casflow parameters are shared across the periods, you can declare a separate cashflow parameters instance and assign them to the scenario instance directly
cashflow_params = [
{
'name':'fix_opex',
'value':-5000,
'target':'opex',
},
{
'name':'var_opex',
'value':-5,
'target':'opex',
'multiply':'oil_volume',
},
{
'name':'income',
'value':60,
'target':'income',
'multiply':'oil_volume',
}]
s1 = Scenario(
name='base',
periods=[p1,p2],
cashflow_params=cashflow_params
)
Notice each period forecast will produce different amount of iterations. The first period will produce two and the second one.
s1_f = s1.generate_forecast(freq_output='M')
print(s1_f)
iteration oil_rate water_rate oil_cum gas_rate \ date 2021-01 0 655.596404 344.403596 20323.488531 196.678921 2021-01 1 677.822890 322.177110 21012.509598 203.346867 2021-02 0 570.189855 429.810145 36288.804475 171.056957 2021-02 1 634.191986 365.808014 38769.885213 190.257596 2021-03 0 492.473724 507.526276 51555.489924 147.742117 2021-03 1 591.337678 408.662322 57101.353244 177.401304 2021-04 0 423.296192 576.703808 64254.375683 126.988858 2021-04 1 548.741612 451.258388 73563.601594 164.622484 2021-05 0 365.930746 634.069254 75598.228821 109.779224 2021-05 1 508.583792 491.416208 89329.699161 152.575138 2021-06 0 318.932312 681.067688 85166.198172 95.679694 2021-06 1 471.241328 528.758672 103466.939006 141.372398 2021-07 0 280.603871 719.396129 93864.918158 84.181161 2021-07 1 436.919472 563.080528 117011.442627 131.075841 2021-08 0 248.692374 751.307626 101574.381744 74.607712 2021-08 1 405.104841 594.895159 129569.692696 121.531452 2021-09 0 222.779776 777.220224 108257.775023 66.833933 2021-09 1 376.705969 623.294031 140870.871765 113.011791 2021-10 0 201.191650 798.808350 114494.716172 60.357495 2021-10 1 351.020360 648.979640 151752.502920 105.306108 2021-11 0 182.997778 817.002222 119984.649499 54.899333 2021-11 1 327.798148 672.201852 161586.447357 98.339444 2021-12 0 167.547576 832.452424 125178.624349 50.264273 2021-12 1 306.832786 693.167214 171098.263710 92.049836 2022-01 0 160.262718 839.737282 125338.887067 48.078815 2022-01 1 296.570066 703.429934 171394.833776 88.971020 2022-01 0 655.596404 344.403596 20323.488531 196.678921 2022-02 0 570.189855 429.810145 36288.804475 171.056957 2022-03 0 492.473724 507.526276 51555.489924 147.742117 2022-04 0 423.296192 576.703808 64254.375683 126.988858 2022-05 0 365.930746 634.069254 75598.228821 109.779224 2022-06 0 318.932312 681.067688 85166.198172 95.679694 2022-07 0 280.603871 719.396129 93864.918158 84.181161 2022-08 0 248.692374 751.307626 101574.381744 74.607712 2022-09 0 222.779776 777.220224 108257.775023 66.833933 2022-10 0 201.191650 798.808350 114494.716172 60.357495 2022-11 0 182.997778 817.002222 119984.649499 54.899333 2022-12 0 167.547576 832.452424 125178.624349 50.264273 2023-01 0 160.262718 839.737282 125338.887067 48.078815 water_cum bsw wor wor_1 delta_time fluid_rate \ date 2021-01 10676.511469 0.344404 0.527821 1.527821 1.0 1000.0 2021-01 9987.490402 0.322177 0.475875 1.475875 1.0 1000.0 2021-02 22711.195525 0.429810 0.756560 1.756560 1.0 1000.0 2021-02 20230.114787 0.365808 0.577364 1.577364 1.0 1000.0 2021-03 38444.510076 0.507526 1.034639 2.034639 1.0 1000.0 2021-03 32898.646756 0.408662 0.691873 1.691873 1.0 1000.0 2021-04 55745.624317 0.576704 1.366647 2.366647 1.0 1000.0 2021-04 46436.398406 0.451258 0.823190 1.823190 1.0 1000.0 2021-05 75401.771179 0.634069 1.737483 2.737483 1.0 1000.0 2021-05 61670.300839 0.491416 0.967229 1.967229 1.0 1000.0 2021-06 95833.801828 0.681068 2.139911 3.139911 1.0 1000.0 2021-06 77533.060994 0.528759 1.123044 2.123044 1.0 1000.0 2021-07 118135.081842 0.719396 2.568406 3.568406 1.0 1000.0 2021-07 94988.557373 0.563081 1.289862 2.289862 1.0 1000.0 2021-08 141425.618256 0.751308 3.025539 4.025539 1.0 1000.0 2021-08 113430.307304 0.594895 1.469646 2.469646 1.0 1000.0 2021-09 164742.224977 0.777220 3.492783 4.492783 1.0 1000.0 2021-09 132129.128235 0.623294 1.655689 2.655689 1.0 1000.0 2021-10 189505.283828 0.798808 3.974506 4.974506 1.0 1000.0 2021-10 152247.497080 0.648980 1.850023 2.850023 1.0 1000.0 2021-11 214015.350501 0.817002 4.468218 5.468218 1.0 1000.0 2021-11 172413.552643 0.672202 2.051770 3.051770 1.0 1000.0 2021-12 239821.375651 0.832452 4.972179 5.972179 1.0 1000.0 2021-12 193901.736290 0.693167 2.260286 3.260286 1.0 1000.0 2022-01 240661.112933 0.839737 5.239754 6.239754 1.0 1000.0 2022-01 194605.166224 0.703430 2.371884 3.371884 1.0 1000.0 2022-01 10676.511469 0.344404 0.527821 1.527821 1.0 1000.0 2022-02 22711.195525 0.429810 0.756560 1.756560 1.0 1000.0 2022-03 38444.510076 0.507526 1.034639 2.034639 1.0 1000.0 2022-04 55745.624317 0.576704 1.366647 2.366647 1.0 1000.0 2022-05 75401.771179 0.634069 1.737483 2.737483 1.0 1000.0 2022-06 95833.801828 0.681068 2.139911 3.139911 1.0 1000.0 2022-07 118135.081842 0.719396 2.568406 3.568406 1.0 1000.0 2022-08 141425.618256 0.751308 3.025539 4.025539 1.0 1000.0 2022-09 164742.224977 0.777220 3.492783 4.492783 1.0 1000.0 2022-10 189505.283828 0.798808 3.974506 4.974506 1.0 1000.0 2022-11 214015.350501 0.817002 4.468218 5.468218 1.0 1000.0 2022-12 239821.375651 0.832452 4.972179 5.972179 1.0 1000.0 2023-01 240661.112933 0.839737 5.239754 6.239754 1.0 1000.0 fluid_cum gas_cum oil_volume water_volume gas_volume \ date 2021-01 31000.0 6097.046559 20276.242593 10723.757407 6097.046559 2021-01 31000.0 6303.752879 20988.830611 10011.169389 6303.752879 2021-02 59000.0 10886.641342 15926.259334 12073.740666 4789.594783 2021-02 59000.0 11630.965564 17736.778097 10263.221903 5327.212684 2021-03 90000.0 15466.646977 15228.601876 15771.398124 4580.005635 2021-03 90000.0 17130.405973 18309.326030 12690.673970 5499.440409 2021-04 120000.0 19276.312705 12667.931665 17332.068335 3809.665727 2021-04 120000.0 22069.080478 16441.874075 13558.125925 4938.674505 2021-05 151000.0 22679.468646 11317.565289 19682.434711 3403.155941 2021-05 151000.0 26798.909748 15746.405444 15253.594556 4729.829270 2021-06 181000.0 25549.859452 9547.208449 20452.791551 2870.390805 2021-06 181000.0 31040.081702 14119.635565 15880.364435 4241.171954 2021-07 212000.0 28159.475447 8681.176852 22318.823148 2609.615996 2021-07 212000.0 35103.432788 13527.851520 17472.148480 4063.351086 2021-08 243000.0 30472.314523 7695.071433 23304.928567 2312.839076 2021-08 243000.0 38870.907809 12543.126062 18456.873938 3767.475020 2021-09 273000.0 32477.332507 6671.830902 23328.169098 2005.017984 2021-09 273000.0 42261.261530 11287.918873 18712.081127 3390.353721 2021-10 304000.0 34348.414852 6226.925472 24773.074528 1871.082345 2021-10 304000.0 45525.750876 10869.243605 20130.756395 3264.489347 2021-11 334000.0 35995.394850 5481.731833 24518.268167 1646.979998 2021-11 334000.0 48475.934207 9823.116077 20176.883923 2950.183331 2021-12 365000.0 37553.587305 5186.735906 25813.264094 1558.192455 2021-12 365000.0 51329.479113 9501.706757 21498.293243 2853.544906 2022-01 366000.0 37601.666120 160.262718 839.737282 48.078815 2022-01 366000.0 51418.450133 296.570066 703.429934 88.971020 2022-01 31000.0 6097.046559 20276.242593 10723.757407 6097.046559 2022-02 59000.0 10886.641342 15926.259334 12073.740666 4789.594783 2022-03 90000.0 15466.646977 15228.601876 15771.398124 4580.005635 2022-04 120000.0 19276.312705 12667.931665 17332.068335 3809.665727 2022-05 151000.0 22679.468646 11317.565289 19682.434711 3403.155941 2022-06 181000.0 25549.859452 9547.208449 20452.791551 2870.390805 2022-07 212000.0 28159.475447 8681.176852 22318.823148 2609.615996 2022-08 243000.0 30472.314523 7695.071433 23304.928567 2312.839076 2022-09 273000.0 32477.332507 6671.830902 23328.169098 2005.017984 2022-10 304000.0 34348.414852 6226.925472 24773.074528 1871.082345 2022-11 334000.0 35995.394850 5481.731833 24518.268167 1646.979998 2022-12 365000.0 37553.587305 5186.735906 25813.264094 1558.192455 2023-01 366000.0 37601.666120 160.262718 839.737282 48.078815 period scenario date 2021-01 pdp base 2021-01 pdp base 2021-02 pdp base 2021-02 pdp base 2021-03 pdp base 2021-03 pdp base 2021-04 pdp base 2021-04 pdp base 2021-05 pdp base 2021-05 pdp base 2021-06 pdp base 2021-06 pdp base 2021-07 pdp base 2021-07 pdp base 2021-08 pdp base 2021-08 pdp base 2021-09 pdp base 2021-09 pdp base 2021-10 pdp base 2021-10 pdp base 2021-11 pdp base 2021-11 pdp base 2021-12 pdp base 2021-12 pdp base 2022-01 pdp base 2022-01 pdp base 2022-01 pud base 2022-02 pud base 2022-03 pud base 2022-04 pud base 2022-05 pud base 2022-06 pud base 2022-07 pud base 2022-08 pud base 2022-09 pud base 2022-10 pud base 2022-11 pud base 2022-12 pud base 2023-01 pud base
sns.lineplot(data=s1_f, x=s1_f.index.to_timestamp(), y='oil_rate', hue='iteration', style='period')
<AxesSubplot:xlabel='date', ylabel='oil_rate'>
When generating the cashflow an internal operation of broadcasting the iterations to produce, in this case, two cashflow models:
- cashflow model 1: Period_1 Iteration_0 + Period_2 Iteration_0
- cashflow model 2: Period_1 Iteration_1 + Period_2 Iteration_0
s1_c = s1.generate_cashflow(freq_output='M')
s1_c[1].fcf()
income_base-pdp | income_base-pud | total_income | fix_opex_base-pdp | var_opex_base-pdp | fix_opex_base-pud | var_opex_base-pud | total_opex | capex_base-pdp | capex_base-pud | total_capex | fcf | cum_fcf | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2021-01 | 1.259330e+06 | 0.000000e+00 | 1.259330e+06 | -5000.0 | -104944.153053 | 0.0 | 0.000000 | -109944.153053 | -5000000.0 | 0.0 | -5000000.0 | -3.850614e+06 | -3.850614e+06 |
2021-02 | 1.064207e+06 | 0.000000e+00 | 1.064207e+06 | -5000.0 | -88683.890486 | 0.0 | 0.000000 | -93683.890486 | 0.0 | 0.0 | 0.0 | 9.705228e+05 | -2.880092e+06 |
2021-03 | 1.098560e+06 | 0.000000e+00 | 1.098560e+06 | -5000.0 | -91546.630149 | 0.0 | 0.000000 | -96546.630149 | 0.0 | 0.0 | 0.0 | 1.002013e+06 | -1.878079e+06 |
2021-04 | 9.865124e+05 | 0.000000e+00 | 9.865124e+05 | -5000.0 | -82209.370374 | 0.0 | 0.000000 | -87209.370374 | 0.0 | 0.0 | 0.0 | 8.993031e+05 | -9.787755e+05 |
2021-05 | 9.447843e+05 | 0.000000e+00 | 9.447843e+05 | -5000.0 | -78732.027218 | 0.0 | 0.000000 | -83732.027218 | 0.0 | 0.0 | 0.0 | 8.610523e+05 | -1.177232e+05 |
2021-06 | 8.471781e+05 | 0.000000e+00 | 8.471781e+05 | -5000.0 | -70598.177827 | 0.0 | 0.000000 | -75598.177827 | 0.0 | 0.0 | 0.0 | 7.715800e+05 | 6.538567e+05 |
2021-07 | 8.116711e+05 | 0.000000e+00 | 8.116711e+05 | -5000.0 | -67639.257599 | 0.0 | 0.000000 | -72639.257599 | 0.0 | 0.0 | 0.0 | 7.390318e+05 | 1.392889e+06 |
2021-08 | 7.525876e+05 | 0.000000e+00 | 7.525876e+05 | -5000.0 | -62715.630308 | 0.0 | 0.000000 | -67715.630308 | 0.0 | 0.0 | 0.0 | 6.848719e+05 | 2.077761e+06 |
2021-09 | 6.772751e+05 | 0.000000e+00 | 6.772751e+05 | -5000.0 | -56439.594367 | 0.0 | 0.000000 | -61439.594367 | 0.0 | 0.0 | 0.0 | 6.158355e+05 | 2.693596e+06 |
2021-10 | 6.521546e+05 | 0.000000e+00 | 6.521546e+05 | -5000.0 | -54346.218023 | 0.0 | 0.000000 | -59346.218023 | 0.0 | 0.0 | 0.0 | 5.928084e+05 | 3.286404e+06 |
2021-11 | 5.893870e+05 | 0.000000e+00 | 5.893870e+05 | -5000.0 | -49115.580387 | 0.0 | 0.000000 | -54115.580387 | 0.0 | 0.0 | 0.0 | 5.352714e+05 | 3.821676e+06 |
2021-12 | 5.701024e+05 | 0.000000e+00 | 5.701024e+05 | -5000.0 | -47508.533786 | 0.0 | 0.000000 | -52508.533786 | 0.0 | 0.0 | 0.0 | 5.175939e+05 | 4.339270e+06 |
2022-01 | 1.779420e+04 | 1.216575e+06 | 1.234369e+06 | -5000.0 | -1482.850328 | -5000.0 | -101381.212966 | -112864.063293 | 0.0 | -450000.0 | -450000.0 | 6.715047e+05 | 5.010774e+06 |
2022-02 | 0.000000e+00 | 9.555756e+05 | 9.555756e+05 | 0.0 | 0.000000 | -5000.0 | -79631.296668 | -84631.296668 | 0.0 | 0.0 | 0.0 | 8.709443e+05 | 5.881719e+06 |
2022-03 | 0.000000e+00 | 9.137161e+05 | 9.137161e+05 | 0.0 | 0.000000 | -5000.0 | -76143.009380 | -81143.009380 | 0.0 | 0.0 | 0.0 | 8.325731e+05 | 6.714292e+06 |
2022-04 | 0.000000e+00 | 7.600759e+05 | 7.600759e+05 | 0.0 | 0.000000 | -5000.0 | -63339.658324 | -68339.658324 | 0.0 | 0.0 | 0.0 | 6.917362e+05 | 7.406028e+06 |
2022-05 | 0.000000e+00 | 6.790539e+05 | 6.790539e+05 | 0.0 | 0.000000 | -5000.0 | -56587.826445 | -61587.826445 | 0.0 | 0.0 | 0.0 | 6.174661e+05 | 8.023494e+06 |
2022-06 | 0.000000e+00 | 5.728325e+05 | 5.728325e+05 | 0.0 | 0.000000 | -5000.0 | -47736.042245 | -52736.042245 | 0.0 | 0.0 | 0.0 | 5.200965e+05 | 8.543591e+06 |
2022-07 | 0.000000e+00 | 5.208706e+05 | 5.208706e+05 | 0.0 | 0.000000 | -5000.0 | -43405.884259 | -48405.884259 | 0.0 | 0.0 | 0.0 | 4.724647e+05 | 9.016055e+06 |
2022-08 | 0.000000e+00 | 4.617043e+05 | 4.617043e+05 | 0.0 | 0.000000 | -5000.0 | -38475.357166 | -43475.357166 | 0.0 | 0.0 | 0.0 | 4.182289e+05 | 9.434284e+06 |
2022-09 | 0.000000e+00 | 4.003099e+05 | 4.003099e+05 | 0.0 | 0.000000 | -5000.0 | -33359.154512 | -38359.154512 | 0.0 | 0.0 | 0.0 | 3.619507e+05 | 9.796235e+06 |
2022-10 | 0.000000e+00 | 3.736155e+05 | 3.736155e+05 | 0.0 | 0.000000 | -5000.0 | -31134.627360 | -36134.627360 | 0.0 | 0.0 | 0.0 | 3.374809e+05 | 1.013372e+07 |
2022-11 | 0.000000e+00 | 3.289039e+05 | 3.289039e+05 | 0.0 | 0.000000 | -5000.0 | -27408.659166 | -32408.659166 | 0.0 | 0.0 | 0.0 | 2.964953e+05 | 1.043021e+07 |
2022-12 | 0.000000e+00 | 3.112042e+05 | 3.112042e+05 | 0.0 | 0.000000 | -5000.0 | -25933.679532 | -30933.679532 | 0.0 | 0.0 | 0.0 | 2.802705e+05 | 1.071048e+07 |
2023-01 | 0.000000e+00 | 9.615763e+03 | 9.615763e+03 | 0.0 | 0.000000 | -5000.0 | -801.313590 | -5801.313590 | 0.0 | 0.0 | 0.0 | 3.814449e+03 | 1.071430e+07 |
n_cashflows = len(s1_c)
fig, ax= plt.subplots(n_cashflows,1,figsize=(15,7))
for i in range(n_cashflows):
s1_c[i].plot(cum=True, ax=ax[i])
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
Period Dependency¶
As mentioned above, the period Dependency is set by declaring the depends
keyword on the period instance whose start date depends on other period.
The next example shows the definitions of two periods which one of them a probabilistic variable has been set.
p3_dict = {
'name':'pdp',
'dca': {
'ti':'2021-01-01',
'di':0.025,
'freq_di':'M',
'qi':{'dist':'norm', 'kw':{'loc':1500,'scale':200}}, #[800,1000],
'b':0,
},
'start':'2021-01-01',
'end':'2027-01-01',
'freq_output':'A',
'rate_limit': 300,
'cashflow_params':[
{
'name':'capex',
'value':{
'date':['2021-01-01'],
'value':[-5000000]
},
'target':'capex'
}
]
}
p4_dict = {
'name':'pud',
'dca': {
'ti':'2022-01-01',
'di':0.3,
'freq_di':'A',
'qi':3000,
'b':0,
},
'start':'2022-01-01',
'end':'2027-01-01',
'freq_output':'A',
'depends':{'period':'pdp'},
'cashflow_params':[
{
'name':'wo',
'value':-500000,
'period':1,
'target':'capex'
},
{
'name':'abandon',
'value':-300000,
'period':-1,
'target':'capex'
},
]
}
To create a scenario you can also pass a dictionary well structuted instead of create all classes separately, like Periods.
By declaring the iter
key with an integer the forecast will iterate this number. Notice that, the Period 4 has neither probabilistic variables nor multiple variables however as it depends on the end date of the first. Consequently the function creates the number of iterations required to reach 10 fully iterations that covers both periods.
s2_dict = {
'name':'Dependency',
'periods':[
p3_dict,
p4_dict
],
'cashflow_params': cashflow_params,
'iter':10
}
s2_dict
{'name': 'Dependency', 'periods': [{'name': 'pdp', 'dca': {'ti': '2021-01-01', 'di': 0.025, 'freq_di': 'M', 'qi': {'dist': 'norm', 'kw': {'loc': 1500, 'scale': 200}}, 'b': 0}, 'start': '2021-01-01', 'end': '2027-01-01', 'freq_output': 'A', 'rate_limit': 300, 'cashflow_params': [{'name': 'capex', 'value': {'date': ['2021-01-01'], 'value': [-5000000]}, 'target': 'capex'}]}, {'name': 'pud', 'dca': {'ti': '2022-01-01', 'di': 0.3, 'freq_di': 'A', 'qi': 3000, 'b': 0}, 'start': '2022-01-01', 'end': '2027-01-01', 'freq_output': 'A', 'depends': {'period': 'pdp'}, 'cashflow_params': [{'name': 'wo', 'value': -500000, 'period': 1, 'target': 'capex'}, {'name': 'abandon', 'value': -300000, 'period': -1, 'target': 'capex'}]}], 'cashflow_params': [{'name': 'fix_opex', 'value': -5000, 'target': 'opex'}, {'name': 'var_opex', 'value': -5, 'target': 'opex', 'multiply': 'oil_volume'}, {'name': 'income', 'value': 60, 'target': 'income', 'multiply': 'oil_volume'}], 'iter': 10}
s2 = Scenario(**s2_dict)
print(type(s2))
<class 'dcapy.schedule.schedule.Scenario'>
Generate Forecast
s2_f = s2.generate_forecast(iter=10, seed=21)
print(s2_f)
oil_rate oil_cum iteration oil_volume period scenario date 2021 1489.607150 0.000000e+00 0 468800.999434 pdp Dependency 2022 1098.939651 4.688010e+05 0 407326.632111 pdp Dependency 2023 810.729430 8.146533e+05 0 300500.294141 pdp Dependency 2024 598.105827 1.069802e+06 0 221910.986683 pdp Dependency 2025 440.877785 1.258475e+06 0 163712.145277 pdp Dependency ... ... ... ... ... ... ... 2027 2222.454662 9.460135e+05 7 946013.494512 pud Dependency 2026 3000.000000 0.000000e+00 8 473006.747256 pud Dependency 2027 2222.454662 9.460135e+05 8 946013.494512 pud Dependency 2026 3000.000000 0.000000e+00 9 473006.747256 pud Dependency 2027 2222.454662 9.460135e+05 9 946013.494512 pud Dependency [80 rows x 6 columns]
/home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:245: RuntimeWarning: invalid value encountered in true_divide (np.power(qi / rate, b) - 1)/(b * di) /home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:68: RuntimeWarning: divide by zero encountered in true_divide return qi/np.power(1+b*di*time_array,1/b) /home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:85: RuntimeWarning: divide by zero encountered in true_divide g = np.power(b*di*time_array+1,(b-1)/b) /home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:86: RuntimeWarning: divide by zero encountered in true_divide h = np.power(b*di*ti+1,(b-1)/b) /home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:68: RuntimeWarning: divide by zero encountered in true_divide return qi/np.power(1+b*di*time_array,1/b) /home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:85: RuntimeWarning: divide by zero encountered in true_divide g = np.power(b*di*time_array+1,(b-1)/b) /home/scuervo/Documents/dev/apps/dcapy/dcapy/dca/arps.py:86: RuntimeWarning: divide by zero encountered in true_divide h = np.power(b*di*ti+1,(b-1)/b)
sns.lineplot(data=s2_f, x=s2_f.index.to_timestamp(), y='oil_rate', hue='iteration',style='period')
<AxesSubplot:xlabel='date', ylabel='oil_rate'>
s2_c = s2.generate_cashflow(freq_output='A')
print(f'Number of cashflow models {len(s2_c)}')
Number of cashflow models 10
s2_c[0].fcf()
income_Dependency-pdp | income_Dependency-pud | total_income | fix_opex_Dependency-pdp | var_opex_Dependency-pdp | fix_opex_Dependency-pud | var_opex_Dependency-pud | total_opex | capex_Dependency-pdp | wo_Dependency-pud | abandon_Dependency-pud | total_capex | fcf | cum_fcf | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2021 | 2.812806e+07 | 0.000000e+00 | 2.812806e+07 | -5000.0 | -2.344005e+06 | 0.0 | 0.000000e+00 | -2.349005e+06 | -5000000.0 | 0.0 | 0.0 | -5000000.0 | 2.077905e+07 | 2.077905e+07 |
2022 | 2.443960e+07 | 0.000000e+00 | 2.443960e+07 | -5000.0 | -2.036633e+06 | 0.0 | 0.000000e+00 | -2.041633e+06 | 0.0 | 0.0 | 0.0 | 0.0 | 2.239796e+07 | 4.317702e+07 |
2023 | 1.803002e+07 | 0.000000e+00 | 1.803002e+07 | -5000.0 | -1.502501e+06 | 0.0 | 0.000000e+00 | -1.507501e+06 | 0.0 | 0.0 | 0.0 | 0.0 | 1.652252e+07 | 5.969954e+07 |
2024 | 1.331466e+07 | 0.000000e+00 | 1.331466e+07 | -5000.0 | -1.109555e+06 | 0.0 | 0.000000e+00 | -1.114555e+06 | 0.0 | 0.0 | 0.0 | 0.0 | 1.220010e+07 | 7.189964e+07 |
2025 | 9.822729e+06 | 0.000000e+00 | 9.822729e+06 | -5000.0 | -8.185607e+05 | 0.0 | 0.000000e+00 | -8.235607e+05 | 0.0 | 0.0 | 0.0 | 0.0 | 8.999168e+06 | 8.089881e+07 |
2026 | -3.775426e+07 | 2.838040e+07 | -9.373852e+06 | -5000.0 | 3.146188e+06 | -5000.0 | -2.365034e+06 | 7.711544e+05 | 0.0 | -500000.0 | -300000.0 | -800000.0 | -9.402698e+06 | 7.149611e+07 |
2027 | 0.000000e+00 | 5.676081e+07 | 5.676081e+07 | 0.0 | 0.000000e+00 | -5000.0 | -4.730067e+06 | -4.735067e+06 | 0.0 | -500000.0 | -300000.0 | -800000.0 | 5.122574e+07 | 1.227219e+08 |
s2.npv([0.15], freq_rate='A',freq_cashflow='A').reset_index().to_dict()
{'index': {0: 0.1499999999999999, 1: 0.1499999999999999, 2: 0.1499999999999999, 3: 0.1499999999999999, 4: 0.1499999999999999, 5: 0.1499999999999999, 6: 0.1499999999999999, 7: 0.1499999999999999, 8: 0.1499999999999999, 9: 0.1499999999999999}, 'npv': {0: 83387511.45599285, 1: 82960222.54647115, 2: 91277731.89554133, 3: 88872673.70059997, 4: 89139483.06955868, 5: 85885826.29488969, 6: 82277300.0707481, 7: 82070212.93389057, 8: 91900627.35896699, 9: 83671291.75916964}, 'iteration': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}}
n_cashflows = len(s2_c)
def cell_ijk(cell_id,nx,ny):
cell_id +=1
k=np.ceil(cell_id/(nx*ny)).astype(int)
j=np.ceil((cell_id-(nx*ny)*(k-1))/nx).astype(int)
i=np.ceil(cell_id-(nx*ny*(k-1))-nx*(j-1)).astype(int)
return i-1,j-1,k-1
fig, ax= plt.subplots(5,2,figsize=(20,15))
for idx in range(n_cashflows):
c = cell_ijk(idx+1,5,2)
print(idx,c)
s2_c[idx].plot(cum=True, format='m',ax=ax[c[0]-1,c[1]])
0 (1, 0, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
1 (2, 0, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
2 (3, 0, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
3 (4, 0, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
4 (0, 1, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
5 (1, 1, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
6 (2, 1, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
7 (3, 1, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
8 (4, 1, 0)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
9 (0, 0, 1)
/home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:351: UserWarning: FixedFormatter should only be used together with FixedLocator grax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks]) /home/scuervo/Documents/dev/apps/dcapy/dcapy/cashflow/cashflow.py:359: UserWarning: FixedFormatter should only be used together with FixedLocator spax.set_yticklabels([fmt.format(i/format_dict[format]['factor']) for i in ticks_cum])
from dcapy.auth import Credential
cred = Credential(token='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImIyZDQ5NjMyLWM0MzEtNDAzYi04OTEyLTJiZGIyOTA3NTMxNCIsIm5hbWUiOiJTYW50aWFnbyIsImxhc3RfbmFtZSI6IkN1ZXJ2byIsInVzZXJuYW1lIjoic2N1ZXJ2bzkxIiwiZXhwIjoxNjI2OTI2NTk3fQ.n3HuheJvoQKF9RNKTC9gEstC449EWd2qsrWR7f30V2U')
s2.insert_db(cred, 'Scenario-Cash tutorial')
'01de434e-d393-4f3e-8ecf-98e86b4dd39c'
sd = Scenario()
sd.get_db('01de434e-d393-4f3e-8ecf-98e86b4dd39c',cred)
type(sd)
dcapy.schedule.schedule.Scenario