Explorar el Código

[research/lotterysim] premint coexist zero-coin; although headstart unactivated, set to zero

ertosns hace 3 años
padre
commit
6e7f7367dd

+ 6 - 5
script/research/lotterysim/core/constants.py

@@ -4,7 +4,7 @@ N_TERM = 2
 CONTROLLER_TYPE_ANALOGUE=-1
 CONTROLLER_TYPE_DISCRETE=0
 CONTROLLER_TYPE_TAKAHASHI=1
-ERC20DRK=2.1*10**9
+ERC20DRK=2.1*10**7
 
 L = 28948022309329048855892746252171976963363056481941560715954676764349967630337.0
 
@@ -15,6 +15,7 @@ REWARD_MIN = 1
 REWARD_MAX = 1000
 
 SLOT = 90
+ONE_MONTH = Num(60*60*24*30/SLOT)
 ONE_YEAR = Num(365.25*24*60*60/SLOT)
 ONE_MONTH = int(30*24*60*60/SLOT)
 VESTING_PERIOD = ONE_MONTH
@@ -36,9 +37,9 @@ REWARD_MAX_HP = Num(REWARD_MAX)
 
 ACC_WINDOW = 100
 
-BASE_L = 0.00001*L
+BASE_L = 0.0001*L
 BASE_L_HP = Num(BASE_L)
 
-# HEADSTART AIRDROP period ~ 1 month
-HEADSTART_AIRDROP=2880# 28800
-SLASHING_RATIO = 0.000001
+# HEADSTART AIRDROP period
+HEADSTART_AIRDROP = 288
+SLASHING_RATIO = 0.0001

+ 11 - 12
script/research/lotterysim/core/darkie.py

@@ -18,27 +18,29 @@ class Darkie():
         return Darkie(self.stake)
 
     def apy_scaled_to_runningtime(self, rewards):
+        '''
         avg_apy = 0
         for idx, reward in enumerate(rewards):
-            init_stake = Num(self.initial_stake[idx-1]) if len(self.initial_stake)>=idx else Num(self.initial_stake[-1])
-            current_epoch_staked_tokens = Num(self.strategy.staked_tokens_ratio[idx-1]) * init_stake
+            #init_stake = Num(self.initial_stake[idx-1]) if len(self.initial_stake)>=idx else Num(self.initial_stake[-1])
+            current_epoch_staked_tokens = Num(self.strategy.staked_tokens_ratio[idx-1]) * Num(self.initial_stake[idx-1])
             avg_apy += (Num(reward) / current_epoch_staked_tokens) if current_epoch_staked_tokens!=0 else 0
         return avg_apy * Num(ONE_YEAR/(self.slot/EPOCH_LENGTH)) if self.slot  and self.initial_stake[0]>0 >0 else 0
+        '''
+        return -1
 
     def vesting_wrapped_initial_stake(self):
         #print('initial stake: {}, corresponding vesting: {}'.format(self.initial_stake[0], self.vesting[int((self.slot)/VESTING_PERIOD)]))
         # note index is previous slot since update_vesting is called after background execution.
-        #return self.current_vesting() if self.slot>0 else self.initial_stake[-1]
-        return (self.current_vesting() if self.slot>0 else self.initial_stake[-1]) + self.initial_stake[-1]
+        #returns  vesting stake plus initial stake gained from zero coin headstart during aridrop period
+        #return (self.current_vesting() if self.slot>0 else self.initial_stake[-1]) + self.initial_stake[-1]
+        vesting = self.current_vesting()
+        return vesting if vesting > 0 else  self.initial_stake[0]
 
     def apr_scaled_to_runningtime(self):
         initial_stake = self.vesting_wrapped_initial_stake()
         #print('stake: {}, initial_stake: {}'.format(self.stake, initial_stake))
         assert self.stake >= initial_stake, 'stake: {}, initial_stake: {}, slot: {}, current: {}, previous: {} vesting'.format(self.stake, initial_stake, self.slot, self.current_vesting(), self.prev_vesting())
