Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: 10Accademy-InsightStreamInc/Scalable_Backtesting_Infrastructure_for_Crypto_Trading
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: dev-abuke/Scalable_Backtesting_Infrastructure_for_Crypto_Trading
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Able to merge. These branches can be automatically merged.
Loading
Showing with 21,683 additions and 24,000 deletions.
  1. +1 −1 .gitignore
  2. +35 −0 0.5.1
  3. +33 −0 Dockerfile.backend
  4. +29 −0 Dockerfile.frontend
  5. +125 −7 README.md
  6. +26 −0 airflow/Dockerfile
  7. +112 −0 airflow/dags/backtest_dag.py
  8. +83 −0 airflow/dags/fetch_stock_data.py
  9. +137 −0 airflow/docker-compose.yml
  10. +1 −0 airflow/logs/scheduler/latest
  11. +17 −0 airflow/requirements.txt
  12. +117 −0 alembic.ini
  13. +1 −0 alembic/README
  14. +68 −0 alembic/env.py
  15. +26 −0 alembic/script.py.mako
  16. +1 −0 backend/auth.py
  17. +136 −36 backend/main.py
  18. +22 −8 backend/models.py
  19. +22 −8 backend/schemas.py
  20. +9 −21 frontend/.gitignore
  21. +67 −7 frontend/README.md
  22. +0 −15 frontend/index.html
  23. +16,129 −3,673 frontend/package-lock.json
  24. +22 −26 frontend/package.json
  25. +0 −6 frontend/postcss.config.js
  26. +0 −3 frontend/public/analyticshelp.svg
  27. +0 −4 frontend/public/analyticslogout.svg
  28. BIN frontend/public/avatar-1@2x.png
  29. BIN frontend/public/avatar@2x.png
  30. BIN {updated_frontend → frontend}/public/favicon.ico
  31. +0 −3 frontend/public/icon.svg
  32. +1 −0 {updated_frontend → frontend}/public/index.html
  33. +0 −17 frontend/public/logo.svg
  34. BIN {updated_frontend → frontend}/public/logo192.png
  35. BIN {updated_frontend → frontend}/public/logo512.png
  36. 0 {updated_frontend → frontend}/public/manifest.json
  37. +0 −4 frontend/public/notification.svg
  38. 0 {updated_frontend → frontend}/public/robots.txt
  39. +0 −3 frontend/public/setupaccount-setup.svg
  40. +0 −3 frontend/public/short-arrow.svg
  41. BIN frontend/public/trailing-icon@2x.png
  42. +0 −1 frontend/public/vite.svg
  43. +38 −0 frontend/src/App.js
  44. +0 −66 frontend/src/App.jsx
  45. +0 −103 frontend/src/components/Auth0FormsLogin.jsx
  46. +0 −90 frontend/src/components/Auth0FormsSignup.jsx
  47. +245 −0 frontend/src/components/BacktestForm.js
  48. +0 −44 frontend/src/components/DesktopDefault.jsx
  49. +0 −61 frontend/src/components/DesktopDefault1.jsx
  50. +0 −148 frontend/src/components/InputFields.jsx
  51. +46 −9 {updated_frontend → frontend}/src/components/Login.js
  52. +65 −0 frontend/src/components/Navbar.js
  53. +166 −0 frontend/src/components/Profile.js
  54. +0 −372 frontend/src/components/ResultData.jsx
  55. +124 −0 frontend/src/components/SceneList.js
  56. +67 −15 {updated_frontend → frontend}/src/components/Signup.js
  57. +0 −14 frontend/src/global.css
  58. +7 −0 {updated_frontend → frontend}/src/index.css
  59. 0 {updated_frontend → frontend}/src/index.js
  60. +0 −20 frontend/src/index.jsx
  61. +0 −79 frontend/src/pages/Backtest.jsx
  62. +0 −11 frontend/src/pages/Login.jsx
  63. +0 −47 frontend/src/pages/Result.jsx
  64. +0 −11 frontend/src/pages/Signup.jsx
  65. +0 −13 frontend/src/reportWebVitals.jsx
  66. +10 −65 frontend/tailwind.config.js
  67. +0 −10 frontend/vite.config.mjs
  68. +1 −1 kafka_topic/conduktor.yml
  69. +2 −0 kafka_topic/kafka_config.py
  70. +15 −0 mlruns/0/10907cb5bf4b4682a3e3263cd492417d/meta.yaml
  71. +1 −0 mlruns/0/10907cb5bf4b4682a3e3263cd492417d/tags/mlflow.runName
  72. +1 −0 mlruns/0/10907cb5bf4b4682a3e3263cd492417d/tags/mlflow.source.name
  73. +1 −0 mlruns/0/10907cb5bf4b4682a3e3263cd492417d/tags/mlflow.source.type
  74. +1 −0 mlruns/0/10907cb5bf4b4682a3e3263cd492417d/tags/mlflow.user
  75. +15 −0 mlruns/0/157a11fadf914d06b512b2d1a68754f1/meta.yaml
  76. +1 −0 mlruns/0/157a11fadf914d06b512b2d1a68754f1/tags/mlflow.runName
  77. +1 −0 mlruns/0/157a11fadf914d06b512b2d1a68754f1/tags/mlflow.source.name
  78. +1 −0 mlruns/0/157a11fadf914d06b512b2d1a68754f1/tags/mlflow.source.type
  79. +1 −0 mlruns/0/157a11fadf914d06b512b2d1a68754f1/tags/mlflow.user
  80. +15 −0 mlruns/0/1b0617c0c97a49758cab155987a2d886/meta.yaml
  81. +1 −0 mlruns/0/1b0617c0c97a49758cab155987a2d886/tags/mlflow.runName
  82. +1 −0 mlruns/0/1b0617c0c97a49758cab155987a2d886/tags/mlflow.source.name
  83. +1 −0 mlruns/0/1b0617c0c97a49758cab155987a2d886/tags/mlflow.source.type
  84. +1 −0 mlruns/0/1b0617c0c97a49758cab155987a2d886/tags/mlflow.user
  85. +15 −0 mlruns/0/28292ef1274c481ebf9936cfdc9e9503/meta.yaml
  86. +1 −0 mlruns/0/28292ef1274c481ebf9936cfdc9e9503/tags/mlflow.runName
  87. +1 −0 mlruns/0/28292ef1274c481ebf9936cfdc9e9503/tags/mlflow.source.name
  88. +1 −0 mlruns/0/28292ef1274c481ebf9936cfdc9e9503/tags/mlflow.source.type
  89. +1 −0 mlruns/0/28292ef1274c481ebf9936cfdc9e9503/tags/mlflow.user
  90. +15 −0 mlruns/0/2c4c2b32f9da42ddb0b822945ee4ea6d/meta.yaml
  91. +1 −0 mlruns/0/2c4c2b32f9da42ddb0b822945ee4ea6d/tags/mlflow.runName
  92. +1 −0 mlruns/0/2c4c2b32f9da42ddb0b822945ee4ea6d/tags/mlflow.source.name
  93. +1 −0 mlruns/0/2c4c2b32f9da42ddb0b822945ee4ea6d/tags/mlflow.source.type
  94. +1 −0 mlruns/0/2c4c2b32f9da42ddb0b822945ee4ea6d/tags/mlflow.user
  95. +15 −0 mlruns/0/3a75507364fe4469a8bb8a1505cddde7/meta.yaml
  96. +1 −0 mlruns/0/3a75507364fe4469a8bb8a1505cddde7/tags/mlflow.runName
  97. +1 −0 mlruns/0/3a75507364fe4469a8bb8a1505cddde7/tags/mlflow.source.name
  98. +1 −0 mlruns/0/3a75507364fe4469a8bb8a1505cddde7/tags/mlflow.source.type
  99. +1 −0 mlruns/0/3a75507364fe4469a8bb8a1505cddde7/tags/mlflow.user
  100. +15 −0 mlruns/0/8c8467413b3649468d9106ac74299ae4/meta.yaml
  101. +1 −0 mlruns/0/8c8467413b3649468d9106ac74299ae4/tags/mlflow.runName
  102. +1 −0 mlruns/0/8c8467413b3649468d9106ac74299ae4/tags/mlflow.source.name
  103. +1 −0 mlruns/0/8c8467413b3649468d9106ac74299ae4/tags/mlflow.source.type
  104. +1 −0 mlruns/0/8c8467413b3649468d9106ac74299ae4/tags/mlflow.user
  105. +15 −0 mlruns/0/abf9771578174b5799bccecaff95bb9e/meta.yaml
  106. +1 −0 mlruns/0/abf9771578174b5799bccecaff95bb9e/tags/mlflow.runName
  107. +1 −0 mlruns/0/abf9771578174b5799bccecaff95bb9e/tags/mlflow.source.name
  108. +1 −0 mlruns/0/abf9771578174b5799bccecaff95bb9e/tags/mlflow.source.type
  109. +1 −0 mlruns/0/abf9771578174b5799bccecaff95bb9e/tags/mlflow.user
  110. +15 −0 mlruns/0/dd1d90c2e84a435ea34fec307bcbdf5d/meta.yaml
  111. +1 −0 mlruns/0/dd1d90c2e84a435ea34fec307bcbdf5d/tags/mlflow.runName
  112. +1 −0 mlruns/0/dd1d90c2e84a435ea34fec307bcbdf5d/tags/mlflow.source.name
  113. +1 −0 mlruns/0/dd1d90c2e84a435ea34fec307bcbdf5d/tags/mlflow.source.type
  114. +1 −0 mlruns/0/dd1d90c2e84a435ea34fec307bcbdf5d/tags/mlflow.user
  115. +15 −0 mlruns/0/e06de0a320274556841c3f4223c24246/meta.yaml
  116. +1 −0 mlruns/0/e06de0a320274556841c3f4223c24246/tags/mlflow.runName
  117. +1 −0 mlruns/0/e06de0a320274556841c3f4223c24246/tags/mlflow.source.name
  118. +1 −0 mlruns/0/e06de0a320274556841c3f4223c24246/tags/mlflow.source.type
  119. +1 −0 mlruns/0/e06de0a320274556841c3f4223c24246/tags/mlflow.user
  120. +15 −0 mlruns/0/ead61f5ce7614436983485000a89a3ac/meta.yaml
  121. +1 −0 mlruns/0/ead61f5ce7614436983485000a89a3ac/tags/mlflow.runName
  122. +1 −0 mlruns/0/ead61f5ce7614436983485000a89a3ac/tags/mlflow.source.name
  123. +1 −0 mlruns/0/ead61f5ce7614436983485000a89a3ac/tags/mlflow.source.type
  124. +1 −0 mlruns/0/ead61f5ce7614436983485000a89a3ac/tags/mlflow.user
  125. +6 −0 mlruns/0/meta.yaml
  126. BIN my_model.keras
  127. +1,138 −14 notebooks/backtesting.ipynb
  128. +94 −26 notebooks/kafka.ipynb
  129. +1,976 −35 notebooks/lstm.ipynb
  130. +3 −1 requirements.txt
  131. BIN scaler.gz
  132. BIN screenshots/image.png
  133. BIN screenshots/workflow.png
  134. +125 −61 scripts/backtesting/main.py
  135. +44 −5 scripts/backtesting/strategies/base_strategy.py
  136. +91 −12 scripts/backtesting/strategies/lstm_strategy.py
  137. +6 −1 scripts/backtesting/strategies/macd_strategy.py
  138. 0 scripts/backtesting/strategies/{ rsi_strategy.py → rsi_strategy.py}
  139. 0 scripts/backtesting/strategies/{ sma_strategy.py → sma_strategy.py}
  140. 0 scripts/backtesting/util/{ user_input.py → user_input.py}
  141. +0 −23 updated_frontend/.gitignore
  142. +0 −70 updated_frontend/README.md
  143. +0 −18,470 updated_frontend/package-lock.json
  144. +0 −45 updated_frontend/package.json
  145. +0 −26 updated_frontend/src/App.js
  146. +0 −150 updated_frontend/src/components/BacktestForm.js
  147. +0 −22 updated_frontend/src/components/Navbar.js
  148. +0 −14 updated_frontend/tailwind.config.js
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ celerybeat.pid

# SageMath parsed files
*.sage.py

mlruns/
# Environments
.env
.venv
35 changes: 35 additions & 0 deletions 0.5.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Collecting nixtla
Downloading nixtla-0.5.1-py3-none-any.whl.metadata (4.8 kB)
Requirement already satisfied: httpx in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from nixtla) (0.27.0)
Requirement already satisfied: pandas in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from nixtla) (2.2.2)
Requirement already satisfied: pydantic in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from nixtla) (2.7.4)
Requirement already satisfied: requests in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from nixtla) (2.32.3)
Collecting tenacity (from nixtla)
Downloading tenacity-8.4.1-py3-none-any.whl.metadata (1.2 kB)
Collecting utilsforecast>=0.1.7 (from nixtla)
Downloading utilsforecast-0.1.11-py3-none-any.whl.metadata (7.4 kB)
Requirement already satisfied: numpy in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from utilsforecast>=0.1.7->nixtla) (1.26.4)
Requirement already satisfied: packaging in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from utilsforecast>=0.1.7->nixtla) (24.1)
Requirement already satisfied: python-dateutil>=2.8.2 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from pandas->nixtla) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from pandas->nixtla) (2024.1)
Requirement already satisfied: tzdata>=2022.7 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from pandas->nixtla) (2024.1)
Requirement already satisfied: anyio in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from httpx->nixtla) (4.4.0)
Requirement already satisfied: certifi in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from httpx->nixtla) (2024.6.2)
Requirement already satisfied: httpcore==1.* in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from httpx->nixtla) (1.0.5)
Requirement already satisfied: idna in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from httpx->nixtla) (3.7)
Requirement already satisfied: sniffio in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from httpx->nixtla) (1.3.1)
Requirement already satisfied: h11<0.15,>=0.13 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from httpcore==1.*->httpx->nixtla) (0.14.0)
Requirement already satisfied: annotated-types>=0.4.0 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from pydantic->nixtla) (0.7.0)
Requirement already satisfied: pydantic-core==2.18.4 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from pydantic->nixtla) (2.18.4)
Requirement already satisfied: typing-extensions>=4.6.1 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from pydantic->nixtla) (4.12.2)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from requests->nixtla) (3.3.2)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from requests->nixtla) (2.2.2)
Requirement already satisfied: six>=1.5 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from python-dateutil>=2.8.2->pandas->nixtla) (1.16.0)
Requirement already satisfied: exceptiongroup>=1.0.2 in c:\users\user\downloads\ten_academy\week9\scalable_backtesting_infrastructure_for_crypto_trading\backtest\lib\site-packages (from anyio->httpx->nixtla) (1.2.1)
Downloading nixtla-0.5.1-py3-none-any.whl (71 kB)
---------------------------------------- 71.4/71.4 kB 561.5 kB/s eta 0:00:00
Downloading utilsforecast-0.1.11-py3-none-any.whl (40 kB)
---------------------------------------- 40.6/40.6 kB 978.0 kB/s eta 0:00:00
Downloading tenacity-8.4.1-py3-none-any.whl (27 kB)
Installing collected packages: tenacity, utilsforecast, nixtla
Successfully installed nixtla-0.5.1 tenacity-8.4.1 utilsforecast-0.1.11
33 changes: 33 additions & 0 deletions Dockerfile.backend
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Use the official Python base image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt .

