In Search of Yield in Imaginary Internet Money

Intro to the Bitcoin cash-and-carry trade

Kevin Kuo (RStudio, Kasa AI)

While most of the content on this blog has focused on the liabilities side of the balance sheet of insurers, in this post we take a look at the asset side of things, through a trendy lens!

Of course, none of what follow is financial/investments/trading advice :)

Much wow and Boomercoin

While Dog Money has been popular on TikTok lately and pretty much established itself as an asset class, the OG, Bitcoin, has also captured a respectable share of headlines. Regardless of what you think of cryptocurrencies in general (whether it’s all a massive scam or the future of France), it’s probably worth keeping an eye on as a professional in the insurance industry. While MicroStrategy (MacroStrategy?) and Tesla, which is getting more and more involved with insurance, have been more vocal about Bitcoin, some traditional insurers have quietly added it to their balance sheets1.

Getting that yield

One way to take advantage of an appreciating asset is to simply have it on your balance sheet and watch it go up (relative to your currency of denomination), but sometimes things aren’t up only, and you might end up under water, possibly very deeply so. A casual -30% drawdown isn’t a great look if you’re trying to be a steady, conservative insurer.

How do we incorporate Bitcoin into our asset strategy, then, if we don’t want to be subjected to the wild swings in quarterly investments PnL? If you took a look at a random insurer’s balance sheet, you’d probably that bonds and other fixed income products take up at least half of the assets. Bonds are great from an insurance company’s perspective. For the most part, you know what you’ll be getting, and when you’ll be getting them. The issue with low interest rate environments, like the one we’re in now, though, is that while you still know what you’ll be getting, you know you’re not gonna be getting very much.

What if we could take a trade with Bitcoin that behaves like a bond but with better yield? For portfolio managers at insurers who still feel a bit iffy about crypto, something like this might be a more interesting starting point for discussion.

The most obvious trade

Indeed, I’m talking about the BTC cash-and-carry trade, which is arguably the most popular and important trade in the space2. For the benefit of practitioners who don’t work with investments regularly, and actuaries who took the FM/MFE exams a few too many years ago, let’s take this apart in detail.


A future contract is an agreement to buy or sell a particular asset at some predetermined time in the future. These contracts can be settled via physical delivery or be cash settled. As an example of the former, if you’re long (bought) a contract of live cattle futures on the day it expires, you have to show up at the livestock yard at the preset time with enough trucks to take delivery of your ~30 heads of cattle. Futures for Bitcoin tend to be of the latter type, i.e., instead of exchanging actual Bitcoins with your counterparty, you receive or pay the price difference of BTC at expiration relative to when you entered into the contract.


Bitcoin futures trade on various exchanges and come in different flavors. As a first example, we’ll take a look at Bybit. While one can look up prices on the Web UI, all exchanges offer API access, which we’ll get used to working with now, to enable more systematic data gathering in future posts.

Our first order of business is to grab the identifiers of the futures contracts and their prices from the exchange.

r <- GET("") |> 
futures_symbols <- r$result |> 
  keep(\(x) grepl(r"(BTCUSD.+\d$)", x$alias)) |> 
  sapply(\(x) setNames(x$name, x$alias))
 BTCUSD1231  BTCUSD0924  BTCUSD0625 
futures_prices <- futures_symbols |> 
  lapply(\(x) {
    r <- GET("", query = list(symbol = x)) |> 
  }) |> |> 
  pivot_longer(everything(), values_to = "price")

# A tibble: 3 x 2
  name       price   
  <chr>      <chr>   
1 BTCUSD1231 40180.50
2 BTCUSD0924 39371.00
3 BTCUSD0625 38559.50

Here, the numbers after BTCUSD denote the dates of expiration, so 0625 means June 25th, and 1231 means December 31st.

Let’s next plot the current prices of each contract.

futures_prices |> 
  ggplot(aes(x = as.factor(name), y = price, group = 1)) +
  geom_line() +
  theme_bw() +

We see that the “curve” is upwards sloping, and the fancy finance term for this is contango (its opposite, where the slope is down, is called backwardation). The reasons for this behavior is manifold and we won’t delve into them here, but a reasonable first approximation is that the world wants to be net long BTC, and is willing to pay a premium to do so.

The Trade

Now let’s take a look at the price of Bitcoin. Since Bybit is a purely derivatives exchange, we need to look elsewhere for spot (i.e. actual Bitcoin) prices. Again, arbitrarily picking an exchange for this example, we’ll look at Coinbase:

r <- GET("")
content(r) |> str()
List of 3
 $ bids    :List of 1
  ..$ :List of 3
  .. ..$ : chr "38577.54"
  .. ..$ : chr "0.36569759"
  .. ..$ : int 3
 $ asks    :List of 1
  ..$ :List of 3
  .. ..$ : chr "38577.55"
  .. ..$ : chr "0.03182631"
  .. ..$ : int 2
 $ sequence: num 2.65e+10

