You’re together on a Friday night with friends and a lively conversation about Bitcoin takes place. One person shrugs off Bitcoin saying, “Bitcoin has no intrinsic value and is going to zero.” Another immediately chimes, “Bitcoin is going to replace all fiat currency and it will be worth a million dollars within a few years.” Sides are quickly chosen and you’re left wondering, “What is the fair value of Bitcoin anyway?” You do a quick internet search and find yourself reading this blog post.

In less than 10 minutes, I will walk you through a quick and easy way to estimate the fair value of Bitcoin. It’s not perfect and I anticipate performing additional analyses in the future. But it’s a good starting point for rationally valuing Bitcoin.


Bitcoin is a software protocol (set of rules) to store and transfer value over the internet through a decentralized network of nodes running the software. It requires no trust between parties, no central authority to regulate it, and is limited in supply. Value is stored in the possession of private keys, and value can be transferred to anyone, anywhere instantaneously. Nodes on the network validate transactions and “miners” are economically incentivized to group transactions into blocks. Each block is cryptographically linked to the previous block forming a chain – hence the term “blockchain”. Blocks are difficult to create and transactions become effectively immutable after an hour.

Bitcoin is an open source project and anyone can contribute code. Anyone can run a full node and mine blocks, although the latter requires a large investment in specialized equipment to do it profitably. January 3, 2009 marked the creation of the first block and a new block has been created every 10 minutes, on average, since then.

To learn more visit Wikipedia. Watch YouTube videos from Andreas Antonopoulos, a leading Bitcoin expert, to gain a deeper understanding. And if you want to gain a technical understanding of Bitcoin, read his Book, Mastering Bitcoin: Programming the Open Blockchain.

What is fair value?

Fair value is best viewed as the rational price where unemotional and indifferent buyers and sellers agree to exchange goods and services. Said differently, fair value is the market value without the volatility associated with emotion and temporary demand/ supply imbalances. Fair value is not intrinsic value as nothing has intrinsic value. All value comes from the utility derived by the persons controlling the assets after the exchange.

Fair value is not market value even though people often use the terms interchangeably. Market value is the clearing price(s) where willing buyers and sellers are balanced. Market value is governed by the Law of Supply and Demand. If buyers outnumber sellers, prices rise so more sellers enter the market and buyers leave. On the other hand, if sellers outnumber buyers, prices fall so more buyers enter the market and sellers leave. Market prices can swing wildly when the balance between buyers and sellers becomes unstable. This happened during the 2008 financial crises and during 2013 and 2017 with Bitcoin.

What is the fair value of Bitcoin?

My approach is to value Bitcoin as a network using Metcalfe’s law. According to Wikipedia, Metcalfe’s law states:

“The value of a telecommunications network is proportional to the square of the number of connected users of the system (\(n^2\))”.

He and others also proposed models using \(nlog(n)\) proportionality rather than \(n^2\). I will limit my analysis to the \(n^2\) version.

My motivation for using this approach comes from fundamentally viewing Bitcoin as a network of participants using its native utility to store and transfer value to each other.

\(n\) represents the number of users and is unknown in the case of Bitcoin. What is known is the number of unspent transaction outputs (UXTO). The UXTO is the collection of Bitcoin addresses that can be spent in a future input transaction. There is an unknown relationship between the UXTO and the number of Bitcoin users with the minimum relationship being 1:1, if every Bitcoin owner had one and only one UXTO. The UXTO is analogous to individual coins, of arbitrary amount, in the physical sense of money, but the number of UXTO a Bitcoin holder likely has is more closely analogous to the number of physical places a person stores traditional money (i.e. wallet/ purse, checking account, savings account, brokerage account, piggy bank, etc.). As such, it would be expected that on average people will have more than one, but not a large number of UXTO. The UXTO is a sufficient proxy for the number of users.

In summary, the market capitalization of Bitcoin will be modeled as a linear function as follows:

\(v = kn^2 + \epsilon\)

\(v\) represents the market capitalization of the Bitcoin network; \(n\) the number of UXTO; and \(k\) the constant (slope) to be estimated. \(\epsilon\) is the difference between Bitcoin’s market capitalization and its fair value implied by the model (\(\epsilon = v - kn^2\)). The estimated fair value at each time step, \(i\), is \(k_i(n^2)_i\), where \(k_i\) is the slope of the best-fitting line using the data from \(t_1, t_2, t_3 ... t_i\) and \((n^2)_i\) is the squared UTXO at time step, \(i\).

Setup and download data

I begin by loading the necessary R packages and creating two helper functions: .fetchseries and .joinseries. The helper functions facilitate extracting the data from the data.frame holding the downloaded data and joining them.


