Calculate the APR of your delegations (not dlease)

in HiveDevs4 years ago (edited)

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] * 365 / delta.days * 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.

Sort:  

This is the way to go. Make your own path to move forward. Your efforts are laudable. It will be helpful for the people who are looking for APR Calculations. Keep it up your good work. Gitplait is looking for a user kike you.

Your post has been curated with @gitplait community account because this is the kind of publications we like to see in our community.

Join our Community on Hive and Chat with us on Discord.

[Gitplait-Team]

Thanks, appreciate it!

.

Yep, you are right! I reused a script and forgot to take that part out. Thanks for pointing it out.

I have picked your post for my daily hive voting initiative, Keep it up and Hive On!!

Congratulations @gadrian! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s) :

You got more than 3250 replies. Your next target is to reach 3500 replies.

You can view your badges on your board And compare to others on the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Support the HiveBuzz project. Vote for our proposal!