Originally published January 5, 2018 @ 9:22 am

The script below makes use of Coinbase API, bash arrays, and gnuplot to generate a basic short-term analysis of bitcoin prices. I will also show you how to run this script in background mode using tmux and send the output to a Web page using seashells.

The bitcoin is difficult to analyze. Is it a currency, a commodity, a speculative asset? It’s all of those things but not entirely. I choose to look at cryptocurrencies as a massively multiplayer online game.

Calling bitcoin value a “bubble” or a “pyramid scheme” is misleading. Cryptocurrencies just don’t fit into our usual financial toolbox and our definitions need some work. In the meantime, it’s every man for himself.

I can’t tell when bitcoin price will change or by how much. Having said that, because there are people involved, every change carries kinetic energy, if you will. A sudden drop in price, for example, causes a panic-driven sell-off that will eventually exhaust its momentum. This second derivative – acceleration and deceleration – is what we can analyze reasonably well.

Here’s a sample script output:

  Spot
   15080.63 ++++-++-+-++-+-++-++-+-++-+-++-++-+-++-+-++-++-+-++-++-+-++*+-++-++-+-++-+-++-++++
            +       +       +       +       +        +       +       + *     +       +       +
            |                                                          *                     |
   15047.66 ++*****                                                    *                    ++
   15037.91 ++*   * **** ****                                          *                    ++
   15027.99 +**   * *  * ******                                        *                    ++
   15018.91 +*    ***  * *  ****                                       *                    ++
   15009.00 +*         * *     *  **                                   *                    ++
   14999.00 +*         ***     ********                                *                   ***
   14991.40 +*                   ** ***                                *                 ***++
   14985.01 +*                        ***                              *                 *  ++
   14969.99 +*                          *      ****                    *         ***    **  ++
   14962.01 +*                          ** *****  *                    *         * *    *   ++
   14952.47 +*                           ******   *** *                *         * ******   ++
   14941.01 +*                           ******   ******               *         *          ++
   14935.03 +*                           ***           *               *         *          ++
   14927.02 +*                           *             **           *******  *****          ++
   14916.02 +*                                          *           *** ***  *              ++
   14904.01 +*                                          ******      ***   * **              ++
   14900.21 +*                                               **     *     ***               ++
            |*                                                *     *                        |
   14880.01 +*                                                **    *                       ++
   14870.21 +*      +       +       +       +        +       + ******+       +       +      ++
   14858.67 +*++-++-+-++-+-++-++-+-++-+-++-++-+-++-+-++-++-+-++**+*+-++-+-++-++-+-++-+-++-++++
          00:45   01:00   01:15   01:30   01:45    02:00   02:15   02:30   02:45   03:00   03:15
                                                  Time

2018-01-05  03:14:56
-------     -------   -------  -------   -------  -------   -------
.           ΔSpot     (%)      ΔSell     (%)      ΔBuy      (%)
2           .99       0%       .98       0%       .62       0%
5           2.99      .01%     2.47      .01%     1.56      .01%
10          32.77     .21%     32.45     .21%     27.29     .18%
30          72.77     .48%     72.05     .48%     73.45     .48%
60          95.97     .64%     95.02     .64%     97.90     .65%
-------     -------   -------  -------   -------  -------   -------
Now         14999.99  .        14850.36  .        15150.32
δ           .70       .        -149.63   -1.00    150.33    .99

The graph shows the past three hours of bitcoin spot price just to help you visualize the trend. Consider the following line from this example:

60 95.97 .64% 95.02 .64% 97.90 .65

The fields are:

  1. Summary of changes for the past 60 minutes
  2. Change in BTC spot price in USD
  3. Change in BTC spot price in %
  4. Change in BTC sell price in USD
  5. Change in BTC sell price in %
  6. Change in BTC buy price in USD
  7. Change in BTC buy price in %

The last line of the output:

δ .70 . -149.63 -1.00 150.33 .99

The fields are:

  1. n/a
  2. Difference between fields 4 and 6
  3. n/a
  4. Difference between sell and spot prices in USD
  5. Difference between sell and spot prices in %
  6. Difference between buy and spot prices in USD
  7. Difference between buy and spot prices in %

The second field on the last line gives you an idea of where the price is heading and how fast. A positive double-digit number, for example, shows that Coinbase is raising the buy price that is indicative of high demand. That number a time-trend analysis of its own, if I have time…

Now, to run this script in background mode I suggest using tmux. Here are some useful shortcuts. To send the output to a Web page, I recommend seashells. Some info here. Here’s an example of installing and running everything on a CentOS system:

yum -y install tmux
pip install seashells
d="/var/adm/bin"
n="coinbase_v3_btc_ticker"
mkdir -p ${d}
cd ${d}
curl -k -s0  https://raw.githubusercontent.com/igoros777/kw/master/${n}.sh > ${d}/${n}.sh
chmod 755 ${d}/${n}.sh
ln -s ${d}/${n}.sh /usr/bin/btcticker

Now you can start a new tmux session, run the btcticker script in background mode, redirecting to seashells.io, and detach from the session:

tmux new -s btcticker
/usr/bin/btcticker | seashells --delay 5 &
# Make sure to copy the "serving at https://seashells.io/v/*" line
tmux detach

Obviously, since the maximum time interval in the script is one hour, it will take that long for the data array to become fully populated.

