#! /usr/bin/gawk -f # Last edited on 2014-01-21 22:21:55 by stolfilocal # Reads from stdin a raw transaction log obtained from http://bitcoinwisdom.com/. # Writes to stderr its statistics. # # All input records must have the same date and must be sorted by time. BEGIN \ { abort = -1; odt = ""; # Date of previous record. otm = ""; # Time of previous record. min_price = 9999999999; max_price = -9999999999; min_volume = 9999999999; max_volume = -9999999999; ntrans = 0; # Count of transactions. sum_vp2 = 0; # Sum of {volume*price^2}. sum_vp = 0; # Sum of {volume*price}. sum_v = 0; # Sum of {volume}. sum_v2 = 0; # Sum of {volume^2}. min_tm = "99:99:99"; max_tm = "00:00:00"; } (abort >= 0) { exit abort; } /(^[ ]*([#]|$))|[!]/ \ { # Blank or header line ignore next; } /^20[0-9][0-9]-[0-1][0-9]-[0-3][0-9][ ][0-2][0-9][:][0-6][0-9][:][0-6][0-9]/ \ { # Appears to be a trasaction record: if (NF != 6) { data_error(("invalid trans record")); } dt = $1; tm = $2; price = 0+$4; volume = 0+$6 if (dt != odt) { if (odt == "") { odt = dt; } else { data_error(("date is not constant in file")); } } if ((otm != "") && (tm < otm)) { data_error(("times are not monotonic")); } ntrans++; sum_vp2 += volume*price*price; sum_vp += volume*price; sum_v += volume; sum_v2 += volume*volume; if (price < min_price) { min_price = price; } if (price > max_price) { max_price = price; } if (volume < min_volume) { min_volume = volume; } if (volume > max_volume) { max_volume = volume; } if (tm < min_tm) { min_tm = tm; } if (tm > max_tm) { max_tm = tm; } next; } // \ { data_error(("bad format")); } END \ { if (abort >= 0) { exit abort; } printf "%d transactions in interval\n", ntrans > "/dev/stderr"; avg_price = sum_vp/sum_v; var_price = (sum_vp2 - sum_vp*sum_vp/sum_v)/sum_v; dev_price = (var_price <= 0 ? 0 : sqrt(var_price)); printf "price min = %.8f max = %.8f avg = %.8f dev = %.8f\n", min_price, max_price, avg_price, dev_price > "/dev/stderr"; avg_volume = sum_v/ntrans; var_volume = (sum_v2 - sum_v*sum_v/ntrans)/ntrans; dev_volume = (var_volume <= 0 ? 0 : sqrt(var_volume)); printf "volume min = %.8f max = %.8f avg = %.8f dev = %.8f\n", min_volume, max_volume, avg_volume, dev_volume > "/dev/stderr"; tm_lo = time_to_minutes(min_tm); tm_hi = time_to_minutes(max_tm); delta_tm = tm_hi - tm_lo; printf "log spans %.3f minutes (%s to %s)\n", delta_tm, min_tm, max_tm > "/dev/stderr"; if (delta_tm > 0) { trans_rate = (ntrans - 1)/delta_tm; printf "average %.4f transactions per minute\n", trans_rate > "/dev/stderr"; volume_rate = sum_v/delta_tm; printf "average %.8f BTC trade per minute\n", volume_rate > "/dev/stderr"; } } function time_to_minutes(tm, H,M,S) { if (tm !~ /^[0-2][0-9][:][0-6][0-9][:][0-6][0-9]$/) { data_error(("invalid time")); } H = substr(tm,1,2) + 0; M = substr(tm,4,2) + 0; S = substr(tm,7,2) + 0; return 60*H + M + S/60.0; } function data_error(msg) { printf "%s:%s: ** %s\n", FILENAME, FNR, msg > "/dev/stderr"; printf " «%s»\n", $0 > "/dev/stderr"; abort = 1; exit(abort); } function arg_error(msg) { printf "** %s\n", msg > "/dev/stderr"; abort = 1; exit(abort); }