Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/shunjizhan/crypto-portfolio-viewer

View your aggregated cryptocurrency portfolio -- across exchanges, ETH wallet, and any other places 🎉🎉
https://github.com/shunjizhan/crypto-portfolio-viewer

bitcoin ccxt cli-tool coingecko coingecko-api coingecko-client crypto crypto-exchange-api crypto-exchange-software cryptocurrencies cryptocurrency cryptocurrency-api cryptocurrency-exchanges cryptocurrency-portfolio cryptocurrency-prices cryptocurrency-trading-bot cryptocurrency-wallet nodejs portfolio-viewer trading-bot

Last synced: 18 days ago
JSON representation

View your aggregated cryptocurrency portfolio -- across exchanges, ETH wallet, and any other places 🎉🎉

Awesome Lists containing this project

README

        

# Crypto Portfolio Viewer
View your **aggregated** cryptocurrency portfolio automagically, no matter where the assets are located:
- ✅ Exchanges
- ✅ ETH wallets
- ✅ Anywhere else, no problem!
- ⭕️ Polkadot parachains (soon)
- ⭕️ BSC & HECO (someday)

___
## Foreword
As a crypto trader *~~pro~~*, I have long been struggling with tracking all my tokens in a unified way, since they locate in so many different places: Binance, Huobi, Coinbase, FTX, ETH hot/cold wallets, BTC wallets, BSC, HECO, ICOs, mining machines... 🤯

If you are facing similar issues, this is for you. 🎉

I made this tool for every crypto lover ❤️, like you and I, to manage all assets more conveniently. So we can be more focused on making wise trading decisions. 🥳

___
## Basic Usage
### 🌀 install
```
$ yarn add crypto-portfolio-viewer
$ npm install crypto-portfolio-viewer --save
```
### 🌀 import
```ts
/* ----- CommonJS ----- */
const {
getPortfolio,
printPortfolioNicely, // optional
} = require('crypto-portfolio-viewer');

/* ----- ES modules ----- */
import {
getPortfolio,
printPortfolioNicely, // optional
} from 'crypto-portfolio-viewer';
```

### 🌀 eth + erc20 assets
we can easily view all ETH and ERC20 tokens using ETH addresses.
```ts
const addresses = [
'0x0000000000000000000000000000000000011111',
'0x00000000000000000000000000000000000fffff',
// ......
];

(async () => {
const portfolio = await getPortfolio({ addresses });
printPortfolioNicely(portfolio);
})();
```