If you forgot to grab the serving at https://seashells.io/v/* line, just re-attach to the tmux session (tmux a -t btcticker), activate the scrolling mode (CTRL-b [), use the page-up key to get to the point where you started the btcticket script and copy the URL. Then exit the scroll mode (q) and detach from the session (tmux detach).

The script is below and you can also download it here.

#!/bin/bash
configure() {
  t=60
  tp=10800
  unset a b
  g="1 2 5 10 30 60"
  k="t:3 l:4 y:5"
}

aadd() {
  a+=("$(for i in spot sell buy; do grep -oP "(?<=\")[0-9]{1,}\.[0-9]{1,2}(?=\")" \
  <(curl -m10 -k -s0 https://api.coinbase.com/v2/prices/${i}?currency=USD 2>/dev/null); done | \
  sed 'N;N;s/\n/ /g' | awk -v d="$(date +'%Y-%m-%d %H:%M:%S')" '{print d,$0}')")
}

aprint() {
  for ((i = 0; i < ${#a[@]}; i++)) ; do echo "${a[$i]}" ; done
}

acount() {
  (( g = `printf '%s\n' ${#a[@]}` - 1 )) && echo ${g}
}

vset() {
  for i in $(echo ${g}); do
    for j in $(echo ${k}); do
      eval $(echo `awk -F: '{print $1}' <<<${j}`${i})=
      eval $(echo `awk -F: '{print $1}' <<<${j}`${i})=$(aprint | tail -${i} | head -1 | \
      awk -v f=`awk -F: '{print $2}' <<<${j}` '{print $f}')
    done
  done 2>/dev/null
}

dset() {
  for i in $(echo ${g}); do
    for j in $(echo ${k}); do
      eval $(echo d`awk -F: '{print $1}' <<<${j}`${i})=
      eval $(echo d`awk -F: '{print $1}' <<<${j}`${i})=$(echo "scale=2;$(eval echo \
      $`echo $(awk -F: '{print $1}' <<<${j})1`)-$(eval echo $`echo $(awk -F: '{print $1}' \
      <<<${j})${i}`)"|bc -l)
      eval $(echo dp`awk -F: '{print $1}' <<<${j}`${i})=
      eval $(echo dp`awk -F: '{print $1}' <<<${j}`${i})=$(echo "scale=2;100*($(eval echo $`echo $(awk -F: '{print $1}' \
      <<<${j})1`)-$(eval echo $`echo $(awk -F: '{print $1}' <<<${j})${i}`))/$(eval echo $`echo $(awk -F: '{print $1}' \
      <<<${j})${i}`)"|bc -l)%
    done
  done 2>/dev/null
}

dprint() {
  echo ". ΔSpot (%) ΔSell (%) ΔBuy (%)"
  for i in $(echo ${g} | awk '{$1=""; print $0}'); do
    echo -n "${i} "
    for j in $(echo ${k}); do
      eval echo $`echo d$(awk -F: '{print $1}' <<<${j})${i}` $`echo dp$(awk -F: '{print $1}' <<<${j})${i}`
    done | sed 'N;N;s/\n/ /g'
  done
}

rprint() {
  echo ""
  date +'%Y-%m-%d %H:%M:%S'
  echo "------- ------- ------- ------- ------- ------- -------"
  dprint | column -t
  echo "------- ------- ------- ------- ------- ------- -------"
  echo "${a[`acount`]}" | awk '{print "Now",$3,".",$4,".",$5}'
  dlt=$(echo "scale=2;$(echo ${a[`acount`]} | awk '{print $4}')-\
  $(echo \"${a[`acount`]}\" | awk '{print $3}' | sed 's/"//g')" | bc -l)
  pdlt=$(echo "scale=2;100*($(echo ${a[`acount`]} | awk '{print $4}')-\
  $(echo \"${a[`acount`]}\" | awk '{print $3}' | sed 's/"//g'))/\
  $(echo ${a[`acount`]} | awk '{print $4}')" | bc -l)
  dly=$(echo "scale=2;$(echo ${a[`acount`]} | awk '{print $5}')-\
  $(echo \"${a[`acount`]}\" | awk '{print $3}' | sed 's/"//g')" | bc -l)
  pdly=$(echo "scale=2;100*($(echo ${a[`acount`]} | awk '{print $5}')-\
  $(echo \"${a[`acount`]}\" | awk '{print $3}' | sed 's/"//g'))/\
  $(echo ${a[`acount`]} | awk '{print $5}')" | bc -l)
  dlty=$(echo "scale=2;${dlt}+${dly}" | bc -l)
  echo "δ ${dlty} . ${dlt} ${pdlt} ${dly} ${pdly}"
}

gplot() {
  aprint | tail -$(echo "scale=0;${tp}/${t}" | bc -l) | \
  gnuplot -e "set terminal dumb 96 28; unset key; set style data labels; set xdata time; \
  set xlabel 'Time'; set ylabel 'Spot'; set autoscale; set timefmt '%Y-%m-%d %H:%M:%S';
  set format x '%H:%M'; \
  plot '-' using 1:3:ytic(3) with histeps"
}

# RUNTIME
configure
for (( ; ; )); do
  aadd; vset; dset; clear; gplot; rprint | column -t; sleep ${t}
done