{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# GRU-SAC Trading Pipeline: Example Usage\n",
    "\n",
    "This notebook demonstrates how to instantiate and run the refactored `TradingPipeline` class.\n",
    "\n",
    "**Goal:** Run the complete pipeline (data loading, feature engineering, GRU training/loading, calibration, optional SAC training, backtesting) using a configuration file and inspect the results."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Imports and Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initial sys.path: ['/home/yasha/develop', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '', '/home/yasha/develop/gru_sac_predictor/.venv/lib/python3.10/site-packages']\n",
      "Notebook directory (notebook_dir): /home/yasha/develop/gru_sac_predictor/notebooks\n",
      "Calculated path for imports (project_root_for_imports): /home/yasha/develop/gru_sac_predictor\n",
      "Checking if /home/yasha/develop/gru_sac_predictor is in sys.path...\n",
      "Path not found. Adding /home/yasha/develop/gru_sac_predictor to sys.path.\n",
      "sys.path after insert: ['/home/yasha/develop/gru_sac_predictor', '/home/yasha/develop', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '', '/home/yasha/develop/gru_sac_predictor/.venv/lib/python3.10/site-packages']\n",
      "Package path (package_path): /home/yasha/develop/gru_sac_predictor/gru_sac_predictor\n",
      "Src path (src_path): /home/yasha/develop/gru_sac_predictor/gru_sac_predictor/src\n",
      "\n",
      "Attempting to import TradingPipeline...\n",
      "ERROR: Failed to import TradingPipeline: No module named 'gru_sac_predictor.src'\n",
      "Final sys.path before error: ['/home/yasha/develop/gru_sac_predictor', '/home/yasha/develop', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '', '/home/yasha/develop/gru_sac_predictor/.venv/lib/python3.10/site-packages']\n",
      "Please verify the calculated paths above and ensure the directory containing 'gru_sac_predictor' is correctly added to sys.path.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "import yaml\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.image as mpimg\n",
    "import logging\n",
    "\n",
    "print(f'Initial sys.path: {sys.path}')\n",
    "\n",
    "# --- Path Setup ---\n",
    "# Initialize project_root to None\n",
    "project_root = None\n",
    "project_root_for_imports = None # Initialize separately for clarity\n",
    "try:\n",
    "    notebook_dir = os.path.abspath('') # Get current directory (should be notebooks/)\n",
    "    print(f'Notebook directory (notebook_dir): {notebook_dir}')\n",
    "\n",
    "    # *** CORRECTED LINE BELOW ***\n",
    "    # Go up ONE level to get the directory containing the gru_sac_predictor package\n",
    "    # Assuming notebook is in develop/gru_sac_predictor/notebooks/\n",
    "    # This should result in '/home/yasha/develop/gru_sac_predictor'\n",
    "    project_root_for_imports = os.path.dirname(notebook_dir)\n",
    "    print(f'Calculated path for imports (project_root_for_imports): {project_root_for_imports}')\n",
    "\n",
    "    # Add the calculated path to sys.path to allow imports from gru_sac_predictor\n",
    "    print(f'Checking if {project_root_for_imports} is in sys.path...')\n",
    "    if project_root_for_imports not in sys.path:\n",
    "        print(f'Path not found. Adding {project_root_for_imports} to sys.path.')\n",
    "        sys.path.insert(0, project_root_for_imports)\n",
    "        print(f'sys.path after insert: {sys.path}')\n",
    "    else:\n",
    "        print(f'Path {project_root_for_imports} already in sys.path.')\n",
    "\n",
    "    # Define project_root consistently, used later for finding config.yaml\n",
    "    project_root = project_root_for_imports\n",
    "    if project_root: # Check if project_root was set successfully\n",
    "        package_path = os.path.join(project_root, 'gru_sac_predictor')\n",
    "        src_path = os.path.join(package_path, 'src')\n",
    "        print(f'Package path (package_path): {package_path}')\n",
    "        print(f'Src path (src_path): {src_path}')\n",
    "    else:\n",
    "        print(\"Project root could not be determined.\")\n",
    "\n",
    "except Exception as e:\n",
    "    print(f'Error during path setup: {e}')\n",
    "\n",
    "# --- Import the main pipeline class ---\n",
    "print(\"\\nAttempting to import TradingPipeline...\")\n",
    "try:\n",
    "    # Now this import should work if the path setup is correct\n",
    "    from gru_sac_predictor.src.trading_pipeline import TradingPipeline\n",
    "    print('Successfully imported TradingPipeline.')\n",
    "except ImportError as e:\n",
    "    print(f'ERROR: Failed to import TradingPipeline: {e}')\n",
    "    print(f'Final sys.path before error: {sys.path}')\n",
    "    print(\"Please verify the calculated paths above and ensure the directory containing 'gru_sac_predictor' is correctly added to sys.path.\")\n",
    "    # Handle error appropriately, maybe raise it\n",
    "except Exception as e: # Catch other potential errors\n",
    "    print(f'An unexpected error occurred during import: {e}')\n",
    "    print(f'Final sys.path before error: {sys.path}')\n",
    "\n",
    "# Configure basic logging for the notebook\n",
    "logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Configuration\n",
    "\n",
    "Specify the path to the configuration file (`config.yaml`). This file defines all parameters for the data, models, training, and backtesting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using config file: /home/../gru_sac_predictor/config.yaml\n",
      "ERROR: Config file not found at /home/../gru_sac_predictor/config.yaml\n"
     ]
    }
   ],
   "source": [
    "# Path to the configuration file \n",
    "# Assumes config.yaml is in the gru_sac_predictor package directory, one level above src\n",
    "config_rel_path = '../config.yaml'\n",
    "# Construct absolute path relative to the project root identified earlier\n",
    "if 'project_root' in locals():\n",
    "    config_abs_path = os.path.join(project_root, config_rel_path)\n",
    "else:\n",
    "    print('ERROR: project_root not defined. Cannot find config file.')\n",
    "    config_abs_path = None\n",
    "\n",
    "if config_abs_path:\n",
    "    print(f'Using config file: {config_abs_path}')\n",
    "    # Verify the config file exists\n",
    "    if not os.path.exists(config_abs_path):\n",
    "        print(f'ERROR: Config file not found at {config_abs_path}')\n",
    "    else:\n",
    "        print('Config file found.')\n",
    "        # Optionally load and display config for verification\n",
    "        try:\n",
    "            with open(config_abs_path, 'r') as f:\n",
    "                config_data = yaml.safe_load(f)\n",
    "            # print('\\nConfiguration:')\n",
    "            # print(yaml.dump(config_data, default_flow_style=False)) # Pretty print\n",
    "        except Exception as e:\n",
    "            print(f'Error reading config file: {e}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Instantiate and Run the Pipeline\n",
    "\n",
    "Create an instance of the `TradingPipeline` and run its `execute()` method. This will perform all the steps defined in the configuration.\n",
    "\n",
    "**Note:** Depending on the configuration (especially `train_gru` and `train_sac` flags) and the data size, this cell might take a significant amount of time to run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pipeline_instance = None # Define outside try block\n",
    "if 'TradingPipeline' in locals() and config_abs_path and os.path.exists(config_abs_path): \n",
    "    try:\n",
    "        # Instantiate the pipeline\n",
    "        pipeline_instance = TradingPipeline(config_path=config_abs_path)\n",
    "        \n",
    "        # Execute the full pipeline\n",
    "        print('\\n=== Starting Pipeline Execution ===')\n",
    "        pipeline_instance.execute()\n",
    "        print('=== Pipeline Execution Finished ===')\n",
    "        \n",
    "    except FileNotFoundError as e:\n",
    "        print(f'ERROR during pipeline instantiation (FileNotFound): {e}')\n",
    "    except Exception as e:\n",
    "        print(f'An error occurred during pipeline execution: {e}')\n",
    "        logging.error('Pipeline execution failed.', exc_info=True) # Log traceback\n",
    "else:\n",
    "    print('TradingPipeline class not imported, config path invalid, or config file not found. Cannot run pipeline.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Inspect Results\n",
    "\n",
    "After the pipeline execution, we can inspect the results stored within the `pipeline_instance` object and the files saved to the run directory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if pipeline_instance is not None and pipeline_instance.backtest_metrics:\n",
    "    print('\\n--- Backtest Metrics --- ')\n",
    "    # Pretty print the metrics dictionary\n",
    "    metrics = pipeline_instance.backtest_metrics\n",
    "    # Update Run ID in metrics before printing\n",
    "    metrics['Run ID'] = pipeline_instance.run_id \n",
    "    \n",
    "    for key, value in metrics.items():\n",
    "        if key == \"Confusion Matrix (GRU Signal vs Actual Dir)\":\n",
    "             print(f'{key}:\\n{np.array(value)}') \n",
    "        elif key == \"Classification Report (GRU Signal)\":\n",
    "             print(f'{key}:\\n{value}')\n",
    "        elif isinstance(value, float):\n",
    "             print(f'{key}: {value:.4f}')\n",
    "        else:\n",
    "             print(f'{key}: {value}')\n",
    "else:\n",
    "    print('\\nPipeline object not found or backtest did not produce metrics.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if pipeline_instance is not None and pipeline_instance.backtest_results_df is not None:\n",
    "    print('\\n--- Backtest Results DataFrame (Head) --- ')\n",
    "    pd.set_option('display.max_columns', None) # Show all columns\n",
    "    pd.set_option('display.width', 1000) # Wider display\n",
    "    display(pipeline_instance.backtest_results_df.head())\n",
    "    print('\\n--- Backtest Results DataFrame (Tail) --- ')\n",
    "    display(pipeline_instance.backtest_results_df.tail())\n",
    "    \n",
    "    # Display basic stats\n",
    "    print('\\n--- Backtest Results DataFrame (Description) --- ')\n",
    "    display(pipeline_instance.backtest_results_df.describe())\n",
    "else:\n",
    "    print('\\nPipeline object not found or backtest did not produce results DataFrame.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Display Saved Plots\n",
    "\n",
    "Load and display the plots generated during the backtest. These are saved in the `results/<run_id>` directory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if pipeline_instance is not None and pipeline_instance.dirs.get('results'):\n",
    "    results_dir = pipeline_instance.dirs['results']\n",
    "    run_id = pipeline_instance.run_id\n",
    "    print(f'Looking for plots in: {results_dir}\\n')\n",
    "    \n",
    "    plot_files = [\n",
    "        f'backtest_summary_{run_id}.png', \n",
    "        f'confusion_matrix_{run_id}.png', \n",
    "        f'reliability_curve_val_{run_id}.png' # Optional validation plot\n",
    "    ]\n",
    "    \n",
    "    for plot_file in plot_files:\n",
    "        plot_path = os.path.join(results_dir, plot_file)\n",
    "        if os.path.exists(plot_path):\n",
    "            print(f'--- Displaying: {plot_file} ---')\n",
    "            try:\n",
    "                img = mpimg.imread(plot_path)\n",
    "                # Determine appropriate figure size based on plot type\n",
    "                figsize = (15, 12) if 'summary' in plot_file else (7, 6)\n",
    "                plt.figure(figsize=figsize)\n",
    "                plt.imshow(img)\n",
    "                plt.axis('off') # Hide axes for image display\n",
    "                plt.title(plot_file)\n",
    "                plt.show()\n",
    "            except Exception as e:\n",
    "                 print(f'  Error loading/displaying plot {plot_file}: {e}')\n",
    "        else:\n",
    "            print(f'Plot not found: {plot_path}')\n",
    "            \n",
    "else:\n",
    "    print('\\nPipeline object not found or results directory is not available. Cannot display plots.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Conclusion\n",
    "\n",
    "This notebook demonstrated the basic workflow of using the `TradingPipeline`. You can modify the `config.yaml` file to experiment with different parameters, data ranges, and control flags (e.g., enabling/disabling GRU or SAC training). The results (metrics, plots, detailed CSV) are saved in the run-specific directory under `results/`."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
