Skip to content

Instantly share code, notes, and snippets.

@erlingpaulsen
Created January 15, 2021 12:18
Show Gist options
  • Save erlingpaulsen/3813d26d3d025b66c816ff9c2c6120c2 to your computer and use it in GitHub Desktop.
Save erlingpaulsen/3813d26d3d025b66c816ff9c2c6120c2 to your computer and use it in GitHub Desktop.
Python script for connecting to your Coinbase account through the API. Used to compute and plot the balance and cost per wallet and in total, in addition to calculate the total profit/loss. Will calculate to your native currency.
import json, hmac, hashlib, time, requests
import numpy as np
from requests.auth import AuthBase
import matplotlib.pyplot as plt
# Name of account holder (only for displaying)
USER = 'My name'
# API key and secret. Create these in your Coinbase account with all read permissions selected for all accounts
API_KEY = 'xxx'
API_SECRET = 'xxx'
# API version time should match the API version displayed in your account page
API_VERSION_TIME = '2021-01-14'
# API base URL
API_URL = 'https://api.coinbase.com/v2/'
# Native currency
NATIVE_CURRENCY = 'NOK'
# Create custom authentication for Coinbase API
class CoinbaseWalletAuth(AuthBase):
def __init__(self, api_key, secret_key):
self.api_key = api_key
self.secret_key = secret_key.encode('utf8')
def __call__(self, request):
timestamp = str(int(time.time()))
message = timestamp + request.method + request.path_url + (request.body or '')
message = message.encode('utf8')
signature = hmac.new(self.secret_key, message, hashlib.sha256).hexdigest()
request.headers.update({
'CB-ACCESS-SIGN': signature,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': self.api_key,
'CB-VERSION': API_VERSION_TIME,
})
return request
auth = CoinbaseWalletAuth(API_KEY, API_SECRET)
# Total balance and total cost in native currency
total_balance_native = 0
total_cost_native = 0
# Dictionary for storing balance and cost per account/wallet
account_balances = {}
account_costs = {}
# Get all accounts
r_account = requests.get(API_URL + 'accounts?limit=100', auth=auth)
for account in r_account.json()['data']:
account_id = account['id']
account_name = account['currency']['name']
account_balance = account['balance']['amount']
account_currency = account['currency']['code']
account_cost_native = 0
account_balance_native = 0
# If account balance greater than zero, compute the balance in native currency
if (float(account_balance) > 0):
exchange_rates = requests.get(API_URL + 'exchange-rates?currency={0}'.format(account_currency)).json()['data']['rates']
account_balance_native = np.multiply(float(account_balance), float(exchange_rates[NATIVE_CURRENCY]))
total_balance_native += account_balance_native
# Get all buys in account
r_buy = requests.get(API_URL + 'accounts/{0}/buys?limit=100'.format(account_id), auth=auth)
transactions = []
for buy in r_buy.json()['data']:
buy_id = buy['id']
transaction_date = buy['payout_at'].split('T')[0]
transaction_amount = buy['amount']['amount']
transaction_amount_currency = buy['amount']['currency']
transaction_fee_amount = buy['fee']['amount']
transaction_fee_currency = buy['fee']['currency']
transaction_cost_amount = buy['total']['amount']
transaction_cost_currency = buy['total']['currency']
# If transaction is completed, print details, compute cost in native currency and add to total account cost
if buy['status'] == 'completed':
transactions.append('{0:.4f} {1} for {2:.1f} {3} on {4}'.format(float(transaction_amount), transaction_amount_currency, float(transaction_cost_amount), transaction_cost_currency, transaction_date))
exchange_rates = requests.get(API_URL + 'exchange-rates?currency={0}'.format(transaction_cost_currency)).json()['data']['rates']
transaction_cost_native = np.multiply(float(transaction_cost_amount), float(exchange_rates[NATIVE_CURRENCY]))
account_cost_native += float(transaction_cost_native)
# Add total account cost to total cost
total_cost_native += account_cost_native
# If total account balance or cost is greater than zero, add to dict for plotting and print details
if (float(account_balance) > 0) or (account_cost_native > 0):
account_balances[account_currency] = account_balance_native
account_costs[account_currency] = account_cost_native
print('{0}:\n\tBalance: {1:.4f} {2} = {3:.1f} {4}'.format(account_name, float(account_balance), account_currency, account_balance_native, NATIVE_CURRENCY))
print('\tTotal Cost: {0:.1f} {1}'.format(account_cost_native, NATIVE_CURRENCY))
if len(transactions) > 0:
print('\tTransactions:')
for t in transactions:
print('\t\t{0}'.format(t))
print('')
# Total profit/loss
profit_loss_native = total_balance_native - total_cost_native
profit_loss_percent = np.multiply(np.divide(profit_loss_native, total_balance_native), 100)
print('Total:\n\tBalance: {0:.1f} {1}'.format(total_balance_native, NATIVE_CURRENCY))
print('\tCost: {0:.1f} {1}'.format(total_cost_native, NATIVE_CURRENCY))
print('\tProfit/Loss: {0:.1f} {1}, {2:.2f} %'.format(profit_loss_native, NATIVE_CURRENCY, profit_loss_percent))
# Plotting balance and cost per account in native currency
labels = list(account_balances.keys())
x = np.arange(len(labels))
width = 0.35
fig, ax = plt.subplots(figsize=(12,6))
rects1 = ax.bar(x - width/2, account_balances.values(), width, label='Balance')
rects2 = ax.bar(x + width/2, account_costs.values(), width, label='Cost')
ax.set_ylabel(NATIVE_CURRENCY)
ax.set_title('{0} - Balance and Cost per Wallet - Total Profit/Loss is {1:.2f} %'.format(USER, profit_loss_percent))
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()
plt.grid(True)
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment