In [1]:
###############################
# Alunos
# André Ferreira Bem Silva
# Fernando D'Império
# Marcos Vinício Siqueira
###############################
# Neste arquivo estão contidos os três
# exercícios da mina de ouro
###############################
import math
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import random
import seaborn as sns
import scipy as sp
from scipy.stats import norm

In [2]:
class GoldMineExerciseBase(object):
    
    def __init__(self):
        #Problem constants
        self._gold_price = 400
        self._gold_cost = 300
        self._gold_volatility = 0.3
        self._half_square_gold_volatility = 0.5 * self._gold_volatility**2
        self._gold_extraction_quantity = 10_000
        self._risk_free_interest_rate = 0.1
        self._number_of_years = 10
    
    def _calc_results_for_year(self, gold_price_last_year, years_delta):
        return gold_price_last_year * math.exp((self._risk_free_interest_rate - self._half_square_gold_volatility) * years_delta + self._gold_volatility * math.sqrt(years_delta) * norm.ppf(np.random.uniform()))

    def run_mine_year_simulation(self):
        gold_prices = [self._gold_price for i in range(0, self._number_of_years)]
        for i in range(1, self._number_of_years):
            gold_prices[i] = self._calc_results_for_year(gold_price_last_year = gold_prices[i - 1], years_delta = 1)
            
        return gold_prices
    
    def _calculate_gold_quantity(self, gold_price):
        return 0 if gold_price < self._gold_cost else self._gold_extraction_quantity

    def calc_year_risk_from_index(self, i):
        return math.exp(-(i % self._number_of_years) * self._risk_free_interest_rate)
    
    def add_profit_and_npv_to_df(self, simulations_df):
        simulations_df['profit'] = (simulations_df['gold_price'] - simulations_df['gold_cost']) * simulations_df['gold_quantity']
        #simulations_df['npv'] = simulations_df.year.map(lambda i: simulations_df.iloc[i]['profit'] * self.calc_year_risk_from_index(i))
        simulations_df['npv'] = simulations_df['profit'] * simulations_df['year'].map(lambda year: self.calc_year_risk_from_index(year))
    
class GoldMineExercise1(GoldMineExerciseBase):
    def __init__(self):
        GoldMineExerciseBase.__init__(self)
        
    def _create_simulation(self, simulation_index):
        gold_prices = self.run_mine_year_simulation()
        output_rows = []
        
        for i in range(0, self._number_of_years):
            gold_price = gold_prices[i]
            
            output_rows.append({
                    'gold_price': gold_price, 
                    'gold_cost': self._gold_cost, 
                    'gold_quantity': self._calculate_gold_quantity(gold_price), 
                    'simulation': simulation_index,
                    'year': i
                })
            
        return pd.DataFrame(output_rows)
            
    def create_simulations(self, number_of_simulations):
        simulation_df = pd.DataFrame(columns = ['gold_price', 'gold_cost', 'gold_quantity', 'simulation', 'year'])
        
        return pd.concat(
            [self._create_simulation(simulation_index) for simulation_index in range(0, number_of_simulations)],
            ignore_index = True
        )

In [3]:
# Creates object to solve exercise 1
first_exercise = GoldMineExercise1()
simulations_df = first_exercise.create_simulations(50_000)
#Creates new columns to solve the problems
first_exercise.add_profit_and_npv_to_df(simulations_df)
simulations_df


Out[3]:
gold_cost gold_price gold_quantity simulation year profit npv
0 300 400.000000 10000 0 0 1.000000e+06 1.000000e+06
1 300 348.580064 10000 0 1 4.858006e+05 4.395706e+05
2 300 455.791939 10000 0 2 1.557919e+06 1.275517e+06
3 300 317.898138 10000 0 3 1.789814e+05 1.325927e+05
4 300 265.336622 0 0 4 -0.000000e+00 -0.000000e+00
5 300 267.759499 0 0 5 -0.000000e+00 -0.000000e+00
6 300 341.205915 10000 0 6 4.120592e+05 2.261429e+05
7 300 302.950390 10000 0 7 2.950390e+04 1.465120e+04
8 300 627.823253 10000 0 8 3.278233e+06 1.473005e+06
9 300 649.038167 10000 0 9 3.490382e+06 1.419083e+06
10 300 400.000000 10000 1 0 1.000000e+06 1.000000e+06
11 300 631.672673 10000 1 1 3.316727e+06 3.001098e+06
12 300 917.606646 10000 1 2 6.176066e+06 5.056536e+06
13 300 1349.368355 10000 1 3 1.049368e+07 7.773912e+06
14 300 1038.056239 10000 1 4 7.380562e+06 4.947339e+06
15 300 723.717308 10000 1 5 4.237173e+06 2.569975e+06
16 300 653.123226 10000 1 6 3.531232e+06 1.937981e+06
17 300 1032.252628 10000 1 7 7.322526e+06 3.636259e+06
18 300 1036.106231 10000 1 8 7.361062e+06 3.307539e+06
19 300 920.108708 10000 1 9 6.201087e+06 2.521174e+06
20 300 400.000000 10000 2 0 1.000000e+06 1.000000e+06
21 300 317.868780 10000 2 1 1.786878e+05 1.616834e+05
22 300 359.257072 10000 2 2 5.925707e+05 4.851559e+05
23 300 307.015283 10000 2 3 7.015283e+04 5.197049e+04
24 300 293.006550 0 2 4 -0.000000e+00 -0.000000e+00
25 300 452.977162 10000 2 5 1.529772e+06 9.278534e+05
26 300 478.142689 10000 2 6 1.781427e+06 9.776678e+05
27 300 1052.951884 10000 2 7 7.529519e+06 3.739048e+06
28 300 1670.759725 10000 2 8 1.370760e+07 6.159220e+06
29 300 1836.137063 10000 2 9 1.536137e+07 6.245467e+06
... ... ... ... ... ... ... ...
499970 300 400.000000 10000 49997 0 1.000000e+06 1.000000e+06
499971 300 639.795338 10000 49997 1 3.397953e+06 3.074595e+06
499972 300 533.165318 10000 49997 2 2.331653e+06 1.908996e+06
499973 300 425.790128 10000 49997 3 1.257901e+06 9.318762e+05
499974 300 338.234460 10000 49997 4 3.823446e+05 2.562932e+05
499975 300 300.833942 10000 49997 5 8.339423e+03 5.058116e+03
499976 300 286.180472 0 49997 6 -0.000000e+00 -0.000000e+00
499977 300 387.784068 10000 49997 7 8.778407e+05 4.359228e+05
499978 300 610.982188 10000 49997 8 3.109822e+06 1.397333e+06
499979 300 765.175130 10000 49997 9 4.651751e+06 1.891261e+06
499980 300 400.000000 10000 49998 0 1.000000e+06 1.000000e+06
499981 300 222.032838 0 49998 1 -0.000000e+00 -0.000000e+00
499982 300 540.578799 10000 49998 2 2.405788e+06 1.969693e+06
499983 300 565.585204 10000 49998 3 2.655852e+06 1.967504e+06
499984 300 603.665477 10000 49998 4 3.036655e+06 2.035531e+06
499985 300 1154.255025 10000 49998 5 8.542550e+06 5.181319e+06
499986 300 1171.354993 10000 49998 6 8.713550e+06 4.782098e+06
499987 300 1505.986199 10000 49998 7 1.205986e+07 5.988750e+06
499988 300 2722.530462 10000 49998 8 2.422530e+07 1.088513e+07
499989 300 2380.654198 10000 49998 9 2.080654e+07 8.459309e+06
499990 300 400.000000 10000 49999 0 1.000000e+06 1.000000e+06
499991 300 526.911747 10000 49999 1 2.269117e+06 2.053182e+06
499992 300 560.767872 10000 49999 2 2.607679e+06 2.134987e+06
499993 300 808.385949 10000 49999 3 5.083859e+06 3.766216e+06
499994 300 984.324948 10000 49999 4 6.843249e+06 4.587167e+06
499995 300 1067.483704 10000 49999 5 7.674837e+06 4.655024e+06
499996 300 1242.478501 10000 49999 6 9.424785e+06 5.172432e+06
499997 300 1522.066338 10000 49999 7 1.222066e+07 6.068602e+06
499998 300 1573.938194 10000 49999 8 1.273938e+07 5.724173e+06
499999 300 2099.551408 10000 49999 9 1.799551e+07 7.316430e+06

500000 rows × 7 columns


In [4]:
simulations_npv = simulations_df.groupby(['simulation'])['npv'].agg(sum)
# Solution for Exercise 1
print('Mean value = ', round(np.mean(simulations_npv), 2), ' Median  value = ', round(np.median(simulations_npv), 2))


Mean value =  20822509.22  Median  value =  14343296.32

In [5]:
ax = sns.distplot(simulations_npv)
plt.xlabel('Net Present Value')
plt.ylabel('# Ocurrences')


Out[5]:
Text(0, 0.5, '# Ocurrences')

In [6]:
class GoldMineExercise2(GoldMineExerciseBase):
    def __init__(self):
        GoldMineExerciseBase.__init__(self)
        self._gold_expansion_cost = 320
        self._gold_enhanced_extraction = 15_000
        self._expansion_total_cost = 8_000_000
        
    def add_build_costs_if_building_expansion(self, expand_now, expanded):
        return self._expansion_total_cost if expand_now != expanded else 0
        
    def expand_this_year_flag(self, cut_expand, gold_price):
        return cut_expand > gold_price
    
    def calc_gold_cost_expanded_or_not(self, expanded):
        return self._gold_expansion_cost if expanded else self._gold_cost
    
    def calc_gold_quantity_expanded_or_not(self, expanded):
        return self._gold_extraction_quantity if expanded else self._gold_enhanced_extraction
        
    def _create_simulation(self, simulation_index):
        simulation_columns = [
            'simulation', 'year', 'gold_price', 'gold_cost', 'gold_quantity', 
            'expanded', 'build_costs', 'cut_expand'
        ]
        simulation_df = pd.DataFrame(columns = simulation_columns)
        
        output_rows = [{
            'year': 0, 
            'simulation': simulation_index,
            'gold_price': self._gold_price, 
            'gold_cost': self._gold_cost,
            'gold_quantity': self._gold_extraction_quantity,
            'expanded': False, 
            'cut_expand': 0, 
            'build_costs' : 0,
        }]
        gold_year_prices = self.run_mine_year_simulation()
        
        for i in range(1, self._number_of_years):
            previous_year = i - 1
            cut_expand = random.randint(256, 2080)
            expanded = self.expand_this_year_flag(gold_year_prices[i], cut_expand) or output_rows[previous_year]['expanded']
            build_costs = self.add_build_costs_if_building_expansion(expanded, output_rows[previous_year]['expanded'])
            
            output_rows.append({
                'gold_price': gold_year_prices[i],
                'gold_cost': self.calc_gold_cost_expanded_or_not(output_rows[previous_year]['expanded']),
                'cut_expand': cut_expand,
                'expanded': expanded,
                'build_costs': build_costs,
                'simulation': simulation_index,
                'gold_quantity': self.calc_gold_quantity_expanded_or_not(output_rows[previous_year]['expanded']), 
                'year': i
            })
        
        return pd.DataFrame(output_rows)
    
    def create_simulations(self, number_of_simulations):
        simulations = [self._create_simulation(i) for i in range(0, number_of_simulations)]

        return pd.concat(simulations, ignore_index = True)
    
    def add_profit_and_npv_to_df(self, simulations_df):
        GoldMineExerciseBase.add_profit_and_npv_to_df(self, simulations_df)
        
        simulations_df['f_profit'] = (simulations_df['gold_price'] - simulations_df['gold_cost']) * simulations_df['gold_quantity'] - simulations_df['build_costs']
        simulations_df['f_npv'] = simulations_df['f_profit'] * simulations_df['year'].map(lambda year: self.calc_year_risk_from_index(year))

In [7]:
second_exercise = GoldMineExercise2() 
simulations2_df = second_exercise.create_simulations(50_000)
second_exercise.add_profit_and_npv_to_df(simulations2_df)
simulations2_df


Out[7]:
build_costs cut_expand expanded gold_cost gold_price gold_quantity simulation year profit npv f_profit f_npv
0 0 0 False 300 400.000000 10000 0 0 1.000000e+06 1.000000e+06 1.000000e+06 1.000000e+06
1 0 620 False 300 547.214525 15000 0 1 3.708218e+06 3.355334e+06 3.708218e+06 3.355334e+06
2 8000000 349 True 300 598.418378 15000 0 2 4.476276e+06 3.664865e+06 -3.523724e+06 -2.884981e+06
3 0 999 True 320 789.635297 10000 0 3 4.696353e+06 3.479144e+06 4.696353e+06 3.479144e+06
4 0 2053 True 320 845.226060 10000 0 4 5.252261e+06 3.520696e+06 5.252261e+06 3.520696e+06
5 0 1305 True 320 858.521517 10000 0 5 5.385215e+06 3.266298e+06 5.385215e+06 3.266298e+06
6 0 1658 True 320 1121.093198 10000 0 6 8.010932e+06 4.396493e+06 8.010932e+06 4.396493e+06
7 0 1733 True 320 1352.513011 10000 0 7 1.032513e+07 5.127308e+06 1.032513e+07 5.127308e+06
8 0 1291 True 320 2027.787056 10000 0 8 1.707787e+07 7.673582e+06 1.707787e+07 7.673582e+06
9 0 874 True 320 1859.921734 10000 0 9 1.539922e+07 6.260855e+06 1.539922e+07 6.260855e+06
10 0 0 False 300 400.000000 10000 1 0 1.000000e+06 1.000000e+06 1.000000e+06 1.000000e+06
11 0 1924 False 300 242.828310 15000 1 1 -8.575753e+05 -7.759663e+05 -8.575753e+05 -7.759663e+05
12 0 424 False 300 166.838278 15000 1 2 -1.997426e+06 -1.635354e+06 -1.997426e+06 -1.635354e+06
13 0 1881 False 300 234.579604 15000 1 3 -9.813059e+05 -7.269693e+05 -9.813059e+05 -7.269693e+05
14 0 1492 False 300 209.225993 15000 1 4 -1.361610e+06 -9.127145e+05 -1.361610e+06 -9.127145e+05
15 0 1405 False 300 187.547449 15000 1 5 -1.686788e+06 -1.023089e+06 -1.686788e+06 -1.023089e+06
16 0 1351 False 300 116.179630 15000 1 6 -2.757306e+06 -1.513241e+06 -2.757306e+06 -1.513241e+06
17 0 1391 False 300 111.794408 15000 1 7 -2.823084e+06 -1.401902e+06 -2.823084e+06 -1.401902e+06
18 0 1001 False 300 149.121430 15000 1 8 -2.263179e+06 -1.016912e+06 -2.263179e+06 -1.016912e+06
19 0 265 False 300 153.757025 15000 1 9 -2.193645e+06 -8.918693e+05 -2.193645e+06 -8.918693e+05
20 0 0 False 300 400.000000 10000 2 0 1.000000e+06 1.000000e+06 1.000000e+06 1.000000e+06
21 0 1134 False 300 473.530005 15000 2 1 2.602950e+06 2.355247e+06 2.602950e+06 2.355247e+06
22 0 1790 False 300 410.687463 15000 2 2 1.660312e+06 1.359348e+06 1.660312e+06 1.359348e+06
23 0 938 False 300 468.635660 15000 2 3 2.529535e+06 1.873926e+06 2.529535e+06 1.873926e+06
24 0 2024 False 300 693.985419 15000 2 4 5.909781e+06 3.961445e+06 5.909781e+06 3.961445e+06
25 0 1826 False 300 594.587214 15000 2 5 4.418808e+06 2.680143e+06 4.418808e+06 2.680143e+06
26 0 1223 False 300 531.586339 15000 2 6 3.473795e+06 1.906459e+06 3.473795e+06 1.906459e+06
27 0 2051 False 300 566.228872 15000 2 7 3.993433e+06 1.983080e+06 3.993433e+06 1.983080e+06
28 0 1144 False 300 354.236735 15000 2 8 8.135510e+05 3.655520e+05 8.135510e+05 3.655520e+05
29 0 761 False 300 368.653743 15000 2 9 1.029806e+06 4.186879e+05 1.029806e+06 4.186879e+05
... ... ... ... ... ... ... ... ... ... ... ... ...
499970 0 0 False 300 400.000000 10000 49997 0 1.000000e+06 1.000000e+06 1.000000e+06 1.000000e+06
499971 0 1689 False 300 500.920956 15000 49997 1 3.013814e+06 2.727012e+06 3.013814e+06 2.727012e+06
499972 0 1935 False 300 579.107957 15000 49997 2 4.186619e+06 3.427714e+06 4.186619e+06 3.427714e+06
499973 0 1677 False 300 455.120186 15000 49997 3 2.326803e+06 1.723738e+06 2.326803e+06 1.723738e+06
499974 0 1381 False 300 379.413024 15000 49997 4 1.191195e+06 7.984821e+05 1.191195e+06 7.984821e+05
499975 0 1451 False 300 621.650175 15000 49997 5 4.824753e+06 2.926360e+06 4.824753e+06 2.926360e+06
499976 8000000 467 True 300 649.689950 15000 49997 6 5.245349e+06 2.878709e+06 -2.754651e+06 -1.511784e+06
499977 0 1614 True 320 622.081309 10000 49997 7 3.020813e+06 1.500091e+06 3.020813e+06 1.500091e+06
499978 0 723 True 320 722.062804 10000 49997 8 4.020628e+06 1.806585e+06 4.020628e+06 1.806585e+06
499979 0 586 True 320 790.453432 10000 49997 9 4.704534e+06 1.912721e+06 4.704534e+06 1.912721e+06
499980 0 0 False 300 400.000000 10000 49998 0 1.000000e+06 1.000000e+06 1.000000e+06 1.000000e+06
499981 0 1019 False 300 609.995914 15000 49998 1 4.649939e+06 4.207439e+06 4.649939e+06 4.207439e+06
499982 0 1379 False 300 588.918290 15000 49998 2 4.333774e+06 3.548194e+06 4.333774e+06 3.548194e+06
499983 0 1349 False 300 698.740834 15000 49998 3 5.981113e+06 4.430917e+06 5.981113e+06 4.430917e+06
499984 8000000 476 True 300 599.702063 15000 49998 4 4.495531e+06 3.013445e+06 -3.504469e+06 -2.349116e+06
499985 0 596 True 320 648.738177 10000 49998 5 3.287382e+06 1.993898e+06 3.287382e+06 1.993898e+06
499986 0 2016 True 320 390.776852 10000 49998 6 7.077685e+05 3.884316e+05 7.077685e+05 3.884316e+05
499987 0 279 True 320 509.465126 10000 49998 7 1.894651e+06 9.408560e+05 1.894651e+06 9.408560e+05
499988 0 1043 True 320 484.314700 10000 49998 8 1.643147e+06 7.383135e+05 1.643147e+06 7.383135e+05
499989 0 582 True 320 385.552478 10000 49998 9 6.555248e+05 2.665165e+05 6.555248e+05 2.665165e+05
499990 0 0 False 300 400.000000 10000 49999 0 1.000000e+06 1.000000e+06 1.000000e+06 1.000000e+06
499991 0 947 False 300 343.226978 15000 49999 1 6.484047e+05 5.867008e+05 6.484047e+05 5.867008e+05
499992 0 1907 False 300 391.107062 15000 49999 2 1.366606e+06 1.118882e+06 1.366606e+06 1.118882e+06
499993 0 592 False 300 465.008297 15000 49999 3 2.475124e+06 1.833617e+06 2.475124e+06 1.833617e+06
499994 0 1237 False 300 386.261180 15000 49999 4 1.293918e+06 8.673390e+05 1.293918e+06 8.673390e+05
499995 0 650 False 300 331.461259 15000 49999 5 4.719189e+05 2.862333e+05 4.719189e+05 2.862333e+05
499996 0 966 False 300 283.629965 15000 49999 6 -2.455505e+05 -1.347610e+05 -2.455505e+05 -1.347610e+05
499997 0 1571 False 300 171.420264 15000 49999 7 -1.928696e+06 -9.577621e+05 -1.928696e+06 -9.577621e+05
499998 0 1460 False 300 153.056788 15000 49999 8 -2.204148e+06 -9.903876e+05 -2.204148e+06 -9.903876e+05
499999 0 1986 False 300 176.373089 15000 49999 9 -1.854404e+06 -7.539443e+05 -1.854404e+06 -7.539443e+05

