Skip to main content

Building an ML Model With Crypto Price Data

Cryptocurrency markets are known for their volatility, making them a fascinating domain for data science and predictive modeling. In this tutorial, we'll explore how to use GraphQL to retrieve historical trading data and use machine learning with Python to build a simple cryptocurrency price prediction model.

We will use the Bitquery API for fetching Ethereum-based decentralized exchange (DEX) trading data and scikit-learn for building a Random Forest Regressor model.

Prerequisites

You need to have these libraries and packages installed to process the next part of the tutorial. Use the snippet below to install the following:

import pandas as pd
from sklearn.preprocessing import StandardScaler

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error

pip install graphql-core

This command installs the graphql-core package, which is a Python library for working with GraphQL queries and responses. It is used to make GraphQL requests to the Bitquery API for fetching cryptocurrency trading data.

Step 1: Fetching Historical Trading Data with GraphQL

First, we need to obtain historical trading data for our cryptocurrency. We'll use GraphQL and Bitquery API for this purpose. The code snippet below demonstrates how to construct a GraphQL query to retrieve Ethereum DEX trades for a specific base and quote currency within a given time range.

import requests

graphql_endpoint = "https://graphql.bitquery.io/"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ory_at_...'
}

Replace with actual values for $baseAddress and $interval

base_address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
interval = 5

Define the GraphQL query

graphql_query = """
query ($baseAddress: String, $interval: Int) {
ethereum(network: ethereum) {
dexTrades(
baseCurrency: {is: $baseAddress}
date: {since: "2023-07-30", till: "2023-07-31"}
options: {limit: 1000, desc: "timeInterval.minute"}
quoteCurrency: {is: "0xdAC17F958D2ee523a2206206994597C13D831ec7"}
priceAsymmetry: {lt: 1}
) {
timeInterval {
minute(count: $interval)
}
sellCurrency: quoteCurrency {
address
}
avg: quotePrice(calculate: average)
}
}
}
"""

Define the variables for the query

variables = {
"baseAddress": base_address,
"interval": interval
}

Make the GraphQL request

response = requests.post(graphql_endpoint, json={"query": graphql_query, "variables": variables}, headers=headers)

Check the response

if response.status_code == 200:
json_data = response.json()
print(json_data)
else:
print(f"Error: {response.status_code}, {response.text}")

The output of this step would be JSON Data in the format as shown below:

{'data': {'ethereum': {'dexTrades': [{'timeInterval': {'minute': '2023-07-30 23:55:00'}, 'sellCurrency': {'address': '0xdac17f958d2ee523a2206206994597c13d831ec7'}, 'avg': 1862.5050814903102},

Step 2: Data Preprocessing

After obtaining the trading data, we need to preprocess it and build a machine-learning model for price prediction. In the following code snippet, we extract the required data, convert it into DataFrame and finally convert the timestamp to a numeric format.

Extract relevant data

trade_data = json_data['data']['ethereum']['dexTrades']
df = pd.json_normalize(trade_data)

df['timeInterval.minute'] = pd.to_datetime(df['timeInterval.minute'])

Convert datetime to timestamp (numeric representation)

df['timeInterval.minute'] = df['timeInterval.minute'].astype(int) / 10**9 # divide by 10^9 to convert nanoseconds to seconds

Now column is of float data type

print(df['timeInterval.minute'])

After running the code, you will be able to see a normalized DataFrame with timestamp data converted to float.

Step 3: Training and Evaluating the Model

This step involves defining features, splitting the data, standardizing features, building a RandomForestRegressor model, training the model, making predictions, and evaluating the model. Here, the target is ‘avg’ as we are going to predict the price of the current day.

Define features and target

features = ['timeInterval.minute']
target = ['avg']

X = df[features]
y = df[target]

Split the data into training and testing sets

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Standardize the features

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

Build a RandomForestRegressor model

model = RandomForestRegressor(n_estimators=100, random_state=42)

Train the model

model.fit(X_train_scaled, y_train)

Make predictions on the test set

predictions = model.predict(X_test_scaled)

Evaluate the model

mse = mean_squared_error(y_test, predictions)
print(f'Mean Squared Error: {mse}')

Sample Output:

Mean Squared Error: 0.66590544255975

Step 5: Testing in Recent Prices Data

Now, let's apply our trained model to predict recent cryptocurrency prices. We'll construct another GraphQL query to fetch recent trading data and use our model for predictions. To get the recent prices data, you can use the query below:

Define the GraphQL query

graphql_query =
query ($baseAddress: String, $interval: Int) {
ethereum(network: ethereum) {
dexTrades(
baseCurrency: {is: $baseAddress}
date: {since: "2024-01-01", till: "2024-01-02"}
options: {limit: 1000, desc: "timeInterval.minute"}
quoteCurrency: {is: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"}
priceAsymmetry: {lt: 1}
) {
timeInterval {
minute(count: $interval)
}
sellCurrency: quoteCurrency {
address
}
avg: quotePrice(calculate: average)
}
}
}

Now, follow the same steps to normalize the data as we did to get the training dataset. After obtaining the dataset, preprocess the features as discussed earlier. Now, do feature engineering for the testing data to obtain the ‘avg’ as we targeted.

We preprocess the recent trading data and use our trained model for predictions.

features = ['timeInterval.minute']
target = ['avg']

X = df[features]
y = df[target]

Split the data into training and testing sets

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Standardize the features

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

recent_prices_predictions = model.predict(X_test_scaled)

Display predictions for recent prices

print("Predictions for Recent Prices:")
print(recent_prices_predictions)

Sample Output:

Predictions for Recent Prices: [1856.33533188 1876.33664406 1881.45406742 1855.9330]

Thus, we have built an ML model with blockchain data using BitQuery DEX API to fetch Ethereum-based decentralized exchange (DEX) trading data.