Skip to content

Example Portfolio Management

Alfred Holmes edited this page Mar 18, 2021 · 1 revision

This is an example of how to set up automatic spot account balancing with the BinanceBot framework. In this guide we set up a simple script that connects to the binance websockets API to track the prices of various currencies and trades when the portfolio is sufficiently different from the target portfolio. The final script can be found at examples/rebalance.py

  1. Import the required files - in this script we will use the OrderBookManager and SpotAccount classes also make sure you've set up the keys.py file as described above. We import sys so that the script can be saved in the examples folder and executed from the root of the cloned repository. We'll also need asyncio to manage the asynchronous tasks. So we'll add the following to examples/rebalance_tutorial.py
import sys
sys.path.append("./")
import keys
from binancebots.accounts import SpotAccount
import asyncio
  1. For the main loop we need to get the current account balances, so we'll create a SpotAccount instance to track the account balances and prices. Let's implement this first. We'll write a simple main function and call it with asyncio in the standard way.
async def main():
	acc = account(keys.API, keys.SECRET)

	await acc.get_account_data()
	print(acc.spot_balances)

	await acc.close()

if __name__ == '__main__':
	asyncio.run(main())	

if we run the script you will see a print out of your spot account balance. SpotAccount does not track 0 balances so if you have not deposited to Binance you will get an empty dictionary. The function SpotAccount.get_account_data pulls the available spot market meta-data from the Binance API and gets the current account information, which contains the account balances.

$ python3 examples/rebalance_tutorial.py
{'USDT': 120.30743}
  1. Now we'll call the SpotAccount.weighted_portfolio function to get the relative values of the portfolio and decide if the portfolio is far enough away from the desired portfolio to bother rebalancing: we'll say that a portfolio needs rebalancing if at least 10% of the portfolio is in the wrong asset. Before calling the SpotAccount.weighted_portfolio we need to use the websocket API to listen to the relevant orderbooks so that the bot can access real time market data. The new main function looks like this.
async def main():
	acc = SpotAccount(keys.API, keys.SECRET)
	await acc.get_account_data()

	weighted_portfolio = await acc.weighted_portfolio(['USDT', 'BTC', 'ETH'])
	print(weighted_portfolio)

	await acc.close()

and running this gives the following output

$ python3 examples/rebalance_tutorial.py
{'USDT': 1.0, 'BTC': 0.0, 'ETH': 0.0}
  1. Next we'll construct a target portfolio and get the account to trade into that portfolio using the SpotAccount.trade_to_portfoliofunction, altering the main function to
async def main():
	acc = SpotAccount(keys.API, keys.SECRET)
	await acc.get_account_data()


	await acc.trade_to_portfolio({'BTC': 0.3333333333333333, 'ETH': 0.3333333333333333, 'USDT': 0.3333333333333333})

	weighted = await acc.weighted_portfolio()
	print(weighted)

	await acc.close()

and running gives

$ python3 examples/rebalance_tutorial.py
{'BTC': 0.33337537473449314, 'ETH': 0.3330803484495062, 'USDT': 0.3335442768160007}

so the portfolio has been altered.

  1. Now we have got the trading working, all that is left to do is to check whether or not to balance the portfolio when the program is run. If we don't add this in, then whenever the program runs it will attempt to balance the portfolio, but it is likely that the trades will be below the minimum (around $10) trade volume allowed by Binance and so won't be executed. With small account balances, this may also be true even with the minimum threshold.

We'll make a final change to the main function

async def main():
	acc = SpotAccount(keys.API, keys.SECRET)
	await acc.get_account_data()

	target_portfolio = {'BTC': 0.3333333333333333, 'ETH': 0.3333333333333333, 'USDT': 0.3333333333333333}


	weighted = await acc.weighted_portfolio(target_portfolio)
	print('Initial portfolio: ', weighted)

	diff = sum([abs(target_portfolio[s] - weighted[s]) for s in target_portfolio])

	if diff > 0.1:
		print('Performing rebalance')
		await acc.trade_to_portfolio(target_portfolio)
	else:
		print('Portfolio difference of ', diff, 'too low to trade')
	

	weighted = await acc.weighted_portfolio()
	print('Final portfolio: ', weighted)

	await acc.close()

and so running gives

$ python3 examples/rebalance.py
Current portfolio:  {'ETH': 0.3341554385631097, 'USDT': 0.33259670426848686, 'BTC': 0.3332478571684033}
Portfolio difference of  0.0016442104595528195 too low to trade
{'BTC': 0.3332478571684033, 'ETH': 0.3341554385631097, 'USDT': 0.33259670426848686}

Clone this wiki locally