### 🌀 exchange assets
we can easily view all exchanges assets using exchange api keys. Exchange namings please refer to [ccxt](https://github.com/ccxt/ccxt#supported-cryptocurrency-exchange-markets).
```ts
const keys = {
binance: {
apiKey: "xxxxxxxxxx",
secret: "yyyyyyyyyy"
},
ftx: {
apiKey: "aaaaaaaaaa",
secret: "bbbbbbbbbb",
},
// ......
};

(async () => {
const portfolio = await getPortfolio({ keys });
printPortfolioNicely(portfolio);
})();
```
[](#other-assets)
### 🌀 any other assets
we can easily view any other assets by hard coding their counts.
```ts
const othertokens = {
"BTC": [8.5], // in mysterious wallet
"BNB": [200], // in BSC
"ETH": [10, 30], // uni-LP, sushi-LP
"USDT": [
1000, // borrowed by Alex
2000, // borrowed by Kate
5000, // my mining machine's value
],
// ......
};

(async () => {
const portfolio = await getPortfolio({ othertokens });
printPortfolioNicely(portfolio);
})();
```

### 🌀 ALL assets
> Being able to aggregate all assets is the soul of a portfolio viewer.
>
> -- Aristotélēs

we can easily view **all of our assets across many different places**, by combining the usages above.
```ts
const keys = {
binance: {
apiKey: "xxxxxxxxxx",
secret: "yyyyyyyyyy"
},
ftx: {
apiKey: "aaaaaaaaaa",
secret: "bbbbbbbbbb",
},
};

const addresses = [
'0x0000000000000000000000000000000000011111',
'0x00000000000000000000000000000000000fffff',
];

const othertokens = {
"BTC": [8.5], // in cold wallet
"BNB": [200], // in BSC
"ETH": [10, 30], // uni-LP, sushi-LP
"USDT": [
1000, // borrowed by Alex
2000, // borrowed by Kate
5000, // my mining machine's value
],
};

(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
});

printPortfolioNicely(portfolio);
})();
```

#### 🌀 example result
```shell
$ node getPortfolio.js
started to fetch portfolio data ...
(1/5) fetching exchange token counts ...
(2/5) fetching ERC20 token counts ...
(3/5) fetching other token counts ...
(4/5) fetching all token prices ...
(5/5) calculating all token values ...
finished!! Let's go Bitcoin!!

----------------------------------------------------------
₿ Binance tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $25000 | 100% | ₿2.5 | $0 | 0 |
| BTC | $10000 | 40% | ₿1 | $10000 | 1 |
| ETH | $10000 | 40% | ₿1 | $1000 | 10 |
| BNB | $5000 | 20% | ₿0.5 | $100 | 50 |

----------------------------------------------------------
₿ FTX tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $15000 | 100% | ₿1.5 | $0 | 0 |
| BTC | $10000 | 66% | ₿1 | $10000 | 1 |
| ATOM | $10000 | 66% | ₿1 | $20 | 500 |
| USDT | $-5000 | -33% | ₿-0.5 | $1 | -5000 |
// negative value means borrowed from contract or margin
// this can be disabled or customized

----------------------------------------------------------
₿ ETH + ERC20 tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $30000 | 100% | ₿2 | $0 | 0 |
| UNI | $20000 | 66% | ₿2 | $50 | 400 |
| ETH | $10000 | 33% | ₿1 | $1000 | 10 |

----------------------------------------------------------
₿ other tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $50000 | 100% | ₿5 | $0 | 0 |
| DOT | $30000 | 60% | ₿3 | $100 | 300 |
| KSM | $20000 | 40% | ₿2 | $1000 | 20 |

----------------------------------------------------------
₿ all tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $120000 | 100% | ₿12 | $0 | 0 |
| DOT | $30000 | 25% | ₿3 | $100 | 300 |
| KSM | $20000 | 16.7% | ₿2 | $1000 | 20 |
| UNI | $20000 | 16.7% | ₿2 | $50 | 400 |
| BTC | $20000 | 16.7% | ₿2 | $10000 | 2 |
| ETH | $20000 | 16.7% | ₿2 | $1000 | 20 |
| ATOM | $10000 | 8.3% | ₿1 | $20 | 500 |
| BNB | $5000 | 4.1% | ₿0.5 | $100 | 50 |
| USDT | $-5000 | -4.1% | ₿-0.5 | $1 | -5000 |
```
___
## Advanced Usage
### 🔥 custom printer
> Viewing result nicely is the soul of a portfolio viewer.
>
> --Shakespeare

we can easily print the result in your favorite fashion:
```ts
const myFavoritePrinter = portfolio => { ... };

(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
});

myFavoritePrinter(portfolio);
})();
```
### 🔥 combine results
by default we view each exchange and each ETH address separately:
```shell
----------------------------------------------------------
₿ Binance tokens ₿
----------------------------------------------------------
......
----------------------------------------------------------
₿ FTX tokens ₿
----------------------------------------------------------
......
----------------------------------------------------------
₿ 0x1234...5678 tokens ₿
----------------------------------------------------------
......
----------------------------------------------------------
₿ 0x9876...5432 tokens ₿
----------------------------------------------------------
```

to simplify our portfolio, we can combine them as a whole
```ts
(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
combineExchanges: true, // <--here!
combineAddresses: true, // <--here!
});

printPortfolioNicely(portfolio);
})();
```
```shell
----------------------------------------------------------
₿ exchange tokens ₿
----------------------------------------------------------
all exchange tokens combined print here ......
----------------------------------------------------------
₿ ETH tokens ₿
----------------------------------------------------------
all ETH + ERC20 tokens combined print here ......
```

### 🔥 contract/future accounts
For contract/future/margin assets in exchanges, since the `ccxt` library that we rely on doesn't yet provide unified interfaces for these accounts, there is no automatted way to catch them into the exchange result.

But don't worry, we have 2 different ways to inlcude them into our portfolio:

#### 1) hard code
We can hard code these assets in `othertokens`. (see [example](#any-other-assets) above)

This is pretty convenient, but we will have to manually update `othertokens` whenever assets change in future accounts.

#### 2) custom `fetcher`
We can also provide a custom `fetcher` for each exchange, or call it `adapter` if you prefer.

This is more flexible and powerful. One huge advantage is being able to include contract positions as assets, **which I personally use A LOT!!** 🥰. It enables us to more precisely calculate portfolio details.

For example, if we have `1000 USDT collateral`, as well as a contract position of `BTC long (2000 USDT worth)`, then technically our 'real' portfolio should look like
```ts
{
BTC: { USD_value: 2000, ... }, // longed
USDT: { USD_value: -1000, ... }, // 1000 (collateral) - 2000 (borrowed)
TOTAL: { USD_value: 1000, ... }, // net worth
}
```
with method 1 (hard code), on the other hand, our 'fake' portfolio looks like
```ts
{
BTC: { USD_value: 0, ... }, // totally ignores contract positions!
USDT: { USD_value: 1000, ... }, // 1000 (collateral)
TOTAL: { USD_value: 1000, ... }, // net worth
}
```

#### available fetchers
There are already 2 fetchers that I personally use, feel free to use them directly if you happen to use these exchanges : )

You can also reference them to write your own, or even better, contribute your custom fetchers : )
```ts
const {
getPortfolio,
printPortfolioNicely,
fetchers,
} = require('./crypto-portfolio-viewer');

const {
fetchBinanceContractBalances,
fetchFTXContractBalances,
} = fetchers;

(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
extraFetchers: { // <--here!
binance: fetchBinanceContractBalances,
ftx: fetchFTXContractBalances,,
},
});

printPortfolioNicely(portfolio);
})();
```

### 🔥 LP tokens
Currently we don't support automatically "decode" LP tokens to their real values, to track these assets, please hard code them in [other tokens](#any-other-assets).

LP tokens' "decoding" might be implemented in the future : )
___

## APIs Summary
available parameters for `getPortfolio()`:
| param | type | default | required? | description |
|------------------|--------|---------|-----------|-----------------------------------|
| keys | object | {} | no | exchange api keys |
| addresses | array | [] | no | erc20 addresses |
| othertokens | object | {} | no | other tokens |
| extraFetchers | object | {} | no | customized fetcher for exchanges |
| combineExchanges | bool | false | no | combine exchange assets in result |
| combineAddresses | bool | false | no | combine erc20 assets in result |
| verbose | bool | true | no | you know it |

___
## Bugs? Questions? Contributions?
Feel free to [open an issue](https://github.com/shunjizhan/crypto-portfolio-viewer/issues), or create a pull request!
___
## Special Thanks
Really appreciate all the fantastic works by [ccxt](https://github.com/ccxt/ccxt) and [coingecko-api](https://github.com/miscavage/CoinGecko-API), which provide super useful utilities supporting this library.
___

## UI
coming soon