GPT-4 for Crypto On-Chain Analysis

In this guide, we'll discuss how we can use GPT-4 to summarize and analyze on-chain trading signals of crypto assets.

9 months ago   •   7 min read

By Peter Foy

In our previous guides on GPT-4 for finance, we've explored several applications of large language models (LLMs) for financial analysis, including analyzing fianncial statement & ratios, summarizing enarnigns call transcipts, and more.

In this guide, we'll shift our focus to applying GPT-4 for cypto on-chain analysis, which as higlihted on our guide on what is on-chain analysis:

...is an emerging field that involves examining the fundamentals, utility, and transaction activity of a cryptocurrency and its blockchain data.

For this project, we'll expand on our AI financial analyst Streamlit app and add a dropdown for crypto on-chain analysis.

To build the app, we'll be using the CryptoCompare API, which in turn provides on-chain trading signals powered by IntoTheBlock, which is:

...an intelligence company that leverages machine learning and advanced statistics to extract intelligent signals for crypto-assets.

First, we'll show the raw data from the API call so we can verify everything, then we'll provide a summary of each trading signal, including the value, score, and sentiment. Finally, we'll have GPT-4 provide analysis of each signal and summarize the overall insights:

  • In/Out Money Variance: This momentum signal calculates the net change of in/out of the money addresses, if the number of "In the Money" addresses is increasing this would be a bullish signal. In the money means addresses that would make a profit on the tokens they hold because they acquired the tokens at a lower price.
  • Large Transactions Variance: Momentum signal that is bullish when the short term trend of the number of txs > $100k is greater than the long term average.
  • Addresses Net Growth: Momentum signal that gives an indication of the tokens underlying network health by measuring the amount of new addresses minus the addresses that have their balances emptied. It is bullish when more addresses are being created than emptied.
  • Concentration Variance: The Concentration signal is based on the accumulation (bullish) or reduction (bearish) of addresses with more than 0.1% of the circulating supply.

Alright, now that we know what we're building, let's jump into the code.

Step 0: Installs & Imports

Just like our previous projects, the first step is to install and import the required libraries, in this case we'll need to install the following with pip:

pip install streamlit openai requests

Next, we'll import these into new Python script on_chain_analysis.py, and we'll also place our API keys for CryptoCompare and OpenAI in our apikey.py:

import streamlit as st
import openai
import requests
from apikey import OPENAI_API_KEY, CC_API_KEY

openai.api_key = OPENAI_API_KEY

Step 1: Retrieving Trading Signals

Next, let's go and retrieve the trading signals from IntoTheBlock (via the CryptoCompare API). Here we'll create a function called fetch_trading_signals(), which takes in the cryptocurrency ticker as input:

def fetch_trading_signals(crypto):
    url = f"https://min-api.cryptocompare.com/data/tradingsignals/intotheblock/latest?fsym={crypto}&api_key={CC_API_KEY}"
    response = requests.get(url)
    data = response.json()

    if 'Response' in data and data['Response'] == 'Success':
        return data['Data']
    else:
        st.error("Unable to fetch trading signals. Please ensure the cryptocurrency symbol is correct and try again.")
        return None

Step 2: Generating a Trading Signals Summary

Given that raw trading signal data can be challenging to read and interpret on its own, next we want to create a textual summary of each signal that we can feed into GPT-4 for further explanation and analysis.

To do so, first we'll start by extracting the trading signals from the API call and formatting them into a more readable string, which can then be fed to GPT-4 for analysis.

Trading Signals Summary

Let's start by creating a function called generate_trading_signals_summary, whcih takes in two parameters trading_signals and placeholder_response.

  • trading_signals is the API response from IntoTheBlock which contains trading signal data for a given crpyto asset. The data is in dictionary format and four key signals are extracted: In/Out Money Variance, Large Transactions Variance, Addresses Net Growth, and Concentration Variance.
  • placeholder_response is a placeholder that will be used later to display the GPT-4 generated trading signal analysis in streaming format

Preparing the Summary

  • After extracting the trading signals, we'll then construct a string summary with these values with each of the trading signal values, scores, and sentiment:
def generate_trading_signals_summary(trading_signals, placeholder_response):
    # Extract key trading signals
    inOutVar = trading_signals['inOutVar']
    largetxsVar = trading_signals['largetxsVar']
    addressesNetGrowth = trading_signals['addressesNetGrowth']
    concentrationVar = trading_signals['concentrationVar']

    summary = f"""
    The latest trading signals for the cryptocurrency are as follows:

    - In/Out Money Variance: {inOutVar['value']} (Score: {inOutVar['score']}, Sentiment: {inOutVar['sentiment']})
    - Large Transactions Variance: {largetxsVar['value']} (Score: {largetxsVar['score']}, Sentiment: {largetxsVar['sentiment']})
    - Addresses Net Growth: {addressesNetGrowth['value']} (Score: {addressesNetGrowth['score']}, Sentiment: {addressesNetGrowth['sentiment']})
    - Concentration Variance: {concentrationVar['value']} (Score: {concentrationVar['score']}, Sentiment: {concentrationVar['sentiment']})
    """

Using GPT-4 for On-Chain Analysis

Next, we're going to feed this textual summary into GPT-4 using OpenAI's ChatCompletion.create method. As the docs highlgiht:

The main input is the messages parameter. Messages must be an array of message objects, where each object has a role (either "system", "user", or "assistant") and content (the content of the message). Conversations can be as short as 1 message or fill many pages.

In this case, we're setting the "system" message to "You are an AI trained to provide crypto on-chain analysis based on trading signals...", and then we pass in the string trading signal summary we just created in the initial "user" role.

Here we also set stream=True to enable real-time streaming of the model's response.

def generate_trading_signals_summary(trading_signals, placeholder_response):
    ...

	# Call GPT-3.5/4 for analysis
    response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[
        {
            "role": "system",
            "content": "You are an AI trained to provide crypto on-chain analysis based on trading signals. You have knowledge about different types of trading signals, including In/Out Money Variance, Large Transactions Variance, Addresses Net Growth, and Concentration Variance.",
        },
        {
            "role": "user",
            "content": f"""
            Please analyze the following data and provide detailed insights for each trading signal:

            {summary}

            For each trading signal, consider the following:
            - Explain what the signal means and how it's calculated.
            - Analyze the specific value and score of the signal, and provide your interpretation.
            - Based on the sentiment, explain the potential impact on the crypto asset's future performance.
            - Provide overall insights from all these signals combined and potential investment strategy.

            Note: Write in a human-readable format, round numbers to two decimal places, and make the analysis understandable for both experts and beginners in cryptocurrency trading.
            """
        }
    ],
    stream=True 
)

Displaying the Response

Finally, we need to chunk the response as it comes in so we can display it in real-time. Here's how it works:

  • We create an empty string, assistant_response, to hold the response text
  • The response is streamed from GPT-4 as it's generated, so it arrives in "chunks", where each chunk is a dictionary that contains new parts of the message from the "assistant" respne
  • For each chunk, if it contains a new 'content' part of the AI's response, that content is appended onto the assistant_response
  • After each addition to  assistant_response, the content is immedately written to the placeholder_response Streamlit object in markdown format, enabling streaming.
    # Display the response
    assistant_response = ""
    for chunk in response:
        if "role" in chunk["choices"][0]["delta"]:
            continue
        elif "content" in chunk["choices"][0]["delta"]:
            r_text = chunk["choices"][0]["delta"]["content"]
            assistant_response += r_text
            placeholder_response.markdown(assistant_response, unsafe_allow_html=True)  # add this

    return assistant_response

Step 3: Building the Streamlit Frontend

Now that we have our trading signals & GPT-4 analysis, let's create a function on_chain_analysis() for our Streamlit frontend. Here's how it works:

  • Title:  First we set the title of the app with st.title()
  • Ticker Input Field: Next,  we use st.text_input() to create an input field where users can enter the crypto asset ticker they're interested in.
  • Check and Run: Next, the st.button() creates a button called "Run", and if the button is pressed and the crypto input field isn't empty, the function proceeds by converting the input to uppercase.
  • Retrieving On-Chain Trading Signals:  Next, we call the fetch_trading_signals(crypto) function for the specified crypto asset and store the result in in trading_signals.
  • Displaying Raw Data: We then display the raw API call in an expandable section is created using st.expander(), which if clicked displays the raw trading signals  with st.write(trading_signals).
  • Generate GPT-4 Analysis: Next, if the trading_signals is not None, a placeholder is created in the Streamlit app using st.empty(). This placeholder will be used later display the streaming response from GPT-4. The generate_trading_signals_summary(trading_signals, placeholder_response) function is then called to generate and display the GPT-4 powered analysis of the on-chain trading signals.
  • Error Handling: Lastly, if the crypto field is empty when the "Run" button is clicked, or if trading_signals is None (meaning the fetch_trading_signals(crypto) call didn't succeed), a warning is displayed asking the user to enter a valid ticker.
def on_chain_analysis():
    st.title('GPT-4 for On-Chain Analysis')

    crypto = st.text_input("Please enter the crypto symbol:")

    if st.button('Run'):
        if crypto:
            # Convert crypto to uppercase
            crypto = crypto.upper()

            # Get trading signals
            trading_signals = fetch_trading_signals(crypto)

            # Display DataFrame with st.expander
            with st.expander("Show Raw Data"):
                st.write(trading_signals)

            # Generate GPT-4 Analysis
            if trading_signals is not None:
                placeholder_response = st.empty()  # create placeholder
                generate_trading_signals_summary(trading_signals, placeholder_response)
            else:
                st.warning('Please enter a valid cryptocurrency symbol and click "Run" to fetch the trading signals.')
        else:
            st.warning('Please enter a valid cryptocurrency symbol and click "Run" to fetch the trading signals.')

Now, all the we need is to add another dropdown to our main() function, which allows users to choose between Equities and Crypto AI Analyst, and if the crypto on-chain analysis is chosen we run the main on_chain_analysis() function:

def main():
    st.sidebar.title('AI Financial Analyst')
    mode = st.sidebar.selectbox("Choose your Analysis Type:", ["Equities AI Analyst", "Crypto AI Analyst"])

    if mode == 'Equities AI Analyst':
        equities_mode = st.sidebar.selectbox("Select Analysis Method:",
            ["Financial Statements", "Financial Ratios"])
        
        elif equities_mode == 'Financial Statements':
            financial_statements()
        elif equities_mode == 'Financial Ratios':
            financial_ratios()
        
    elif mode == 'Crypto AI Analyst':
        crypto_mode = st.sidebar.selectbox("Select Analysis Method:",
            ["On Chain Analysis"])

        if crypto_mode == 'On Chain Analysis':
            on_chain_analysis()



if __name__ == '__main__':
    main()

Summary: GPT-4 for Crypto On-Chain Analysis

In this guide, we saw how we can take our first steps towards using GPT-4 for crypto on-chain analysis.

While still quite a simple app, I'm still convinced that GPT-4 can play a major role in making financial analysis a little bit less daunting and more accessible for investors, particularly when it comes to crypto as there are significantly less qualified analysts to begin with.

That said, in order to provide a more comprehensive analysis of an asset, over the next few articles we'll continue exploring different API endpoints for both equities and crypto that are well-suited to GPT-4 when it comes to financial analysis.

Spread the word

Keep reading