This shows that we can buy BTC at a rate of 1 Bitcoin for $38,577.55 United States Dollars. This is, of course, a bit lower than the $40,180.5 we saw earlier for the BTCUSD December 31st futures on Bybit. Even for those of us new to this, we can start go guess what the trade could look like: Buy some BTC from Coinbase, and at the same time sell the 12/31 futures, and we should somehow capture the ~$1,602.95 difference. And, indeed, modulo some logistical details, that’s in fact what we’d execute!

  1. Borrow $\(q_S\).
  2. Buy $\(q_S\) worth of BTC on Coinbase.
  3. Deposit the coins on Bybit, and sell some (specifically, $\(q_F\) worth) of 12/31 BTCUSD futures.
  4. Wait until 12/31 when the futures position expires.
  5. Move the BTC to Coinbase and sell it for USD.

Let’s now calculate how much dough we can make (if any at all!). Since we’ve got a mathematicall inclined readership on this blog, we’ll try to compute the PnL in general. To do that, first some more notation. We’ll denote by \(p_S\) the current spot price of BTC, \(p_F\) the price of the 12/31 futures contract, and \(p_T\) the (as of now unknown) price of Bitcoin on 12/31.

The PnL on the spot purchase is straightforward:

\[ \text{PnL}_{S} = \frac{q_S}{p_S}(p_T - p_S). \] The futures contract, on the other hand, may seem a bit weird for those who are used to traditional finance products. On Bybit, the futures have “inverse” payoff and are “coin margined”. The latter means that you post collateral in BTC and receive/pay PnL in BTC. The inverse bit means the PnL is calculated off percentage moves rather than linearly, in other words, the PnL in BTC is

\[ q_F(\frac{1}{p_T} - \frac{1}{p_F}). \] To get this in dollar terms, we would need to multiply by the BTC/USD exchange rate at expiry, so that

\[ \text{PnL}_F = q_F(\frac{1}{p_T} - \frac{1}{p_F}) \times p_T, \]

and we have the PnL for the trade coming out to be, with a little bit of algebra,

\[ \text{PnL} = \frac{q_S}{p_S}(p_T - p_S) + \frac{q_F}{p_F}(p_F - p_T). \]

Now, if we sell just the right number \(q_F\) of contracts, we can make the \(p_T\) term go away, effectively removing our exposure to BTC price movements. As my calculus instructor from college would say, by inspection, we choose \(q_F = q_S\frac{p_F}{p_S}\), and end up with

\[ \text{PnL} = \frac{q_S}{p_S}(p_F - p_S). \] Hence, we’ve come up with a bond that’s going to pay us a yield of \((p_F - p_S) / p_S\).

This corresponds to an annualized yield of

days_to_maturity <- as.integer(lubridate::as_date("2021-12-31") - lubridate::today())
365 / days_to_maturity * (p_F - p_S) / p_S
[1] 0.07659722

How does 7.66% stack up with the junk bonds held by your company?


OK, so what’s the catch?

The biggest issue is probably actually convincing the asset management team that this isn’t a scam, and working through regulatory considerations, e.g., after taking into account risk capital required to put on the trade, is the net yield still reasonable?

On the trade itself, the three main considerations are mark-to-market risk, exchange counterparty risk, and execution risk.

While we know that, on 12/31, the futures price is going to be about equal to the spot price, the market could move against us between now and then. The basis, or spread between futures and spot, is currently $1,602.95, but it could widen to, say, $3,000 or more, before they converge on expiration. Depending on how risk management parameters are set up, this could be problematic.

When you deposit your Bitcoin on an exchange, there is always a chance, however small, that it randomly shuts down and you never see your coins again. To mitigate this, you could spread your trade out on several exchanges, and also utilize leverage so that you don’t have to deposit the full amount of the trade. If leverage is employed, you’ll have to keep an eye on the margin requirements in case the futures trade goes against you, and post additional collateral lest you get liquidated, or be forced to close your position.

Finally, another consideration is that of execution risk. If we’re putting a $10,000 trade on, the market impact is minimal. However, if we’re instead doing $10 million, slippage can start becoming an issue if we’re not careful. If we’re holding the position until the literal second of expiration, we’ll also need to be mindful of the futures contract settlement mechanism, which differs from exchange to exchange, but all involve taking some sort of time weighted average of the prices for a period of time before expiration.

Down the Rabbit Hole

In this post, we provide a gentle intro to crypto via the BTC cash-and-carry trade. In future posts, we’ll look into other venues that could potentially be incorporated into an investment strategy, and explore how more advanced analytics can be utilized to analyze risk.

Also, if you’re a crypto enthusiast working in insurance and have thoughts to share, please reach out!