Posts

Calculate the APR of your delegations (not dlease)

avatar of @gadrian
25
@gadrian
·
0 views
·
4 min read

A while ago I found myself looking for a tool to easily calculate the APR for my delegations which paid something back.

I'm not talking about dlease delegations, because their site is well crafted and the APR is in the center of it, both for the delegators and for the delegatees.

But you might delegate to other services which also share all or part of the ROI generated from the delegation you offered.

So after not finding what I was looking for, I decided to make my own script to calculate the APRs of the delegations.

The script is written in Python and I'll share it with you below. You are free to play around with it and adapt it to your needs.

What can you do with the script?

  • calculate APRs for the delegations from one account to a number of specified accounts (introduced as a comma-separated list; note: accounts from the list are not tested if they are real Hive accounts, typos will generate a KeyError error)
  • delegations updates between start date and stop date are tracked and APR is calculated for each distinct period
  • the algorithm allows different delegatees and paying accounts

Limitations

  • something I haven't added in the script although I should have is a distinction between HIVE and HBD for payments received. I wasn't bothered because all my payments were received in HIVE.
  • it doesn't work for delegations via dlease or any other systems where delegations to different accounts are aggregated when payment is being made
  • it doesn't take into account the 5 days cooldown period when calculating the APR
  • it doesn't work if payment is being made to a different account than the one from which the delegations are being made (this can of course be added but I didn't)

Python Script

import sys 
from beem import Hive 
from beem.account import Account 
from beem.nodelist import NodeList 
import time 
from datetime import datetime, timedelta 
from datetime import date 
 
