project ready

This commit is contained in:
starlord 2024-05-09 10:00:56 -07:00
parent 3b06bc307e
commit 1d34619e7e
4 changed files with 177 additions and 2 deletions

View file

@ -1,3 +1,31 @@
# cryptfolio
# Crypto Portfolio
Quick view of crypto assets...
This is a basic script to use `bash | jq` to process the contents of a `.json` "configuration" file and deliver the current status of a portfolio of crypto-currencies based on data retrieved from the [Kucoin API](https://www.kucoin.com/api) (which *requires no key*).
Results are delivered via an encoded [itty.bitty](https://about.bitty.site) url and can be downloaded as `csv` records.
[**Here is an example.**](https://itty.bitty.site/#Portfolio/XQAAAAT//////////wAeCEUG0O+oKBdZ2an16qclP3ZWSMUzhiDsEZ6qy1sgvhIq6Hr2L4YPd7IJhqr4o8AZqF9O9RftB9GDuVd2SlkYO7UY2awqwmBdB6MalZZnLcYV3O8NcFqO7TrHGf5CHNaQh3RY3FDPWDwhpMAQixOrVtPbWsnuwOKfsQtPTVqBibnT3EgSReJIx+p7vNOMDKV5s29g6OWtMkpuKgGXpwYnQtx3+8VrHAbsKHgM2MYHKk8sL6rdDCIPZQUWOW19GSrBC629KYV3J6BNWjcXhgW+B64age7uWmielfhcrbFdHJTt9P8PjQuYsHoLt6CELj/qKkzaaGn7ellVvKKm3VMSQx0zI0SGg328iuW6yDF0FNeS3S6sw8PovseMmn6nIg0M31y2WnvDylZVIVVjEXrEsV27XyVWpXiOGeLhmg5aYUqPlrqxBjiKbKUWpEwyoGIYLRXT1Tf2HYQQjXXICXACt69bI8+kHFkG3qyGlVXlZhKqcfa9gDUY9d3aB4OciyuZcy3cJTHZ0jQxqF9xO/Oqrg9RbSYTLsQQYdPyZpj9YprCNak7WcS+AwlyaMuEoNSE+/kq7vlKu9wcC7GRnirrFD12ydrvasGdHPsMFndVWuuKFq4jO7GCSrK6KzPi1yAkZYMsbhm132fgiCY4rBlEQFTwOqHn0TSqgpVFsfGCm7SwUldSHy3zzv0fLRsC9BTTEtbBU2ODylCMKVufr5EcHey76YvhumCd3YCqXf5zXpzPbFRLvi2HkL8Q8nb6Se4mfa5WYyh5hNaQLtyPb3X55iyvvnJmttyjTEhosbW5ucUCzYzb55n7kcImt+srD+YnjDEaERccGLNiFXJT0UUCo5LdUrViU1DbJTFpEEuA+5avLmw3KVmsR1jOdncSmYJ9oeBFpPp2h+Pl1zCDy4igbzKzsC+WJ0A2HM5ODjxfb/Sq5ULPxi+qZg51gmuLldJUofxYxekYESgEIwcL3zH5nqG5DcSlIX0Jtn1OD+7Xgp/NeT0rO97KTVy0yeeEpDytv8hUAkd8exAWtXOS/AfTAxrltVNPwx0ljsmBfWvLFaf+/Cl8jw==)
## How It Works
### Update Portfolio
Update the `wallet.json` file with an array of objects each containing the **token ID**, **amount you have invested**, and **balance** for each of your currencies.
> Make sure your token IDs match what is expected by the API. ([https://api.kucoin.com/api/v3/currencies](https://www.kucoin.com/docs/rest/spot-trading/market-data/get-currency-list))
### Execute Script
Simply run `portfolio.sh` manually or via `cron` as you like.
The script will read `wallet.json` for the tokens it needs to check and then make calls to the Kucoin API to determine prices, comparing that to your indicated balances and evaluating whether or not you are profiting.
The results are inserted into `template.html` using placeholders (via `sed`), which is then [encoded in itty.bitty](https://github.com/alcor/itty-bitty/wiki/#generating-links-programmatically) to be generated as a unique but constant webpage.
> You can bookmark the link, or click the "Download CSV" button (which uses some light JavaScript) to save the results.
## ntfy Alerts
While one can simply click on the generated link (or have it delivered any way, really), the `portfolio.sh` script comes pre-built with the functionality to deliver the results via a [ntfy](https://ntfy.sh) service.
The `wallet.json` file contains configuration options to specify the server and topic for delivery, and a message will be sent making the notification clickable, taking you directly to the results page.

68
portfolio.sh Executable file
View file

@ -0,0 +1,68 @@
#!/bin/bash
# current dir
dir="$(dirname $(realpath $0))"
# get files
wallet="${dir}/wallet.json"
template="${dir}/template.html"
# list tokens
tokens=$(jq -r '.tokens | map(.token) | join(",")' $wallet)
# fetch prices
prices=$(curl "https://api.kucoin.com/api/v1/prices?base=USD&currencies=${tokens}" | \
jq '[.data | to_entries[] | {token: .key, price: .value} | .price |= tonumber]')
# date stamp
dts=$(echo -n "As of $(date '+%F %T %:::z')")
# build portfolio
portfolio=$(jq -s '[ .[0] + .[1] | group_by(.token)[] | add ]' \
<(echo "$(jq '.tokens' $wallet)") <(echo "$prices"))
# calculate value
calc=$(jq '[.[] | .["value"] = .balance * .price | .["margin"] = .value - .investment | .["movement"] = .margin / .investment]' \
<(echo "$portfolio"))
# create rows
readarray -t tokens < <(jq -c '.[]' <(echo $calc))
for t in "${tokens[@]}"; do
tok=$(echo $t | jq '.token' | tr -d '"');
bal=$(echo $t | jq '.balance|tonumber');
prc=$(echo $t | jq '.price|tonumber');
inv=$(echo $t | jq '.investment|tonumber');
val=$(echo $t | jq '.value|tonumber');
mar=$(echo $t | jq '.margin|tonumber');
mov=$(echo $t | jq '.movement|tonumber');
row=$(echo "${row}<tr><td class=\"left\">${tok}</td><td>${bal}</td><td>"$(printf "$%.2f\n" $prc)"</td><td>"$(printf "$%.2f\n" $inv)"</td><td>"$(printf "$%.2f\n" $val)"</td><td>"$(printf "$%.2f\n" $mar)"</td><td>"$(printf "%.3f\n" $mov)"</td></tr>");
csv=$(echo "${csv}"$(echo -n $(date +",['"%F"','"%T"','"%:::z"'"))",'${tok}','${bal}','${prc}','${inv}','${val}','${mar}','${mov}']");
# Sum up
tot_inv=$(echo "${tot_inv:-0}+$inv" | bc);
tot_val=$(echo "${tot_val:-0}+$val" | bc);
tot_mar=$(echo "${tot_mar:-0}+$mar" | bc);
done
# format array
csv=$(echo $csv | sed 's|^,||g')
# calculate movement
tot_mov=$(echo "scale=3 ; $tot_mar / $tot_inv" | bc)
# fill template
page=$(cat $template | sed "s|%row%|$row|g;s|%inv%|"$(printf "$%.2f\n" $tot_inv)"|g;s|%val%|"$(printf "$%.2f\n" $tot_val)"|g;s|%mar%|"$(printf "$%.2f\n" $tot_mar)"|g;s|%mov%|"$(printf "%.4f\n" $tot_mov)"|g;s|%dts%|$dts|g;s|%csv_data%|$csv|g;s|%dts_fln%|"$(echo -n $(date '+%F_%T%:::z'))"|g")
# encode link
itty=$(echo -n $page | lzma -9 | base64 -w0 | xargs -0 printf "https://itty.bitty.site/#Portfolio/%s\n")
# send signal
ntfy=$(jq -r '.ntfy | "\(.server)/\(.topic)"' $wallet)
curl \
-H "title: Portfolio Update" \
-H "tags: coin" -H "click: ${itty}" \
-d "Click Here" $ntfy

60
template.html Normal file
View file

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html>
<head>
<title>Crypto Portfolio</title>
<style>
table {
border-style: solid;
border-width: 3px;
}
td, th {
border-style: solid;
border-width: 2px;
}
td {
text-align: right;
}
td.left {
text-align: left;
}
</style>
</head>
<body>
<table>
<tr>
<th>Token</th><th>Balance</th><th>Price</th><th>Investment</th><th>Value</th><th>Margin</th><th>Movement</th>
</tr>
%row%
<tr>
<td class="left"><b>Total</b></td><td></td><td></td><td><b>%inv%</b></td><td><b>%val%</b></td><td><b>%mar%</b></td><td><b>%mov%</b></td>
</tr>
</table>
<p><i>%dts%</i></p>
<button onclick="download_csv_file()"> Download CSV </button>
</body>
<script>
var csvFileData = [
%csv_data%
];
function download_csv_file() {
var csv = 'Date,Time,Zone,Token,Balance,Price,Investment,Value,Margin,Movement\n';
csvFileData.forEach(function(row) {
csv += row.join(',');
csv += "\n";
});
document.write(csv);
var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
hiddenElement.target = '_blank';
hiddenElement.download = 'CSV_Portfolio_%dts_fln%.csv';
hiddenElement.click();
}
</script>
</html>

19
wallet.json Normal file
View file

@ -0,0 +1,19 @@
{
"tokens": [
{
"token": "BTC",
"investment": 50,
"balance": 0.0008
},
{
"token": "ETH",
"investment": 35,
"balance": 0.012
}
],
"ntfy": {
"server": "https://ntfy.sh",
"topic": "topic123"
}
}