Skip to content

Commit

Permalink
Replacing lending by earn operation/endpoints/processing.
Browse files Browse the repository at this point in the history
  • Loading branch information
diegomanuel committed Feb 17, 2024
1 parent ae6b9a1 commit 55073ec
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 39 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ By using the `BINANCE()` formula in your spreadsheet, you can get data fetched f
* Current market [prices](#operation-prices-public)
* Historical market [OHLCV](#operation-history-public)
* Last [24h stats](#operation-stats24h-public)
* Total [account assets](#operation-account-private) from Binance wallets (SPOT + LENDING + CROSS + ISOLATED + FUTURES + SUB-ACCOUNTS)
* Total [account assets](#operation-account-private) from Binance wallets (SPOT + EARN + CROSS + ISOLATED + FUTURES + SUB-ACCOUNTS)
* All current [open orders](#operation-ordersopen-private) (SPOT + CROSS + ISOLATED + FUTURES)
* Latest [done/finished orders](#operation-ordersdone-private) (SPOT + CROSS + ISOLATED + FUTURES)
* Historical [orders table](#operation-orderstable-private) (SPOT + CROSS + ISOLATED + FUTURES)
Expand Down Expand Up @@ -154,9 +154,10 @@ Some operations are **private**, meaning they **do require a Binance API key** t
* `=BINANCE("stats/24h", A1:A3, "ticker: BTC, headers: false")` Optionally you can give more options like not returning table headers.

### Operation: `"account"` (private)
`=BINANCE("account")` will return total account assets from Binance wallets (SPOT + LENDING + CROSS + ISOLATED + FUTURES + SUB-ACCOUNTS).
`=BINANCE("account")` will return total account assets from Binance wallets (SPOT + EARN + CROSS + ISOLATED + FUTURES + SUB-ACCOUNTS).
* `=BINANCE("account", "spot")` Display assets summary for SPOT wallet.
* `=BINANCE("account", "lending")` Display assets summary for LENDING (Flexible Earn) wallet.
* `=BINANCE("account", "earn")` Display assets summary for EARN (flexible+locked) wallet.
**NOTE:** Just 100 items from flexible and 100 from locked. This needs to be improved by adding pagination support when calling Binance API.
* `=BINANCE("account", "cross")` Display assets summary for CROSS MARGIN wallet.
* If you don't use this wallet (0 assets there), you should disable it from "Binance->Wallets" main menu.
* `=BINANCE("account", "isolated")` Display assets summary for ISOLATED MARGIN wallet.
Expand Down
2 changes: 1 addition & 1 deletion config.gs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const USE_PROXY = false;

// Other settings
let DEBUG = false; // If enabled, will output more logs to the AppScript console
const VERSION = "v0.5.5";
const VERSION = "v0.6.0";
const REPO_URL = "https://github.com/diegomanuel/binance-to-google-sheets";
const SPOT_API_URL = "https://api.binance.com";
const FUTURES_API_URL = "https://fapi.binance.com";
Expand Down
63 changes: 48 additions & 15 deletions misc/wallet.gs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@
function BinWallet(OPTIONS) {
OPTIONS = OPTIONS || {}; // Init options
const WALLET_PROP_NAME = "BIN_ACCOUNT_WALLET";
const utils = BinUtils();

return {
isEnabled,
getAssets,
getSpotAssets,
getLendingAssets,
getEarnAssets,
getCrossAssets,
getIsolatedAssets,
getFuturesAssets,
getDeliveryAssets,
getSubAccountAssets,
setSpotAssets,
setLendingAssets,
setEarnAssets,
setCrossAssets,
setIsolatedAssets,
setFuturesAssets,
Expand All @@ -25,7 +26,8 @@ function BinWallet(OPTIONS) {
getIsolatedPairs,
setIsolatedPairs,
parseSpotAsset,
parseLendingAsset,
parseEarnFlexibleAsset,
parseEarnLockedAsset,
parseCrossMarginAsset,
parseIsolatedMarginAsset,
parseFuturesAsset,
Expand All @@ -52,10 +54,10 @@ function BinWallet(OPTIONS) {
}

/**
* Returns the account wallet assets for LENDING (flexible earn)
* Returns the account wallet assets for EARN (flexible+locked)
*/
function getLendingAssets(symbol) {
return getAssets("lending", symbol);
function getEarnAssets(symbol) {
return getAssets("earn", symbol);
}

/**
Expand Down Expand Up @@ -107,10 +109,10 @@ function BinWallet(OPTIONS) {
}

/**
* Sets account wallet data for LENDING (flexible earn)
* Sets account wallet data for EARN (flexible+locked)
*/
function setLendingAssets(data) {
return setAssetsData("lending", data);
function setEarnAssets(data) {
return setAssetsData("earn", data);
}

/**
Expand Down Expand Up @@ -195,9 +197,34 @@ function BinWallet(OPTIONS) {
};
}

function parseLendingAsset(asset) {
function parseEarnFlexibleAsset(asset) {
const amount = parseFloat(asset.totalAmount);
const totalRewards = parseFloat(asset.cumulativeTotalRewards);
const apr = parseFloat(asset.latestAnnualPercentageRate);
return {
symbol: asset.asset,
free: 0,
locked: amount,
borrowed: 0,
interest: 0,
total: amount,
net: amount,
netBTC: 0, // Missing!
totalRewards,
apr,
type: "flexible",
duration: "-",
accrue: "-",
autoSubscribe: utils.parseBool(asset.autoSubscribe) ? "yes" : "no"
};
}

function parseEarnLockedAsset(asset) {
const amount = parseFloat(asset.amount);
const netBTC = parseFloat(asset.amountInBTC);
const totalRewards = parseFloat(asset.rewardAmt);
const apr = parseFloat(asset.apy);
const duration = parseFloat(asset.duration);
const accrue = parseFloat(asset.accrualDays);
return {
symbol: asset.asset,
free: 0,
Expand All @@ -206,7 +233,13 @@ function BinWallet(OPTIONS) {
interest: 0,
total: amount,
net: amount,
netBTC: netBTC
netBTC: 0, // Missing!
totalRewards,
apr,
type: "locked",
duration,
accrue,
autoSubscribe: utils.parseBool(asset.autoSubscribe) ? "yes" : "no"
};
}

Expand Down Expand Up @@ -320,9 +353,9 @@ function BinWallet(OPTIONS) {
totals = Object.keys(spot).reduce(function(acc, symbol) {
return _accAssetHelper(acc, symbol, spot[symbol]);
}, totals);
const lending = getLendingAssets();
totals = Object.keys(lending).reduce(function(acc, symbol) {
return _accAssetHelper(acc, "LEND"+symbol, lending[symbol]);
const earn = getEarnAssets();
totals = Object.keys(earn).reduce(function(acc, symbol) {
return _accAssetHelper(acc, "EARN"+symbol, earn[symbol]);
}, totals);
if (isEnabled("cross")) {
const cross = getCrossAssets();
Expand Down
76 changes: 56 additions & 20 deletions tasks/do-account-info.gs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ function BinDoAccountInfo() {
const bw = BinWallet();

run("spot", opts);
run("lending", opts);
if (bw.isEnabled("earn")) {
run("earn", opts);
}
if (bw.isEnabled("cross")) {
run("cross", opts);
}
Expand Down Expand Up @@ -83,8 +85,8 @@ function BinDoAccountInfo() {

function execute(type, options) {
Logger.log("[BinDoAccountInfo]["+type.toUpperCase()+"] Running..");
const wallet_type = type === "futures/positions" ? "futures" : type;
if (!BinWallet().isEnabled(wallet_type)) { // The "overview" case will always be true

if (!BinWallet().isEnabled(_walletMainType(type))) { // The "overview" case will always be true
Logger.log("[BinDoAccountInfo]["+type.toUpperCase()+"] The wallet is disabled!");
return [["The "+type.toUpperCase()+" wallet is disabled! Enable it from 'Binance->Wallets' main menu."]];
}
Expand All @@ -109,25 +111,28 @@ function BinDoAccountInfo() {
refresh();
return; // We don't return any data here!
}
const wallet_type = type === "futures/positions" ? "futures" : type;
if (!BinWallet().isEnabled(wallet_type)) { // The wallet is disabled..
if (!BinWallet().isEnabled(_walletMainType(type))) { // The wallet is disabled..
return; // ..so we don't return any data here!
}

const br = new BinRequest(opts);
if (type === "spot") {
return br.get("api/v3/account", "", "");
}
if (type === "lending") {
return br.get("sapi/v1/lending/union/account", "", "");
if (_walletMainType(type) === "earn") {
return {
// @TODO: This will only get 100 items... I'd need to add pagination support
flexible: br.get("sapi/v1/simple-earn/flexible/position", "size=100", ""),
locked: br.get("sapi/v1/simple-earn/locked/position", "size=100", "")
};
}
if (type === "cross") {
return br.get("sapi/v1/margin/account", "", "");
}
if (type === "isolated") {
return br.get("sapi/v1/margin/isolated/account", "", "");
}
if (type === "futures" || type === "futures/positions") {
if (_walletMainType(type) === "futures") {
const options = Object.assign({futures: true}, opts);
return new BinRequest(options).get("fapi/v2/account", "", "");
}
Expand All @@ -154,16 +159,15 @@ function BinDoAccountInfo() {
if (type === "overview") {
return parseOverview(show_headers);
}
const wallet_type = type === "futures/positions" ? "futures" : type;
if (!BinWallet().isEnabled(wallet_type)) { // The wallet is disabled..
if (!BinWallet().isEnabled(_walletMainType(type))) { // The wallet is disabled..
return []; // ..so we return empty data here!
}

if (type === "spot") {
return parseSpot(data, show_headers);
}
if (type === "lending") {
return parseLending(data, show_headers);
if (_walletMainType(type) === "earn") {
return parseEarn(data, show_headers);
}
if (type === "cross") {
return parseCrossMargin(data, show_headers);
Expand Down Expand Up @@ -233,28 +237,50 @@ function BinDoAccountInfo() {
return [...general, ...sorted];
}

function parseLending(data, show_headers) {
function parseEarn(data, show_headers) {
const wallet = BinWallet();
const header = ["Asset", "Amount", "Amount BTC"];
const header = ["Asset", "Amount", "Total Rewards", "APR", "Type", "Duration Days", "Accrue Days", "Auto-Subscribe"];

const assets = [];
const balances = (data.positionAmountVos || []).reduce(function(rows, a) {
const asset = wallet.parseLendingAsset(a);
const flexible_balances = (data.flexible.rows || []).reduce(function(rows, a) {
const asset = wallet.parseEarnFlexibleAsset(a);
if (asset.total > 0) { // Only return assets with balance
assets.push(asset);
rows.push([
asset.symbol,
asset.total,
asset.totalRewards,
asset.apr,
asset.type,
asset.duration,
asset.accrue,
asset.autoSubscribe
]);
}
return rows;
}, []);
const locked_balances = (data.locked.rows || []).reduce(function(rows, a) {
const asset = wallet.parseEarnLockedAsset(a);
if (asset.total > 0) { // Only return assets with balance
assets.push(asset);
rows.push([
asset.symbol,
asset.net,
asset.netBTC
asset.total,
asset.totalRewards,
asset.apr,
asset.type,
asset.duration,
asset.accrue,
asset.autoSubscribe
]);
}
return rows;
}, []);

// Save assets to wallet
wallet.setLendingAssets(assets);
wallet.setEarnAssets(assets);

const sorted = BinUtils().sortResults(balances);
const sorted = BinUtils().sortResults([...flexible_balances, ...locked_balances]);
return show_headers ? [header, ...sorted] : sorted;
}

Expand Down Expand Up @@ -463,6 +489,16 @@ function BinDoAccountInfo() {
return [...general, ...balances];
}

function _walletMainType(type) {
if (type === "futures/positions") {
return "futures";
}
if (type === "earn/simple") {
return "earn";
}
return type;
}

// Return just what's needed from outside!
return {
tag,
Expand Down
8 changes: 8 additions & 0 deletions ui/menu.gs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function BinMenu(ui) {
const disabled = BinSetup().getDisabledWallets();
const walletEnabled = (type) => disabled[type] ? "Enable" : "Disable";
return ui.createMenu("Wallets")
.addItem(walletEnabled("earn")+" EARN Wallet", "toggleWalletEarn")
.addItem(walletEnabled("cross")+" CROSS Margin Wallet", "toggleWalletCross")
.addItem(walletEnabled("isolated")+" ISOLATED Margin Wallet", "toggleWalletIsolated")
.addItem(walletEnabled("futures")+" FUTURES USD-M Wallet", "toggleWalletFutures")
Expand Down Expand Up @@ -140,6 +141,13 @@ function showAPILastUpdate() {
ui.alert("Binance API last call", formatted, ui.ButtonSet.OK);
}

/**
* Displays a confirmation to enable/disable EARN wallet
*/
function toggleWalletEarn() {
BinSetup().toggleWalletDisabled("earn", SpreadsheetApp.getUi());
}

/**
* Displays a confirmation to enable/disable CROSS wallet
*/
Expand Down

0 comments on commit 55073ec

Please sign in to comment.