if __name__ == "__main__": 
    nodelist = NodeList() 
    nodelist.update_nodes() 
    blockchain_instance = Hive(node=nodelist.get_hive_nodes())     
    assert blockchain_instance.is_hive 
 
    your_account_name = input("Enter your account name: ") 
    try: 
        your_account = Account(your_account_name, blockchain_instance=blockchain_instance) 
    except: 
        print('Something went wrong! Does the account exist on Hive? Check the spelling!') 
        sys.exit() 
 
    delegatee_accounts_names = [] 
    delegatee_accounts_names_str = input("Delegations to calculate APR for (comma-separated list, i.e.: account1, account2, account3): ") 
    delegatee_accounts_names = delegatee_accounts_names_str.strip().split(',') 
    paying_accounts_names = {} 
    for delegatee_account_name in delegatee_accounts_names: 
        delegatee_accounts_names[delegatee_accounts_names.index(delegatee_account_name)] = delegatee_account_name.strip() 
        delegatee_account_name = delegatee_account_name.strip() 
        paying_account_name = input('Enter paying account name for delegation at %s (leave empty if it\'s the same): ' % delegatee_account_name) 
        if paying_account_name == "": 
            paying_account_name = delegatee_account_name 
        paying_accounts_names[delegatee_account_name] = paying_account_name 
    print('Paying accounts: %s' % paying_accounts_names) 
 
    print('----') 
    print('Make sure the start date is older than the first delegation you included in the analysis!') 
    print('Otherwise your first delegation operation won\'t be found, because the algorithm doesn\'t look in reverse history from the start date.') 
    start_date_str = input('Enter start date (YY-MM-DD): ') 
    start_date = datetime.strptime(start_date_str, '%y-%m-%d') 
    stop_date_str = input('Enter stop date (YY-MM-DD, leave empty for today): ') 
    if stop_date_str == "": 
        stop_date = datetime.combine(date.today(), datetime.min.time()) 
    else: 
        stop_date = datetime.strptime(stop_date_str, '%y-%m-%d') 
 
    # transactions         
    acc_op = ['transfer', 'delegate_vesting_shares'] 
 
    current_start_date = {} 
    current_stop_date = {} 
    current_delegated_amount_hp = {} 
 
    current_total_amount_received = {} 
 
    for transactions in your_account.history(start_date, stop_date, use_block_num=False, only_ops=acc_op): 
        if transactions['type'] == 'delegate_vesting_shares': 
            if transactions['delegator'] != your_account_name: 
                continue 
            if transactions['delegatee'] not in delegatee_accounts_names: 
                continue 
            delegatee_account_name = transactions['delegatee'] 
            if delegatee_account_name in current_start_date: 
                print('----') 
                print('APR before the delegation update for %s:' % delegatee_account_name) 
                current_stop_date[delegatee_account_name] = datetime.strptime(transactions['timestamp'], '%Y-%m-%dT%H:%M:%S') 
                delta = current_stop_date[delegatee_account_name] - current_start_date[delegatee_account_name] #+ timedelta(days=5) # timedelta = 5 days cooldown 
                if current_delegated_amount_hp[delegatee_account_name] > 0 and delta.days > 0: 
                    apr = float(current_total_amount_received[paying_accounts_names[delegatee_account_name]] / current_delegated_amount_hp[delegatee_account_name] * 365 / delta.days * 100) 
                else: 
                    apr = -1.0 # if delegation or period is zero 
                print('%s had delegated %.3f HP to %s at %s' % (your_account_name, current_delegated_amount_hp[delegatee_account_name], delegatee_account_name, current_start_date[delegatee_account_name])) 
                print('Delegation date: %s' % current_start_date[delegatee_account_name]) 
                print('Stop date: %s' % current_stop_date[delegatee_account_name]) 
                print('Period (in days): %s' % delta.days)         
                print('Total amount received by %s from %s for delegation to % s, in the given period: %.3f HIVE' % (your_account_name, paying_accounts_names[delegatee_account_name], delegatee_account_name, current_total_amount_received[paying_accounts_names[delegatee_account_name]])) 
                if apr != -1.0: 
                    print('APR during the period=%.2f%%' % apr) 
                else: 
                    print('APR: Undefined - either the period or the delegation is zero!') 
                 
                current_start_date[delegatee_account_name] = current_stop_date[delegatee_account_name]                 
                current_stop_date[delegatee_account_name] = stop_date 
 
                current_total_amount_received[delegatee_account_name] = 0.0 
            else: 
                current_start_date[delegatee_account_name] = datetime.strptime(transactions['timestamp'], '%Y-%m-%dT%H:%M:%S')                 
                current_stop_date[delegatee_account_name] = stop_date 
            current_delegated_amount_hp[delegatee_account_name] = (float(transactions['vesting_shares']['amount']) / 1000000) * (blockchain_instance.get_hive_per_mvest() / 1000000) 
             
         
        if transactions['type'] == 'transfer': 
            if transactions['from'] not in paying_accounts_names.values(): 
                continue 
            if transactions['from'] in current_total_amount_received: 
                current_total_amount_received[transactions['from']] += float(transactions['amount']['amount']) / 1000 
            else: 
                current_total_amount_received[transactions['from']] = float(transactions['amount']['amount']) / 1000 
 
    for delegatee_account_name in delegatee_accounts_names:         
        delta = current_stop_date[delegatee_account_name] - current_start_date[delegatee_account_name] #+ timedelta(days=5) # timedelta = 5 days cooldown 
        if current_delegated_amount_hp[delegatee_account_name] > 0 and delta.days > 0: 
            apr = float(current_total_amount_received[paying_accounts_names[delegatee_account_name]] / current_delegated_amount_hp[delegatee_account_name] <em> 365 / delta.days </em> 100) 
        else: 
            apr = -1.0 # if delegation or period is zero 
         
        print('----') 
        print('%s delegated %.3f HP to %s at %s' % (your_account_name, current_delegated_amount_hp[delegatee_account_name], delegatee_account_name, current_start_date[delegatee_account_name])) 
        print('Delegation date: %s' % current_start_date[delegatee_account_name]) 
        print('Stop date: %s' % current_stop_date[delegatee_account_name]) 
        print('Period (in days): %s' % delta.days)         
        print('Total amount received by %s from %s for delegation to % s, in the given period: %.3f HIVE' % (your_account_name, paying_accounts_names[delegatee_account_name], delegatee_account_name, current_total_amount_received[paying_accounts_names[delegatee_account_name]])) 
        if apr != -1.0: 
            print('APR during the period=%.2f%%' % apr) 
        else: 
            print('APR: Undefined - either the period or the delegation is zero!') 

Code EDIT: Removed the unnecessary posting key request and making a few print outputs a little clearer.