Algorithmic Leveraged Yield-Farming on Alpaca Finance using Python

Vol. 2 of the Crypto Quant series

Harrison Schick
9 min readJan 6, 2023

A Foreword

Welcome back to vol. 2 of the Crypto Quant series where I feature available tools and technologies for novice and experienced developers looking to explore quantitative development in the decentralized finance (DeFi) space.

In this article we will be discussing algorithmic leveraged yield-farming on the Alpaca Finance protocol, using Python as our development language of choice.

What is the Alpaca Finance protocol?

Alpaca Finance — Fair-launch leveraged yield farming protocol on BNB Chain & Fantom

Alpaca Finance is most notorious for being the 1st and largest lending protocol allowing leveraged yield farming on the Binance Smart Chain (BSC). The protocol helps lenders earn safe and stable yields, while offering borrowers undercollateralized loans for leveraged yield farming positions, vastly multiplying their farming principals and resulting profits.‌

The protocol currently has a mouth-watering TVL of $395,571,729, making it the 3rd largest protocol on the Binance Smart Chain (BSC) as of 12/27/2022.

What is “Algorithmic Yield-Farming”?

Before moving on, we need to establish the fact that yield farming is a term used to describe the process of maximizing returns on cryptocurrency investments by actively investing and/or moving funds between different yield-generating protocols or assets. This can involve earning interest on stablecoins, participating in liquidity pools, or providing liquidity to lending protocols. You can read in-depth about yield farming here.

alpacafinance.org/farm

Now, Algorithmic yield farming, also known as “smart yield farming,” is a term used to describe the use of automated algorithms to maximize returns from yield farming strategies on decentralized finance (DeFi) protocols.

Traditionally, investors must manually move their funds between different yield farming assets in order to maximize returns using the protocol’s web-interface. However, those with an expert understanding of the blockchain (or awareness of available tools) can engage in algorithmic yield farming to automate this process by using algorithms to continuously analyze the market and identify the most lucrative yield farming opportunities. These algorithms directly interact with the smart contracts on-chain in response to pre-determined triggers, to then automatically displace funds between protocols or assets in order to optimize returns.

Photo by Markus Spiske

As with any investment, it is important to carefully consider the potential risks and rewards before participating in algorithmic yield farming.

Why Should You Use Leverage?

Leverage can increase yield farming returns on decentralized finance (DeFi) protocols by allowing investors to amplify their potential returns. Leverage refers to the use of borrowed funds in exchange for borrow interest to increase the size of an investment, which can potentially increase the returns on that investment.

In the context of yield farming, leverage can be used to increase the amount of capital available for yield farming, which can potentially increase the returns on that capital. For example, an investor might use leverage (borrowed funds) on Alpaca Finance to increase their capital by 4x, which would allow them to 4x the returns on their yield farming strategy.

However, it’s important to note that leverage also increases the risk of an investment, as it amplifies both potential returns and potential losses. As such, it is important to carefully consider the potential risks and rewards before using leverage in yield farming or any other investment strategy.

Getting Started on Alpaca Finance

We will be using the Automated Vault position type on Alpaca Finance for the sake of our algorithmic leveraged yield-farming example. These are tokenized vaults that run complex DeFi strategies for you, similar to an on-chain hedge fund. If you do not currently own any shares of an automated vault on Alpaca, this section will get you started

Alpaca Finance Dashboard — Automated Vaults

To view the available automated vaults on Alpaca Finance, you can head over to app.alpacafinance.org/vault. Make sure to connect your wallet and switch to the Binance Smart Chain (BNB).

Entering the Vault

Alpaca Finance — BUSD/BTCB 3x Leveraged Savings Automated Vault

The vault being used as an example will be the BUSD/BTCB 3x Leveraged Savings strategized vault. You can enter the vault by purchasing the token (similar to purchasing shares in an ETF). In this case, the vault token is L3X-BUSDBTCB-PCS1.

The savings vault is a long strategy that involves earning higher annual percentage yields (APYs) than traditional lending or staking through the use of high-leverage yield farming. The capital invested is deployed to earn yields in these farming positions, but there is no risk of liquidation due to the simultaneous farming of long and short positions and regular rebalancing to maintain the desired exposure.

Alpaca Finance — Purchase Shares of BTCB Savings (3x) Vault

To invest in this vault, simple click Invest on the dashboard, and supply your desired amount of BTCB to receive vault shares. You will need to approve your BTCB before depositing.

Alpaca Finance — My Position

I’ve acquired ~14.5 shares in the vault for testing purposes. You can view your holdings at https://app.alpacafinance.org/portfolio/vault.

🛠️ Engage in Algorithmic Leveraged Yield-Farming Using Python

Now that we’ve established the basics of Alpaca Finance and the technical topics at hand, we can get to the fun part — algorithmic yield-farming on Alpaca Finance using Python.

For this application we will be using the alpaca-finance package listed on PyPi, an unofficial Python package that wraps Alpaca Finance positions on the Binance Smart Chain. I am the sole developer of this package, inspired by the lack of 3rd party tools to manage DeFi investments. This package allows you to algorithmically engage in the following activities (regarding Automated Vaults on Alpaca Finance) using your own Python environment:

  • Get position metrics such as yields, tvl, capacity, cost basis, pnl, shares, and more.
  • Approve tokens
  • Invest & Withdraw tokens from the vault
  • Close position (completely withdraw from vault)

Setup your Local Environment

In order to use this package, you can use pip for installation. Before installing, please ensure that your environment is using Python version 3.9 or higher, then run the following command in your terminal:

pip install --upgrade alpaca-finance

Create your AutomatedVaultPosition Instance

In order to interact with a vault position, you will need to create a position instance. A position instance requires the following:

  • A public wallet key (the owner of the instance)
  • The position key (should match the key on Alpaca Finance dashboard)
Alpaca Finance — How to Obtain a Position Key

Once you’ve fetched the required parameters, you can created a position instance like so (using our current example vault & my BNB address). As you can see, we’ve provided the position key as the first parameter, and the owner’s wallet address as the second parameter:

from alpaca_finance.automated_vault import AutomatedVaultPosition

position = AutomatedVaultPosition("L3x-BUSDBTCB-PCS1",
"0xC9E6e248928aC18eD6b103653cBcF66d23B743C6")

Gather Position Metrics using Python

We can fetch valuable position metrics for our analytics, using my newly opened position in L3x-BUSDBTCB-PCS1 as an example.

Primary metrics:

# Fetch current yields:
position.yields()

# Returns:
[-2.1640052935125613, -2.140821, 3.8161799588764396, 3.889724]
# 0 - current APR (%) (excluding trading fee)
# 1 - current APY (%) (excluding trading fee)
# 2 - current APR (%)
# 3 - current APY (%)
# Fetch current TVL:
position.tvl()

# Returns:
[731196.1655794256, 2241306.9218222513]
# - TVL in USD (total value locked)
# - TVL in USD Including Debt
# Fetch current pool capacity:
position.capacity()

# Returns:
5000000.0
# Fetch position cost-basis (total entry cost in USD):
position.cost_basis()

# Returns:
9.021791294864768
# - Vault entry cost (in USD)
# Fetch current value of position (in USD)
position.current_value()

# Returns:
9.02163634494947
# - Total current position value (in USD)
# Fetch all-time PnL (in USD)
position.pnl()

# Returns:
-0.036578653150128204
# - Total current position profit/loss (in USD)
# Fetch shares (in USD)
position.shares()

# Returns:
(14538342006362084231, 14.538342006362084, 9.02036537391047)
# 0 - Total shares (in wei)
# 1 - Total shares
# 2 - Total USD value of shares

Other metrics/attributes of the position:

position.owner_address  # Owner's wallet address 
position.owner_key # Owner's private key (if set)
position.key # The vault key
position.name # The vault name
position.address # The vault address
position.vault_type # The vault's strategy type
position.stable_token # The vault's stable token (BEP20Token object)
position.asset_token # The vault's asset token (BEP20Token object)

