Created
June 17, 2024 14:00
-
-
Save zhulinchng/23be1e1464ba9042c49241be962cbe2b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
from collections import defaultdict | |
token = '' # Wise token | |
host = 'https://api.wise.com' | |
targetCurrencies = ['MYR', 'TWD'] | |
def dfs(graph, start, end, value, visited): | |
if start not in graph or start in visited: | |
return -1.0 | |
if start == end: | |
return value | |
visited.add(start) | |
neighbors = graph[start] | |
for neighbor, neighbor_value in neighbors.items(): | |
rate = dfs(graph, neighbor, end, value * neighbor_value, visited) | |
if rate != -1.0: | |
return rate | |
return -1.0 | |
def get_data(url, token): | |
if token is not None: | |
headers = { | |
'Authorization': 'Bearer ' + token | |
} | |
response = requests.get(url, headers=headers) | |
else: | |
response = requests.get(url) | |
return response.json() | |
def getEstimate(sourceCurrency: str, targetCurrency: str, amount: int, token: str, host: str, fee: float = 0.01): | |
# fee is hardcoded due to no info from Wise | |
rate = get_data(f'{host}/v1/rates?source={sourceCurrency}&target={targetCurrency}', token=token)[0]['rate'] | |
return rate * amount * (1 - fee), rate | |
def getBalance(balances, targetCurrency, token, host): | |
total = 0 | |
for balance in balances: | |
sourceCurrency = balance['currency'] | |
if sourceCurrency == targetCurrency: | |
total += balance['amount']['value'] | |
else: | |
amount = balance['amount']['value'] | |
total += getEstimate(sourceCurrency, targetCurrency, amount, token, host)[0] | |
return round(total, 2) | |
def calculate_conversion_rates(rates, query): | |
# Build graph | |
graph = defaultdict(dict) | |
for flow, value in rates.items(): | |
from_currency, to_currency = flow | |
graph[from_currency][to_currency] = value | |
graph[to_currency][from_currency] = 1/value | |
# Perform DFS for each query | |
from_currency, to_currency = query | |
visited = set() | |
rate = dfs(graph, from_currency, to_currency, 1.0, visited) | |
return rate | |
def getTotal(balances, targetCurrencies, token, host, fee=0.01, printTotals=True): | |
# fee is hardcoded due to no info from Wise | |
total = dict() | |
rates = dict() | |
npass = 0 | |
for trg in targetCurrencies: | |
total[trg] = 0 | |
for balance in balances: | |
sourceCurrency = balance['currency'] | |
if sourceCurrency == trg: | |
total[trg] += balance['amount']['value'] | |
else: | |
amount = balance['amount']['value'] | |
if npass == 0: | |
rates[(sourceCurrency, trg)] = getEstimate(sourceCurrency, trg, 1, token, host)[1] | |
conversion = rates[(sourceCurrency, trg)] | |
else: | |
conversion = calculate_conversion_rates(rates, (sourceCurrency, trg)) | |
if conversion == -1.0: | |
conversion = getEstimate(sourceCurrency, trg, 1, token, host)[1] | |
rates[(sourceCurrency, trg)] = conversion | |
total[trg] += conversion * amount * (1 - fee) | |
total[trg] = round(total[trg], 2) | |
npass += 1 | |
if printTotals: | |
print({k: f'{v:,.2f}' for k, v in total.items()}) | |
return total | |
profiles = get_data(f'{host}/v2/profiles', token) | |
profileID = profiles[0]['id'] | |
balances_list = get_data(f'{host}/v4/profiles/{profileID}/balances?types=STANDARD', token) | |
balances = [b for b in balances_list if b['amount']['value'] > 0] | |
getTotal(balances, targetCurrencies, token, host, | |
fee=0.01, printTotals=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment