import numpy as np, pandas as pd, matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
The process starts in the way showed below.
The Average of the ensemble wealth at the beginning of the process is 100.
starting_process = pd.DataFrame({i:100 for i in np.arange(100)}, index = ['step 0'])
starting_process['Sample Average'] = starting_process.mean(axis=1)
starting_process
The ensemble_step function updates the wealth of the ensamble of a single step</b>
def ensemble_step(single_wealths, N):
f = lambda x: x * np.random.choice([0.6,1.5])
new_step = single_wealths.iloc[-1].to_frame().T.apply(f)
new_step.index = ['step %s'%N]
new_step['Sample Average'] = new_step.apply(np.mean, axis=1)
return pd.concat([single_wealths, new_step])
The ensemble_simulation simulates a single stocastic process of the ensemble wealth for N steps.
We start with a simulation of 8 steps. Below you can see how it looks. The last column is the sample average of each step.
def ensamble_simulation(starting, steps): # ensamble simulation where 'steps' is the number of steps we choose
stocastic_process = starting
for i in range(1,steps):
stocastic_process = ensemble_step(stocastic_process,str(i))
return stocastic_process
steps = 8
complete_process = ensamble_simulation(starting_process, steps)
complete_process #simulation of 8 steps
Below we plot the values of the Sample Average for each step
averages = complete_process['Sample Average']
y = averages.to_frame().set_index(np.arange(steps))
ax = y.plot(grid=True,figsize=(10,10), linestyle = '--', marker = 'o');
ax.set_xlabel('Steps for the whole ensamble', fontsize=12);
ax.axis([-0.2,7.4, min(y.values)-min(y.values)/50, max(y.values)+ max(y.values)/50]);
Below we calculate the average of the sample averages.
averages.mean()
Now we do the same thing, but we do 8 simulations, not only one.
So we have 8 stocastic wealth processes, each consisting of 8 steps
from itertools import product
list_averages = []
fig, axes = plt.subplots(2,4, figsize=(18,10))
t1 = (0,1)
t2 = (0,1,2,3)
generate_x_y = product(t1,t2)
for i in range(8):
complete_process = ensamble_simulation(starting_process, steps)
averages = complete_process['Sample Average']
list_averages.append(averages.mean())
g,k = next(generate_x_y)
y = averages.to_frame().set_index(np.arange(steps))
y.plot(grid=True, ax = axes[g,k], linestyle = '--', marker = 'o');
axes[g,k].set_xlabel('Steps for the whole ensamble', fontsize=12);
axes[g,k].axis([-0.2,7.4, min(y.values)-min(y.values)/50, max(y.values)+ max(y.values)/50 ])
Below you can see the averages of the sample averages for each stocastic wealth process.
averages_value = pd.Series(list_averages) # sample averages of 8 simulation with 8 time steps
averages_value
To understand how this column moves with time, we increase the number of steps of each simulation
Below we have 8 stocastic processes, and each process consists of 50 steps.
steps = 50
complete_process = ensamble_simulation(starting_process, steps)
list_averages = []
fig, axes = plt.subplots(2,4, figsize=(18,10))
t1 = (0,1)
t2 = (0,1,2,3)
generate_x_y = product(t1,t2)
for i in range(8):
complete_process = ensamble_simulation(starting_process, steps)
averages = complete_process['Sample Average']
list_averages.append(averages.mean())
g,k = next(generate_x_y)
y = averages.to_frame().set_index(np.arange(steps))
y.plot(grid=True, ax = axes[g,k], linestyle = '--');
axes[g,k].set_xlabel('Steps for the whole ensamble', fontsize=12);
axes[g,k].axis([-2,53, min(y.values)-min(y.values)/50, max(y.values)+ max(y.values)/50 ])
Let's see the column of the averages value. The expected value of the ensemble wealth has increased.
averages_value = pd.Series(list_averages) # sample averages of 8 simulations with 50 time steps
averages_value
Ok, now we carry on the steps of each simulation from 50 steps to 350 steps.
Below you can see the paths of 8 stocastic processes, each consisting of 350 steps.
What do you notice?
steps = 350
complete_process = ensamble_simulation(starting_process, steps)
list_averages = []
fig, axes = plt.subplots(2,4, figsize=(18,10))
t1 = (0,1)
t2 = (0,1,2,3)
generate_x_y = product(t1,t2)
for i in range(8):
complete_process = ensamble_simulation(starting_process, steps)
averages = complete_process['Sample Average']
list_averages.append(averages.mean())
g,k = next(generate_x_y)
y = averages.to_frame().set_index(np.arange(steps))
y.plot(grid=True, ax = axes[g,k], linestyle = '--');
axes[g,k].set_xlabel('Steps for the whole ensamble', fontsize=12);
axes[g,k].axis([-2,360, min(y.values)-min(y.values)/50, max(y.values)+ max(y.values)/50])
In the graphs showed above, i notice that all the stocastic process are doomed in the long term
So, as only every single wealth person is doomed in time, in the same way the ensemble wealth is doomed in time under the multiplicative dynamics of the hypothesis.
But what about the expectated value of the wealth?
Below you can see the averages for each stocastic process...
averages_value = pd.Series(list_averages) # sample averages of 8 simulations with 350 time steps
averages_value
averages_value.mean()
We start with an ensemble wealth average of 100.
After 350 steps, the ensemble wealth average is 21553.
The wealth is doomed over time (steps), but the ensemble average increases with time.
The ensemble average isn't a good benchmark for the variable over time under multiplicative dynamic.
Here the discussion on Twitter