import datetime, requests import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import json, collections, os UTC_OFFSET = -14400 # Local offset from UTC START_DATE = "2016-01-01" # Day to start chat TMP_DIR = "/tmp" # Writable temp directory, without trailing slash def unix_to_date(unix_timestamp): """ Convert a Unix timestamp (in UTC) to the corresponding Date object """ return datetime.datetime.utcfromtimestamp(unix_timestamp).strftime('%Y-%m-%d-%H') def pnx_average(poloniex_price, day): """ Take the Poloniex unweighted average price for a given day (6 data points)""" total = 0.0 for hour in range(0, 24, 4): formatted_date = day + "-" + format(hour, '02d') if not formatted_date in poloniex_price: return 0.0 total += poloniex_price[formatted_date] return total/6.0 def zero_to_nan(values): """Replace every 0 with 'nan' and return a copy.""" return [float('nan') if x==0 else x for x in values] start_unix_utc = int(datetime.datetime.strptime(START_DATE, '%Y-%m-%d').strftime("%s")) + UTC_OFFSET # Download market data if not exists if not os.path.exists(TMP_DIR + "/btc_eth"): open(TMP_DIR + "/btc_eth", "w").write(requests.get("https://poloniex.com/public?command=returnChartData¤cyPair=BTC_ETH&start=" + str(start_unix_utc) + "&end=9999999999&period=14400").text) btc_eth_raw = json.loads(open(TMP_DIR + "/btc_eth").read()) if not os.path.exists(TMP_DIR + "/btc_etc"): open(TMP_DIR + "/btc_etc", "w").write(requests.get("https://poloniex.com/public?command=returnChartData¤cyPair=BTC_ETC&start=" + str(start_unix_utc) + "&end=9999999999&period=14400").text) btc_etc_raw = json.loads(open(TMP_DIR + "/btc_etc").read()) if not os.path.exists(TMP_DIR + "/btc_usd"): open(TMP_DIR + "/btc_usd", "w").write(requests.get("http://api.coindesk.com/v1/bpi/historical/close.json?start=" + START_DATE + "&end=2018-01-01").text) btc_usd = json.loads(open(TMP_DIR + "/btc_usd").read(), object_pairs_hook=collections.OrderedDict) btc_eth_all = dict([(unix_to_date(int(x['date'])), float(x['weightedAverage'])) for x in btc_eth_raw]) btc_etc_all = dict([(unix_to_date(int(x['date'])), float(x['weightedAverage'])) for x in btc_etc_raw]) dates = [] eth_prices = [] etc_prices = [] btc_prices = [] for day in btc_usd['bpi']: # Bitcoin prices dates += [datetime.datetime.strptime(day + "-12", '%Y-%m-%d-%H')] eth_prices += [pnx_average(btc_eth_all, day)] etc_prices += [pnx_average(btc_etc_all, day)] btc_prices += [btc_usd['bpi'][day]] ethc_prices = [0.0 if y == 0.0 else x + y for x, y in zip(eth_prices, etc_prices)] def graph_all(eth_prices, etc_prices, ethc_prices, Y_MAX, y_label): ethc_line, = plt.plot_date(dates, zero_to_nan(ethc_prices), label="ETH+ETC", fmt="b-") eth_line, = plt.plot_date(dates, eth_prices, label="ETH", fmt="g-") etc_line, = plt.plot_date(dates, zero_to_nan(etc_prices), label="ETC", fmt="r-") line_date = datetime.datetime.strptime("2016-10-18-12", '%Y-%m-%d-%H') plt.axvline(line_date, color='g') plt.text(line_date + datetime.timedelta(days=-5),Y_MAX * .25,'DoS Fork 1',rotation=90) line_date = datetime.datetime.strptime("2016-11-22-15", '%Y-%m-%d-%H') plt.axvline(line_date, color='g') plt.text(line_date + datetime.timedelta(days=2),Y_MAX * .25,'DoS Fork 2',rotation=90) line_date = datetime.datetime.strptime("2016-10-25-04", '%Y-%m-%d-%H') plt.axvline(line_date, color='r') plt.text(line_date + datetime.timedelta(days=2),Y_MAX * .25,'ETC DoS Fork',rotation=90) line_date = datetime.datetime.strptime("2016-06-17-03", '%Y-%m-%d-%H') plt.axvline(line_date, color='b') plt.text(line_date + datetime.timedelta(days=2),Y_MAX * .25,'DAO Attack',rotation=90) line_date = datetime.datetime.strptime("2016-04-30-00", '%Y-%m-%d-%H') plt.axvline(line_date, color='b') plt.text(line_date + datetime.timedelta(days=2),Y_MAX * .25,'DAO Announced',rotation=90) line_date = datetime.datetime.strptime("2016-07-20-15", '%Y-%m-%d-%H') plt.axvline(line_date, color='b') plt.text(line_date + datetime.timedelta(days=2),Y_MAX * .25,'DAO Fork',rotation=90) line_date = datetime.datetime.strptime("2017-01-13-20", '%Y-%m-%d-%H') plt.axvline(line_date, color='red') plt.text(line_date + datetime.timedelta(days=2),Y_MAX * .25,'ETC DieHard Fork',rotation=90) plt.title("Ethereum and Forks Market Response", fontsize=22) plt.xlabel("Date", fontsize=18) plt.ylabel(y_label, fontsize=18) plt.legend(handles=[ethc_line, eth_line, etc_line]) #plt.gca().set_yscale('log') # Uncomment these two lines for log scale #plt.ylim(0, Y_MAX) plt.show() eth_usd = [0.0 if y == 0.0 else x * y for x, y in zip(btc_prices, eth_prices)] etc_usd = [0.0 if y == 0.0 else x * y for x, y in zip(btc_prices, etc_prices)] ethc_usd = [0.0 if y == 0.0 else x * y for x, y in zip(btc_prices, ethc_prices)] graph_all(eth_usd, etc_usd, ethc_usd, 25, "Price (USD)") graph_all(eth_prices, etc_prices, ethc_prices, .035, "Price (BTC)") eth_then_ethc_usd = [x if y == 0.0 else y for x, y in zip(eth_usd, ethc_usd)] plt.plot_date(dates, zero_to_nan(eth_then_ethc_usd), fmt="b-") plt.title("Forks as a Currency - Holder Perspective", fontsize=22) plt.xlabel("Date", fontsize=18) plt.ylabel("Price (USD)", fontsize=18) plt.show()