-        #if self.slot%100==0:
-            #print('stake: {}, initial stake: {}'.format(self.stake, initial_stake))
-            #print(self.initial_stake)
-        apr = Num(self.stake - initial_stake) / Num(initial_stake) *  Num(ONE_YEAR/(self.slot)) if self.slot> 0 and initial_stake>0 else 0
+        apr = Num(self.stake - initial_stake) / Num(initial_stake) *  Num(ONE_YEAR/(self.slot)) if initial_stake > 0 and self.slot>0 else 0
         return apr
 
     def staked_tokens(self):
@@ -76,10 +78,7 @@ class Darkie():
             # staked ratio is added in strategy
             self.strategy.set_ratio(self.slot, apr)
             # epoch stake is added
-            if self.slot < HEADSTART_AIRDROP:
-                self.initial_stake +=[self.stake]
-        #if self.slot == HEADSTART_AIRDROP:
-        #    self.initial_stake += [self.stake]
+            self.initial_stake += [self.stake]
         T = target(self.f, self.strategy.staked_value(self.stake))
         won = lottery(T, hp)
         self.won_hist += [won]

+ 8 - 11
script/research/lotterysim/core/lottery.py

@@ -6,6 +6,7 @@ from core.darkie import *
 from pid.cascade import *
 from tqdm import tqdm
 import random
+
 class DarkfiTable:
     def __init__(self, airdrop, running_time, controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, dt=1, kc=0, ti=0, td=0, ts=0, debug=False, r_kp=0, r_ki=0, r_kd=0):
         self.Sigma=airdrop
@@ -31,19 +32,15 @@ class DarkfiTable:
         # random running time
         rand_running_time = random.randint(1,self.running_time) if rand_running_time else self.running_time
         self.running_time = rand_running_time
-        #if rand_running_time and debug:
-            #print("random running time: {}".format(self.running_time))
-            #print('running time: {}'.format(self.running_time))
-
         rt_range = tqdm(np.arange(0,self.running_time, 1))
+        merge_length = 0
         for count in rt_range:
-        #while count < self.running_time:
+            merge_length = 0
             winners=0
             f = self.secondary_pid.pid_clipped(float(feedback), debug)
 
             if count%EPOCH_LENGTH == 0:
                 acc = self.secondary_pid.acc()
-                #staked_ratio = self.avg_stake_ratio()
                 reward = self.primary_pid.pid_clipped(acc, debug)
                 self.rewards += [reward]
 
@@ -58,7 +55,7 @@ class DarkfiTable:
 
             for i in range(len(self.darkies)):
                 winners += self.darkies[i].won_hist[-1]
-                ###
+
             self.winners +=[winners]
             feedback = winners
             if self.winners[-1]==1:
@@ -73,7 +70,7 @@ class DarkfiTable:
                 # resolve finalization
                 self.Sigma += self.rewards[-1]
                 # resync nodes
-                merge_length = 0
+
                 for i in reversed(self.winners[:-1]):
                     if i !=1:
                         merge_length+=1
@@ -93,9 +90,9 @@ class DarkfiTable:
                             break
                     self.darkies[darkie_winning_idx].resync_stake(resync_reward)
                     self.Sigma += resync_reward
-            rt_range.set_description('epoch: {}, issuance {} DRK, acc: {}%, stake = {}%, sr: {}%, reward:{}, apr: {}%'.format(int(count/EPOCH_LENGTH), round(self.Sigma,2), round(acc,2)*100, round(total_stake/self.Sigma*100 if self.Sigma>0 else 0,2), round(self.avg_stake_ratio()*100,2) , round(self.rewards[-1],2), round(self.avg_apr(),2)*100))
+            rt_range.set_description('epoch: {}, fork: {} issuance {} DRK, acc: {}%, stake = {}%, sr: {}%, reward:{}, apr: {}%'.format(int(count/EPOCH_LENGTH), merge_length, round(self.Sigma,2), round(acc*100, 2), round(total_stake/self.Sigma*100 if self.Sigma>0 else 0,2), round(self.avg_stake_ratio()*100,2) , round(self.rewards[-1],2), round(self.avg_apr()*100,2)))
             #print('[2]stake: {}, sigma: {}, reward: {}'.format(total_stake, self.Sigma, self.rewards[-1]))
