Skip to content
Snippets Groups Projects
Commit c54180ea authored by Holger's avatar Holger
Browse files

Snapshot improved

* get_data is now fast
* update_rewards added
* enable_rewards added to build
* build_curation_arrays added
parent 48f2b5ed
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,7 @@ from datetime import datetime, timedelta, date, time ...@@ -10,6 +10,7 @@ from datetime import datetime, timedelta, date, time
import math import math
import random import random
import logging import logging
from bisect import bisect_left
from beem.utils import formatTimeString, formatTimedelta, remove_from_dict, reputation_to_score, addTzInfo, parse_time from beem.utils import formatTimeString, formatTimedelta, remove_from_dict, reputation_to_score, addTzInfo, parse_time
from beem.amount import Amount from beem.amount import Amount
from beem.account import Account from beem.account import Account
...@@ -44,29 +45,37 @@ class AccountSnapshot(list): ...@@ -44,29 +45,37 @@ class AccountSnapshot(list):
self.ops_statistics = beembase.operationids.operations.copy() self.ops_statistics = beembase.operationids.operations.copy()
for key in self.ops_statistics: for key in self.ops_statistics:
self.ops_statistics[key] = 0 self.ops_statistics[key] = 0
self.reward_timestamps = []
self.author_rewards = []
self.curation_rewards = []
self.curation_per_1000_SP_timestamp = []
self.curation_per_1000_SP = []
def get_data(self, timestamp=None): def get_data(self, timestamp=None, index=0):
""" Returns snapshot for given timestamp""" """ Returns snapshot for given timestamp"""
if timestamp is None: if timestamp is None:
timestamp = datetime.utcnow() timestamp = datetime.utcnow()
timestamp = addTzInfo(timestamp) timestamp = addTzInfo(timestamp)
for (ts, own, din, dout, steem, sbd) in zip(self.timestamps, self.own_vests, # Find rightmost value less than x
self.delegated_vests_in, i = bisect_left(self.timestamps, timestamp)
self.delegated_vests_out, if i:
self.own_steem, index = i - 1
self.own_sbd): else:
sum_in = sum([din[key].amount for key in din]) return {}
sum_out = sum([dout[key].amount for key in dout]) ts = self.timestamps[index]
sp_in = self.steem.vests_to_sp(sum_in, timestamp=ts) own = self.own_vests[index]
sp_out = self.steem.vests_to_sp(sum_out, timestamp=ts) din = self.delegated_vests_in[index]
sp_own = self.steem.vests_to_sp(own, timestamp=ts) dout = self.delegated_vests_out[index]
sp_eff = sp_own + sp_in - sp_out steem = self.own_steem[index]
if timestamp < ts: sbd = self.own_sbd[index]
continue sum_in = sum([din[key].amount for key in din])
else: sum_out = sum([dout[key].amount for key in dout])
return {"timestamp": ts, "vests": own, "delegated_vests_in": din, "delegated_vests_out": dout, sp_in = self.steem.vests_to_sp(sum_in, timestamp=ts)
"sp_own": sp_own, "sp_eff": sp_eff, "steem": steem, "sbd": sbd} sp_out = self.steem.vests_to_sp(sum_out, timestamp=ts)
return {} sp_own = self.steem.vests_to_sp(own, timestamp=ts)
sp_eff = sp_own + sp_in - sp_out
return {"timestamp": ts, "vests": own, "delegated_vests_in": din, "delegated_vests_out": dout,
"sp_own": sp_own, "sp_eff": sp_eff, "steem": steem, "sbd": sbd, "index": index}
def get_account_history(self, start=None, stop=None, use_block_num=True): def get_account_history(self, start=None, stop=None, use_block_num=True):
""" Uses account history to fetch all related ops """ Uses account history to fetch all related ops
...@@ -86,6 +95,11 @@ class AccountSnapshot(list): ...@@ -86,6 +95,11 @@ class AccountSnapshot(list):
] ]
) )
def update_rewards(self, timestamp, curation_reward, author_vests, author_steem, author_sbd):
self.reward_timestamps.append(timestamp)
self.curation_rewards.append(curation_reward)
self.author_rewards.append({"vests": author_vests, "steem": author_steem, "sbd": author_sbd})
def update(self, timestamp, own, delegated_in=None, delegated_out=None, steem=0, sbd=0): def update(self, timestamp, own, delegated_in=None, delegated_out=None, steem=0, sbd=0):
""" Updates the internal state arrays """ Updates the internal state arrays
...@@ -135,7 +149,7 @@ class AccountSnapshot(list): ...@@ -135,7 +149,7 @@ class AccountSnapshot(list):
self.delegated_vests_out.append(new_deleg) self.delegated_vests_out.append(new_deleg)
def build(self, only_ops=[], exclude_ops=[]): def build(self, only_ops=[], exclude_ops=[], enable_rewards=False):
""" Builds the account history based on all account operations """ Builds the account history based on all account operations
:param array only_ops: Limit generator by these :param array only_ops: Limit generator by these
...@@ -263,18 +277,24 @@ class AccountSnapshot(list): ...@@ -263,18 +277,24 @@ class AccountSnapshot(list):
continue continue
if op['type'] == "curation_reward": if op['type'] == "curation_reward":
if "curation_reward" in only_ops: if "curation_reward" in only_ops or enable_rewards:
vests = Amount(op['reward'], steem_instance=self.steem) vests = Amount(op['reward'], steem_instance=self.steem)
if "curation_reward" in only_ops:
self.update(ts, vests, 0, 0) self.update(ts, vests, 0, 0)
if enable_rewards:
self.update_rewards(ts, vests, 0, 0, 0)
continue continue
if op['type'] == "author_reward": if op['type'] == "author_reward":
if "author_reward" in only_ops: if "author_reward" in only_ops or enable_rewards:
# print(op) # print(op)
vests = Amount(op['vesting_payout'], steem_instance=self.steem) vests = Amount(op['vesting_payout'], steem_instance=self.steem)
steem = Amount(op['steem_payout'], steem_instance=self.steem) steem = Amount(op['steem_payout'], steem_instance=self.steem)
sbd = Amount(op['sbd_payout'], steem_instance=self.steem) sbd = Amount(op['sbd_payout'], steem_instance=self.steem)
if "author_reward" in only_ops:
self.update(ts, vests, 0, 0, steem, sbd) self.update(ts, vests, 0, 0, steem, sbd)
if enable_rewards:
self.update_rewards(ts, 0, vests, steem, sbd)
continue continue
if op['type'] == "producer_reward": if op['type'] == "producer_reward":
...@@ -331,6 +351,35 @@ class AccountSnapshot(list): ...@@ -331,6 +351,35 @@ class AccountSnapshot(list):
self.own_sp.append(sp_own) self.own_sp.append(sp_own)
self.eff_sp.append(sp_eff) self.eff_sp.append(sp_eff)
def build_curation_arrays(self, end_date=None, sum_days=7):
""" Build curation arrays"""
self.curation_per_1000_SP_timestamp = []
self.curation_per_1000_SP = []
if sum_days <= 0:
raise ValueError("sum_days must be greater than 0")
index = 0
curation_sum = 0
days = (self.reward_timestamps[-1] - self.reward_timestamps[0]).days // sum_days * sum_days
if end_date is None:
end_date = self.reward_timestamps[-1] - timedelta(days=days)
for (ts, vests) in zip(self.reward_timestamps, self.curation_rewards):
if vests == 0:
continue
sp = self.steem.vests_to_sp(vests, timestamp=ts)
data = self.get_data(timestamp=ts, index=index)
index = data["index"]
if "sp_eff" in data and data["sp_eff"] > 0:
curation_1k_sp = sp / data["sp_eff"] * 1000 / sum_days * 7
else:
curation_1k_sp = 0
if ts < end_date:
curation_sum += curation_1k_sp
else:
self.curation_per_1000_SP_timestamp.append(end_date)
self.curation_per_1000_SP.append(curation_sum)
end_date = end_date + timedelta(days=sum_days)
curation_sum = 0
def __str__(self): def __str__(self):
return self.__repr__() return self.__repr__()
......
#!/usr/bin/python
import sys
import datetime as dt
from beem.amount import Amount
from beem.utils import parse_time, formatTimeString, addTzInfo
from beem.instance import set_shared_steem_instance
from beem import Steem
from beem.snapshot import AccountSnapshot
import matplotlib as mpl
# mpl.use('Agg')
# mpl.use('TkAgg')
import matplotlib.pyplot as plt
if __name__ == "__main__":
if len(sys.argv) != 2:
# print("ERROR: command line paramter mismatch!")
# print("usage: %s [account]" % (sys.argv[0]))
account = "holger80"
else:
account = sys.argv[1]
acc_snapshot = AccountSnapshot(account)
acc_snapshot.get_account_history()
acc_snapshot.build(enable_rewards=True)
acc_snapshot.build_curation_arrays()
timestamps = acc_snapshot.curation_per_1000_SP_timestamp
curation_per_1000_SP = acc_snapshot.curation_per_1000_SP
plt.figure(figsize=(12, 6))
opts = {'linestyle': '-', 'marker': '.'}
plt.plot_date(timestamps, curation_per_1000_SP, label="Curation reward per week and 1k SP", **opts)
plt.grid()
plt.legend()
plt.title("Curation over time - @%s" % (account))
plt.xlabel("Date")
plt.ylabel("Curation rewards (SP / (week * 1k SP))")
plt.show()
# plt.savefig("curation_per_week-%s.png" % (account))
print("last curation reward per week and 1k sp %.2f SP" % (curation_per_1000_SP[-1]))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment