Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client/mm: CEX balance tracking and auto-rebalancing #2568

Merged
merged 9 commits into from
Dec 2, 2023

Conversation

martonp
Copy link
Collaborator

@martonp martonp commented Oct 13, 2023

    multi: Return TxID from Send and add TransactionConfirmations
    
    Send and Withdraw are updated to return a transaction ID. Also,
    a TransactionConfirmations function is added to the wallet interface
    which allows callers to determine the amount of confirmations a wallet
    transaction has.
    client/mm/libxc: Add deposit/withdraw functionality to CEX interface
    
    - Deposit and Withdraw functionality is added to the CEX interface
    and is implemented in Binance.
    - The CEX interface is updated to take uint32 assetIDs instead of strings
    to represent assets.
    - The "weth.polygon" and "wbtc.polygon" assets are renamed to be
    "eth.polygon" and "btc.polygon". This makes it clear that "btc" and
    "btc.polygon" are the same asset, just on different networks.
    client/mm: Tracking of CEX balances
    
    Tracking of CEX balances for each bot is implemented in a similar fashion
    to tracking bot balances on the DEX. A `wrappedCEX` is created for each
    bot which behaves as if the entire balance of the CEX is the amount that
    is allocated for each bot.
    client/mm: Simple arb bot auto-rebalancing
    
    This implements auto-rebalancing in the simple arbitrage strategy. This is
    an optional functionality that allows the user to specify a minimum
    balance of each asset that should be on both the DEX and the CEX. If the
    balance dips below this amount, then either a deposit or withdrawal will
    be done to make the balances equal.

Comment on lines 131 to 132
ticker := time.NewTicker(time.Second * 20)
giveUp := time.NewTimer(time.Minute * 10)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed deferring Stop() for both tickers.

Comment on lines 256 to 261

w.tradesMtx.Lock()
defer w.tradesMtx.Unlock()

w.subscriptionIDMtx.RLock()
defer w.subscriptionIDMtx.RUnlock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd want to avoid nested locks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subscriptionID could be atomic actually.. but what's wrong with locking two things at once?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing really wrong since they are protecting different data. But might lead to unexpected issues, I think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it could cause a deadlock if in another location the locks are acquired in the reverse order.

client/mm/libxc/binance.go Outdated Show resolved Hide resolved
client/asset/btc/btc.go Show resolved Hide resolved
client/mm/mm_simple_arb.go Outdated Show resolved Hide resolved
client/asset/interface.go Outdated Show resolved Hide resolved
@@ -63,6 +74,10 @@ func (c *BotConfig) requiresPriceOracle() bool {
return false
}

func (c *BotConfig) requiresCEX() bool {
return c.SimpleArbConfig != nil || c.MMWithCEXConfig != nil
Copy link
Member

@buck54321 buck54321 Oct 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just make BotCEXCfg a field of, or embedded in, SimpleArbConfig and MMWithCEXConfig?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it like this because the strategy doesn't need to know anything about the CEX it's trading on. Creating the CEXes and allocating the balances is the purview of the level above the strategies. I was kind of split on this, thought it could go either way.

client/mm/libxc/binance.go Outdated Show resolved Hide resolved
client/mm/libxc/binance.go Outdated Show resolved Hide resolved
@@ -550,6 +633,56 @@ func (m *MarketMaker) botBalance(botID string, assetID uint32) uint64 {
return 0
}

func (m *MarketMaker) modifyBotCEXBalance(botID string, assetID uint32, amount uint64, increase bool) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delta-based value tracking tends to be fragile. Much better to find an idempotent pattern, such that we track the server's reported balance and pending deposits/withdraws to calculate balance.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server's balance doesn't really tell us much because the balance of the CEX will be split between multiple bots. Also, not just deposits/withdrawals change the balance, but also trades. Maybe a better pattern would be to keep track of each of the actions which changed the balance and how much it changed it by. Then we could definitely avoid any double counting. Is this kind of what you're suggesting?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave it up to you. Just wanted to point out the scary pattern.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably right, I'll think of something. The balance management for the DEX should be updated then too.

dex/bip-id.go Outdated Show resolved Hide resolved
client/core/core.go Outdated Show resolved Hide resolved
client/mm/config.go Outdated Show resolved Hide resolved
client/asset/btc/btc.go Show resolved Hide resolved
client/asset/interface.go Outdated Show resolved Hide resolved
client/core/core.go Outdated Show resolved Hide resolved
client/mm/libxc/binance.go Outdated Show resolved Hide resolved
client/mm/libxc/binance.go Outdated Show resolved Hide resolved
client/mm/wrapped_cex.go Outdated Show resolved Hide resolved
// Assign to balance to the bot as long as the wallet
// knows about the transaction.
w.mm.modifyBotBalance(w.botID, []*balanceMod{{balanceModIncrease, assetID, balTypeAvailable, withdrawnAmt}})
onConfirm()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed to exist from the point of view of our node but not confirmed really if 0 confs. Should this wait for some amount of confs?

}

if !trade.sell && calc.BaseToQuote(trade.rate, trade.qty) > trade.quoteFilled {
unfilledQty := calc.BaseToQuote(trade.rate, trade.qty) - trade.quoteFilled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this trade have been completed at different rates? If taker maybe some quote was taken at a better rate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original reserved amount was calc.BaseToQuote(trade.rate, trade.qty). The amount of quote that was used is trade.quoteFilled. quoteFilled is the amount of quote that was used to buy the base in this trade, regardless of what the rate was.

martonp and others added 7 commits November 26, 2023 19:35
Send and Withdraw are updated to return a transaction ID. Also,
a TransactionConfirmations function is added to the wallet interface
which allows callers to determine the amount of confirmations a wallet
transaction has.
- Deposit and Withdraw functionality is added to the CEX interface
and is implemented in Binance.
- The CEX interface is updated to take uint32 assetIDs instead of strings
to represent assets.
- The "weth.polygon" and "wbtc.polygon" assets are renamed to be
"eth.polygon" and "btc.polygon". This makes it clear that "btc" and
"btc.polygon" are the same asset, just on different networks.
Tracking of CEX balances for each bot is implemented in a similar fashion
to tracking bot balances on the DEX. A `wrappedCEX` is created for each
bot which behaves as if the entire balance of the CEX is the amount that
is allocated for each bot.
This implements auto-rebalancing in the simple arbitrage strategy. This is
an optional functionality that allows the user to specify a minimum
balance of each asset that should be on both the DEX and the CEX. If the
balance dips below this amount, then either a deposit or withdrawal will
be done to have an equal amount of the asset on both exchanges.
@martonp martonp force-pushed the cexRebalance branch 2 times, most recently from b96b239 to 6d22e0c Compare November 27, 2023 03:34
Copy link
Member

@buck54321 buck54321 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review. I'll get back into this tomorrow.

I'll just drop this diff here. buck54321/dcrdex@996b2a6...buck54321:dcrdex:cexbalances. Do with it what you will.

client/mm/libxc/binance.go Outdated Show resolved Hide resolved
client/mm/libxc/binance.go Show resolved Hide resolved
client/mm/libxc/binance.go Show resolved Hide resolved
client/mm/libxc/interface.go Outdated Show resolved Hide resolved
client/mm/libxc/interface.go Outdated Show resolved Hide resolved
Comment on lines 47 to 50
MinBaseAmt uint64 `json:"minBaseAmt"`
MinBaseTransfer uint64 `json:"minBaseTransfer"`
MinQuoteAmt uint64 `json:"minQuoteAmt"`
MinQuoteTransfer uint64 `json:"minQuoteTransfer"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like none of these should need to be manually set. We should know when to trigger an auto-rebalance based on lot size and bot setttings. Min transfers too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some people would want to be more aggressive with rebalancing and some people less. If someone allocates 4 lots on both sides of a market for simple arb, when should this be rebalanced? For Arb+mm, if there are a few matches in one direction, and there's not enough balance for all the placements on one side of the market, maybe someone would want to rebalance ASAP, while others would want to give it some time because the market may move in the other direction. I don't think there's a one size fits all.

client/mm/wrapped_cex.go Outdated Show resolved Hide resolved
client/mm/wrapped_cex.go Outdated Show resolved Hide resolved
client/asset/interface.go Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arb+mm doesn't get auto-rebalance?

Copy link
Member

@buck54321 buck54321 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not going to add anything to this now. I know you were looking at some refactoring of the balance tracking anyway. If you can just address outstanding comments, we'll get this in.

@martonp
Copy link
Collaborator Author

martonp commented Dec 1, 2023

@buck54321 I've made the changes. Adding rebalancing to mm+arb required some new logic, so that could still use a review.

@buck54321 buck54321 merged commit f9289bd into decred:master Dec 2, 2023
5 checks passed
@martonp martonp deleted the cexRebalance branch January 20, 2024 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants