Skip to main content

Crypto made easy

· 6 min read
Amanda Martin

Are you crypto-curious?

The fascination with cryptocurrency is going strong, especially after Elon Musk fanned the flames by voicing his preference for Dogecoin over Bitcoin. Cryptocurrency dominated trending Google searches in 2021, with Dogecoin and Ethereum making the top 10 list of most popular searches. If you have more than a casual interest, Deephaven provides essential tools to get you started. We'll show you how to use crypto data to make informed choices on entering and leaving the crypto market.

Earlier this year, we wrote a program to pull live and historical crypto prices. We stream data from CoinGecko and use that data to know when the current price is high or lower than a value based on historical data.

In this iteration, we compute exponential moving averages (EMAs), standard deviations, and averages on the data to help you choose when to buy and sell your favorite crypto.

img

To get started, launch Deephaven (see our quick start) and run our original code, included below. You'll need the appropriate import statements for working with real-time data.

Python code for our Crypto program

To use CoinGecko, we need to install the PyCoinGecko library. See How to install Python packages for the different ways to do this. In this case, we install it for a one-time use.

import os

os.system("pip install pycoingecko")
from pycoingecko import CoinGeckoAPI

from deephaven.DateTimeUtils import secondsToTime, millisToTime
from deephaven.TableTools import merge
from deephaven import DynamicTableWriter

import deephaven.Types as dht
import jpy

from time import sleep, time
import pandas as pd
import threading

# secondsToSleep should be 10 or higher. If too fast, will hit request limit.

secondsToSleep = 60

# if getHistory = true, the days to pull

daysHistory = 2

# coins to get data

ids = ['bitcoin', 'ethereum', 'litecoin', 'dogecoin', 'tether', 'binancecoin', 'cardano', 'ripple', 'polkadot']

getHistory = False

getLive = False

# below this line there are no variables that need changed

########################################################################

def get_coingecko_table_historical(daysHistory = 90):
tableArray = []
cg = CoinGeckoAPI()

# get historical data
for id in ids:
coin_data_hist = cg.get_coin_market_chart_by_id(id, vs_currency = "usd", days = daysHistory)
sub = pd.DataFrame(coin_data_hist)
coin_query = "Coin = `{id}`".format(id=id)
tableArray.append(dataFrameToTable(sub).view("Timestamp = millisToTime((long)prices_[i][0])", coin_query, "Price = prices_[i][1]", "MarketCap = market_caps_[i][1]", "TotalVolume = total_volumes_[i][1]").moveColumnsUp("Timestamp", "Coin"))
return merge(tableArray).selectDistinct("Timestamp", "Coin", "Price", "MarketCap", "TotalVolume").sortDescending("Timestamp", "Coin").formatColumns("Price = Decimal(`#,###.############`)")

def get_coingecko_table_live(secondsToSleep = 60):
cg = CoinGeckoAPI()

# array to store tables for current and previous data
tableArray=[]

tableWriter = DynamicTableWriter(['Coin', 'Timestamp', 'Price', 'MarketCap', 'TotalVolume'], [dht.string, dht.datetime, dht.double, dht.double, dht.double])

tableArray.append(tableWriter.getTable())
result = merge(tableArray).selectDistinct('Timestamp', 'Coin', 'Price', 'MarketCap', 'TotalVolume').sortDescending('Timestamp', 'Coin').formatColumns("Price = Decimal(`#,###.############`)")

def thread_func():
cg.get_coins_markets(vs_currency = 'usd')

while True:
coin_data = cg.get_price(ids, vs_currencies = 'usd', include_market_cap = True, include_24hr_vol = True, include_24hr_change = False, include_last_updated_at = True)

for id in ids:
#Add new data to the dynamic table
tableWriter.logRow( id, secondsToTime(int(coin_data[id]['last_updated_at'])), float(coin_data[id]['usd']), coin_data[id]['usd_market_cap'], coin_data[id]['usd_24h_vol'])

sleep(secondsToSleep)

thread = threading.Thread(target = thread_func)
thread.start()
return result

HistoricalCryptoTable = None
LiveCryptoTable = None

if getHistory:
HistoricalCryptoTable = get_coingecko_table_historical(daysHistory)

if getLive:
LiveCryptoTable = get_coingecko_table_live(secondsToSleep)

Now the fun part. Let's do some analysis on the coins. First, let's see what assets we can pull. This code gets a list of all IDs currently in CoinGecko and save them as a list to filter.

import json
import requests

coins_available =[]

headers = {'accept': 'application/json',}
response = requests.get('https://api.coingecko.com/api/v3/coins/list', headers=headers)
resp = json.loads(response.content)

for d in resp:
for key in d.keys():
if(key =='id'):
coins_available.append(d[key])

That is A LOT of assets so it's to limit them to what we actually want; in this case, we'll filter the assets to only those that contain the string doge.

import re
r = re.compile("^.*doge.*$")
ids = list(filter(r.match, coins_available))[:25]

We end up with over 200 assets without trimming. For ease, I'm going to create a targeted list of IDs to work with - the first 25 values. The code below re-runs LiveCryptoTable and HistoricalCryptoTable. Remember there is a pull limit, so only run HistoricalCryptoTable once.

getHistory = False

getLive = True

if getHistory:
HistoricalCryptoTable = get_coingecko_table_historical(daysHistory)

if getLive:
LiveCryptoTable = get_coingecko_table_live(secondsToSleep)

We can even merge the data for a seamless table:

combined_crypto = merge(LiveCryptoTable, HistoricalCryptoTable)

The steps above collect and organize our data. Now, we can perform EMAs.

Here we add a column that contains our EMA value and highlights if the current price is above that value. EMAs are familiar tools to stock investors and allow us to see how the asset has changed with time. EMAs keep track of the average with the newest values having more weight than older values. This rolling window of averages can give us insight into what the crypto asset might do next. In this EMA, we set the window to be just 10 minutes - like everything in this code example, you can fine-tune this value to fit your data needs.

from deephaven.MovingAverages import ByEmaSimple
from deephaven.TableTools import timeTable

ema1sec = ByEmaSimple('BD_SKIP','BD_SKIP','TIME',10,'MINUTES', type='LEVEL')

ema_data = combined_crypto.update("EMA_data = ema1sec.update(Timestamp, Price)").lastBy()
ema_data_grouped = combined_crypto.update("EMA_data = ema1sec.update(Timestamp, Price, Coin)")\
.lastBy("Coin").sort("Coin")\
.formatColumns("Price = Decimal(`#,###.############`)", "EMA_data = Decimal(`#,###.############`)")\
.formatColumnWhere("Coin", "EMA_data < Price", "IVORY")

You can easily create different calculations, such as standard deviations and averages, by modifying the code:


from deephaven import Aggregation as agg, as_list

agg_list = as_list([
agg.AggStd("Std_price = Price"),\
agg.AggAvg("Avg_price = Price")
])

std_data= ema_data_grouped.join(combined_crypto.aggBy(agg_list, "Coin"), "Coin")\
.formatColumns("Std_price = Decimal(`#,###.############`)", "Avg_price = Decimal(`#,###.############`)")\
.formatColumnWhere("Coin", " Price < Avg_price - Std_price", "IVORY")

This code provides a basic starter. Change the crypto assets to monitor your personal favorites, or switch out the calculations to suit your needs. Deephaven enables you to make smart choices about entering and leaving the market. With the speed of data changes in the crypto world, it's important to use the fastest real-time data engine possible: Deephaven.

We hope this program inspires you. If you make something of your own or have an idea to share, we'd love to hear about it on Gitter!

Develop with Deephaven Core