Coins: 16,626
Exchanges: 1,201
Market Cap: $3.427T 2.4%
24h Vol: $84.525B
Gas: 1.934 GWEI
Go Ad-free
API
TABLE OF CONTENTS

How to Build a Crypto Portfolio Rebalancing Tool with TensorFlow

4.8
| by
Roxait
|
Edited by
Julia Ng
-

Managing a cryptocurrency portfolio can be challenging due to the volatile nature of crypto markets. AI-powered tools are becoming increasingly popular to help traders and investors make data-driven decisions. In this guide, we’ll show you how to build a crypto portfolio rebalancing tool using TensorFlow and the CoinGecko API. By the end of this tutorial, you’ll have a working model that predicts crypto price trends and implements rebalancing strategies based on AI predictions.

What is Portfolio Rebalancing?

Portfolio rebalancing is the process of realigning asset weights in an investment portfolio. In crypto, rebalancing helps manage risk and maintain a desired allocation despite price fluctuations. For instance, if your portfolio is split 60% Bitcoin (BTC) and 40% Ethereum (ETH), a sudden rise in BTC’s price could skew your allocation. Rebalancing restores the portfolio to its target allocation.

How AI & Machine Learning Enhance Rebalancing

With machine learning, you can predict price trends and make smarter decisions about when and how to rebalance your portfolio. Using TensorFlow, we’ll train an LSTM (Long Short-Term Memory) model to forecast price movements based on historical data.

Crypto Portfolio Rebalancing with AI - CoinGecko API


Prerequisites

Before getting started, ensure you have a basic working knowledge of the following:

Python

This project heavily relies on Python programming, and hence, it is essential to understand Python syntax, libraries, and how to manipulate data. Ensure Python (version 3.8 or higher) is installed on your system. Python’s package manager, pip, is required for installing the dependencies used in this project - we'll outline the installation steps below.

CoinGecko API

We will use the CoinGecko API's free Demo plan to fetch market chart data for cryptocurrencies—specifically, the endpoint /coins/{id}/market_chart.

💡Pro-tip: You may cross-reference coins' API id via the /coins/list endpoint or through this Google Sheet.

The Demo API plan is freely accessible to anyone with a CoinGecko account, capped at 10,000 calls monthly and a 30 calls/min rate limit. Explore 60+ endpoints on our API documentation, or create a Demo account to try it out!

Machine Learning Basics & Familiarity with TensorFlow

Familiarity with machine learning's core concepts, such as datasets, models, training, testing, and evaluation, will help you understand the workflow.

Specifically, we'll be leveraging the TensorFlow machine learning framework, used for creating and training models. Familiarity with TensorFlow or a similar library (like PyTorch) is crucial to implementing the LSTM model used in this project.

Data Visualization Basics

We’ll use Matplotlib for visualizing data and predictions – understanding how to create line plots and customize visualizations will be helpful.

Familiarity with NumPy (for numerical operations) and Pandas (for handling tabular data) is essential, as these libraries form the backbone of data manipulation in Python.

Text Editor or IDE

A robust text editor or IDE like Visual Studio Code (VSCode) or PyCharm is recommended for coding. These tools provide features such as syntax highlighting, debugging, and extensions to improve the development experience.

Python & Pip Package Installation using Visual Studio Code

To install Python and pip using VSCode, first download and install Python from the official Python website, ensuring to check the box that says "Add Python to PATH" during installation. Once installed, verify Python and pip are working by opening a terminal and running python --version and pip --version. If you're using macOS or Linux, follow the platform-specific instructions on the Python website.

Next, download and install Visual Studio Code from the VSCode website, and then open VSCode. Install the Python extension by navigating to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X on macOS), searching for "Python" by Microsoft, and clicking "Install." After that, you can verify pip is installed by running pip --version in the terminal. If it’s not installed, you can run python -m ensurepip --upgrade to install it. You can now install any required Python packages using pip, for example, pip install requests.

For project isolation, it’s recommended to use a virtual environment. To create one, run python -m venv venv in the terminal, then activate it with .\\venv\\Scripts\\activate on Windows or source venv/bin/activate on macOS/Linux. With the virtual environment active, install any dependencies needed for your project using pip. To deactivate, simply type deactivate. You can run your Python code by creating a .py file in VSCode and running it via the terminal or by right-clicking it and selecting "Run Python File in Terminal." This setup ensures you have everything to start coding with Python in VSCode.

Note: To install TensorFlow on Windows, use Python 3.11. Create a virtual environment and install TensorFlow with pip install tensorflow pandas numpy requests sci-kit-learn flask. Switching to Python 3.11 solved the compatibility issue.

pip installation guide

With these prerequisites in place, you’ll be well-equipped to start building your AI-powered crypto portfolio rebalancing tool. Let’s dive in!


File Structure of the Crypto Portfolio Rebalancer

Here is the file structure for the Crypto Portfolio Rebalancer project:

/project-directory

    /templates

        index.html

    /static

        script.js

    app.py

    rebalance.py

file structure

Step 1. Crypto Portfolio Rebalancing Code Script

In this section, we'll delve into rebalance.py, the key script that powers our AI-powered crypto portfolio rebalancing tool. We'll explore the essential imports, functions, and logic that make this program work.

import requests

import numpy as np

import tensorflow as tf

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import LSTM, Dense

from sklearn.preprocessing import MinMaxScaler

# Step 1: Fetch Historical Data Using CoinGecko API

def fetch_historical_data(crypto_id, currency='usd', days='90', api_key=None):

    url = f"https://api.coingecko.com/api/v3/coins/{crypto_id}/market_chart"

    params = {'vs_currency': currency, 'days': days}

    headers = {'Authorization': f'Bearer {api_key}'} if api_key else {}

    response = requests.get(url, params=params, headers=headers)

    data = response.json()

    prices = [price[1] for price in data['prices']]

    return prices

# Step 2: Preprocess the Data

def preprocess_data(prices, sequence_length=30):

    scaler = MinMaxScaler()

    prices = np.array(prices).reshape(-1, 1)

    scaled_prices = scaler.fit_transform(prices)

    sequences = []

    targets = []

    for i in range(len(scaled_prices) - sequence_length):

        sequences.append(scaled_prices[i:i + sequence_length])

        targets.append(scaled_prices[i + sequence_length])

    return np.array(sequences), np.array(targets), scaler

# Step 3: Build and Train the LSTM Model

def build_lstm_model(input_shape):

    model = Sequential([

        LSTM(50, return_sequences=True, input_shape=input_shape),

        LSTM(50),

        Dense(1)

    ])

    model.compile(optimizer='adam', loss='mse')

    return model

# Step 4: Predict Future Prices Using LSTM Model

def predict_price(model, sequences, scaler):

    # Predict the next price

    last_sequence = sequences[-1].reshape(1, -1, 1)

    predicted_price_scaled = model.predict(last_sequence)

    # Inverse transform to get the actual price

    predicted_price = scaler.inverse_transform(predicted_price_scaled)

    return float(predicted_price[0][0])  # Convert to standard float

# Step 5: Rebalance the Portfolio

def rebalance_portfolio(current_allocation, predicted_prices, target_allocation):

    # Calculate the current total value of the portfolio

    current_value = sum(current_allocation)

   # Calculate target values based on current total value and target allocation percentages

    target_values = [current_value * ta for ta in target_allocation]

   # Calculate adjustments required to reach target values

    adjustments = []

    for current, target, predicted in zip(current_allocation, target_values, predicted_prices):

        # Adjust the current allocation based on predicted prices to meet the target allocation

        adjusted_value = target / predicted

        adjustments.append(adjusted_value - current)

    # Round adjustments and predicted prices to 3 decimal places for consistency

    adjustments = [round(adj, 3) for adj in adjustments]

    predicted_prices = [round(price, 3) for price in predicted_prices]

    return adjustments, predicted_prices

In summary, rebalance.py is designed to fetch historical price data, preprocess it for model training, build and train an LSTM model to predict future prices, and then use these predictions to rebalance a cryptocurrency portfolio according to target allocations. Each step is critical for the overall functionality of the rebalancing tool, ensuring that the portfolio is aligned with future market predictions. This results in a dynamic and effective portfolio management strategy powered by AI.


