diff --git a/README.md b/README.md index 5f35e68..520bfa0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,31 @@ -# cryptfolio +# Crypto Portfolio -Quick view of crypto assets... \ No newline at end of file +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. diff --git a/portfolio.sh b/portfolio.sh new file mode 100755 index 0000000..3f01862 --- /dev/null +++ b/portfolio.sh @@ -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¤cies=${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}${tok}${bal}"$(printf "$%.2f\n" $prc)""$(printf "$%.2f\n" $inv)""$(printf "$%.2f\n" $val)""$(printf "$%.2f\n" $mar)""$(printf "%.3f\n" $mov)""); + 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 diff --git a/template.html b/template.html new file mode 100644 index 0000000..a8fbb5c --- /dev/null +++ b/template.html @@ -0,0 +1,60 @@ + + + + Crypto Portfolio + + + + + + + + %row% + + + +
TokenBalancePriceInvestmentValueMarginMovement
Total%inv%%val%%mar%%mov%
+

%dts%

+ + + + diff --git a/wallet.json b/wallet.json new file mode 100644 index 0000000..30fd08f --- /dev/null +++ b/wallet.json @@ -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" + } +} +