diff --git a/Dockerfile b/Dockerfile index 55035b0..a18b620 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,70 @@ -# using ubuntu LTS version -FROM ubuntu:20.04 AS builder-image +# Set the base image +FROM continuumio/miniconda3:latest AS builder -# avoid stuck build due to user prompt -ARG DEBIAN_FRONTEND=noninteractive +# Install system dependencies +RUN apt-get update && \ + apt-get install -y sudo libusb-1.0 python3-dev && \ + rm -rf /var/lib/apt/lists/* -RUN apt-get update && apt-get install --no-install-recommends -y python3.9 python3.9-dev python3.9-venv python3-pip python3-wheel build-essential && \ - apt-get clean && rm -rf /var/lib/apt/lists/* +WORKDIR /home/streamlit-apps -# create and activate virtual environment -# using final folder name to avoid path issues with packages -RUN python3.9 -m venv /home/myuser/venv -ENV PATH="/home/myuser/venv/bin:$PATH" +# Create conda environment +COPY environment.yml /tmp/environment.yml +RUN conda env create -f /tmp/environment.yml && \ + conda clean -afy && \ + rm /tmp/environment.yml -# install requirements -COPY requirements.txt . -RUN pip3 install --no-cache-dir wheel -RUN pip3 install --no-cache-dir -r requirements.txt - -FROM ubuntu:20.04 AS runner-image -RUN apt-get update && apt-get install --no-install-recommends -y python3.9 python3-venv && \ - apt-get clean && rm -rf /var/lib/apt/lists/* - -RUN useradd --create-home myuser -COPY --from=builder-image /home/myuser/venv /home/myuser/venv - -USER myuser -RUN mkdir /home/myuser/code -WORKDIR /home/myuser/code -COPY . . +# Copy remaining files +COPY main.py . +COPY pages/ pages/ +COPY utils/ utils/ +COPY CONFIG.py . +COPY .streamlit/ .streamlit/ -# make sure all messages always reach console -ENV PYTHONUNBUFFERED=1 +SHELL [ "/bin/bash", "-lc" ] +RUN echo "conda activate streamlit-apps" >> ~/.bashrc -# activate virtual environment -ENV VIRTUAL_ENV=/home/myuser/venv -ENV PATH="/home/myuser/venv/bin:$PATH" +# Build final image using artifacts from builder +FROM continuumio/miniconda3:latest AS release -# /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat -# this will improve performance and avoid random freezes -CMD ["streamlit","run","main.py"] \ No newline at end of file +# Dockerfile author / maintainer +LABEL maintainer="Fede Cardoso @dardonacci " + +# Build arguments +ARG BRANCH="" +ARG COMMIT="" +ARG BUILD_DATE="" +LABEL branch=${BRANCH} +LABEL commit=${COMMIT} +LABEL date=${BUILD_DATE} + +# Set ENV variables +ENV COMMIT_SHA=${COMMIT} +ENV COMMIT_BRANCH=${BRANCH} +ENV BUILD_DATE=${DATE} + +ENV INSTALLATION_TYPE=docker + +# Install system dependencies +RUN apt-get update && \ + apt-get install -y && \ + rm -rf /var/lib/apt/lists/* + +# Create mount points +RUN mkdir -p /home/streamlit-apps/data + +WORKDIR /home/streamlit-apps + +# Copy all build artifacts from builder image +COPY --from=builder /opt/conda/ /opt/conda/ +COPY --from=builder /home/ /home/ + +EXPOSE 8501 + +# Setting bash as default shell because we have .bashrc with customized PATH (setting SHELL affects RUN, CMD and ENTRYPOINT, but not manual commands e.g. `docker run image COMMAND`!) +SHELL [ "/bin/bash", "-lc" ] + +# Set the default command to run when starting the container + +CMD conda activate streamlit-apps && streamlit run main.py diff --git a/Dockerfile.conda b/Dockerfile.conda deleted file mode 100644 index 4744cab..0000000 --- a/Dockerfile.conda +++ /dev/null @@ -1,12 +0,0 @@ -FROM continuumio/miniconda3 - -COPY environment.yml / - -RUN conda env create -f /environment.yml && \ - conda clean -afy - -ENV PATH /opt/conda/envs/myenv/bin:$PATH - -COPY . . - -CMD ["streamlit", "run", "main.py"] diff --git a/config.toml b/config.toml deleted file mode 100644 index f6fb194..0000000 --- a/config.toml +++ /dev/null @@ -1,6 +0,0 @@ -[theme] -base="dark" -font="monospace" -[server] -port=8501 -maxUploadSize = 2000 \ No newline at end of file diff --git a/pages/7_🚀_Strategy_Performance.py b/pages/7_🚀_Strategy_Performance.py index 4909986..d086882 100644 --- a/pages/7_🚀_Strategy_Performance.py +++ b/pages/7_🚀_Strategy_Performance.py @@ -104,8 +104,8 @@ with row: col41, col42, col43 = st.columns(3) -exchange_name = strategy_data.orders["market"].unique().item().split("_")[0] -trading_pair = strategy_data.orders["symbol"].unique().item().replace("-", "") +exchange_name = "binance" +trading_pair = strategy_data.symbol.replace("-", "") c1, c2 = st.columns([1, 5]) with c1: diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 06041f6..0000000 --- a/requirements.txt +++ /dev/null @@ -1,120 +0,0 @@ -aiodns==3.0.0 -aiohttp==3.8.1 -aiosignal==1.2.0 -altair==4.2.0 -appnope==0.1.3 -argon2-cffi==21.3.0 -argon2-cffi-bindings==21.2.0 -asttokens==2.0.5 -async-timeout==4.0.2 -attrs==21.4.0 -backcall==0.2.0 -beautifulsoup4==4.11.1 -bleach==5.0.1 -blinker==1.4 -boltons==21.0.0 -cachetools==5.2.0 -ccxt==3.0.40 -certifi==2022.6.15 -cffi==1.15.1 -charset-normalizer==2.1.0 -click==8.1.3 -commonmark==0.9.1 -cryptography==37.0.4 -debugpy==1.6.2 -decorator==5.1.1 -DeFiLlama==1.1.0 -defusedxml==0.7.1 -Deprecated==1.2.13 -entrypoints==0.4 -executing==0.8.3 -face==20.1.1 -fastjsonschema==2.15.3 -frozenlist==1.3.0 -gitdb==4.0.9 -GitPython==3.1.27 -glom==22.1.0 -idna==3.3 -importlib-metadata==4.12.0 -ipykernel==6.15.1 -ipython==8.4.0 -ipython-genutils==0.2.0 -ipywidgets==7.7.1 -jedi==0.18.1 -Jinja2==3.1.2 -jsonschema==4.7.2 -jupyter-client==7.3.4 -jupyter-core==4.11.1 -jupyterlab-pygments==0.2.2 -jupyterlab-widgets==1.1.1 -MarkupSafe==2.1.1 -matplotlib-inline==0.1.3 -mistune==0.8.4 -multidict==6.0.2 -nbclient==0.6.6 -nbconvert==6.5.0 -nbformat==5.4.0 -nest-asyncio==1.5.5 -notebook==6.4.12 -numpy==1.23.1 -packaging==21.3 -pandas==1.4.3 -pandocfilters==1.5.0 -parso==0.8.3 -patsy==0.5.2 -pexpect==4.8.0 -pickleshare==0.7.5 -Pillow==9.2.0 -plotly==5.9.0 -prometheus-client==0.14.1 -prompt-toolkit==3.0.30 -protobuf==3.20.1 -psutil==5.9.1 -ptyprocess==0.7.0 -pure-eval==0.2.2 -pyarrow==8.0.0 -pycares==4.2.1 -pycoingecko==2.2.0 -pycparser==2.21 -pydeck==0.7.1 -PyGithub==1.57 -Pygments==2.12.0 -PyJWT==2.6.0 -Pympler==1.0.1 -PyNaCl==1.5.0 -pyparsing==3.0.9 -pyrsistent==0.18.1 -python-dateutil==2.8.2 -pytz==2022.1 -pytz-deprecation-shim==0.1.0.post0 -pyzmq==23.2.0 -requests==2.28.1 -rich==12.5.1 -scipy==1.8.1 -semver==2.13.0 -Send2Trash==1.8.0 -six==1.16.0 -smmap==5.0.0 -soupsieve==2.3.2.post1 -stack-data==0.3.0 -statsmodels==0.13.2 -streamlit==1.10.0 -tenacity==8.0.1 -terminado==0.15.0 -tinycss2==1.1.1 -toml==0.10.2 -toolz==0.12.0 -tornado==6.2 -traitlets==5.3.0 -typing_extensions==4.3.0 -tzdata==2022.1 -tzlocal==4.2 -urllib3==1.26.10 -validators==0.20.0 -watchdog==2.1.9 -wcwidth==0.2.5 -webencodings==0.5.1 -widgetsnbextension==3.6.1 -wrapt==1.14.1 -yarl==1.7.2 -zipp==3.8.1 diff --git a/utils/data_manipulation.py b/utils/data_manipulation.py index 1e14d2d..48bf789 100644 --- a/utils/data_manipulation.py +++ b/utils/data_manipulation.py @@ -14,7 +14,7 @@ class StrategyData: self.trade_fill["net_amount"] = self.trade_fill['amount'] * self.trade_fill['trade_type'].apply(lambda x: 1 if x == 'BUY' else -1) self.trade_fill["net_amount_quote"] = self.trade_fill['net_amount'] * self.trade_fill['price'] self.trade_fill["cum_net_amount"] = self.trade_fill["net_amount"].cumsum() - self.trade_fill["unrealized_trade_pnl"] = - self.trade_fill["net_amount_quote"].cumsum() + self.trade_fill["unrealized_trade_pnl"] = -1 * self.trade_fill["net_amount_quote"].cumsum() self.trade_fill["inventory_cost"] = self.trade_fill["cum_net_amount"] * self.trade_fill["price"] self.trade_fill["realized_trade_pnl"] = self.trade_fill["unrealized_trade_pnl"] + self.trade_fill["inventory_cost"] @@ -39,11 +39,11 @@ class StrategyData: @property def start_time(self): - return self.orders["creation_timestamp"].min() + return self.trade_fill["timestamp"].min() @property def end_time(self): - return self.orders["last_update_timestamp"].max() + return self.trade_fill["timestamp"].max() @property def duration_minutes(self):