500000 rows × 12 columns


In [8]:
simulations2_npv = simulations2_df.groupby(['simulation'])['f_npv'].agg(sum)
# Solution for Exercise 2
print('Mean value = ', round(np.mean(simulations2_npv), 2), ' Median  value = ', round(np.median(simulations2_npv), 2))


Mean value =  19204613.77  Median  value =  13808634.41

In [9]:
ax = sns.distplot(simulations2_npv)
plt.xlabel('Net Present Value')
plt.ylabel('# Ocurrences')


Out[9]:
Text(0, 0.5, '# Ocurrences')

In [10]:
class GoldMineExercise3(GoldMineExerciseBase):
    def __init__(self):
        GoldMineExerciseBase.__init__(self)
        self._gold_cost = 250
        self._gold_extraction_fixed_costs = 1_000_000 
        self._mine_startup_cost = 2_000_000
        self._mine_shutdown_cost = 1_500_000
        self._number_of_years = 20
        
    def _create_simulation(self, simulation_index):
        simulation_columns = [
            'simulation', 'year', 'gold_price', 'gold_cost', 'gold_quantity',
            'opened_mine', 'open_cut', 'closed_mine', 'close_cut', 'mine_is_open'
        ]
        
        simulation_df = pd.DataFrame(columns = simulation_columns)
        gold_year_prices = self.run_mine_year_simulation()
        
        output_rows = []
        
        for i in range(0, self._number_of_years):
            mine_is_open = self._is_mine_open_flag(output_rows, i)
            gold_price = gold_year_prices[i]
            
            output_rows.append({
                'year': i, 
                'simulation': simulation_index,
                'gold_price': gold_price, 
                'gold_cost': self._gold_cost,
                'gold_quantity': self._gold_extraction_quantity if mine_is_open else 0,
                'mine_is_open': mine_is_open,
                'closed_mine': self._close_mine_flag(random.randint(0, 2000), gold_price, mine_is_open),
                'opened_mine': self._open_mine_flag(random.randint(0, 300), gold_price, mine_is_open)
            })
        
        return pd.DataFrame(output_rows)
    
    def _calc_status_based_costs(self, mine_is_open, close_flag, open_flag):
        return (0 if mine_is_open else self._gold_extraction_fixed_costs) + (self._mine_shutdown_cost if close_flag else 0) + (self._mine_startup_cost if open_flag else 0)
    
    def _previous_base_cash_flow_or_zero(self, output_rows, year):
        0 if year == 0 else output_rows[year]['base_cash_flow']
    
    def _is_mine_open_flag(self, output_rows, year):
        return True if year == 0 else (output_rows[year - 1]['mine_is_open'] and not output_rows[year - 1]['closed_mine']) or output_rows[year - 1]['opened_mine']
    
    def _open_mine_flag(self, cut_open, gold_price, is_open_flag):
        return not is_open_flag and gold_price > cut_open
    
    def _close_mine_flag(self, cut_close, gold_price, is_open_flag):
        return is_open_flag and gold_price <= cut_close
    
    def create_simulations(self, number_of_simulations):
        simulations = [self._create_simulation(i) for i in range(0, number_of_simulations)]

        return pd.concat(simulations, ignore_index = True)
    
    def add_profit_and_npv_to_df(self, simulations_df):
        cash_flow_multiplier = simulations_df['mine_is_open'].map(lambda mine_is_open: 1 if mine_is_open else 0)
        base_cash_flow = (simulations_df['gold_price'] - simulations_df['gold_cost']) * simulations_df['gold_quantity'] * cash_flow_multiplier
        fixed_costs = simulations_df.year.map(lambda i: self._calc_status_based_costs(simulations_df.iloc[i]['mine_is_open'], simulations_df.iloc[i]['closed_mine'], simulations_df.iloc[i]['opened_mine']))
        
        simulations_df['fixed_costs'] = fixed_costs
        simulations_df['profit'] = base_cash_flow - fixed_costs
        simulations_df['npv'] = simulations_df['profit'] * simulations_df['year'].map(lambda year: self.calc_year_risk_from_index(year))