.fetchseries <- function(x, series_name) {
  x %>%
    filter(dataset == series_name) %>%
    select(data) %>%

.joinseries <- function(x_series, y_series, x_name, y_name) {
  # dates don't align -- will interpolate
  #   'uxto' == 1.5 day interval
  #   'market_cap' == 2.0 day interval
  #   'market_price' == 2.0 day interval
  # 'x' value is interpolated at 'y' time.  
  approx(x = x_series$date_time,
         y = x_series$value,
         xout = y_series$date_time) %>%
    as_tibble() %>%
    left_join(x = .,
              y = y_series,
              by = c('x' = 'date_time')) %>%
    rename(!!x_name := y,
           !!y_name := value,
           date_time = x) %>%
} provides charts and downloadable data on Bitcoin. I need three of the datasets they provide. I load the URL paths into a list and download in a single function call.

# download selected datasets
blockchain_data <-  list('uxto' = '',
                         'market_cap' = '',
                         'market_price' = '') %>%
  as_tibble() %>%
  gather(key = 'dataset',
         value = 'url') %>%
  mutate(data = map(.x = url,
                    .f = function(x) read_csv(file = x,
                                              col_names = c('date_time',
                                              col_types = cols(date_time = col_datetime(format = ''),
                                                                value = col_double()))))

# each row contains a dataset
blockchain_data %>% print()
## # A tibble: 3 x 3
##   dataset      url                                          data          
##   <chr>        <chr>                                        <list>        
## 1 uxto <tibble [1,51~
## 2 market_cap <tibble [1,66~
## 3 market_price <tibble [1,66~

Perform linear regressions at each time step, \(i\)

I extract the uxto and market_cap from the downloaded datasets and fit a linear model at each time step, \(i\).

# extract market_cap  and uxto data from downloaded data
# and add calculated fields (n2 = uxto squared):
ls <- list('x_series' = 'market_cap',
           'y_series' = 'uxto')

dat <- map(.x = ls,
           .f = function(x) .fetchseries(blockchain_data, x)) %$%
  .joinseries(x_series, y_series, ls$x_series, ls$y_series) %>%
  mutate(n2 = uxto ^ 2)

# i == time step
i <- seq(1:nrow(dat))

# fit a linear model at each time step and
# return list of fitted linear models
fit_lm <- map(.x = i,
              .f = function(x) {dat %>%
                  filter(row_number() <= x) %>%
                  lm(formula = market_cap ~ n2 + 0,
                     data = .)

# number of models fitted
length(fit_lm) %>% print()
## [1] 1514

Visualize the results

First, I plot how \(k\) evolves over time by extracting the coefficients from each linear model and then scaling and plotting them.

# extract coefficients (k) from model and bind to data
dat <- map_dbl(.x = i,
               .f = function(x) fit_lm[[x]]$coefficients) %>%
  as_tibble() %>%
  rename(k = value) %>%
  bind_cols(dat, .)

# plot k (scaled)
dat %>%
  ggplot(mapping = aes(x = date_time, y = (scale(k) %>% as.vector()))) +
  geom_line() + 
  labs(x = 'Date', y = 'Scaled k') +
  ggtitle(label = 'Scaled k at each time step') +

\(k\) appears stationary, but changes significantly over time as it captures the uncertainty implied in the market swings.

Next, I plot the ratio between Bitcoin market capitalization and its implied fair value.

# extract the fitted value at each time step, i, and bind to data
# the fitted value == fair value implied by model.
dat <- map_dbl(.x = i,
               .f = function(x) fit_lm[[x]]$fitted.value[x]) %>%
  as_tibble() %>%
  rename(fair_value = value) %>%
  bind_cols(dat, .) %>%
  mutate(ratio = market_cap / fair_value)

# plot ratio == market_cap / fair_value
dat %>%
  ggplot(mapping = aes(x = date_time)) +
  geom_line(mapping = aes(y = ratio), color = 'black') +
  geom_abline(intercept = 1, slope = 0, color = 'red') +
  labs(x = 'Date', y = 'Market Capitalization to Fair Value Ratio') + 
  ggtitle(label = 'Bitcoin Market Capitalization Relative to Fair Value') +

dat %$%
summary(.$market_cap/ .$fair_value)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.2509  0.7245  0.9183  1.1090  1.2566  4.9256

Bitcoin has been extremely overvalued three times if you believe in the model. The 2017 run-up was less extreme than the run-up at the end of 2013. Also, 2013 was an extremely volatile time as Bitcoin became significantly overvalued twice in that year.

Finally, I plot Bitcoin estimated fair and actual prices.

# extract market_price  and uxto data from downloaded data
# and bind market_price only to data.
# note: need to download uxto because dates down't align.
ls <- list('x_series' = 'market_price',
           'y_series' = 'uxto')

dat <- map(.x = ls,
      .f = function(x) .fetchseries(blockchain_data, x)) %$%
  .joinseries(x_series, y_series, ls$x_series, ls$y_series) %>%
  select(market_price) %>%
  bind_cols(dat, .)

# calculate 'fair_price'
dat <- dat %>%
  mutate(fair_price =  market_price / ratio)

# plot fair and actual prices
dat %>%
  ggplot(mapping = aes(x = date_time)) +
  geom_line(mapping = aes(y = fair_price, color = 'Fair Price')) +
  geom_line(mapping = aes(y = market_price, color = 'Actual Price')) +
  stat_smooth(mapping = aes(y = fair_price, color = 'Fair Price Trend'),
              method = "lm", se = TRUE) +
  scale_y_log10() +
  scale_color_manual('', values = c('Fair Price' = 'blue',
                                    'Actual Price' = 'black',
                                    'Fair Price Trend' = 'dark green')) +
  labs(x = 'Date', y = 'Price (USD) -- Log10 Scale') + 
  ggtitle(label = 'Bitcoin Market Estimated Fair and Actual Prices') +


Bitcoin goes through periods of extreme over-valuations and prolonged under-valuations. As of February 16, 2018, it appears price is converging to fair value and fair value is near the long-term trend line. However, Bitcoin appears to remain significantly over-valued at this time. As of February 16, 2018, the market price was $10,698 and the ‘quick and easy’ estimated fair price is $5,525 making it 93.6% over-valued.

You can now return to the conversation with your friends and share the ideas posted here about estimating the fair value of Bitcoin.