experiments!

This commit is contained in:
Michael Zargham 2019-06-02 16:44:50 -07:00
parent ff4fd7f953
commit 3f712ab0d3
7 changed files with 956 additions and 384 deletions

View File

@ -49,10 +49,11 @@ def withdraw(deltaS, R,S, V0, kappa=default_kappa):
def withdraw_with_tax(deltaS, R,S, V0, exit_tax = default_exit_tax, kappa=default_kappa):
deltaR = R-((S-deltaS)**kappa)/V0
print(deltaR)
quantity_taxed = exit_tax*deltaR
quantity_recieved = (1-exit_tax)*deltaR
realized_price = quantity_recieved/deltaS
return quantity_recieved, quantity_taxed, realized_price

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
import networkx as nx
from scipy.stats import expon, gamma
import numpy as np
from bonding_curve_eq import reserve, invariant,spot_price
from bonding_curve_eq import invariant,spot_price
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cmx
@ -17,17 +17,27 @@ default_theta = .25
default_initial_price = .1
default_kappa = 2
def total_funds_given_total_supply(total_supply, theta = default_theta, initial_price = default_initial_price):
def conviction_order(network, proposals):
S = total_supply
total_funds = theta*reserve(S, S*initial_price)
ordered = sorted(proposals, key=lambda j:network.nodes[j]['conviction'] , reverse=True)
return ordered
def total_funds_given_total_supply(initial_supply, theta = default_theta, initial_price = default_initial_price):
total_raise = initial_price*initial_supply
total_funds = theta*total_raise
return total_funds
def initialize_bonding_curve(initial_supply, initial_price = default_initial_price, kappa =default_kappa, theta = default_theta):
S = initial_supply
R = reserve(S, S*initial_price)*(1-theta)
total_raise = initial_price*S
R = (1-theta)*total_raise
V0 = invariant(R,S,kappa)
@ -50,13 +60,13 @@ def trigger_threshold(requested, funds, supply, beta = default_beta, rho = defau
else:
return np.inf
def initialize_network(n,m, funds_func=total_funds_given_total_supply, trigger_func =trigger_threshold ):
def initialize_network(n,m, funds_func=total_funds_given_total_supply, trigger_func =trigger_threshold, expected_supply = 10**6 ):
network = nx.DiGraph()
for i in range(n):
network.add_node(i)
network.nodes[i]['type']="participant"
h_rv = expon.rvs(loc=0.0, scale=1000)
h_rv = expon.rvs(loc=0.0, scale= expected_supply/n)
network.nodes[i]['holdings'] = h_rv
s_rv = np.random.rand()
@ -162,8 +172,21 @@ def social_affinity_booster(network, proposal, participant):
j=proposal
i=participant
total_inf = np.sum([network.edges[(i,node)]['influence'] for node in participants if (i, node) in influencers ])
boosts=[network.edges[(node,j)]['affinity']*network.edges[(i,node)]['influence']/total_inf for node in participants if (i, node) in influencers ]
i_tokens = network.nodes[i]['holdings']
influence = np.array([network.edges[(i,node)]['influence'] for node in participants if (i, node) in influencers ])
#print(influence)
tokens = np.array([network.edges[(node,j)]['tokens'] for node in participants if (i, node) in influencers ])
#print(tokens)
influence_sum = np.sum(influence)
if influence_sum>0:
boosts = np.sum(tokens*influence)/(influence_sum*i_tokens)
else:
boosts = 0
return np.sum(boosts)
@ -295,7 +318,7 @@ def snap_plot(nets, size_scale = 1/500, ani = False, dims = (20,20), savefigs=Fa
net_cand = [j for j in net_props if net.nodes[j]['status']=='candidate']
for j in net_props:
node_size[j] = net.nodes[j]['funds_requested']*size_scale/4
node_size[j] = net.nodes[j]['funds_requested']*size_scale
if net.nodes[j]['status']=="candidate":
node_color[j] = colors.to_rgba('blue')
trigger = net.nodes[j]['trigger']
@ -316,7 +339,7 @@ def snap_plot(nets, size_scale = 1/500, ani = False, dims = (20,20), savefigs=Fa
net_node_label[j] = ''
for i in net_parts:
node_size[i] = net.nodes[i]['holdings']*size_scale
node_size[i] = net.nodes[i]['holdings']*size_scale/10
node_color[i] = colors.to_rgba('red')
net_node_label[i] = ''
@ -336,14 +359,14 @@ def snap_plot(nets, size_scale = 1/500, ani = False, dims = (20,20), savefigs=Fa
tokens = net.edges[e]['tokens']
included_edge_color[ind] = scalarMap.to_rgba(tokens)
nx.draw(net,
pos=pos,
node_size = node_size,
node_color = node_color,
edge_color = included_edge_color,
edgelist=included_edges,
labels = net_node_label)
plt.title('Tokens Staked by Partipants to Proposals')
# nx.draw(net,
# pos=pos,
# node_size = node_size,
# node_color = node_color,
# edge_color = included_edge_color,
# edgelist=included_edges,
# labels = net_node_label)
# plt.title('Tokens Staked by Partipants to Proposals')
if ani:
nx.draw(net,
@ -373,4 +396,24 @@ def snap_plot(nets, size_scale = 1/500, ani = False, dims = (20,20), savefigs=Fa
False
#anim = animation.ArtistAnimation(fig, , interval=50, blit=True, repeat_delay=1000)
#plt.show()
def pad(vec, length,fill=True):
if fill:
padded = np.zeros(length,)
else:
padded = np.empty(length,)
padded[:] = np.nan
for i in range(len(vec)):
padded[i]= vec[i]
return padded
def make2D(key, data, fill=False):
maxL = data[key].apply(len).max()
newkey = 'padded_'+key
data[newkey] = data[key].apply(lambda x: pad(x,maxL,fill))
reshaped = np.array([a for a in data[newkey].values])
return reshaped

View File

@ -1,6 +1,6 @@
import numpy as np
from conviction_helpers import get_nodes_by_type, get_edges_by_type, social_affinity_booster
from bonding_curve_eq import reserve, spot_price, withdraw_with_tax
from conviction_helpers import get_nodes_by_type, get_edges_by_type, social_affinity_booster, conviction_order
from bonding_curve_eq import reserve, spot_price
#import networkx as nx
from scipy.stats import expon, gamma
@ -76,12 +76,16 @@ def gen_new_proposal(network, funds, supply, trigger_func, scale_factor = 1.0/10
def driving_process(params, step, sL, s):
#placeholder plumbing for random processes
arrival_rate = 10/s['sentiment']
arrival_rate = 10/(1+s['sentiment'])
rv1 = np.random.rand()
new_participant = bool(rv1<1/arrival_rate)
supporters = get_edges_by_type(s['network'], 'support')
len_parts = len(get_nodes_by_type(s['network'], 'participant'))
supply = s['supply']
expected_holdings = .1*supply/len_parts
if new_participant:
h_rv = expon.rvs(loc=0.0, scale=1000)
h_rv = expon.rvs(loc=0.0, scale=expected_holdings)
new_participant_holdings = h_rv
else:
new_participant_holdings = 0
@ -96,7 +100,7 @@ def driving_process(params, step, sL, s):
funds = s['funds']
total_funds_requested = np.sum(fund_requests)
proposal_rate = 10/median_affinity * total_funds_requested/funds
proposal_rate = 1/median_affinity * (1+total_funds_requested/funds)
rv2 = np.random.rand()
new_proposal = bool(rv2<1/proposal_rate)
@ -104,6 +108,9 @@ def driving_process(params, step, sL, s):
funds = s['funds']
scale_factor = funds*sentiment**2/10000
if scale_factor <1:
scale_factor = 1
#this shouldn't happen but expon is throwing domain errors
if sentiment>.4:
funds_arrival = expon.rvs(loc = 0, scale = scale_factor )
@ -178,6 +185,24 @@ def increment_supply(params, step, sL, s, _input):
return (key, value)
def increment_reserve(params, step, sL, s, _input):
supply = s['supply']
supply_arrival = _input['new_participant_holdings']
#increment funds
supply = supply + supply_arrival
kappa = params['kappa']
V0 = params['invariant']
R = reserve(supply, V0, kappa)
key = 'reserve'
value = R
return (key, value)
#functions for partial state update block 2
#Driving processes: completion of previously funded proposals
@ -300,6 +325,7 @@ def trigger_function(params, step, sL, s):
accepted = []
triggers = {}
funds_to_be_released = 0
for j in proposals:
if network.nodes[j]['status'] == 'candidate':
requested = network.nodes[j]['funds_requested']
@ -309,10 +335,26 @@ def trigger_function(params, step, sL, s):
conviction = network.nodes[j]['conviction']
if conviction >threshold:
accepted.append(j)
funds_to_be_released = funds_to_be_released + requested
else:
threshold = np.nan
triggers[j] = threshold
#catch over release and keep the highest conviction results
if funds_to_be_released > funds:
#print('funds ='+str(funds))
#print(accepted)
ordered = conviction_order(network, accepted)
#print(ordered)
accepted = []
release = 0
ind = 0
while release + network.nodes[ordered[ind]]['funds_requested'] < funds:
accepted.append(ordered[ind])
release= network.nodes[ordered[ind]]['funds_requested']
ind=ind+1
return({'accepted':accepted, 'triggers':triggers})
@ -425,7 +467,9 @@ def participants_decisions(params, step, sL, s):
support = []
for j in candidates:
affinity = network.edges[(i, j)]['affinity']*.5+.5*social_affinity_booster(network, j, i)
booster = social_affinity_booster(network, j, i)
#print(booster)
affinity = network.edges[(i, j)]['affinity']+booster
cutoff = sensitivity*np.max([network.edges[(i,p)]['affinity'] for p in candidates])
if cutoff <.5:
cutoff = .5
@ -508,6 +552,7 @@ def update_reserve(params, step, sL, s, _input):
kappa = params['kappa']
V0 = params['invariant']
#print("kappa="+str(kappa))
R = reserve(supply, V0, kappa)
key = 'reserve'
@ -535,20 +580,44 @@ def update_price(params, step, sL, s, _input):
def update_funds(params, step, sL, s, _input):
supply = s['supply']
delta_holdings = _input['delta_holdings']
S = s['supply']
R = s['reserve']
V0=params['invariant']
minus_supply = np.sum([v for v in delta_holdings.values() if v<0])
#print(minus_supply)
min_supply = supply + minus_supply
kappa = params['kappa']
V0 = params['invariant']
old_R = reserve(supply, V0, kappa)
min_R = reserve(min_supply, V0, kappa)
exit_tax = params['tax_rate']
#to avoid overestimating taxes well treat all withdraw before mint
wDS = np.sum([v for v in delta_holdings.values() if v<0])
_,tax, _ = withdraw_with_tax(wDS, R,S, V0, exit_tax, kappa)
funds = s['funds']+ tax
funds = s['funds']+exit_tax*(old_R-min_R)
key = 'funds'
value = funds
return (key, value)
return (key, value)
def pad(vec, length,fill=True):
if fill:
padded = np.zeros(length,)
else:
padded = np.empty(length,)
padded[:] = np.nan
for i in range(len(vec)):
padded[i]= vec[i]
return padded
def make2D(key, data, fill=False):
maxL = data[key].apply(len).max()
newkey = 'padded_'+key
data[newkey] = data[key].apply(lambda x: pad(x,maxL,fill))
reshaped = np.array([a for a in data[newkey].values])
return reshaped