-            assert(round(total_stake,1) <= round(self.Sigma,1))
+            #assert(round(total_stake,1) <= round(self.Sigma,1))
             count+=1
         self.end_time=time.time()
         avg_reward = sum(self.rewards)/len(self.rewards)
@@ -112,7 +109,7 @@ class DarkfiTable:
         return Num(sum([darkie.apr_scaled_to_runningtime() for darkie in self.darkies])/len(self.darkies))
 
     def avg_stake_ratio(self):
-        return sum([darkie.staked_tokens_ratio() for darkie in self.darkies])/len(self.darkies)
+        return sum([darkie.staked_tokens_ratio() for darkie in self.darkies]) / len(self.darkies)
 
     def write(self):
         elapsed=self.end_time-self.start_time

+ 24 - 37
script/research/lotterysim/core/strategy.py

@@ -39,18 +39,13 @@ class LinearStrategy(Strategy):
 
     def set_ratio(self, slot, apr):
         if slot%self.epoch_len==0:
-            if slot < self.airdrop_period:
-                self.staked_tokens_ratio += [1]
-                self.annual_return +=[apr]
-                return
-            sr = Num(apr)/Num(self.target_apy)
-            if sr>1:
-                sr = 1
-            elif sr<0:
-                sr = 0
-            self.staked_tokens_ratio += [sr]
-            self.annual_return += [apr]
-
+                sr = Num(apr)/Num(self.target_apy)
+                if sr>1:
+                    sr = 1
+                elif sr<0:
+                    sr = 0
+                self.staked_tokens_ratio += [sr]
+                self.annual_return += [apr]
 
 class LogarithmicStrategy(Strategy):
     def __init__(self, epoch_len=0):
@@ -59,19 +54,15 @@ class LogarithmicStrategy(Strategy):
 
     def set_ratio(self, slot, apr):
         if slot%self.epoch_len==0:
-            if slot < self.airdrop_period:
-                self.staked_tokens_ratio += [1]
-                self.annual_return +=[apr]
-                return
-            apr_ratio = math.fabs(apr/self.target_apy)
-            fn = lambda x: (math.log(x, 10)+1)/2 * 0.95 + 0.05
-            sr = Num(fn(apr_ratio) if apr_ratio != 0 else 0)
-            if sr>1:
-                sr = 1
-            elif sr<0:
-                sr = 0
-            self.staked_tokens_ratio += [sr]
-            self.annual_return += [apr]
+                apr_ratio = math.fabs(apr/self.target_apy)
+                fn = lambda x: (math.log(x, 10)+1)/2 * 0.95 + 0.05
+                sr = Num(fn(apr_ratio) if apr_ratio != 0 else 0)
+                if sr>1:
+                    sr = 1
+                elif sr<0:
+                    sr = 0
+                self.staked_tokens_ratio += [sr]
+                self.annual_return += [apr]
 
 class SigmoidStrategy(Strategy):
     def __init__(self, epoch_len=0):
@@ -80,18 +71,14 @@ class SigmoidStrategy(Strategy):
 
     def set_ratio(self, slot, apr):
         if slot%self.epoch_len==0:
-            if slot < self.airdrop_period:
-                self.staked_tokens_ratio += [1]
-                self.annual_return +=[apr]
-                return
-            apr_ratio = apr/self.target_apy
-            sr = Num(2/(1+math.pow(math.e, -4*apr_ratio))-1)
-            if sr>1:
-                sr = 1
-            elif sr<0:
-                sr = 0
-            self.staked_tokens_ratio += [sr]
-            self.annual_return += [apr]
+                apr_ratio = apr/self.target_apy
+                sr = Num(2/(1+math.pow(math.e, -4*apr_ratio))-1)
+                if sr>1:
+                    sr = 1
+                elif sr<0:
+                    sr = 0
+                self.staked_tokens_ratio += [sr]
+                self.annual_return += [apr]
 
 def random_strategy(epoch_length=EPOCH_LENGTH):
     rnd = random.random()

+ 2 - 1
script/research/lotterysim/core/utils.py

@@ -41,4 +41,5 @@ def lottery(T, hp=False, log=False):
         lottery_line = str(y)+","+str(T)+"\n"
         with open("/tmp/sim_lottery_history.log", "a+") as f:
             f.write(lottery_line)