# Install the required Python packages
RUN pip install --no-cache-dir -r requirements.txt

# Copy the entire backend project into the container
COPY ./backend .

# Expose the port that FastAPI runs on
EXPOSE 8000

# Set environment variables for the FastAPI app
ENV PYTHONUNBUFFERED=1

ENV BINANCE_API_KEY="FN6iy8IhLMbDR3kVEYp1ZqsN6lj0fZXFRQaRZeJsWuLz6Is7DkVvyb70fwPGDY3B"
ENV DATABASE_URL="postgresql://trading_db_av2v_user:210M6MA9QKEEgVdiasnUdMQDBNN417oy@dpg-cpqojbqj1k6c73bkqq3g-a.oregon-postgres.render.com/trading_db_av2v"
ENV PYCOPG_DATABASE_URL = "postgresql+psycopg2://trading_db_av2v_user:210M6MA9QKEEgVdiasnUdMQDBNN417oy@dpg-cpqojbqj1k6c73bkqq3g-a.oregon-postgres.render.com/trading_db_av2v"
ENV DB_USERNAME='group3'
ENV DB_PASSWORD='group3@week9'
ENV DB_HOST='g3.10academy.org'
ENV DB_PORT=5432
ENV DB_DATABASE='backtest'
ENV AWS_DATABASE_URL="postgresql+psycopg2://group3:group3%40week9@g3.10academy.org/backtest"

# Run the FastAPI app with Uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
29 changes: 29 additions & 0 deletions Dockerfile.frontend
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Use the official Node.js image as the base image
FROM node:16-alpine

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
COPY ./frontend/package*.json ./

# Install the dependencies
RUN npm install

# Copy the rest of the application code to the working directory
COPY ./frontend .

# Build the React application
RUN npm run build

# Use the official Nginx image to serve the React application
FROM nginx:alpine

# Copy the built React application from the previous stage
COPY --from=0 /app/build /usr/share/nginx/html

# Expose port 80
EXPOSE 80

# Start Nginx when the container starts
CMD ["nginx", "-g", "daemon off;"]
132 changes: 125 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# Scalable Crypto Backtesting Infrastructure
# Scalable Stock and Crypto Backtesting Infrastructure

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [Project Structure](#project-structure)
- [Endpoints](#endpoints)
- [Kafka Integration](#kafka-integration)
- [LSTM Integration](#lstm-integration)
- [License](#license)

## Overview

@@ -56,7 +66,20 @@ pip install -r requirements.txt
```
## Project Structure
```bash
├── data/
├── backend/
│ ├── main.py
│ ├── models.py
│ ├── schemas.py
│ ├── database.py
│ ├── auth.py
│ ├── requirements.txt
│ ├── README.md
│ └── scripts
│ ├── backtesting
│ ├── init_data.py
│ ├── kafka_config.py
│ │ ├── main.py
│ └── init_db.py
├── scripts/
│ └── download_data.py
├── tests/
@@ -66,13 +89,108 @@ pip install -r requirements.txt
├── requirements.txt
└── README.md
```

### Set Up Kafka

If you do not have Kafka installed, you can run it using Docker:

docker run -d --name zookeeper -p 2181:2181 zookeeper:3.4.9
docker run -d --name kafka -p 9092:9092 --link zookeeper wurstmeister/kafka:latest

Alternatively, follow the [Kafka Quickstart](https://kafka.apache.org/quickstart) guide to set up Kafka.

### Configure Environment Variables

Create a `.env` file in the root directory and add the following configurations:

- KAFKA_BROKER_URL=localhost:9092
- SCENE_TOPIC=scene_parameters
- RESULT_TOPIC=backtest_results

### Initialize the Database

python -m scripts.init_db

## Backend Usage

### Run the FastAPI Application

uvicorn main:app --reload

### Sending Requests

Use a tool like Postman, Thunder Client, or Curl to interact with the API.

### Endpoints

### Health Check

**GET /health**

### Create Indicator

**POST /indicators/**

```sh
Body
{
"name": "Simple Moving Average",
"symbol": "SMA",
"description": "A simple moving average indicator"
}
```

### Read Indicators

**GET /indicators/**

### Create Stock

**POST /stocks/**

```sh
Body
{
"name": "Apple Inc.",
"symbol": "AAPL",
"description": "Apple Inc. stock"
}
```

### Read Stocks

**GET /stocks/**

### Create Scene

**POST /scenes/**

```sh
Body
{
"period": 20,
"indicator_id": 1,
"stock_id": 1,
"start_date": "2023-01-01",
"end_date": "2023-12-31"
}
```

### Read Scenes

**GET /scenes/**

### Perform Backtest

**POST /backtests/{scene_id}**

### Read Backtest Results

**GET /backtest_results/**

## Contributors
- Abubeker Shamil
- Addisu Alemu
- Michael George
- Sheila Murugi



## License
This project is licensed under the MIT License - see the LICENSE file for details.
@@ -85,4 +203,4 @@ This project is licensed under the MIT License - see the LICENSE file for detail
- Rehmet

**References:**
backtrader, Freqtrade, Vectorbt, Kafka, Airflow, MLflow, CML
backtrader, Freqtrade, Vectorbt, Kafka, Airflow, MLflow, CML
26 changes: 26 additions & 0 deletions airflow/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM apache/airflow:2.9.1

# Switch to root to install system dependencies
USER root

# Install system dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
pkg-config \
libhdf5-dev \
gcc \
python3-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Switch to airflow user to install Python packages
USER airflow

# Copy requirements and install Python packages
COPY requirements.txt .

COPY ../backend ./backend

COPY ../scripts/backtesting ./scripts/backtesting

RUN pip install --no-cache-dir -r requirements.txt
Loading