In [11]:
third_exercise = GoldMineExercise3() 
simulations3_df = third_exercise.create_simulations(50_000)
#third_exercise.add_profit_and_npv_to_df(simulations3_df)
third_exercise.add_profit_and_npv_to_df(simulations3_df)
simulations3_df


Out[11]:
closed_mine gold_cost gold_price gold_quantity mine_is_open opened_mine simulation year fixed_costs profit npv
0 False 250 400.000000 10000 True False 0 0 0 1.500000e+06 1.500000e+06
1 False 250 380.423232 10000 True False 0 1 0 1.304232e+06 1.180118e+06
2 True 250 431.644438 10000 True False 0 2 1500000 3.164444e+05 2.590827e+05
3 False 250 586.233759 0 False True 0 3 3000000 -3.000000e+06 -2.222455e+06
4 True 250 507.074550 10000 True False 0 4 1500000 1.070746e+06 7.177422e+05
5 False 250 534.421384 0 False True 0 5 3000000 -3.000000e+06 -1.819592e+06
6 False 250 426.338402 10000 True False 0 6 0 1.763384e+06 9.677657e+05
7 True 250 553.188423 10000 True False 0 7 1500000 1.531884e+06 7.607112e+05
8 False 250 600.239559 0 False True 0 8 3000000 -3.000000e+06 -1.347987e+06
9 False 250 438.293925 10000 True False 0 9 0 1.882939e+06 7.655460e+05
10 True 250 316.139216 10000 True False 0 10 1500000 -8.386078e+05 -3.085066e+05
11 False 250 203.391745 0 False False 0 11 1000000 -1.000000e+06 -3.328711e+05
12 False 250 195.871617 0 False True 0 12 3000000 -3.000000e+06 -9.035826e+05
13 True 250 285.703019 10000 True False 0 13 1500000 -1.142970e+06 -3.114956e+05
14 False 250 236.942690 0 False True 0 14 3000000 -3.000000e+06 -7.397909e+05
15 True 250 242.952531 10000 True False 0 15 1500000 -1.570475e+06 -3.504203e+05
16 False 250 314.783765 0 False True 0 16 3000000 -3.000000e+06 -6.056896e+05
17 True 250 436.800916 10000 True False 0 17 1500000 3.680092e+05 6.722921e+04
18 False 250 475.833773 0 False True 0 18 3000000 -3.000000e+06 -4.958967e+05
19 True 250 488.206601 10000 True False 0 19 1500000 8.820660e+05 1.319294e+05
20 True 250 400.000000 10000 True False 1 0 0 1.500000e+06 1.500000e+06
21 False 250 324.419794 0 False True 1 1 0 0.000000e+00 0.000000e+00
22 True 250 308.459208 10000 True False 1 2 1500000 -9.154079e+05 -7.494726e+05
23 False 250 207.673647 0 False True 1 3 3000000 -3.000000e+06 -2.222455e+06
24 False 250 192.037852 10000 True False 1 4 1500000 -2.079621e+06 -1.394012e+06
25 True 250 258.608115 10000 True False 1 5 3000000 -2.913919e+06 -1.767381e+06
26 False 250 355.443550 0 False True 1 6 0 0.000000e+00 0.000000e+00
27 True 250 311.307173 10000 True False 1 7 1500000 -8.869283e+05 -4.404355e+05
28 False 250 302.834167 0 False True 1 8 3000000 -3.000000e+06 -1.347987e+06
29 True 250 272.619109 10000 True False 1 9 0 2.261911e+05 9.196243e+04
... ... ... ... ... ... ... ... ... ... ... ...
999970 True 250 842.935313 10000 True False 49998 10 1500000 4.429353e+06 1.629468e+06
999971 False 250 839.479770 0 False True 49998 11 1000000 -1.000000e+06 -3.328711e+05
999972 True 250 1077.559648 10000 True False 49998 12 3000000 5.275596e+06 1.588979e+06
999973 False 250 692.181195 0 False True 49998 13 1500000 -1.500000e+06 -4.087977e+05
999974 False 250 565.145815 10000 True False 49998 14 3000000 1.514581e+05 3.734912e+04
999975 False 250 760.252403 10000 True False 49998 15 1500000 3.602524e+06 8.038318e+05
999976 True 250 781.375737 10000 True False 49998 16 3000000 2.313757e+06 4.671396e+05
999977 False 250 454.514983 0 False True 49998 17 1500000 -1.500000e+06 -2.740253e+05
999978 True 250 584.913520 10000 True False 49998 18 3000000 3.491352e+05 5.771166e+04
999979 False 250 381.100060 0 False True 49998 19 1500000 -1.500000e+06 -2.243529e+05
999980 True 250 400.000000 10000 True False 49999 0 0 1.500000e+06 1.500000e+06
999981 False 250 250.249357 0 False True 49999 1 0 0.000000e+00 0.000000e+00
999982 True 250 275.032199 10000 True False 49999 2 1500000 -1.249678e+06 -1.023150e+06
999983 False 250 249.681289 0 False True 49999 3 3000000 -3.000000e+06 -2.222455e+06
999984 True 250 212.944108 10000 True False 49999 4 1500000 -1.870559e+06 -1.253873e+06
999985 False 250 261.197383 0 False True 49999 5 3000000 -3.000000e+06 -1.819592e+06
999986 True 250 306.229369 10000 True False 49999 6 0 5.622937e+05 3.085933e+05
999987 False 250 222.111125 0 False True 49999 7 1500000 -1.500000e+06 -7.448780e+05
999988 False 250 133.847554 10000 True False 49999 8 3000000 -4.161524e+06 -1.869893e+06
999989 True 250 126.166499 10000 True False 49999 9 0 -1.238335e+06 -5.034694e+05
999990 False 250 113.820405 0 False True 49999 10 1500000 -1.500000e+06 -5.518192e+05
999991 True 250 138.830338 10000 True False 49999 11 1000000 -2.111697e+06 -7.029227e+05
999992 False 250 151.766806 0 False True 49999 12 3000000 -3.000000e+06 -9.035826e+05
999993 True 250 184.330351 10000 True False 49999 13 1500000 -2.156696e+06 -5.877684e+05
999994 False 250 98.111983 0 False False 49999 14 3000000 -3.000000e+06 -7.397909e+05
999995 False 250 119.779607 0 False False 49999 15 1500000 -1.500000e+06 -3.346952e+05
999996 False 250 112.364476 0 False True 49999 16 3000000 -3.000000e+06 -6.056896e+05
999997 True 250 173.350580 10000 True False 49999 17 1500000 -2.266494e+06 -4.140511e+05
999998 False 250 144.061483 0 False True 49999 18 3000000 -3.000000e+06 -4.958967e+05
999999 True 250 273.065277 10000 True False 49999 19 1500000 -1.269347e+06 -1.898545e+05

1000000 rows × 11 columns


In [12]:
simulations3_npv = simulations3_df.groupby(['simulation'])['npv'].agg(sum)
# Solution for Exercise 3
print('Mean value = ', round(np.mean(simulations3_npv), 2), ' Median  value = ', round(np.median(simulations3_npv), 2))


Mean value =  34756783.63  Median  value =  10420984.31

In [13]:
ax = sns.distplot(simulations3_npv)
plt.xlabel('Net Present Value')
plt.ylabel('# Ocurrences')


Out[13]:
Text(0, 0.5, '# Ocurrences')