I put off automating my rebalancing for a long time because the manual version felt fine. Once a quarter I would open a spreadsheet, eyeball how far each position had drifted from where I wanted it, and place a handful of orders. It worked until the day I did the arithmetic on how much I was actually spending in fees to correct drift that would have corrected itself in a week anyway. That is the real reason to automate this, and it is not the reason most people give. Automation is not about saving the twenty minutes. It is about forcing yourself to write down the rule for when a rebalance is worth executing, so a script can refuse to trade when it is not.
The four things a rebalancer actually computes
Strip away the framing and a rebalancer does four things in order, and each one is a place where naive implementations quietly lose money.
First it reads your current holdings and prices them into a single currency, usually your quote asset. This is the boring part, and it is where most bugs live. If you hold the same asset across a spot balance, a staked position, and an open order that is partially filled, and your code only sums the free spot balance, your drift numbers are wrong before you have computed anything. Read everything, including funds locked in resting orders.
Second it computes drift. For each asset, drift is the current weight minus the target weight. If your target for an asset is thirty percent and it now sits at thirty seven, that position is seven percentage points overweight and something else is correspondingly underweight. Weights have to sum to one hundred, which sounds obvious until a coin you forgot about shows up in the balance and quietly steals a few percent of the denominator.
Third it turns drift into a trade list. The instinct is to sell everything overweight down to target and buy everything underweight up to target, but that generates more trades than you need. The minimal version nets the flows: the total dollar amount you need to sell equals the total you need to buy, so you can often route the proceeds of one oversized position directly into the underweight ones without touching positions that are only slightly off.
Fourth, and this is the step almost nobody automates properly, it decides whether to execute at all. More on that below, because it is the whole game.
Threshold or calendar, and why I run both
There are two ways to trigger a rebalance and people treat them like a religious choice. Calendar-based means you rebalance on a fixed schedule, say the first of every quarter, regardless of drift. Threshold-based means you rebalance whenever any position drifts past a band, say five percentage points off target, regardless of the date.
Calendar is predictable and easy to reason about, but it trades on days when nothing has moved and ignores drift that blows out in the middle of a period. Threshold responds to actual movement, but in a choppy market it can fire constantly, and every fire costs you fees and, in a taxable account, a realized gain.
What has worked better for me is a combination. Check drift on a schedule, say daily or weekly, but only actually trade if a threshold is breached. The calendar is just how often you look. The threshold is the thing that decides whether looking turns into trading. That way you are never trading on a quiet day, and you are never blind to a position that quietly doubled three weeks into the quarter.
A reasonable default band is roughly five percentage points absolute, or you can scale it to the size of the target so small positions get a wider relative band. The right number depends on your fee structure and how much drift you can stomach, which is exactly what the next section is about.
The arithmetic that decides whether to trade
Here is the part that turns a rebalancer from a toy into something worth running. Before you place a single order, compare the cost of trading against the benefit of being back on target.
The cost side has two components on most exchanges. There is the explicit fee, some fraction of notional per trade, typically a fraction of a percent for a taker order. And there is the tax cost if the account is taxable, because selling an appreciated position realizes a gain you now owe tax on. That second cost is often far larger than the fee and it is the one people leave out of their scripts entirely. A rebalance that saves you a few basis points of tracking error while realizing a large short-term gain is a bad trade, and your code should be able to see that.
The benefit side is fuzzier. Rebalancing does not reliably increase returns. Its honest job is risk control, keeping you from waking up ninety percent in one asset because it ran. So the question is not "will this make money" but "is my current drift large enough that correcting it is worth the certain cost of correcting it." If a position is one percentage point overweight, the answer is almost always no. Leave it. It will drift back or it will breach the band later and you will handle it then.
A rule of thumb I use: skip any single leg of the rebalance whose trade value is smaller than some multiple, say fifty to a hundred times, of the fee that leg would cost. Below that ratio you are spending real money to correct noise.
The failure modes that actually bite
The wiring is easy. The edge cases are where automated rebalancers go wrong, so here is the checklist I wish I had started with.
- Minimum order sizes. Every exchange has a minimum notional and a minimum quantity per order. Your netted trade list will regularly produce a leg below the minimum, and if you do not filter those out the whole batch can fail or, worse, partially fill and leave you unbalanced in a new direction.
- Lot size and precision. Exchanges round quantities to a step size. Compute the exact amount, then round down to the allowed increment, or your order gets rejected for invalid quantity. Rounding down also means you will never fully close the gap, which is fine. Aim for close, not exact.
- Stale prices. If you compute drift from a cached price and place a market order a few seconds later, the fill can land somewhere else. For volatile assets, price the portfolio and place orders in the same tight window, and treat the resulting weights as approximate.
- Slippage on the big leg. The largest correction is usually one oversized position being trimmed. That single order can move the book if the asset is thin. Split it, or use limit orders and accept that some legs may not fully fill this cycle.
- Fee currency drift. If your fees are paid in a native exchange token, that balance itself drifts and can even show up as a position. Decide whether it is part of the portfolio or overhead, and be consistent.
The safest way to ship this is to run it in dry-run mode first. Have the script compute the full trade list, apply the minimums and rounding and the worth-it test, and then print exactly what it would do without sending anything. Watch it for a few cycles. You will find at least one assumption about your own balances that was wrong, and you would much rather find it in a log line than in a filled order.
If you would rather not wire up raw exchange endpoints for the read-and-price step, a platform that already normalizes balances and routing across many venues saves you the tedious part. That is a chunk of what we built Blockcircle to handle, since non-custodial execution across a lot of exchanges is most of the plumbing. But the logic that matters, the drift band and the worth-it test, is yours to define and it is the part worth getting right regardless of what places the orders.