Invest/Withdraw using Python

The alpaca-finance package offers the required functionality to invest and withdraw from automated vault positions. These functions wrap the smart contract methods on the blockchain to allow you to easily call them in your Python code.

To get started, you will need to set your wallet’s private key in the position class. Your private key is required to sign transactions that modify the state of the blockchain. You can do this using one of two ways:

# 1. Set the private key when you instantiate the position:
position = AutomatedVaultPosition("<your_position_key>",
"<your_wallet_address>",
"<your_private_key>")

# 2. Set your private key in an already existing position instance:
position.owner_key = "<your_private_key>"

Now that you’ve set your private key, we can invest and withdraw from vaults using the following methods:

Invest Stable or Asset Tokens into the Vault:

In order to invest stable or asset token into the vault, we need to determine which token is the stable token, and which is the asset token. To do this, you can use the position’s methods:

position.stable_token.symbol()
position.asset_token.symbol()

# After calling these methods, we discover:
# - Stable Token = BTCB
# - Asset Token = BUSD

With this knowledge, we can invest 10 BUSD into the vault (the asset token) like so:

# Get investment amount (investment amount is in wei)
invest_amt = position.to_wei(10, position.asset_token.decimals())

# Invest the amount into the vault
txn = position.do_invest(asset_token_amt=invest_amt)

Once the transaction has completed, you will receive a TransactionReceipt object. You can view the attributes of this object here.

Withdraw Stable or Asset Tokens from the Vault:

Now that we’ve invested BUSD (asset token) into the vault, we’d like to withdraw some shares to the stable token, BTCB. When withdrawing from the vault using the Python method do_withdraw() you are required to specify an amount of shares, and then specify the percentage of stable token that you’d like to receive. In this case, it’s 1.0 = 100% since we want all of the returned value in the stable token.

# Get the wei amount of shares to withdraw (5)
shares_amt = position.to_wei(5, position.bep20_vault_token.decimals())

# Withdraw the shares in BTCB (Convert All strategy required)
txn = position.do_withdraw(shares_amt, 1.0, strategy="Convert All")

Close Position:

The last transactional method available in the position class is the do_close() method. This method simply calculates your entire position size and withdraws all shares from the position, saving you the effort of calculating this yourself. To close your position, you can use the following method:

# Close the position, and receive all shares in the asset token (0% stable token)
txn = position.do_close(0.0, strategy="Convert All")

💡 Implementation Example

Idea: Now that you’ve learned all of the available methods and metrics in the alpaca-finance package, we want to integrate our own stop-loss algorithm with our newly created position in the Automated Vault, as this is not a feature on the Alpaca Finance dashboard.

Basic Application: Create a bot that will check the PnL of our position continuously. If the loss percentage of our cost-basis falls below a certain threshold, we should exit the position.

from alpaca_finance.automated_vault import AutomatedVaultPosition

# Set up position instance (private key required to sign txns)
position = AutomatedVaultPosition("<your_position_key>",
"<your_wallet_address>",
"<your_private_key>")

# Set stop loss percentage:
loss_pct = -0.05 # = -5%

# Create mainloop:
if __name__ == "__main__":
while True:
entry = position.cost_basis()
current = position.current_value()
pnl_pct = (current - entry) / entry

# If our loss percentage meets/falls below stop-loss, close position
# Receive all funds in the stable token (1.0 = 100%)
if pnl_pct <= loss_pct:
position.do_close(pct_stable=1.0)
break

🎉 Conclusion

Congratulations if you’ve gotten this far! You now know how to:

  • Fetch alpaca-finance automated vault position metrics in your Python projects
  • Invest, Withdraw, and Close automated vault positions using Python

I hope that you’ve found value in this article, and that the alpaca-finance package improves the efficiency and profitability of your algorithmic DeFi systems.

--

--

Harrison Schick

Graduate Student at UT Austin ▪️ Exploring Technical Innovation in TradFi & DeFi ▪️ Find me on GitHub: https://github.com/hschickdevs