In [28]:
import datetime as dt
from steemdata import SteemData

import pandas as pd
import numpy as np

import plotly.plotly as py
import plotly.graph_objs as go
import cufflinks as cf

# helpers
from toolz import keyfilter

def keep(d, whitelist):
    return keyfilter(lambda k: k in whitelist, d)

def omit(d, blacklist):
    return keyfilter(lambda k: k not in blacklist, d)

In [2]:
db = SteemData().db

In [ ]:


In [3]:
# app specific imports
from funcy.seqs import first
from toolz.functoolz import pipe
from steem.account import Account
from steem.utils import parse_time

In [ ]:

Eligible Accounts

Rules:

  1. Need to have at least 0.15MV
  2. Need to have been active in the past 6 months

In [52]:
from steem.converter import Converter
c = Converter()
min_vests = c.sp_to_vests(100)
max_vests = c.sp_to_vests(50000)

In [5]:
conditions = {
    'balances.available.VESTS': {'$gt': min_vests},
}
projection = {
    '_id': 0,
    'name': 1,
    'balances.available.VESTS': 1,
}
accounts = list(db['Accounts'].find(conditions, projection=projection))

In [6]:
len(accounts)


Out[6]:
11524

In [7]:
def last_op_time(username):
    history = Account(username).history_reverse(batch_size=10)
    last_item = first(history)
    if last_item:
        return parse_time(last_item['timestamp'])
    
def filter_inactive(accounts):
    limit = dt.datetime.now() - dt.timedelta(days=180)
    return list(x for x in accounts if x['timestamp'] > limit)

def filter_invalid(accounts):
    return list(x for x in accounts if x['timestamp'])

In [8]:
accounts = [{
    'name': account['name'],
    'timestamp': last_op_time(account['name']),
    'vests': account['balances']['available']['VESTS'],
} for account in accounts]

In [9]:
valid_accounts = pipe(accounts, filter_invalid, filter_inactive)

In [ ]:


In [68]:
def maxval(val, _max=max_vests):
    if val > _max:
        return _max
    return val

In [69]:
df = pd.DataFrame(valid_accounts)
df.drop('timestamp', axis=1, inplace=True)

# ignore steemit account
df.drop(df[df.name.isin(['steemit', 'poloniex'])].index, inplace=True)

# ceil max allowable vests
df['vests'] = df['vests'].apply(maxval)

# count the vests, calc % shares
all_vests = df['vests'].sum()
df['pct_share'] = df['vests'] / all_vests * 100
df['token_share'] = df['vests'] / all_vests * 1_000_000

In [ ]:


In [70]:
df_sorted = df.sort_values('vests', ascending=False)
df_sorted.head()


Out[70]:
name vests pct_share token_share
4383 kushed 1.035075e+08 0.170474 1704.740256
8290 urbanoid 1.035075e+08 0.170474 1704.740256
4637 lofojobee 1.035075e+08 0.170474 1704.740256
8306 val-b 1.035075e+08 0.170474 1704.740256
8305 val-a 1.035075e+08 0.170474 1704.740256

In [71]:
df_sorted[['name', 'vests', 'pct_share', 'token_share']].to_json('raw_dist.json', orient='records')

In [72]:
!cat raw_dist.json | python -m 'json.tool' > distribution.json

In [ ]:


In [40]:
df_sorted.iplot?

In [46]:
df.sort_values('token_share', ascending=False).head()


Out[46]:
name vests pct_share token_share
505 arhag 2.070154e+08 0.274875 2748.746009
8227 twinner 2.070154e+08 0.274875 2748.746009
445 wackou 2.070154e+08 0.274875 2748.746009
6232 ramta 2.070154e+08 0.274875 2748.746009
3557 inv 2.070154e+08 0.274875 2748.746009

In [64]:
df.sort_values('token_share').iplot(
    x='name',
    y='token_share',
    kind='line',
    fill=True,
    title='Token Distribution',
    colors=['blue', 'orange'],
    theme='white',
    legend=False,
    yTitle='Tokens Awarded',
    filename='hypothetical-token-dist'
)


Out[64]:

In [ ]: