diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9823047 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +build/ +data/ +results/ +.stamps/ +.venv/ +__pycache__/ +*.pyc +*.egg-info/ +.git/ +.DS_Store +screenshot.png diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d23d907 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +FROM python:3.11-slim + +# ── System deps (cmake, g++, just) ──────────────────────────────────────────── +RUN apt-get update && apt-get install -y --no-install-recommends \ + cmake \ + g++ \ + make \ + curl \ + && curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# ── Python deps ─────────────────────────────────────────────────────────────── +WORKDIR /app +COPY pyproject.toml ./ +RUN pip install --no-cache-dir \ + streamlit \ + plotly \ + yfinance \ + pandas \ + numpy + +# ── Copy source ─────────────────────────────────────────────────────────────── +COPY core/ ./core/ +COPY strategies/ ./strategies/ +COPY scripts/ ./scripts/ +COPY app.py ./ +COPY CMakeLists.txt ./ +COPY Justfile ./ + +# ── Build C++ core ──────────────────────────────────────────────────────────── +RUN cmake -B build -DCMAKE_BUILD_TYPE=Release \ + && cmake --build build -j$(nproc) + +# ── Runtime dirs ───────────────────────────────────────────────────────────── +RUN mkdir -p data results + +EXPOSE 8501 + +# ── Entrypoint ──────────────────────────────────────────────────────────────── +CMD ["streamlit", "run", "app.py", \ + "--server.address=0.0.0.0", \ + "--server.port=8501", \ + "--server.headless=true"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..31be34d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +services: + backtest: + build: . + ports: + - "8501:8501" + volumes: + - ./data:/app/data + - ./results:/app/results + environment: + - STREAMLIT_SERVER_HEADLESS=true + - STREAMLIT_SERVER_ADDRESS=0.0.0.0 + - STREAMLIT_SERVER_PORT=8501 + restart: unless-stopped