Added detailed Sim object.
Added random trading. Added halving logic for dividends. Added modified illustrations of apy vs ubi charts.
This commit is contained in:
parent
9491d44759
commit
985165d834
226
econ-demo.py
226
econ-demo.py
@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
import tabulate
|
import tabulate
|
||||||
|
|
||||||
# it = 0
|
# it = 0
|
||||||
@ -226,6 +229,90 @@ def draw_apy_inflation(terms=50, linear_label="? (linear)"):
|
|||||||
plt.close()
|
plt.close()
|
||||||
# plt.show()
|
# plt.show()
|
||||||
|
|
||||||
|
def draw_apy_inflation2(terms=50, linear_label="? (linear)"):
|
||||||
|
participants = ["Alice", "Bob", "Charlie"]
|
||||||
|
balances = [100,40,20]
|
||||||
|
|
||||||
|
df = get_balances_over_time (
|
||||||
|
participants, balances, ubi(balances, terms=terms)
|
||||||
|
)
|
||||||
|
total_supply_ubi = calc_total_supply(df)
|
||||||
|
|
||||||
|
df_si = get_balances_over_time (
|
||||||
|
participants, balances,
|
||||||
|
compounding_interest(balances, terms=terms)
|
||||||
|
)
|
||||||
|
total_supply_si = calc_total_supply(df_si)
|
||||||
|
# + 1 because the initial frame is included this time
|
||||||
|
x = [i for i in range(1913,1913+terms+1)]
|
||||||
|
try:
|
||||||
|
assert(len(x) == len(total_supply_si))
|
||||||
|
except AssertionError:
|
||||||
|
print("Assert Error:")
|
||||||
|
print(len(x), len(total_supply_si))
|
||||||
|
print(df_si)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
plt.plot(
|
||||||
|
x, total_supply_ubi, color="cyan", label="dividend = 10"
|
||||||
|
)
|
||||||
|
plt.plot(
|
||||||
|
x, total_supply_si, color="red", label="apy = 0.05"
|
||||||
|
)
|
||||||
|
plt.axvline(x=1960, color='yellow', linestyle='--')
|
||||||
|
plt.title("Supply of Money Over Time")
|
||||||
|
plt.legend()
|
||||||
|
plt.xlabel("Year")
|
||||||
|
plt.ylabel("Total Currency")
|
||||||
|
plt.savefig("inflation-ubi-vs-5apy2.png")
|
||||||
|
plt.close()
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
def draw_apy_inflation3(terms=50, linear_label="? (linear)"):
|
||||||
|
participants = ["Alice", "Bob", "Charlie"]
|
||||||
|
balances = [100,40,20]
|
||||||
|
|
||||||
|
df = get_balances_over_time (
|
||||||
|
participants, balances, ubi(balances, terms=terms)
|
||||||
|
)
|
||||||
|
total_supply_ubi = calc_total_supply(df)
|
||||||
|
|
||||||
|
df_si = get_balances_over_time (
|
||||||
|
participants, balances,
|
||||||
|
compounding_interest(balances, terms=terms)
|
||||||
|
)
|
||||||
|
total_supply_si = calc_total_supply(df_si)
|
||||||
|
# + 1 because the initial frame is included this time
|
||||||
|
x = [i for i in range(1913,1913+terms+1)]
|
||||||
|
try:
|
||||||
|
assert(len(x) == len(total_supply_si))
|
||||||
|
except AssertionError:
|
||||||
|
print("Assert Error:")
|
||||||
|
print(len(x), len(total_supply_si))
|
||||||
|
print(df_si)
|
||||||
|
exit()
|
||||||
|
dy1 = np.gradient(total_supply_ubi, x)
|
||||||
|
dy2 = np.gradient(total_supply_si, x)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
plt.plot(
|
||||||
|
x, dy1, color="cyan", label="deriv. const.div"
|
||||||
|
)
|
||||||
|
plt.plot(
|
||||||
|
x, dy2, color="red", label="deriv. apy"
|
||||||
|
)
|
||||||
|
plt.axvline(x=1960, color='yellow', linestyle='--')
|
||||||
|
plt.axvline(x=1940, color='orange', linestyle='--')
|
||||||
|
plt.title("Change in Supply of Money")
|
||||||
|
plt.legend()
|
||||||
|
plt.xlabel("Year")
|
||||||
|
plt.ylabel("Rate of Inflation")
|
||||||
|
plt.savefig("inflation-ubi-vs-5apy3.png")
|
||||||
|
plt.close()
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
|
||||||
def draw_3ubi_3apy(terms=50):
|
def draw_3ubi_3apy(terms=50):
|
||||||
participants = ["Alice", "Bob", "Charlie"]
|
participants = ["Alice", "Bob", "Charlie"]
|
||||||
balances = [100,40,20]
|
balances = [100,40,20]
|
||||||
@ -361,59 +448,144 @@ def draw_simple_mining_demo():
|
|||||||
# print(m.iloc[:,:5].to_markdown())
|
# print(m.iloc[:,:5].to_markdown())
|
||||||
visualize_wealth_dist(m, filename="wealth-distribution-pow.png")
|
visualize_wealth_dist(m, filename="wealth-distribution-pow.png")
|
||||||
|
|
||||||
|
def trade(players, balances, spend_limit=0.10):
|
||||||
|
assert(len(players) == len(balances))
|
||||||
|
PRICE_FLOOR = 1
|
||||||
|
pl_idx = len(players) - 1
|
||||||
|
# randomly pick two players that will trade
|
||||||
|
buyer = 0
|
||||||
|
seller = 0
|
||||||
|
while buyer == seller:
|
||||||
|
# reroll until the two arent the same
|
||||||
|
buyer = random.choice([i for i in range(0, pl_idx)])
|
||||||
|
seller = random.choice([i for i in range(0, pl_idx)])
|
||||||
|
price = random.uniform(
|
||||||
|
PRICE_FLOOR, spend_limit * balances[buyer]
|
||||||
|
)
|
||||||
|
balances[buyer] -= price
|
||||||
|
balances[seller] += price
|
||||||
|
# print(balances[buyer], balances[seller])
|
||||||
|
return
|
||||||
|
|
||||||
class Sim:
|
class Sim:
|
||||||
def __init__(self, players, balances, terms=50):
|
def __init__(self, players, balances, terms=50, starting_amount=0):
|
||||||
self.players = players
|
self.players = players.copy()
|
||||||
self.balances = balances
|
self.balances = balances.copy()
|
||||||
self.terms = terms
|
self.terms = terms
|
||||||
|
|
||||||
|
self.ADD_NEW_PPL_EVERY = 10
|
||||||
|
self.NEW_PPL_START_WITH_BALANCE = starting_amount
|
||||||
|
self.IS_TRADING = True
|
||||||
|
|
||||||
|
self.IS_HALVING = False
|
||||||
|
self.HALVING_EVERY = 5
|
||||||
|
|
||||||
|
self.TITLE = str()
|
||||||
self.events = []
|
self.events = []
|
||||||
pass
|
|
||||||
|
|
||||||
def add_player(self, name="Danny", balance=50):
|
def add_player(self,
|
||||||
|
balances, name="Player %i", starting_amount=0):
|
||||||
|
name = name % (len(self.players) + 1)
|
||||||
self.players.append(name)
|
self.players.append(name)
|
||||||
self.balances.apend(balance)
|
balances.append(starting_amount)
|
||||||
assert(len(self.players) == len(self.balances))
|
try:
|
||||||
|
assert(len(self.players) == len(balances))
|
||||||
|
except AssertionError as e:
|
||||||
|
print(e)
|
||||||
|
print(len(self.players))
|
||||||
|
print(len(balances))
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
def run(self, update, trade = None):
|
def run(self, update):
|
||||||
i = 0
|
ADD_NEW_PPL_EVERY = self.ADD_NEW_PPL_EVERY
|
||||||
ADD_NEW_PPL_EVERY = 3
|
INIT_AMT = self.NEW_PPL_START_WITH_BALANCE
|
||||||
current_balances = self.balance
|
current_balances = self.balances
|
||||||
result = list()
|
result = list()
|
||||||
while i <= self.terms:
|
|
||||||
|
dividend = 10
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < self.terms:
|
||||||
# add new player?
|
# add new player?
|
||||||
if ADD_NEW_PPL_EVERY > 0 and i % ADD_NEW_PPL_EVERY == 0:
|
if i > 0 \
|
||||||
pass
|
and ADD_NEW_PPL_EVERY > 0 \
|
||||||
|
and i % ADD_NEW_PPL_EVERY == 0:
|
||||||
|
self.add_player(
|
||||||
|
current_balances, starting_amount=INIT_AMT)
|
||||||
new_bal = []
|
new_bal = []
|
||||||
# make players trade if an
|
# make players trade if an
|
||||||
if trade:
|
if self.IS_TRADING:
|
||||||
current_balances = trade(current_balances)
|
trade(self.players, current_balances)
|
||||||
for balance in current_balances:
|
for balance in current_balances:
|
||||||
b = update(balance)
|
if not self.IS_HALVING \
|
||||||
|
or update == mini_apy:
|
||||||
|
b = update(balance)
|
||||||
|
else:
|
||||||
|
b = mini_dividend(balance, dividend=dividend)
|
||||||
new_bal.append(b)
|
new_bal.append(b)
|
||||||
|
|
||||||
result.append(new_bal)
|
result.append(new_bal)
|
||||||
current_balances = new_bal
|
current_balances = new_bal
|
||||||
|
if i > 0 and i % self.HALVING_EVERY == 0:
|
||||||
|
dividend = dividend/2
|
||||||
|
i += 1
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def visualize(self):
|
def visualize(self, data, filename=str()):
|
||||||
pass
|
data.insert(0, self.balances)
|
||||||
|
data2 = [calc_share_of_wealth(row) for row in data]
|
||||||
|
df = pd.DataFrame(data2)
|
||||||
|
|
||||||
|
# +1 to offset 0 index
|
||||||
|
x = [i for i in range(1,df.shape[0] + 1)]
|
||||||
|
assert(len(x) == df.shape[0])
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# each column is the balance over time of an individual
|
||||||
|
for column in df.columns:
|
||||||
|
plt.plot(x, df[column], label=self.players[column] )
|
||||||
|
plt.xlabel("Terms")
|
||||||
|
plt.ylabel("Share of Wealth")
|
||||||
|
plt.title(self.TITLE)
|
||||||
|
# plt.legend()
|
||||||
|
if filename != str():
|
||||||
|
plt.savefig(filename)
|
||||||
|
else:
|
||||||
|
plt.show()
|
||||||
|
plt.close()
|
||||||
|
|
||||||
def mini_apy(balance, rate=0.05):
|
def mini_apy(balance, rate=0.05):
|
||||||
return balance + (balance * rate)
|
return balance + (balance * rate)
|
||||||
|
|
||||||
def mini_ubi(balance, dividend = 10):
|
def mini_dividend(balance, dividend = 10):
|
||||||
return balance + dividend
|
return balance + dividend
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
illustrate_share_of_wealth()
|
# illustrate_share_of_wealth()
|
||||||
visualize_ubi(terms=50)
|
# visualize_ubi(terms=50)
|
||||||
draw_apy_inflation(terms=75)
|
# draw_apy_inflation(terms=75)
|
||||||
draw_apy_inflation(terms=75, linear_label="dividend = 10")
|
# draw_apy_inflation2(terms=75, linear_label="dividend = 10")
|
||||||
draw_3ubi_3apy(terms=75)
|
# draw_apy_inflation3(terms=75, linear_label="dividend = 10")
|
||||||
|
# draw_3ubi_3apy(terms=75)
|
||||||
draw_simple_mining_demo()
|
#
|
||||||
|
# draw_simple_mining_demo()
|
||||||
|
|
||||||
participants = ["Alice", "Bob", "Charlie"]
|
participants = ["Alice", "Bob", "Charlie"]
|
||||||
balances = [100,40,20]
|
balances = [100,40,20]
|
||||||
s = Sim(participants, balances)
|
s = Sim(participants, balances)
|
||||||
|
result = s.run(update=mini_dividend)
|
||||||
|
s.TITLE = "Constant dividend with new players joining and trading"
|
||||||
|
# s.visualize(result, "const-new-players-trade.png")
|
||||||
|
|
||||||
|
t = Sim(participants, balances)
|
||||||
|
result2 = t.run(update=mini_apy)
|
||||||
|
t.TITLE = "APY with new people joining and trading"
|
||||||
|
# t.visualize(result2, "apy-new-playrs-trade.png")
|
||||||
|
|
||||||
|
u = Sim(participants, balances)
|
||||||
|
u.IS_HALVING = True
|
||||||
|
result3 = u.run(update=mini_dividend)
|
||||||
|
# print(pd.DataFrame(result3))
|
||||||
|
u.TITLE = "Halving dividend when new users mine and trade"
|
||||||
|
u.visualize(result3, filename="halving-dividend-new-users-trade.png")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user