darkie.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from core.utils import *
  2. from core.strategy import *
  3. class Darkie():
  4. def __init__(self, airdrop, initial_stake=None, vesting=[], hp=False, commit=True, epoch_len=EPOCH_LENGTH, strategy=random_strategy(EPOCH_LENGTH)):
  5. self.vesting = [0] + vesting
  6. self.stake = (Num(airdrop) if hp else airdrop)
  7. self.initial_stake = [self.stake] # for debugging purpose
  8. self.Sigma = None
  9. self.feedback = None
  10. self.f = None
  11. self.epoch_len=epoch_len # epoch length during which the stake is static
  12. self.strategy = strategy
  13. self.slot = 0
  14. self.won_hist = [] # winning history boolean
  15. def clone(self):
  16. return Darkie(self.stake)
  17. def apy_scaled_to_runningtime(self, rewards):
  18. avg_apy = 0
  19. for idx, reward in enumerate(rewards):
  20. current_epoch_staked_tokens = Num(self.strategy.staked_tokens_ratio[idx-1]) * Num(self.initial_stake[idx-1])
  21. avg_apy += (Num(reward) / current_epoch_staked_tokens) if current_epoch_staked_tokens!=0 else 0
  22. return avg_apy * Num(ONE_YEAR/(self.slot/EPOCH_LENGTH)) if self.slot and self.initial_stake[0]>0 >0 else 0
  23. def apr_scaled_to_runningtime(self):
  24. return Num(self.stake - self.initial_stake[0]) / Num(self.initial_stake[0]) * Num(ONE_YEAR/(self.slot/EPOCH_LENGTH)) if self.slot> 0 and self.initial_stake[0]>0 else 0
  25. def staked_tokens(self):
  26. '''
  27. the ratio of the staked tokens during the epochs
  28. of the total running time
  29. '''
  30. return Num(self.initial_stake[0])*self.staked_tokens_ratio()
  31. def staked_tokens_ratio(self):
  32. staked_ratio = Num(sum(self.strategy.staked_tokens_ratio)/len(self.strategy.staked_tokens_ratio))
  33. #print('type: {}, ratio: {}'.format(self.strategy.type, staked_ratio))
  34. assert staked_ratio <= 1 and staked_ratio >=0, 'staked_ratio: {}'.format(staked_ratio)
  35. return staked_ratio
  36. def set_sigma_feedback(self, sigma, feedback, f, count, hp=True):
  37. self.Sigma = (Num(sigma) if hp else sigma)
  38. self.feedback = (Num(feedback) if hp else feedback)
  39. self.f = (Num(f) if hp else f)
  40. self.slot = count
  41. def run(self, hp=True):
  42. k=N_TERM
  43. def target(tune_parameter, stake):
  44. x = (Num(1) if hp else 1) - (Num(tune_parameter) if hp else tune_parameter)
  45. c = (x.ln() if type(x)==Num else math.log(x))
  46. sigmas = [ c/((self.Sigma+EPSILON)**i) * ( ((L_HP if hp else L)/fact(i)) ) for i in range(1, k+1) ]
  47. scaled_target = approx_target_in_zk(sigmas, Num(stake)) #+ (BASE_L_HP if hp else BASE_L)
  48. return scaled_target
  49. if self.slot % EPOCH_LENGTH ==0 and self.slot > 0:
  50. apr = self.apr_scaled_to_runningtime()
  51. # staked ratio is added in strategy
  52. self.strategy.set_ratio(self.slot, apr)
  53. # epoch stake is added
  54. self.initial_stake +=[self.stake]
  55. T = target(self.f, self.strategy.staked_value(self.stake))
  56. won = lottery(T, hp)
  57. self.won_hist += [won]
  58. def update_vesting(self):
  59. if self.slot >= len(self.vesting):
  60. return 0
  61. slot2vest_index = int(self.slot/28800.0)
  62. slot2vest_prev_index = int((self.slot-1)/28800.0)
  63. slot2vest_index_shifted = slot2vest_index - 1 # by end of month
  64. slot2vest_prev_index_shifted = slot2vest_prev_index - 1 # by end of month
  65. vesting_value = float(self.vesting[slot2vest_index_shifted]) - self.vesting[slot2vest_prev_index_shifted]
  66. self.stake+= vesting_value
  67. return vesting_value
  68. def update_stake(self, reward):
  69. if self.won_hist[-1]:
  70. self.stake+=reward
  71. #print('updating stake, stake: {}, last: {}'.format(self.stake, self.initial_stake[-1]))
  72. def resync_stake(self, reward):
  73. '''
  74. add resync stake
  75. '''
  76. self.stake += reward
  77. def write(self, idx):
  78. with open('log/darkie'+str(idx)+'.log', 'w+') as f:
  79. buf = 'initial stake:'+','.join([str(i) for i in self.initial_stake])
  80. buf += '\r\n'
  81. buf += '(apr,staked ratio,{}):'.format(self.strategy.type)+','.join(['('+str(apr)+','+str(sr)+')' for sr, apr in zip(self.strategy.staked_tokens_ratio, self.strategy.annual_return)])
  82. buf+='\r\n'
  83. buf += 'apr: {}'.format(self.apr_scaled_to_runningtime())
  84. f.write(buf)