Step 2. Build the Frontend User Interface

Here, we’ll create the HTML and CSS for the user interface (UI) that allows users to input their portfolio and target allocation.

HTML (index.html)

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Crypto Portfolio Rebalancer</title>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">

    <style>

        body {

            font-family: Arial, sans-serif;

            background-color: #f4f4f4;

            margin: 0;

            padding: 0;

        }

        .container {

            max-width: 800px;

            margin: 50px auto;

            background: white;

            padding: 20px;

            box-shadow: 0 0 10px rgba(0,0,0,0.1);

            border-radius: 8px;

        }

        h1 {

            text-align: center;

            color: #333;

        }

        .current-prices {

            display: flex;

            justify-content: space-around;

            margin-bottom: 20px;

        }

        .current-prices div {

            text-align: center;

        }

        .current-prices i {

            font-size: 2em;

            margin-bottom: 10px;

        }

        form {

            display: flex;

            flex-direction: column;

        }

        label {

            margin: 10px 0 5px;

            color: #555;

        }

        input {

            padding: 10px;

            margin-bottom: 20px;

            border: 1px solid #ccc;

            border-radius: 4px;

        }

        button {

            padding: 15px;

            color: white;

            background-color: #007bff;

            border: none;

            border-radius: 4px;

            cursor: pointer;

            font-size: 16px;

        }

        button:hover {

            background-color: #0056b3;

        }

        #results {

            margin-top: 20px;

        }

        #results h3 {

            color: #333;

        }

        #results p {

            color: #555;

        }

        #loading {

            display: none;

            text-align: center;

            color: #555;

        }

        .progress-bar-container {

            width: 100%;

            background-color: #f3f3f3;

            border-radius: 4px;

            margin: 20px 0;

        }

        .progress-bar {

            width: 0;

            height: 20px;

            background-color: #007bff;

            border-radius: 4px;

        }

    </style>

</head>

<body>

    <div class="container">

        <h1>AI-Powered Crypto Portfolio Rebalancer</h1>

        <div class="current-prices">

            <div>

                <i class="fab fa-bitcoin"></i>

                <p id="current-btc-price">Loading BTC price...</p>

            </div>

            <div>

                <i class="fab fa-ethereum"></i>

                <p id="current-eth-price">Loading ETH price...</p>

            </div>

        </div>

        <form id="rebalance-form">

            <label for="btc-allocation">BTC Allocation (USD):</label>

            <input type="number" id="btc-allocation" required>

            <label for="eth-allocation">ETH Allocation (USD):</label>

            <input type="number" id="eth-allocation" required>

            <label for="target-btc">Target BTC Allocation (%):</label>

            <input type="number" id="target-btc" required>

            <label for="target-eth">Target ETH Allocation (%):</label>

            <input type="number" id="target-eth" required>

            <button type="submit">Rebalance Portfolio</button>

        </form>

        <div id="loading">Rebalancing, please wait...</div>

        <div class="progress-bar-container">

            <div id="progress-bar" class="progress-bar"></div>

        </div>

        <div id="results"></div>

    </div>

    <sscript src="/static/script.js"></sscript>

</body>

</html>


Step 3. Add Interactivity with JavaScript

To make the UI functional, we’ll connect it to the Python backend for predictions and portfolio rebalancing using JavaScript.

JavaScript File (script.js)

document.addEventListener("DOMContentLoaded", async function() {

    const response = await fetch("/current_prices");

    const data = await response.json();

   

    document.getElementById("current-btc-price").innerText = `Current BTC Price: $${data.btc_price.toFixed(3)}`;

    document.getElementById("current-eth-price").innerText = `Current ETH Price: $${data.eth_price.toFixed(3)}`;

});

 

document.getElementById("rebalance-form").addEventListener("submit", async function (event) {

    event.preventDefault();

    // Show the loading message

    document.getElementById("loading").style.display = "block";

    document.getElementById("results").innerHTML = "";

    // Reset the progress bar

    const progressBar = document.getElementById("progress-bar");

    progressBar.style.width = "0%";

 

    const btcAllocation = parseFloat(document.getElementById("btc-allocation").value);

    const ethAllocation = parseFloat(document.getElementById("eth-allocation").value);

    const targetBTC = parseFloat(document.getElementById("target-btc").value) / 100;

    const targetETH = parseFloat(document.getElementById("target-eth").value) / 100;

   

    const response = await fetch("/rebalance", {

        method: "POST",

        headers: {

            "Content-Type": "application/json",

        },

        body: JSON.stringify({

            current_allocation: [btcAllocation, ethAllocation],

            target_allocation: [targetBTC, targetETH],

        }),

    });

    const result = await response.json();

    console.log(result); // Log the result to see if data is returned

    displayResults(result.adjustments, result.predicted_prices);

    // Hide the loading message

    document.getElementById("loading").style.display = "none";

});

function updateProgressBar(progress) {

    const progressBar = document.getElementById("progress-bar");

    progressBar.style.width = `${progress}%`;

}

function displayResults(adjustments, predicted_prices) {

    const resultsDiv = document.getElementById("results");

    resultsDiv.innerHTML = `

        <h3>Rebalancing Suggestions</h3>

        <p>Adjust BTC by: $${adjustments[0].toFixed(3)}</p>

        <p>Adjust ETH by: $${adjustments[1].toFixed(3)}</p>

        <h3>Predicted Prices</h3>

        <p>Predicted BTC Price: $${predicted_prices[0].toFixed(3)}</p>

        <p>Predicted ETH Price: $${predicted_prices[1].toFixed(3)}</p>

    `;

}

// Example of updating the progress bar incrementally

async function simulateProgress() {

    for (let i = 0; i <= 100; i += 10) {

        updateProgressBar(i);

        await new Promise(resolve => setTimeout(resolve, 100)); // Simulate training time

    }

}

// Call simulateProgress when the form is submitted

document.getElementById("rebalance-form").addEventListener("submit", async function (event) {

    event.preventDefault();

    // Show the loading message

    document.getElementById("loading").style.display = "block";

    document.getElementById("results").innerHTML = "";

    // Reset the progress bar

    const progressBar = document.getElementById("progress-bar");

    progressBar.style.width = "0%";

    const btcAllocation = parseFloat(document.getElementById("btc-allocation").value);

    const ethAllocation = parseFloat(document.getElementById("eth-allocation").value);

    const targetBTC = parseFloat(document.getElementById("target-btc").value) / 100;

    const targetETH = parseFloat(document.getElementById("target-eth").value) / 100;

    // Start simulating progress

    simulateProgress();

    const response = await fetch("/rebalance", {

        method: "POST",

        headers: {

            "Content-Type": "application/json",

        },

        body: JSON.stringify({

            current_allocation: [btcAllocation, ethAllocation],

            target_allocation: [targetBTC, targetETH],

        }),

    });

    const result = await response.json();

    console.log(result); // Log the result to see if data is returned

    displayResults(result.adjustments, result.predicted_prices);

    // Hide the loading message

    document.getElementById("loading").style.display = "none";

});


Step 4. Create the Python Backend

The backend will handle the prediction and rebalancing logic. Use Flask to create an API that connects the JavaScript frontend to the Python logic.

Flask Server (app.py)

from flask import Flask, request, jsonify, render_template

from rebalance import fetch_historical_data, preprocess_data, build_lstm_model, predict_price, rebalance_portfolio

from tqdm import tqdm

app = Flask(__name__)

# Serve the index.html file

@app.route('/')

def home():

    return render_template('index.html')

@app.route('/current_prices', methods=['GET'])

def current_prices():

    api_key = 'CG-api_key '

    btc_prices = fetch_historical_data('bitcoin', api_key=api_key)

    eth_prices = fetch_historical_data('ethereum', api_key=api_key)

    current_btc_price = round(btc_prices[-1], 3)  # Latest BTC price

    current_eth_price = round(eth_prices[-1], 3)  # Latest ETH price

    return jsonify({"btc_price": current_btc_price, "eth_price": current_eth_price})

@app.route('/rebalance', methods=['POST'])

def rebalance():

    data = request.json

    current_allocation = data['current_allocation']

    target_allocation = data['target_allocation']

   # Fetching data from CoinGecko API

    api_key = 'CG-k63f6X3RG6T7MGVf6BdfHWh1'

    btc_prices = fetch_historical_data('bitcoin', api_key=api_key)

    eth_prices = fetch_historical_data('ethereum', api_key=api_key)

   # Preprocessing data

    btc_sequences, btc_targets, btc_scaler = preprocess_data(btc_prices)

    eth_sequences, eth_targets, eth_scaler = preprocess_data(eth_prices)

   

    # Build and train model

    btc_model = build_lstm_model((btc_sequences.shape[1], btc_sequences.shape[2]))

    eth_model = build_lstm_model((eth_sequences.shape[1], eth_sequences.shape[2]))

   # Training BTC model with progress bar

    for epoch in tqdm(range(10), desc="Training BTC Model"):

        btc_model.fit(btc_sequences, btc_targets, epochs=1, batch_size=32, verbose=0)

   # Training ETH model with progress bar

    for epoch in tqdm(range(10), desc="Training ETH Model"):

        eth_model.fit(eth_sequences, eth_targets, epochs=1, batch_size=32, verbose=0)

   # Predict prices using the trained models

    btc_predicted_price = predict_price(btc_model, btc_sequences, btc_scaler)

    eth_predicted_price = predict_price(eth_model, eth_sequences, eth_scaler)

   # Log the predicted prices to ensure they're being generated

    print(f"Predicted BTC Price: {btc_predicted_price}")

    print(f"Predicted ETH Price: {eth_predicted_price}")

   predicted_prices = [btc_predicted_price, eth_predicted_price]

   # Rebalance portfolio

    adjustments, rounded_predicted_prices = rebalance_portfolio(current_allocation, predicted_prices, target_allocation)

   return jsonify({"adjustments": adjustments, "predicted_prices": rounded_predicted_prices})

if __name__ == '__main__':

    app.run(debug=True)


Step 5. Run the Application

  1. Run app.py to start the Flask server backend.
  2. Open index.html in your browser to open the front end:
  3. Enter your portfolio details and target allocation percentages, and click “Rebalance Portfolio.”
  4. View results: The UI will display the rebalancing suggestions based on your input and the AI’s predictions.

Crypto Rebalancer


Conclusion

Congratulations! You’ve developed an AI-powered crypto portfolio rebalancing tool that integrates the CoinGecko API and TensorFlow. This dynamic tool allows us to fetch historical data, analyze real-time data using LSTM, and predict cryptocurrency prices and trends. It also automates the rebalancing of your crypto portfolio by adjusting allocations according to target percentages. Finally, our custom frontend enables us to visualize and analyze the results effectively.

Unlock OHLC chart data - CoinGecko API

What's Next? Expanding Functionality

This guide serves as a foundation for building a crypto portfolio rebalancing tool, but there are several ways to extend its functionality. Adding more cryptocurrencies will expand the range of assets in your portfolio management. You can also improve prediction accuracy by experimenting with different machine learning models and fine-tuning hyperparameters, which could result in more precise rebalancing decisions. Additionally, integrating live crypto exchange APIs like Binance or Coinbase Pro can take your tool to the next level, enabling automated rebalancing in real-time based on market movements. These enhancements can transform your tool into a more powerful and dynamic solution tailored to your unique crypto investing strategy.


If you found this article helpful, you might enjoy our step-by-step guide on backtesting crypto trading strategies with Python.

CoinGecko's Content Editorial Guidelines
CoinGecko’s content aims to demystify the crypto industry. While certain posts you see may be sponsored, we strive to uphold the highest standards of editorial quality and integrity, and do not publish any content that has not been vetted by our editors.
Learn more
Want to be the first to know about upcoming airdrops?
Subscribe to the CoinGecko Daily Newsletter!
Join 600,000+ crypto enthusiasts, traders, and degens in getting the latest crypto news, articles, videos, and reports by subscribing to our FREE newsletter.
Tell us how much you like this article!
Vote count: 5
Roxait
Roxait
With 18 years of pioneering experience in the crypto space, Roxait excels in technical collaborations to develop cutting-edge decentralized solutions. Our commitment to innovation and expertise in blockchain technology has made us a trusted partner in driving the future of decentralized systems. Follow the author on Twitter @roxaittech