-    return y < T if y is not None and T is not None else False
+    won = y < T if y is not None and T is not None else False
+    return won

+ 9 - 7
script/research/lotterysim/discrete_instance_pi_headstart.py

@@ -7,21 +7,23 @@ import scipy.stats as stats
 import math
 from draw import draw
 
-os.system("rm log/*_feedback.hist; rm log/*_output.hist")
+os.system("rm log/*_feedback.hist; rm log/*_output.hist; rm log/darkie*.log")
 
 RUNNING_TIME = int(input("running time:"))
 NODES=1000
+PREMINT = 2.1*10**7
 
 if __name__ == "__main__":
-    darkies = [Darkie(0, strategy=LinearStrategy(EPOCH_LENGTH)) for _ in range(NODES)]
+    mu = PREMINT/NODES
+    darkies = [Darkie(random.gauss(mu, mu/10), strategy=LinearStrategy(EPOCH_LENGTH)) for _ in range(NODES)]
     #dt = DarkfiTable(0, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-2.53, r_ki=29.5, r_kd=53.77)
-    dt = DarkfiTable(0, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-0.719, r_ki=1.6, r_kd=0.1)
+    dt = DarkfiTable(PREMINT, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491,  r_kp=-0.719, r_ki=1.6, r_kd=0.1)
     for darkie in darkies:
         dt.add_darkie(darkie)
     acc, avg_apy, avg_reward, stake_ratio, avg_apr = dt.background(rand_running_time=False)
-    sum_zero_stake = sum([darkie.stake for darkie in darkies[NODES:]])
-    print('acc: {}, avg(apr): {}, avg(reward): {}, stake_ratio: {}'.format(acc, avg_apr, avg_reward, stake_ratio))
-    print('total stake of 0mint: {}, ratio: {}'.format(sum_zero_stake, sum_zero_stake/ERC20DRK))
+    #sum_zero_stake = sum([darkie.stake for darkie in darkies[NODES:]])
+    print('acc: {}, avg(apr): {}%, avg(reward): {}, stake_ratio: {}'.format(acc, round(avg_apr*100,2), avg_reward, stake_ratio))
+    #print('total stake of 0mint: {}, ratio: {}'.format(sum_zero_stake, sum_zero_stake/ERC20DRK))
     dt.write()
     aprs = []
     fortuners = 0.0
@@ -35,7 +37,7 @@ if __name__ == "__main__":
     aprs = sorted(aprs)
     mu = float(sum(aprs)/len(aprs))
     shifted_aprs = [apr - mu for apr in aprs]
-    plt.plot([apr*100 for apr in aprs])
+    plt.plot([round(apr*100,2) for apr in aprs])
     plt.title('annual percentage return, avg: {:}'.format(mu*100))
     plt.savefig('img/apr_distribution.png')
     plt.show()

+ 4 - 20
script/research/lotterysim/plot_darkies.py

@@ -12,32 +12,16 @@ for darkie in glob.glob('log/darkie[0-9]*.log'):
         apr = float(lines[2].split(':')[1].strip())
         initial_stake = [float(item) for item in lines[0].split(':')[1].split(',')]
         idx +=1
-        if sum(initial_stake)!=0 :
-            darkies += [(initial_stake, apr, idx)]
+        darkies += [(initial_stake, apr, idx)]
+plt.figure()
 # plot initial stake
-
 for darkie in darkies:
     plt.plot(darkie[0])
     plt.title('initial stake')
-
-
 legends = []
 for darkie in darkies:
     legend = ["darkie{}".format(darkie[2])]
     legends +=[legend]
-plt.legend(legends)
+plt.legend(legends, loc='upper right')
 plt.savefig("log/plot_darkies_is.png")
-
-# plot apr
-
-for darkie in darkies:
-    plt.plot(darkie[1])
-    plt.title('apr')
-
-
-legends = []
-for darkie in darkies:
-    legend = ["darkie{}".format(darkie[2])]
-    legends +=[legend]
-plt.legend(legends)
-plt.savefig("log/plot_darkies_apr.png")
+plt.close()