diff --git a/README.md b/README.md index ba4d46c..cd0219c 100644 --- a/README.md +++ b/README.md @@ -98,15 +98,16 @@ crypto-trading-backtesting/ 1. **Clone the repository:** ```sh - git clone git@github.com:your-username/crypto_trading_backtesting.git - cd crypto_trading_backtesting + git clone https://github.com/10-academy-w-9/crypto-trading-backtesting.git + cd crypto-trading-backtesting ``` 2. **Set up a virtual environment:** ```sh python3 -m venv venv - source venv/bin/activate # On Windows, use `venv\Scripts\activate` + source venv/bin/activate #linux and Mac + `venv\Scripts\activate` #On Windows ``` 3. **Install Requirements:** ```sh @@ -116,6 +117,10 @@ crypto-trading-backtesting/ ```sh streamlit run src/frontend/app.py ``` +5. **Run Chronos** + ```sh + pip install git+https://github.com/amazon-science/chronos-forecasting.git + ``` ## Usage 1. **Provide input descriptions** of the trading strategies, including scenarios and expected outputs. @@ -132,9 +137,9 @@ This project is licensed under the MIT License. ## Contributors - [@abyt101](https://github.com/AbYT101) - Abraham Teka -- Temesgen Gebreabzgi -- Selamawit Tibebu -- Dereje Hinsermu +- [@temesgen5335](https://github.com/temesgen5335)- Temesgen Gebreabzgi +- [@SelamT94](https://github.com/SelamT94) - Selamawit Tibebu +- [@derejehinsermu](https://github.com/derejehinsermu) - Dereje Hinsermu ## Challenge by diff --git a/notebooks/Chronos.ipynb b/notebooks/Chronos.ipynb new file mode 100644 index 0000000..7ca155e --- /dev/null +++ b/notebooks/Chronos.ipynb @@ -0,0 +1,2210 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "UKmLdWL4Sod6", + "outputId": "413d9d25-c65f-4188-f116-eef4cc1aeca1" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Mounted at /content/drive\n" + ] + } + ], + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b3eFoFYDPXtU" + }, + "source": [ + "## Prerequisite" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Z73JLeUtPcpY" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "4MjKEKx7S5-O", + "outputId": "0057d12e-8886-4846-d7c4-03722575bef8" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting git+https://github.com/amazon-science/chronos-forecasting.git\n", + " Cloning https://github.com/amazon-science/chronos-forecasting.git to /tmp/pip-req-build-sa8dtkyz\n", + " Running command git clone --filter=blob:none --quiet https://github.com/amazon-science/chronos-forecasting.git /tmp/pip-req-build-sa8dtkyz\n", + " Resolved https://github.com/amazon-science/chronos-forecasting.git to commit afd9cfd062b60ca1ba8d7c9daef7dc820489db0a\n", + " Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", + " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", + " Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", + "Requirement already satisfied: torch~=2.0 in /usr/local/lib/python3.10/dist-packages (from chronos==1.2.0) (2.3.0+cu121)\n", + "Requirement already satisfied: transformers~=4.30 in /usr/local/lib/python3.10/dist-packages (from chronos==1.2.0) (4.41.2)\n", + "Collecting accelerate (from chronos==1.2.0)\n", + " Downloading accelerate-0.31.0-py3-none-any.whl (309 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m309.4/309.4 kB\u001b[0m \u001b[31m2.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (3.15.3)\n", + "Requirement already satisfied: typing-extensions>=4.8.0 in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (4.12.2)\n", + "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (1.12.1)\n", + "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (3.3)\n", + "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (3.1.4)\n", + "Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (2023.6.0)\n", + "Collecting nvidia-cuda-nvrtc-cu12==12.1.105 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (23.7 MB)\n", + "Collecting nvidia-cuda-runtime-cu12==12.1.105 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (823 kB)\n", + "Collecting nvidia-cuda-cupti-cu12==12.1.105 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (14.1 MB)\n", + "Collecting nvidia-cudnn-cu12==8.9.2.26 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl (731.7 MB)\n", + "Collecting nvidia-cublas-cu12==12.1.3.1 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl (410.6 MB)\n", + "Collecting nvidia-cufft-cu12==11.0.2.54 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl (121.6 MB)\n", + "Collecting nvidia-curand-cu12==10.3.2.106 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl (56.5 MB)\n", + "Collecting nvidia-cusolver-cu12==11.4.5.107 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl (124.2 MB)\n", + "Collecting nvidia-cusparse-cu12==12.1.0.106 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl (196.0 MB)\n", + "Collecting nvidia-nccl-cu12==2.20.5 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl (176.2 MB)\n", + "Collecting nvidia-nvtx-cu12==12.1.105 (from torch~=2.0->chronos==1.2.0)\n", + " Using cached nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (99 kB)\n", + "Requirement already satisfied: triton==2.3.0 in /usr/local/lib/python3.10/dist-packages (from torch~=2.0->chronos==1.2.0) (2.3.0)\n", + "Collecting nvidia-nvjitlink-cu12 (from nvidia-cusolver-cu12==11.4.5.107->torch~=2.0->chronos==1.2.0)\n", + " Downloading nvidia_nvjitlink_cu12-12.5.40-py3-none-manylinux2014_x86_64.whl (21.3 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.3/21.3 MB\u001b[0m \u001b[31m38.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: huggingface-hub<1.0,>=0.23.0 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (0.23.4)\n", + "Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (1.25.2)\n", + "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (24.1)\n", + "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (6.0.1)\n", + "Requirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (2024.5.15)\n", + "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (2.31.0)\n", + "Requirement already satisfied: tokenizers<0.20,>=0.19 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (0.19.1)\n", + "Requirement already satisfied: safetensors>=0.4.1 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (0.4.3)\n", + "Requirement already satisfied: tqdm>=4.27 in /usr/local/lib/python3.10/dist-packages (from transformers~=4.30->chronos==1.2.0) (4.66.4)\n", + "Requirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from accelerate->chronos==1.2.0) (5.9.5)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch~=2.0->chronos==1.2.0) (2.1.5)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->transformers~=4.30->chronos==1.2.0) (3.3.2)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->transformers~=4.30->chronos==1.2.0) (3.7)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->transformers~=4.30->chronos==1.2.0) (2.0.7)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->transformers~=4.30->chronos==1.2.0) (2024.6.2)\n", + "Requirement already satisfied: mpmath<1.4.0,>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from sympy->torch~=2.0->chronos==1.2.0) (1.3.0)\n", + "Building wheels for collected packages: chronos\n", + " Building wheel for chronos (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for chronos: filename=chronos-1.2.0-py3-none-any.whl size=13875 sha256=735edfc7b0d02aad8271306580936abfb31a308d89ed432800fde062477daa9c\n", + " Stored in directory: /tmp/pip-ephem-wheel-cache-dk6memev/wheels/bf/c1/65/08857e57345ef1b34ba0edb4791f1b2594943e82f34e93a4ab\n", + "Successfully built chronos\n", + "Installing collected packages: nvidia-nvtx-cu12, nvidia-nvjitlink-cu12, nvidia-nccl-cu12, nvidia-curand-cu12, nvidia-cufft-cu12, nvidia-cuda-runtime-cu12, nvidia-cuda-nvrtc-cu12, nvidia-cuda-cupti-cu12, nvidia-cublas-cu12, nvidia-cusparse-cu12, nvidia-cudnn-cu12, nvidia-cusolver-cu12, accelerate, chronos\n", + "Successfully installed accelerate-0.31.0 chronos-1.2.0 nvidia-cublas-cu12-12.1.3.1 nvidia-cuda-cupti-cu12-12.1.105 nvidia-cuda-nvrtc-cu12-12.1.105 nvidia-cuda-runtime-cu12-12.1.105 nvidia-cudnn-cu12-8.9.2.26 nvidia-cufft-cu12-11.0.2.54 nvidia-curand-cu12-10.3.2.106 nvidia-cusolver-cu12-11.4.5.107 nvidia-cusparse-cu12-12.1.0.106 nvidia-nccl-cu12-2.20.5 nvidia-nvjitlink-cu12-12.5.40 nvidia-nvtx-cu12-12.1.105\n" + ] + } + ], + "source": [ + "pip install git+https://github.com/amazon-science/chronos-forecasting.git" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TNVFj6FxPfAH" + }, + "source": [ + "## Test script" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "u5VeXz_GS8f_" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import torch\n", + "from chronos import ChronosPipeline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "def predict_and_plot_crypto_data(\n", + " coin_name,\n", + " crypto_data_dict,\n", + " model_name=\"amazon/chronos-t5-small\",\n", + " prediction_length=12,\n", + " num_samples=20):\n", + "\n", + " \"\"\"\n", + " Predicts and plots cryptocurrency data for multiple coins.\n", + "\n", + " Args:\n", + " crypto_data_dict: Dictionary containing data for each cryptocurrency.\n", + " Keys should be coin names (e.g., 'BTC', 'ETH'), values should be file paths to CSV data.\n", + " model_name: Name of the pre-trained Chronos model (default: \"amazon/chronos-t5-small\").\n", + " prediction_length: Number of future data points to predict (default: 12).\n", + " num_samples: Number of prediction samples to generate (default: 20).\n", + " \"\"\"\n", + "\n", + " # Check if coin exists in data\n", + " if coin_name not in crypto_data_dict:\n", + " raise ValueError(f\"Coin '{coin_name}' not found in data dictionary.\")\n", + "\n", + "\n", + " # Initialize Chronos pipeline once outside the loop for efficiency\n", + " pipeline = ChronosPipeline.from_pretrained(\n", + " model_name,\n", + " device_map=\"cpu\", # use \"cpu\" for CPU inference and \"mps\" for Apple Silicon\n", + " torch_dtype=torch.bfloat16,\n", + " )\n", + "\n", + " predictions = {} # Create an empty dictionary to store results\n", + "\n", + " for coin_name, csv_file in crypto_data_dict.items():\n", + " # Load data for the specific coin\n", + " csv_file = crypto_data_dict[coin_name]\n", + " df = pd.read_csv(csv_file)\n", + "\n", + "\n", + " # Perform prediction\n", + " forecast = pipeline.predict(\n", + " context=torch.tensor(df[\"Close\"]),\n", + " prediction_length=prediction_length,\n", + " num_samples=num_samples,\n", + " )\n", + "\n", + " # Generate forecast index for plotting\n", + " forecast_index = range(len(df), len(df) + prediction_length)\n", + " low, median, high = np.quantile(forecast[0].numpy(), [0.1, 0.5, 0.9], axis=0)\n", + "\n", + " predictions[coin_name] = { # Add results to the dictionary\n", + " \"median\": median,\n", + " \"low\": low,\n", + " \"high\": high\n", + " }\n", + "\n", + "\n", + " # Plot and visualize predictions (replace with your desired plotting logic)\n", + " plt.plot(df[\"Close\"], label=\"Actual\")\n", + " plt.plot(forecast_index, median, label=\"Median Prediction\")\n", + " plt.fill_between(forecast_index, low, high, alpha=0.2, label=\"Prediction Range\")\n", + " plt.title(f\"Predicted {coin_name} Prices\")\n", + " plt.legend()\n", + " plt.show()\n", + "\n", + " return predictions # Return the dictionary containing predictions\n", + "\n", + "# Example usage\n", + "crypto_data = {\n", + " 'BTC' : \"/content/drive/MyDrive/backtesting/datas/yfinance/BTC-USD.csv\",\n", + " 'BNB' : \"/content/drive/MyDrive/backtesting/datas/yfinance/BNB-USD.csv\",\n", + " 'ETH' : \"/content/drive/MyDrive/backtesting/datas/yfinance/ETH-USD.csv\"\n", + "}\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 211 + }, + "id": "5cGwZYzWU7zi", + "outputId": "8949bf65-4858-477b-d74c-1285c0982981" + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "predict_and_plot_crypto_data() missing 1 required positional argument: 'crypto_data_dict'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcrypto_predictions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpredict_and_plot_crypto_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcrypto_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# Access predictions for a specific coin (e.g., 'BTC')\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mbtc_predictions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcrypto_predictions\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'BTC'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: predict_and_plot_crypto_data() missing 1 required positional argument: 'crypto_data_dict'" + ] + } + ], + "source": [ + "crypto_predictions = predict_and_plot_crypto_data(crypto_data)\n", + "\n", + "# Access predictions for a specific coin (e.g., 'BTC')\n", + "btc_predictions = crypto_predictions['BTC']\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "zYabfxk4VySV" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "XYMOyAFYS6Kn" + }, + "outputs": [], + "source": [ + "# Print the median predicted values for all coins\n", + "for coin, prediction in crypto_predictions.items():\n", + " print(f\"Coin: {coin}, Median Prediction: {prediction['median']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Zb-ikw6lU-Oz" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "8PkVm42VU-kw" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import torch\n", + "from chronos import ChronosPipeline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "\n", + "# Define the crypto coins data source dictionary\n", + "crypto_data_dict = {\n", + " 'BTC': \"/content/drive/MyDrive/backtesting/datas/yfinance/BTC-USD.csv\",\n", + " 'BNB': \"/content/drive/MyDrive/backtesting/datas/yfinance/BNB-USD.csv\",\n", + " 'ETH': \"/content/drive/MyDrive/backtesting/datas/yfinance/ETH-USD.csv\"\n", + "}\n", + "\n", + "def predict_and_plot_crypto_data(\n", + " coin_name,\n", + " crypto_data_dict,\n", + " model_name=\"amazon/chronos-t5-small\",\n", + " prediction_length=12,\n", + " num_samples=20):\n", + " \"\"\"\n", + " Predicts and plots cryptocurrency data for a single coin.\n", + "\n", + " Args:\n", + " coin_name: Name of the cryptocurrency (e.g., 'BTC', 'ETH').\n", + " crypto_data_dict: Dictionary containing data for each cryptocurrency.\n", + " Keys should be coin names, values should be file paths to CSV data.\n", + " model_name: Name of the pre-trained Chronos model (default: \"amazon/chronos-t5-small\").\n", + " prediction_length: Number of future data points to predict (default: 12).\n", + " num_samples: Number of prediction samples to generate (default: 20).\n", + " \"\"\"\n", + "\n", + "\n", + "\n", + " # Check if coin exists in data\n", + " if coin_name not in crypto_data_dict:\n", + " raise ValueError(f\"Coin '{coin_name}' not found in data dictionary.\")\n", + "\n", + " # Load data for the specified coin\n", + " csv_file = crypto_data_dict[coin_name]\n", + " df = pd.read_csv(csv_file)\n", + "\n", + " # Initialize Chronos pipeline (can be inside or outside depending on preference)\n", + " pipeline = ChronosPipeline.from_pretrained(\n", + " model_name,\n", + " device_map=\"cpu\", # use \"cpu\" for CPU inference and \"mps\" for Apple Silicon\n", + " torch_dtype=torch.bfloat16,\n", + " )\n", + "\n", + " # Perform prediction\n", + " forecast = pipeline.predict(\n", + " context=torch.tensor(df[\"Close\"]),\n", + " prediction_length=prediction_length,\n", + " num_samples=num_samples,\n", + " )\n", + "\n", + " # Generate forecast index for plotting\n", + " forecast_index = range(len(df), len(df) + prediction_length)\n", + " low, median, high = np.quantile(forecast[0].numpy(), [0.1, 0.5, 0.9], axis=0)\n", + "\n", + " # Plot and visualize predictions (replace with your desired plotting logic)\n", + " plt.plot(df[\"Close\"], label=\"Actual\")\n", + " plt.plot(forecast_index, median, label=\"Median Prediction\")\n", + " plt.fill_between(forecast_index, low, high, alpha=0.2, label=\"Prediction Range\")\n", + " plt.title(f\"Predicted {coin_name} Prices\")\n", + " plt.legend()\n", + " plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "1e-iWVnPYer1" + }, + "outputs": [], + "source": [ + "# Example usage (assuming crypto_data_dict is defined)\n", + "predict_and_plot_crypto_data('BTC', crypto_data_dict) # Call for Bitcoin" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "xnGerO0HjwUY" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f66u-dU2PoEd" + }, + "source": [ + "## Final script" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "E5sffSH1YZgP" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import torch\n", + "from chronos import ChronosPipeline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "\n", + "# Define the crypto coins data source dictionary\n", + "crypto_data_dict = {\n", + " 'BTC': \"/content/drive/MyDrive/backtesting/datas/yfinance/BTC-USD.csv\",\n", + " 'BNB': \"/content/drive/MyDrive/backtesting/datas/yfinance/BNB-USD.csv\",\n", + " 'ETH': \"/content/drive/MyDrive/backtesting/datas/yfinance/ETH-USD.csv\"\n", + "}\n", + "\n", + "def predict_and_plot_crypto_data(\n", + " coin_name,\n", + " crypto_data_dict,\n", + " model_name=\"amazon/chronos-t5-small\",\n", + " prediction_length=12,\n", + " num_samples=20):\n", + " \"\"\"\n", + " Predicts and plots cryptocurrency data for a single coin.\n", + "\n", + " Args:\n", + " coin_name (str): Name of the cryptocurrency (e.g., 'BTC', 'ETH').\n", + " crypto_data_dict (dict): Dictionary containing data for each cryptocurrency.\n", + " Keys should be coin names, values should be file paths to CSV data.\n", + " model_name (str): Name of the pre-trained Chronos model (default: \"amazon/chronos-t5-small\").\n", + " prediction_length (int): Number of future data points to predict (default: 12).\n", + " num_samples (int): Number of prediction samples to generate (default: 20).\n", + "\n", + " Raises:\n", + " ValueError: If coin_name is not found in crypto_data_dict.\n", + "\n", + " Returns:\n", + " tuple: Tuple containing forecast index and median prediction array.\n", + " \"\"\"\n", + "\n", + " # Check if coin exists in data\n", + " if coin_name not in crypto_data_dict:\n", + " raise ValueError(f\"Coin '{coin_name}' not found in data dictionary.\")\n", + "\n", + " # Load data for the specified coin\n", + " csv_file = crypto_data_dict[coin_name]\n", + " df = pd.read_csv(csv_file)\n", + "\n", + " # Initialize Chronos pipeline\n", + " pipeline = ChronosPipeline.from_pretrained(\n", + " model_name,\n", + " device_map=\"cpu\", # use \"cpu\" for CPU inference and \"mps\" for Apple Silicon\n", + " torch_dtype=torch.bfloat16,\n", + " )\n", + "\n", + " # Perform prediction\n", + " forecast = pipeline.predict(\n", + " context=torch.tensor(df[\"Close\"]),\n", + " prediction_length=prediction_length,\n", + " num_samples=num_samples,\n", + " )\n", + "\n", + " # Generate forecast index for plotting\n", + " forecast_index = range(len(df), len(df) + prediction_length)\n", + " low, median, high = np.quantile(forecast[0].numpy(), [0.1, 0.5, 0.9], axis=0)\n", + "\n", + " # Plot and visualize predictions\n", + " plt.figure(figsize=(10, 6)) # Adjust figure size as needed\n", + " plt.plot(df[\"Close\"], label=\"History\")\n", + " plt.plot(forecast_index, median, label=\"Median Prediction\")\n", + " plt.fill_between(forecast_index, low, high, alpha=0.2, label=\"Prediction Range\")\n", + " plt.title(f\"Predicted {coin_name} Prices\")\n", + " plt.xlabel(\"Time\")\n", + " plt.ylabel(\"Price\")\n", + " plt.legend()\n", + " plt.grid(True) # Add gridlines\n", + " plt.show()\n", + "\n", + " return forecast_index, median # Optionally return forecast data for further use\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 975, + "referenced_widgets": [ + "4c9f2a7e292947348ebb5aa19aa60c03", + "58b15f3a31624a74b1a4a37a56f2f5ae", + "f16f944e630446e7b1966def41aafe53", + "320c2b11c79e456a8838aca84d599837", + "811b818b0fd24c90b34b8b9c0901fe9a", + "a44f518f10164079973ae89d8c4b3876", + "09203db3ada742b4a3785c3fe665ee3d", + "fe2d1dd1e23c4466baa8687f97c450f9", + "3bb5fd1624e94602945ca3627331b7d8", + "1f02f26bfc3b4ba289f202345073dd0a", + "70fc8725add84533a7576653a8b8020a", + "4fa70be354c14e3e8604694bf566febc", + "32c8904e009d482bb8944be64e0fddb8", + "86b9f1c841924ee1bad39b03dd958618", + "ad4f30cc6c8a4d509f5ca0d656449d38", + "4f43f6a34df94bd18051a31d7cd1c819", + "9e02799a77904a5793754ffd4a4ace9b", + "cfe5cdc5684448ffaf0934978a36a24d", + "b99e59c882d64c559754685bf2f85604", + "6e80af19da4649169da97cef9adb33ca", + "d0f5c77e876c4def9c10c372623cdeda", + "226132c0b46940d98e6ac9a7aadcb93a", + "7ca46a8d95d648a3a0174ac31686f552", + "5100993ecab644d68fe10668192354d0", + "bffc9604619b4e0aa57c47543c827c2f", + "f0208806b3794f52861e0e6479b79a44", + "6e5ec6a845bb4fa5bae6ffb0501501d2", + "a272b3fe3ac64e598fa355cee75f93f9", + "dff7dc62ea6a422184047b7736847cc2", + "5de195fab8db4ca7831db2cdbcf58c89", + "a2ca7c439661484da168f2f9e166de79", + "7940904720144d16a0ef49787685a401", + "ee802bc384474c80a6490b7cd9431af0" + ] + }, + "id": "Et66P-m6jyZG", + "outputId": "82aedf88-cd53-423b-9093-ab8d8ee02e5a" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.10/dist-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n", + "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:89: UserWarning: \n", + "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", + "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", + "You will be able to reuse this secret in all of your notebooks.\n", + "Please note that authentication is recommended but still optional to access public models or datasets.\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4c9f2a7e292947348ebb5aa19aa60c03", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "config.json: 0%| | 0.00/1.11k [00:00" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "(range(367, 397),\n", + " array([3505.23374465, 3496.22272314, 3514.24476617, 3514.24476617,\n", + " 3514.24476617, 3496.22286966, 3496.22286966, 3514.24461965,\n", + " 3514.24461965, 3496.22286966, 3460.17922314, 3478.20097314,\n", + " 3514.24476617, 3541.27739117, 3649.40789116, 3604.35351617,\n", + " 3604.35351617, 3613.36439117, 3613.36439117, 3532.26636965,\n", + " 3550.28826617, 3532.26636965, 3595.34264117, 3604.35351617,\n", + " 3559.29914117, 3532.26636965, 3541.27739117, 3532.26636965,\n", + " 3478.20097314, 3523.25549465]))" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "predict_and_plot_crypto_data('ETH',crypto_data_dict, prediction_length=30)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "dF49N6fHJB12" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 775 + }, + "id": "O8bQ-Z_gJDAk", + "outputId": "5e977535-c616-4c7a-9dea-5789694ad43f" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.10/dist-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1IAAAIjCAYAAAAJLyrXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC95UlEQVR4nOzdd3hUZdoG8PtMn0kyaaQRkhB6kc4KQaUoRUAXFdsKAmJZFSvqKq7rh1jXtSuCri5YcK3IIqIQUEDpICKdUENJIb1Mpp/vj5lzMkMSMkmmpNy/6/LaZM6Zc955M2TnyfO8zyuIoiiCiIiIiIiIfKYI9QCIiIiIiIhaGgZSREREREREDcRAioiIiIiIqIEYSBERERERETUQAykiIiIiIqIGYiBFRERERETUQAykiIiIiIiIGoiBFBERERERUQMxkCIiIiIiImogBlJERNQoHTt2xIwZM+Tv161bB0EQsG7dupCN6Xznj7EtGzlyJEaOHBnqYRARtRoMpIiIWqDFixdDEAT5P51Oh27duuG+++5DXl5eqIfXICtXrsTcuXNDOgbPuRQEAWFhYejVqxeee+45mEwmr3NnzJgBQRDQt29fiKJY67Xuu+8++fsTJ07UuL7RaET//v3xzjvvwOFw1Du+uXPnej3fYDCgV69eeOqpp1BWVtb0CSAiogZThXoARETUePPmzUN6ejrMZjN+/fVXLFiwACtXrsTevXthMBiCOpbhw4ejqqoKGo2mQc9buXIl5s+fH/JgasyYMZg2bRoAoKKiAr/88gv+8Y9/YPfu3fjqq69qnL9nzx4sXboUkydP9un6f/nLXzBhwgQAQGlpKVauXIn7778fJ0+exL/+9S+frrFgwQKEh4ejoqICq1evxvPPP4+ffvoJGzduhCAIF3zu6tWrfboHERH5hoEUEVELNn78eAwePBgAcMcddyA2NhavvfYa/ve//+Evf/lLrc+prKxEWFiY38eiUCig0+n8ft1g6datG6ZOnSp/f/fdd8NqtWLp0qUwm81er02v1yMlJQXz5s3DddddV28QAwADBw70uv69996LIUOG4LPPPvM5kLr++uvRrl07eXyTJ0/G0qVLsWXLFmRkZNT6HJPJBIPB0OAAl4iILoylfURErcjll18OADh+/DgAVxlaeHg4jh49igkTJiAiIgJTpkwBADidTrzxxhvo3bs3dDodEhIS8Ne//hXFxcVe1xRFEc899xw6dOgAg8GAUaNGYd++fTXuXdcaqa1bt2LChAmIjo5GWFgY+vbtizfffFMe3/z58wF4l9dJ/D3GhkpMTIQgCFCpvP/uqFAo8NRTT+GPP/7At99+26hrC4KAhISEGtduiPN/3iNHjsRFF12EnTt3Yvjw4TAYDHjyySflY+evkTKbzZg7dy66desGnU6HpKQkXHfddTh69Kh8jq8/gx07dmDcuHFo164d9Ho90tPTMXPmzEa/NiKi5o4ZKSKiVkT6ABwbGys/ZrfbMW7cOFx66aV45ZVX5JK/v/71r1i8eDFuu+02PPDAAzh+/Djeeecd7Nq1Cxs3boRarQYAPP3003juuecwYcIETJgwAb/99hvGjh0Lq9Va73gyMzNx1VVXISkpCQ8++CASExNx4MABrFixAg8++CD++te/4uzZs8jMzMQnn3xS4/nBGKPEbDajoKAAgCtrt3HjRnz00Ue45ZZbag12brnlFjz77LOYN28err322nqzUiaTSb5+WVkZfvjhB/z444+YM2eOz2M8X20/78LCQowfPx4333wzpk6dioSEhFqf63A4cNVVV2Ht2rW4+eab8eCDD6K8vByZmZnYu3cvOnfuDMC3n0F+fj7Gjh2LuLg4PPHEE4iKisKJEyewdOnSRr82IqJmTyQiohZn0aJFIgBxzZo14rlz58RTp06Jn3/+uRgbGyvq9Xrx9OnToiiK4vTp00UA4hNPPOH1/F9++UUEIC5ZssTr8R9//NHr8fz8fFGj0YgTJ04UnU6nfN6TTz4pAhCnT58uP/bzzz+LAMSff/5ZFEVRtNvtYnp6upiWliYWFxd73cfzWrNmzRJr+7+jQIyxLgBq/e+aa64RzWaz17nTp08Xw8LCRFEUxY8++kgEIC5dutTrWrNmzZK/P378eJ3Xv+eee7zGXJf/+7//EwGIhw4dEs+dOyceP35cfO+990StVismJCSIlZWVoiiK4ogRI0QA4sKFC2tcY8SIEeKIESPk7//zn/+IAMTXXnutxrnSmHz9GXz77bciAHH79u31vhYiotaCpX1ERC3Y6NGjERcXh5SUFNx8880IDw/Ht99+i+TkZK/z7rnnHq/vv/rqK0RGRmLMmDEoKCiQ/xs0aBDCw8Px888/AwDWrFkDq9WK+++/3yvj8tBDD9U7tl27duH48eN46KGHEBUV5XXMlzVFwRijp0mTJiEzMxOZmZn43//+hzlz5uDHH3/ELbfcUmt3PgCYMmUKunbtinnz5tV5juSuu+6Sr//NN99g1qxZeO+99zB79myfx9i9e3fExcUhPT0df/3rX9GlSxd8//33Xo1FtFotbrvttnqv9c0336Bdu3a4//77axyT5tHXn4H0812xYgVsNpvPr4eIqCVjaR8RUQs2f/58dOvWDSqVCgkJCejevTsUCu+/kalUKnTo0MHrsaysLJSWliI+Pr7W6+bn5wMATp48CQDo2rWr1/G4uDhER0dfcGxS2dlFF13k+wsK8hg9dejQAaNHj5a///Of/4zY2Fg8+uijWLFiBa6++uoaz1EqlXjqqacwffp0LFu2DNdee22d1+/atavX9aUmFW+88QZmzpyJPn361DvGb775BkajEWq1Gh06dJDL7zwlJyf71Fji6NGj6N69+wXXaPn6MxgxYgQmT56MZ555Bq+//jpGjhyJa665Brfccgu0Wm29YyEiaokYSBERtWAXX3yx3LWvLlqttkZw5XQ6ER8fjyVLltT6nLi4OL+NsbGawxivuOIKAMCGDRtqDaQAV1ZKWit1zTXXNPj677zzDjZs2OBTIDV8+HC5a19d9Hp9g8ZwIb7+DARBwNdff40tW7bgu+++w6pVqzBz5ky8+uqr2LJlC8LDw/02JiKi5oKBFBFRG9S5c2esWbMGl1xyyQU/eKelpQFwZSY6deokP37u3LkaXdtquwcA7N271ysTc766yvyCMcb62O12AK59peoiZaVmzJiB//3vf36/fqB07twZW7duhc1mk5t21HaOLz8DydChQzF06FA8//zz+OyzzzBlyhR8/vnnuOOOO/w9fCKikOMaKSKiNujGG2+Ew+HAs88+W+OY3W5HSUkJANcaLLVajbfffttrDdAbb7xR7z0GDhyI9PR0vPHGG/L1JJ7Xkva0Ov+cYIyxPt999x0AoF+/fhc8b+rUqejSpQueeeaZgFw/ECZPnoyCggK88847NY5J8+jrz6C4uLjGGrH+/fsDACwWi38HTkTUTDAjRUTUBo0YMQJ//etf8eKLL+L333/H2LFjoVarkZWVha+++gpvvvkmrr/+esTFxeHRRx/Fiy++iKuuugoTJkzArl278MMPP9RbYqZQKLBgwQJcffXV6N+/P2677TYkJSXh4MGD2LdvH1atWgUAGDRoEADggQcewLhx46BUKnHzzTcHZYyeDh8+jE8//RSAq1X5li1b8NFHH6FLly649dZbL/hcpVKJv//97xds8vDbb7/J1y8vL8fatWvxzTffYNiwYRg7dqzP4/SXadOm4eOPP8bs2bOxbds2XHbZZaisrMSaNWtw7733YtKkST7/DD766CO8++67uPbaa9G5c2eUl5fj3//+N4xGIyZMmBD010ZEFBQh7BhIRESNJLU/r6/dtGer7tq8//774qBBg0S9Xi9GRESIffr0Ef/2t7+JZ8+elc9xOBziM888IyYlJYl6vV4cOXKkuHfvXjEtLe2C7c8lv/76qzhmzBgxIiJCDAsLE/v27Su+/fbb8nG73S7ef//9YlxcnCgIQo1W6P4cY11wXltypVIpdujQQbzrrrvEvLw8n+bUZrOJnTt39qn9uUqlEjt16iQ+9thjYnl5eb3jk9qfnzt37oLnjRgxQuzdu3edxzzbn4uiKJpMJvHvf/+7mJ6eLqrVajExMVG8/vrrxaNHj3qdV9/P4LfffhP/8pe/iKmpqaJWqxXj4+PFq666StyxY0e9r42IqKUSRLGefq1ERERERETkhWukiIiIiIiIGoiBFBERERERUQMxkCIiIiIiImogBlJEREREREQNxECKiIiIiIiogRhIERERERERNRA35AXgdDpx9uxZREREQBCEUA+HiIiIiIhCRBRFlJeXo3379lAo6s47MZACcPbsWaSkpIR6GERERERE1EycOnUKHTp0qPM4AykAERERAFyTZTQaQzoWm82G1atXY+zYsVCr1SEdS2vFOQ48znHgcY4Dj3MceJzjwOMcBx7nOPCCPcdlZWVISUmRY4S6MJAC5HI+o9HYLAIpg8EAo9HIf4wBwjkOPM5x4HGOA49zHHic48DjHAce5zjwQjXH9S35YbMJIiIiIiKiBmIgRURERERE1EAMpIiIiIiIiBqIa6R85HA4YLPZAn4fm80GlUoFs9kMh8MR8Pu1Ra19jpVKJVQqFVv5ExEREQUQAykfVFRU4PTp0xBFMeD3EkURiYmJOHXqFD8IB0hbmGODwYCkpCRoNJpQD4WIiIioVWIgVQ+Hw4HTp0/DYDAgLi4u4B+8nU4nKioqEB4efsENwKjxWvMci6IIq9WKc+fO4fjx4+jatWure41EREREzQEDqXrY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K5PJsHHjRixcuBDx8fFwcHDAvHnz8NZbb/XWZRARERER0U3GoomUEKLLY2xtbbF8+XIsX76802OCgoKwefPmnmwaERERERFRpyw6R4qIiIiIiKgvYiJFRERERERkIiZSREREREREJmIiRUREREREZCImUkRERERERCZiIkVERERERGQiJlJEREREREQmYiJFRERERERkIiZSREREREREJpJbugHWQAgBAKirq7NwSwC1Wo2mpibU1dVBoVBYujk3JMbY/Bhj82OMzY8xNj/G2PwYY/NjjM2vt2PcnhO05widYSIFoL6+HgAQEBBg4ZYQEREREZE1qK+vh4uLS6f7JaKrVOsmoNPpUFJSAicnJ0gkEou2pa6uDgEBASgqKoKzs7NF23KjYozNjzE2P8bY/Bhj82OMzY8xNj/G2Px6O8ZCCNTX18PPzw9SaeczodgjBUAqlcLf39/SzTDi7OzMf4xmxhibH2Nsfoyx+THG5scYmx9jbH6Msfn1Zoyv1hPVjsUmiIiIiIiITMREioiIiIiIyERMpKyMjY0Nli5dChsbG0s35YbFGJsfY2x+jLH5McbmxxibH2Nsfoyx+VlrjFlsgoiIiIiIyETskSIiIiIiIjIREykiIiIiIiITMZEiIiIiIiIyERMpIiIiIiIiEzGRsiLLly9H//79YWtri5EjR+Lw4cOWblKf9cYbb0AikRh9RUVFGfY3NzcjMTERHh4ecHR0xOzZs1FeXm7BFlu/PXv2YObMmfDz84NEIsH69euN9gsh8Prrr8PX1xd2dnaYMmUKsrOzjY6prq7GnDlz4OzsDFdXVzz++ONoaGjoxauwbl3FeP78+Vfc19OmTTM6hjG+umXLlmH48OFwcnKCt7c37rrrLmRlZRkd053Ph8LCQsyYMQP29vbw9vbGiy++CI1G05uXYrW6E+OJEydecS8vWLDA6BjGuHOfffYZYmNjDYuTxsfH4+effzbs5z18/bqKMe/hnvXee+9BIpFg8eLFhm194T5mImUlVq9ejeeffx5Lly7F0aNHMXjwYEydOhUVFRWWblqfNXDgQJSWlhq+9u3bZ9j33HPP4aeffsKaNWuwe/dulJSU4J577rFga61fY2MjBg8ejOXLl3e4/4MPPsDHH3+Mzz//HIcOHYKDgwOmTp2K5uZmwzFz5szBqVOnkJSUhI0bN2LPnj146qmn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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "(range(367, 397),\n", + " array([594.73070968, 594.73070968, 588.23798057, 586.93946431,\n", + " 584.34236844, 590.83507644, 597.32776332, 599.92485919,\n", + " 605.11900869, 601.22339656, 603.82047132, 609.01462082,\n", + " 607.71608345, 607.71608345, 602.52193394, 599.92485919,\n", + " 599.92485919, 598.62632181, 603.82047132, 598.62632181,\n", + " 597.32778443, 598.62632181, 602.52193394, 603.82047132,\n", + " 603.82047132, 599.92485919, 601.22339656, 602.52193394,\n", + " 599.92485919, 599.92485919]))" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "predict_and_plot_crypto_data('BNB',crypto_data_dict, prediction_length=30)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "anSVDe5pJh2h" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "UpJ9IYLxJiD1" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IHwxu8DgKSqR" + }, + "source": [ + "## Testing the accuracy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "hiAjigvDKYhD" + }, + "outputs": [], + "source": [ + "# Define the crypto coins data source dictionary\n", + "crypto_data_dict = {\n", + " 'BTC': \"/content/drive/MyDrive/backtesting/datas/yfinance/BTC-USD.csv\",\n", + " 'BNB': \"/content/drive/MyDrive/backtesting/datas/yfinance/BNB-USD.csv\",\n", + " 'ETH': \"/content/drive/MyDrive/backtesting/datas/yfinance/ETH-USD.csv\"\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "_pV4n8zkKkrZ", + "outputId": "294aad97-1911-4ab5-c2cb-c331e239d3cf" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "summary": "{\n \"name\": \"bnb\",\n \"rows\": 367,\n \"fields\": [\n {\n \"column\": \"Date\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 367,\n \"samples\": [\n \"2023-12-30\",\n \"2023-07-23\",\n \"2023-07-05\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Open\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 156.35783578416468,\n \"min\": 205.2258,\n \"max\": 710.460388,\n \"num_unique_values\": 367,\n \"samples\": [\n 313.841949,\n 241.054657,\n 242.499481\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"High\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 160.59017849855874,\n \"min\": 206.659103,\n \"max\": 720.672607,\n \"num_unique_values\": 367,\n \"samples\": [\n 320.111572,\n 243.976486,\n 243.861115\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Low\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 151.5776883642462,\n \"min\": 203.655441,\n \"max\": 692.994751,\n \"num_unique_values\": 367,\n \"samples\": [\n 313.560059,\n 240.761215,\n 237.120117\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Close\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 156.76779673717954,\n \"min\": 205.229416,\n \"max\": 710.46405,\n \"num_unique_values\": 367,\n \"samples\": [\n 317.166199,\n 242.455963,\n 239.081085\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Adj Close\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 156.76779673717954,\n \"min\": 205.229416,\n \"max\": 710.46405,\n \"num_unique_values\": 367,\n \"samples\": [\n 317.166199,\n 242.455963,\n 239.081085\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Volume\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 936135344,\n \"min\": 203846460,\n \"max\": 5849156503,\n \"num_unique_values\": 367,\n \"samples\": [\n 901159404,\n 279600847,\n 455501209\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", + "type": "dataframe", + "variable_name": "bnb" + }, + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DateOpenHighLowCloseAdj CloseVolume
02023-06-20242.881851247.822693239.018738247.674438247.674438477391843
12023-06-21247.682938253.541931245.548248249.286346249.286346717670519
22023-06-22249.276474256.220032240.052200240.792435240.792435709030407
32023-06-23240.792053248.809784240.094818244.564941244.564941493157882
42023-06-24244.553513248.428619231.994751236.659653236.659653558809140
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "
\n", + "\n", + "
\n", + "
\n" + ], + "text/plain": [ + " Date Open High Low Close Adj Close \\\n", + "0 2023-06-20 242.881851 247.822693 239.018738 247.674438 247.674438 \n", + "1 2023-06-21 247.682938 253.541931 245.548248 249.286346 249.286346 \n", + "2 2023-06-22 249.276474 256.220032 240.052200 240.792435 240.792435 \n", + "3 2023-06-23 240.792053 248.809784 240.094818 244.564941 244.564941 \n", + "4 2023-06-24 244.553513 248.428619 231.994751 236.659653 236.659653 \n", + "\n", + " Volume \n", + "0 477391843 \n", + "1 717670519 \n", + "2 709030407 \n", + "3 493157882 \n", + "4 558809140 " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "csv_file = crypto_data_dict['BNB']\n", + "bnb = pd.read_csv(csv_file)\n", + "\n", + "bnb.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "sVSss9byKrhh", + "outputId": "6bcc2be4-4219-4387-d991-039755fb3e88" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "('2023-06-20', '2024-06-20')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bnb['Date'].min(), bnb['Date'].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "mX2Bx2HmLVjM", + "outputId": "6ef5f8e4-0e52-4f2f-8c4c-d263066c31c9" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "dtype('O')" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bnb['Date'].dtypes" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IrtxxW3JPTOe" + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SRmfrcD0L4LC" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "\n", + "\n", + "bnb['Date'] = pd.to_Datetime(bnb['Date'])\n", + "\n", + "num_days = (bnb['Date'].max() - bnb['Date'].min()) / np.timedelta64(1, 'D') # for days\n", + "num_hours = (bnb['Date'].max() - bnb['Date'].min()) / np.timedelta64(1, 'h') # for hours\n", + "print(num_days)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "HrzVHLbIN-CI" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [ + "b3eFoFYDPXtU" + ], + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "09203db3ada742b4a3785c3fe665ee3d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "1f02f26bfc3b4ba289f202345073dd0a": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "226132c0b46940d98e6ac9a7aadcb93a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "320c2b11c79e456a8838aca84d599837": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_1f02f26bfc3b4ba289f202345073dd0a", + "placeholder": "​", + "style": "IPY_MODEL_70fc8725add84533a7576653a8b8020a", + "value": " 1.11k/1.11k [00:00<00:00, 34.4kB/s]" + } + }, + "32c8904e009d482bb8944be64e0fddb8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_9e02799a77904a5793754ffd4a4ace9b", + "placeholder": "​", + "style": "IPY_MODEL_cfe5cdc5684448ffaf0934978a36a24d", + "value": "model.safetensors: 100%" + } + }, + "3bb5fd1624e94602945ca3627331b7d8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "4c9f2a7e292947348ebb5aa19aa60c03": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_58b15f3a31624a74b1a4a37a56f2f5ae", + "IPY_MODEL_f16f944e630446e7b1966def41aafe53", + "IPY_MODEL_320c2b11c79e456a8838aca84d599837" + ], + "layout": "IPY_MODEL_811b818b0fd24c90b34b8b9c0901fe9a" + } + }, + "4f43f6a34df94bd18051a31d7cd1c819": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4fa70be354c14e3e8604694bf566febc": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_32c8904e009d482bb8944be64e0fddb8", + "IPY_MODEL_86b9f1c841924ee1bad39b03dd958618", + "IPY_MODEL_ad4f30cc6c8a4d509f5ca0d656449d38" + ], + "layout": "IPY_MODEL_4f43f6a34df94bd18051a31d7cd1c819" + } + }, + "5100993ecab644d68fe10668192354d0": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a272b3fe3ac64e598fa355cee75f93f9", + "placeholder": "​", + "style": "IPY_MODEL_dff7dc62ea6a422184047b7736847cc2", + "value": "generation_config.json: 100%" + } + }, + "58b15f3a31624a74b1a4a37a56f2f5ae": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a44f518f10164079973ae89d8c4b3876", + "placeholder": "​", + "style": "IPY_MODEL_09203db3ada742b4a3785c3fe665ee3d", + "value": "config.json: 100%" + } + }, + "5de195fab8db4ca7831db2cdbcf58c89": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6e5ec6a845bb4fa5bae6ffb0501501d2": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6e80af19da4649169da97cef9adb33ca": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "70fc8725add84533a7576653a8b8020a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "7940904720144d16a0ef49787685a401": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7ca46a8d95d648a3a0174ac31686f552": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_5100993ecab644d68fe10668192354d0", + "IPY_MODEL_bffc9604619b4e0aa57c47543c827c2f", + "IPY_MODEL_f0208806b3794f52861e0e6479b79a44" + ], + "layout": "IPY_MODEL_6e5ec6a845bb4fa5bae6ffb0501501d2" + } + }, + "811b818b0fd24c90b34b8b9c0901fe9a": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "86b9f1c841924ee1bad39b03dd958618": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_b99e59c882d64c559754685bf2f85604", + "max": 184632480, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_6e80af19da4649169da97cef9adb33ca", + "value": 184632480 + } + }, + "9e02799a77904a5793754ffd4a4ace9b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a272b3fe3ac64e598fa355cee75f93f9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a2ca7c439661484da168f2f9e166de79": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "a44f518f10164079973ae89d8c4b3876": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "ad4f30cc6c8a4d509f5ca0d656449d38": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d0f5c77e876c4def9c10c372623cdeda", + "placeholder": "​", + "style": "IPY_MODEL_226132c0b46940d98e6ac9a7aadcb93a", + "value": " 185M/185M [00:02<00:00, 71.6MB/s]" + } + }, + "b99e59c882d64c559754685bf2f85604": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "bffc9604619b4e0aa57c47543c827c2f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5de195fab8db4ca7831db2cdbcf58c89", + "max": 142, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_a2ca7c439661484da168f2f9e166de79", + "value": 142 + } + }, + "cfe5cdc5684448ffaf0934978a36a24d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "d0f5c77e876c4def9c10c372623cdeda": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "dff7dc62ea6a422184047b7736847cc2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "ee802bc384474c80a6490b7cd9431af0": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "f0208806b3794f52861e0e6479b79a44": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_7940904720144d16a0ef49787685a401", + "placeholder": "​", + "style": "IPY_MODEL_ee802bc384474c80a6490b7cd9431af0", + "value": " 142/142 [00:00<00:00, 2.24kB/s]" + } + }, + "f16f944e630446e7b1966def41aafe53": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_fe2d1dd1e23c4466baa8687f97c450f9", + "max": 1113, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_3bb5fd1624e94602945ca3627331b7d8", + "value": 1113 + } + }, + "fe2d1dd1e23c4466baa8687f97c450f9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/scripts/forecasting.py b/scripts/forecasting.py new file mode 100644 index 0000000..86724ca --- /dev/null +++ b/scripts/forecasting.py @@ -0,0 +1,77 @@ +import pandas as pd +import torch +from chronos import ChronosPipeline +import matplotlib.pyplot as plt +import numpy as np + + +# Define the crypto coins data source dictionary +crypto_data_dict = { + 'BTC': "/content/drive/MyDrive/backtesting/datas/yfinance/BTC-USD.csv", + 'BNB': "/content/drive/MyDrive/backtesting/datas/yfinance/BNB-USD.csv", + 'ETH': "/content/drive/MyDrive/backtesting/datas/yfinance/ETH-USD.csv" +} + +def predict_and_plot_crypto_data( + coin_name, + crypto_data_dict, + model_name="amazon/chronos-t5-small", + prediction_length=12, + num_samples=20): + """ + Predicts and plots cryptocurrency data for a single coin. + + Args: + coin_name (str): Name of the cryptocurrency (e.g., 'BTC', 'ETH'). + crypto_data_dict (dict): Dictionary containing data for each cryptocurrency. + Keys should be coin names, values should be file paths to CSV data. + model_name (str): Name of the pre-trained Chronos model (default: "amazon/chronos-t5-small"). + prediction_length (int): Number of future data points to predict (default: 12). + num_samples (int): Number of prediction samples to generate (default: 20). + + Raises: + ValueError: If coin_name is not found in crypto_data_dict. + + Returns: + tuple: Tuple containing forecast index and median prediction array. + """ + + # Check if coin exists in data + if coin_name not in crypto_data_dict: + raise ValueError(f"Coin '{coin_name}' not found in data dictionary.") + + # Load data for the specified coin + csv_file = crypto_data_dict[coin_name] + df = pd.read_csv(csv_file) + + # Initialize Chronos pipeline + pipeline = ChronosPipeline.from_pretrained( + model_name, + device_map="cpu", # use "cpu" for CPU inference and "mps" for Apple Silicon + torch_dtype=torch.bfloat16, + ) + + # Perform prediction + forecast = pipeline.predict( + context=torch.tensor(df["Close"]), + prediction_length=prediction_length, + num_samples=num_samples, + ) + + # Generate forecast index for plotting + forecast_index = range(len(df), len(df) + prediction_length) + low, median, high = np.quantile(forecast[0].numpy(), [0.1, 0.5, 0.9], axis=0) + + # Plot and visualize predictions + plt.figure(figsize=(10, 6)) # Adjust figure size as needed + plt.plot(df["Close"], label="History") + plt.plot(forecast_index, median, label="Median Prediction") + plt.fill_between(forecast_index, low, high, alpha=0.2, label="Prediction Range") + plt.title(f"Predicted {coin_name} Prices") + plt.xlabel("Time") + plt.ylabel("Price") + plt.legend() + plt.grid(True) # Add gridlines + plt.show() + + return forecast_index, median # Optionally return forecast data for further use