Related Articles

Select Currency
Suggested Currencies
USD
US Dollar
IDR
Indonesian Rupiah
TWD
New Taiwan Dollar
EUR
Euro
KRW
South Korean Won
JPY
Japanese Yen
RUB
Russian Ruble
CNY
Chinese Yuan
Fiat Currencies
AED
United Arab Emirates Dirham
ARS
Argentine Peso
AUD
Australian Dollar
BDT
Bangladeshi Taka
BHD
Bahraini Dinar
BMD
Bermudian Dollar
BRL
Brazil Real
CAD
Canadian Dollar
CHF
Swiss Franc
CLP
Chilean Peso
CZK
Czech Koruna
DKK
Danish Krone
GBP
British Pound Sterling
GEL
Georgian Lari
HKD
Hong Kong Dollar
HUF
Hungarian Forint
ILS
Israeli New Shekel
INR
Indian Rupee
KWD
Kuwaiti Dinar
LKR
Sri Lankan Rupee
MMK
Burmese Kyat
MXN
Mexican Peso
MYR
Malaysian Ringgit
NGN
Nigerian Naira
NOK
Norwegian Krone
NZD
New Zealand Dollar
PHP
Philippine Peso
PKR
Pakistani Rupee
PLN
Polish Zloty
SAR
Saudi Riyal
SEK
Swedish Krona
SGD
Singapore Dollar
THB
Thai Baht
TRY
Turkish Lira
UAH
Ukrainian hryvnia
VEF
Venezuelan bolívar fuerte
VND
Vietnamese đồng
ZAR
South African Rand
XDR
IMF Special Drawing Rights
Cryptocurrencies
BTC
Bitcoin
ETH
Ether
LTC
Litecoin
BCH
Bitcoin Cash
BNB
Binance Coin
EOS
EOS
XRP
XRP
XLM
Lumens
LINK
Chainlink
DOT
Polkadot
YFI
Yearn.finance
Bitcoin Units
BITS
Bits
SATS
Satoshi
Commodities
XAG
Silver - Troy Ounce
XAU
Gold - Troy Ounce
Select Language
Popular Languages
EN
English
RU
Русский
DE
Deutsch
PL
język polski
ES
Español
VI
Tiếng việt
FR
Français
PT
Português
All Languages
AR
العربية
BG
български
CS
čeština
DA
dansk
EL
Ελληνικά
FI
suomen kieli
HE
עִבְרִית
HI
हिंदी
HR
hrvatski
HU
Magyar nyelv
ID
Bahasa Indonesia
IT
Italiano
JA
日本語
KO
한국어
LT
lietuvių kalba
NL
Nederlands
NO
norsk
RO
Limba română
SK
slovenský jazyk
SL
slovenski jezik
SV
Svenska
TH
ภาษาไทย
TR
Türkçe
UK
украї́нська мо́ва
ZH
简体中文
ZH-TW
繁體中文
Log in
By continuing, you agree to CoinGecko Terms of Service and acknowledge you’ve read our Privacy Policy
or
Forgot your password?
Didn't receive confirmation instructions?
Resend confirmation instructions
Sign up
By continuing, you agree to CoinGecko Terms of Service and acknowledge you’ve read our Privacy Policy
or
Password must contain at least 8 characters including 1 uppercase letter, 1 lowercase letter, 1 number, and 1 special character
Didn't receive confirmation instructions?
Resend confirmation instructions
Forgot your password?
You will receive an email with instructions on how to reset your password in a few minutes.
Resend confirmation instructions
You will receive an email with instructions for how to confirm your email address in a few minutes.
Get the CoinGecko app.
Scan this QR code to download the app now App QR Code Or check it out in the app stores
coingecko
Continue in app
Track prices in real-time
Open App