diff --git a/.github/workflows/Dockerfile b/.github/workflows/Dockerfile new file mode 100644 index 000000000..c47d3efd2 --- /dev/null +++ b/.github/workflows/Dockerfile @@ -0,0 +1,14 @@ + +FROM ubuntu:22.04 + +RUN apt update && \ + apt install -y openjdk-11-jdk python3-pip + +ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/ + +COPY ./wheels /wheels + +RUN pip3 install /wheels/*.whl && \ + rm -rf /wheels/ + +CMD python3 \ No newline at end of file diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 2d9cc066e..1827574e0 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -1,10 +1,16 @@ -name: Build and publish to PyPI +name: Build & Publish -on: push +on: + pull_request: + branches: + - main + push: + branches: + - main jobs: - build-and-publish: - name: Build and publish to PyPI + build-whl: + name: Build WHL runs-on: ubuntu-20.04 steps: - uses: actions/checkout@master @@ -22,7 +28,8 @@ jobs: TAG_NAME=${{ github.event.release.tag_name }} if [ -z "${TAG_NAME}" ] then - echo "::set-output name=version::development" + PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') + echo "::set-output name=version::0.0.0.dev${PR_NUMBER}" else echo "::set-output name=version::${{ github.event.release.tag_name }}" fi @@ -31,15 +38,122 @@ jobs: DH_IB_VERSION: ${{ steps.version.outputs.version }} run: | python -m build - - name: Archive production artifacts + - name: Archive build artifacts uses: actions/upload-artifact@v2 with: - name: Artifacts + name: wheels path: | dist/* -#TODO: publish -# - name: Publish -# if: xxxx -# python -m twine upload --repository testpypi dist/* - + publish-whl: + name: Publish WHL + runs-on: ubuntu-20.04 + needs: [build-whl] + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + steps: + - name: Download Build Artifacts + uses: actions/download-artifact@v3 + with: + name: build-artifacts + path: wheel/ + - name: Publish WHL to PyPi + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.DEEPHAVENIB_PYPI_TOKEN }} + packages_dir: wheel/ + + + build-sphinx: + name: Build Sphinx + runs-on: ubuntu-20.04 + needs: [build-whl] + steps: + - uses: actions/checkout@v1 + - name: Apt installs + run: | + sudo apt update + sudo apt install -y openjdk-11-jdk + - name: Pip installs + run: pip3 install --upgrade sphinx==4.2.0 sphinx-autodoc-typehints furo==2021.10.9 + - name: Download wheels + uses: actions/download-artifact@v3 + with: + name: wheels + - name: Install Whl + run: pip3 install *.whl + - name: Run Sphinx + working-directory: ./sphinx + env: + JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64 + run: | + make html + touch build/html/.nojekyll + - name: Archive Sphinx artifacts + uses: actions/upload-artifact@v1 + with: + name: documentation-html + path: sphinx/build/html/ + + publish-sphinx: + name: Publish Sphinx + runs-on: ubuntu-20.04 + needs: [build-sphinx] + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + steps: + - name: Download Sphinx Artifacts + uses: actions/download-artifact@v3 + with: + name: documentation-html + path: html/ + - name: Deploy Sphinx docs to gh-pages + uses: JamesIves/github-pages-deploy-action@v4.2.3 + with: + branch: gh-pages + folder: html/ + + docker: + name: Build and Publish Docker + runs-on: ubuntu-20.04 + needs: [build-whl] + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v5.2 + - name: Download wheels + uses: actions/download-artifact@v3 + with: + name: wheels + path: wheels/ + - name: Log in to the Container registry + uses: docker/login-action@v1.10.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta-base + uses: docker/metadata-action@v4.0.1 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + type=raw,${{ steps.branch-name.outputs.current_branch }} + - name: Build and push Docker image + uses: docker/build-push-action@v2.7.0 + with: + context: . + file: ./.github/workflows/Dockerfile + push: true + tags: ${{ steps.meta-base.outputs.tags }} + labels: ${{ steps.meta-base.outputs.labels }} + env: + IMAGE_NAME: ${{ github.repository }} diff --git a/.github/workflows/docker-cleanup.yml b/.github/workflows/docker-cleanup.yml new file mode 100644 index 000000000..605a362ad --- /dev/null +++ b/.github/workflows/docker-cleanup.yml @@ -0,0 +1,26 @@ +# Delete Docker images after PR merge +# + +name: 'Clean up Docker images from PR' + +on: + pull_request: + types: [closed] + +jobs: + purge-image: + name: Delete images from ghcr.io + runs-on: ubuntu-20.04 + steps: + - name: Delete image (Base) + uses: chipkent/action-cleanup-package@v1.0.2 + with: + package-name: ${{ github.event.repository.name }}-base + tag: pr-${{ github.event.pull_request.number }} + github-token: ${{ secrets.CI_ACTION_TOKEN }} + - name: Delete image (Downloader) + uses: chipkent/action-cleanup-package@v1.0.2 + with: + package-name: ${{ github.event.repository.name }}-downloader + tag: pr-${{ github.event.pull_request.number }} + github-token: ${{ secrets.CI_ACTION_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml deleted file mode 100644 index 7157b3d97..000000000 --- a/.github/workflows/sphinx.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: "Sphinx Documentation" - -on: - pull_request: - branches: - - main - push: - branches: - - main - workflow_dispatch: - -jobs: - docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Get branch name - id: branch-name - uses: tj-actions/branch-names@v5 - - name: Build Sphinx Docker - env: - BRANCH: ${{ steps.branch-name.outputs.current_branch }} - working-directory: ./sphinx - run: | - docker build . -t deephaven-ib/sphinx --build-arg VERSION=latest --build-arg DH_IB_VERSION=${BRANCH} --build-arg DH_IB_BRANCH=${BRANCH} - - name: Run Sphinx Docker - working-directory: ./sphinx - run: | - docker images - docker run -v `pwd`/build/:/build/deephaven-ib/sphinx/build/ deephaven-ib/sphinx - echo "DOCS FILES:" - find ./build - - uses: actions/upload-artifact@v1 - with: - name: DocumentationHTML - path: sphinx/build/html/ - - name: Deploy to gh-pages - if: github.event_name == 'push' - uses: JamesIves/github-pages-deploy-action@v4.2.3 - with: - branch: gh-pages - folder: sphinx/build/html/ diff --git a/.gitignore b/.gitignore index 8890db45f..72df4f165 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .idea venv dist -src/deephaven_ib.egg-info \ No newline at end of file +src/deephaven_ib.egg-info +docker/data +docker/*/data +docker/*/build \ No newline at end of file diff --git a/README.md b/README.md index 76956b2c1..e9acfe6d1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - # deephaven-ib ![Deephaven Data Labs Logo](docs/assets/Deephaven-Logo-Wordmark-Community-OnLight.png) @@ -174,33 +173,80 @@ upper right corner. ![](docs/assets/config-gear.png) 1) [For Paper Trading] Log into the [Interactive Brokers Web Interface](https://interactivebrokers.com/). 1) [For Paper Trading] In the [Interactive Brokers Web Interface](https://interactivebrokers.com/), navigate to `Account->Settings->Paper Trading Account` and make sure that "Share real-time market data subscriptions with paper trading account?" is set to true. + ## Launch To launch the system: +### Launch with Docker + +This is the most tested way to launch. + 1) Launch [IB Trader Workstation (TWS)](https://www.interactivebrokers.com/en/trading/tws.php). -1) Accept incoming connections to [IB Trader Workstation (TWS)](https://www.interactivebrokers.com/en/trading/tws.php). (May not be required for all sessions.) +2) Accept incoming connections to [IB Trader Workstation (TWS)](https://www.interactivebrokers.com/en/trading/tws.php). (May not be required for all sessions.) ![](docs/assets/allow-connections.png) -1) Build the Docker images: +3) Create a directory for your data and scripts + ```bash + mkdir data + ``` +4) Launch the system (Option 1): + * On Mac: ```bash - ./docker/deephaven_ib_docker.sh build --dh-version + git clone git@github.com:deephaven-examples/deephaven-ib.git + cd deephaven-ib/docker/dev/build.sh + # Set jvm_args to the desired JVM memory for Deephaven + docker run -it -v data:/data -p 10000:10000 deephaven-examples/deephaven-ib:dev python3 -i -c "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" ``` -1) Launch the system: + * On other platforms: ```bash - ./docker/deephaven_ib_docker.sh up --dh-version + # Set jvm_args to the desired JVM memory for Deephaven + docker run -it -v data:/data -p 10000:10000 ghcr.io/deephaven-examples/deephaven-ib python3 -i -c "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" ``` -1) Launch the [Deephaven IDE](https://github.com/deephaven/deephaven-core/blob/main/README.md#run-deephaven-ide) by navigating to [http://localhost:10000/ide/](http://localhost:10000/ide/) in a browser. +5) Launch the system and execute a custom script (Option 2): + * On Mac: + ```bash + git clone git@github.com:deephaven-examples/deephaven-ib.git + cd deephaven-ib/docker/dev/build.sh + # your_script.py must begin with: "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" + # Set jvm_args to the desired JVM memory for Deephaven + cp path/to/your_script.py data/your_script.py + docker run -it -v data:/data -p 10000:10000 deephaven-examples/deephaven-ib:dev python3 -i /data/your_script.py + ``` + * On other platforms: + ```bash + # your_script.py must begin with: "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" + # Set jvm_args to the desired JVM memory for Deephaven + cp path/to/your_script.py data/your_script.py + docker run -it -v data:/data -p 10000:10000 ghcr.io/deephaven-examples/deephaven-ib python3 -i /data/your_script.py + ``` +7) Launch the [Deephaven IDE](https://github.com/deephaven/deephaven-core/blob/main/README.md#run-deephaven-ide) by navigating to [http://localhost:10000/ide/](http://localhost:10000/ide/) in a browser. -## Shutdown -To shut down the system: -```bash -./docker/deephaven_ib_docker.sh down --dh-version -``` +### Launch with a local installation (No Docker) -## Help -To get help on running the system: -```bash -./docker/deephaven_ib_docker.sh help -``` +> **_NOTE:_** Deephaven pip install does not yet supported on all architectures. This launch should work on Linux (AMD64 and ARM64) and Windows WSL. It is not yet supported on Windows without WSL or Mac. For these architectures, you should use the Docker installation. As soon as Deephaven supports these architectures for pip, [deephaven-ib](https://github.com/deephaven-examples/deephaven-ib) will work. + +It is possible to use [deephaven-ib](https://github.com/deephaven-examples/deephaven-ib) without docker, but this is a +new feature and has not been well tested. To do this: +1) Launch [IB Trader Workstation (TWS)](https://www.interactivebrokers.com/en/trading/tws.php). +2) Accept incoming connections to [IB Trader Workstation (TWS)](https://www.interactivebrokers.com/en/trading/tws.php). (May not be required for all sessions.) +![](docs/assets/allow-connections.png) +3) Install [deephaven-ib](https://github.com/deephaven-examples/deephaven-ib): + ```bash + pip3 install deephaven-ib + ``` +4) Install Java 11 and set the appropriate `JAVA_HOME` environment variable. +5) Launch the system (Option 1): + ```bash + # Set jvm_args to the desired JVM memory for Deephaven + python3 -i -c "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" + ``` +6) Launch the system and execute a custom script (Option 2): + ```bash + # your_script.py must begin with: "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" + # Set jvm_args to the desired JVM memory for Deephaven + python3 -i /data/your_script.py + ``` +7) Launch the [Deephaven IDE](https://github.com/deephaven/deephaven-core/blob/main/README.md#run-deephaven-ide) by navigating to [http://localhost:10000/ide/](http://localhost:10000/ide/) in a browser. +8) Use `host=localhost` for the hostname in the examples # Use deephaven-ib diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 4abbbb617..000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -ARG VERSION - -FROM ghcr.io/deephaven/server:${VERSION} - -ARG DH_IB_VERSION -ARG DH_IB_BRANCH - -# Install requirements -RUN apt update && \ - apt install --yes git python3-venv && \ - python3 -m pip install --upgrade pip && \ - python3 -m pip install --upgrade setuptools wheel build twine - -# Invalidate the cache below here, so that the latest repo changes get cloned -ARG CACHEBUST - -# Build and install deephaven-ib -RUN mkdir /build && \ - cd /build && \ - git clone --branch ${DH_IB_BRANCH} https://github.com/deephaven-examples/deephaven-ib.git && \ - cd deephaven-ib && \ - python3 -m build && \ - pip3 install dist/*.whl && \ - rm -rf /build diff --git a/docker/deephaven_ib_docker.sh b/docker/deephaven_ib_docker.sh deleted file mode 100755 index c87d4b611..000000000 --- a/docker/deephaven_ib_docker.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o pipefail -set -o nounset - -__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -function build() { - cd ${__dir} - docker-compose pull - docker-compose build ${NO_CACHE} -} - -function up() { - cd ${__dir} - docker-compose up -d -} - -function down() { - cd ${__dir} - docker-compose down -v -} - -function help() { - file_name=`basename "$0"` - echo "Usage: ${file_name} [--dh-version ] [--branch ] [--no-cache]" - echo "" - echo "${file_name} controls deephaven-ib Docker deployments." - echo "The latest deephaven-ib for a branch is downloaded from GitHub. Local changes are ignored." - echo "User data is stored in ./docker/data" - echo "" - echo "Modes:" - echo "------" - echo "build - build Docker images for the system" - echo "up - launch the system" - echo "build_up - build the Docker images for the system and launch the system" - echo "down - shut down the system" - echo "help - print a help message" - echo "" - echo "Options:" - echo "--------" - echo "--dh-version - deephaven image versions to use" - echo "--branch - deephaven-ib branch to use" - echo "--no-cache - do not use the Docker cache when building images" - exit -1 -} - -if [[ $# -eq 0 ]] ; then - help -fi - -ACTION=$1 -shift -export VERSION=latest -export DH_IB_BRANCH=main -export CACHEBUST=$(date +%s) -NO_CACHE="" - -while [[ $# -gt 0 ]]; do - case $1 in - "--dh-version") - shift - export VERSION=$1 - ;; - "--branch") - shift - export DH_IB_BRANCH=$1 - ;; - "--no-cache") - NO_CACHE="--no-cache" - ;; - *) - help - ;; - esac - shift -done - -echo "ACTION=${ACTION}" -echo "DH_VERSION=${VERSION}" -echo "DH_IB_BRANCH=${DH_IB_BRANCH}" -echo "NO_CACHE=${NO_CACHE}" -echo "CACHEBUST=${CACHEBUST}" - -case "$ACTION" in - "build") - build - ;; - "up") - up - ;; - "build_up") - build - up - ;; - "down") - down - ;; - *) - help - ;; -esac \ No newline at end of file diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile new file mode 100644 index 000000000..68cd4eeab --- /dev/null +++ b/docker/dev/Dockerfile @@ -0,0 +1,28 @@ +# +# A docker image from the current repository. +# + +FROM ubuntu:22.04 + +ARG DH_IB_VERSION=dev + +# Install requirements + +RUN apt update && \ + apt install -y openjdk-11-jdk && \ + ln -s /usr/lib/jvm/java-11-openjdk-*/ /usr/lib/jvm/java-11-openjdk && \ + apt install --yes git python3-venv python3-pip && \ + pip3 install --upgrade setuptools wheel build twine + +ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk + +# Build and install deephaven-ib + +COPY ./build /build + +RUN cd /build && \ + python3 -m build && \ + pip3 install dist/*.whl && \ + rm -rf /build + +CMD python3 diff --git a/docker/dev/README.md b/docker/dev/README.md new file mode 100644 index 000000000..645cbd2d3 --- /dev/null +++ b/docker/dev/README.md @@ -0,0 +1,19 @@ +# Build Docker Image From Current Deephaven-IB Checkout + +This directory contains the ingredients to build Docker images from the current, checked-out deephaven-ib repository. + +This is useful when doing local development or when offical images are not available for your platform. + +## Build Image + +```bash +./build.sh +``` + +## Run image in interactive mode + +```bash +# Set jvm_args to the desired JVM memory for Deephaven +docker run -it -v data:/data -p 10000:10000 deephaven-examples/deephaven-ib:dev python3 -i -c "from deephaven_server import Server; _server = Server(port=10000, jvm_args=["-4g"]); _server.start()" +``` + diff --git a/docker/dev/build.sh b/docker/dev/build.sh new file mode 100755 index 000000000..e9243f7c0 --- /dev/null +++ b/docker/dev/build.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# +# Build a docker image from the current repository. +# + +__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd ${__dir} + +rm -rf build +mkdir build +rsync -av ../.. build --exclude docker + +docker build -t deephaven-examples/deephaven-ib:dev -f Dockerfile . + +rm -rf build \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index f782e7f5f..000000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,49 +0,0 @@ -version: "3.4" - -services: - grpc-api: - build: - context: . - args: - VERSION: ${VERSION:-latest} - DH_IB_VERSION: ${DH_IB_BRANCH:-main} - DH_IB_BRANCH: ${DH_IB_BRANCH:-main} - CACHEBUST: ${CACHEBUST:-0} - expose: - - '8080' - volumes: - - ./data:/data - - api-cache:/cache - environment: - - JAVA_TOOL_OPTIONS=-Xmx4g -Ddeephaven.console.type=python - #-Ddeephaven.application.dir=/app.d - - web: - image: ghcr.io/deephaven/web:${VERSION:-latest} - expose: - - '80' - volumes: - - ./data:/data - - web-tmp:/tmp - - grpc-proxy: - image: ghcr.io/deephaven/grpc-proxy:${VERSION:-latest} - environment: - - BACKEND_ADDR=grpc-api:8080 - depends_on: - - grpc-api - expose: - - '8080' - - envoy: - image: ghcr.io/deephaven/envoy:${VERSION:-latest} - depends_on: - - web - - grpc-proxy - - grpc-api - ports: - - "${PORT:-10000}:10000" - -volumes: - web-tmp: - api-cache: diff --git a/docker/release/Dockerfile b/docker/release/Dockerfile new file mode 100644 index 000000000..0eeaf8764 --- /dev/null +++ b/docker/release/Dockerfile @@ -0,0 +1,15 @@ +# +# A docker image from released python packages +# + +FROM ubuntu:22.04 + +RUN apt update && \ + apt install -y openjdk-11-jdk python3-pip && \ + ln -s /usr/lib/jvm/java-11-openjdk-*/ /usr/lib/jvm/java-11-openjdk && \ + +ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk/ + +RUN pip3 install deephaven-ib + +CMD python3 \ No newline at end of file diff --git a/docker/release/README.md b/docker/release/README.md new file mode 100644 index 000000000..1dc579dd0 --- /dev/null +++ b/docker/release/README.md @@ -0,0 +1,18 @@ +# Build Docker Image From The Most Recent pip-installable Deephaven-IB Release + +This directory contains the ingredients to build Docker images from the most recent pip-installable deephaven-ib release. + +In general, you will want to use the officially released images at [https://github.com/deephaven-examples/deephaven-ib/pkgs/container/deephaven-ib](https://github.com/deephaven-examples/deephaven-ib/pkgs/container/deephaven-ib). + +## Build Image + +```bash +./build.sh +``` + +## Run image in interactive mode + +```bash +# Set jvm_args to the desired JVM memory for Deephaven +docker run -it -v data:/data -p 10000:10000 deephaven-examples/deephaven-ib:release python3 -i -c "from deephaven_server import Server; _server = Server(port=10000, jvm_args=['-Xmx4g']); _server.start()" +``` diff --git a/docker/release/build.sh b/docker/release/build.sh new file mode 100755 index 000000000..812266baa --- /dev/null +++ b/docker/release/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# +# Build a docker image from released python packages +# + +__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd ${__dir} + +docker build -t deephaven-examples/deephaven-ib:release -f Dockerfile . \ No newline at end of file diff --git a/examples/example_all_functionality.py b/examples/example_all_functionality.py index 2a3bb34ff..35a17f4ce 100644 --- a/examples/example_all_functionality.py +++ b/examples/example_all_functionality.py @@ -68,10 +68,10 @@ def get_contracts() -> Dict[str, Contract]: # Index contract = Contract() - contract.symbol = "DAX" + contract.symbol = "VIX" contract.secType = "IND" - contract.currency = "EUR" - contract.exchange = "DTB" + contract.currency = "USD" + contract.exchange = "CBOE" rst["index_1"] = contract # CFD @@ -90,23 +90,23 @@ def get_contracts() -> Dict[str, Contract]: contract.secType = "FUT" contract.exchange = "GLOBEX" contract.currency = "USD" - contract.lastTradeDateOrContractMonth = "202206" + contract.lastTradeDateOrContractMonth = "202209" rst["future_1"] = contract contract = Contract() contract.secType = "FUT" contract.exchange = "GLOBEX" contract.currency = "USD" - contract.localSymbol = "MESZ2" + contract.localSymbol = "MESU2" rst["future_2"] = contract contract = Contract() contract.symbol = "DAX" contract.secType = "FUT" - contract.exchange = "DTB" + contract.exchange = "EUREX" contract.currency = "EUR" - contract.lastTradeDateOrContractMonth = "202206" - contract.multiplier = "5" + contract.lastTradeDateOrContractMonth = "202209" + contract.multiplier = "1" rst["future_3"] = contract contract = Contract() @@ -129,7 +129,7 @@ def get_contracts() -> Dict[str, Contract]: contract.exchange = "BOX" contract.currency = "USD" contract.lastTradeDateOrContractMonth = "20230120" - contract.strike = 2800 + contract.strike = 110 contract.right = "C" contract.multiplier = "100" rst["option_1"] = contract @@ -161,7 +161,7 @@ def get_contracts() -> Dict[str, Contract]: contract.secType = "FOP" contract.exchange = "GLOBEX" contract.currency = "USD" - contract.lastTradeDateOrContractMonth = "202206" + contract.lastTradeDateOrContractMonth = "202209" contract.strike = 4700 contract.right = "C" contract.multiplier = "50" @@ -419,7 +419,7 @@ def get_contracts() -> Dict[str, Contract]: contract.exchange = "BOX" contract.currency = "USD" contract.lastTradeDateOrContractMonth = "20230120" -contract.strike = 2800 +contract.strike = 110 contract.right = "C" contract.multiplier = "100" diff --git a/examples/example_beta_calc.py b/examples/example_beta_calc.py index e0deff010..9b7d8b1e9 100644 --- a/examples/example_beta_calc.py +++ b/examples/example_beta_calc.py @@ -247,7 +247,7 @@ def check_table_size(dh_table, table_name, expected_size=1): hedge_qty = hedge_info[0] hedge_last_px = hedge_info[1] hedge_side = "BUY" if hedge_qty > 0 else "SELL" -hedge_limit_px = hedge_last_px + 0.05 * (1 if hedge_side is "BUY" else -1) +hedge_limit_px = hedge_last_px + 0.05 * (1 if hedge_side == "BUY" else -1) # Create an order with the IB API: order = Order() diff --git a/examples/example_read_only_functionality.py b/examples/example_read_only_functionality.py index c47e8c8ff..41efc2cef 100644 --- a/examples/example_read_only_functionality.py +++ b/examples/example_read_only_functionality.py @@ -64,10 +64,10 @@ def get_contracts() -> Dict[str, Contract]: # Index contract = Contract() - contract.symbol = "DAX" + contract.symbol = "VIX" contract.secType = "IND" - contract.currency = "EUR" - contract.exchange = "DTB" + contract.currency = "USD" + contract.exchange = "CBOE" rst["index_1"] = contract # CFD @@ -86,23 +86,23 @@ def get_contracts() -> Dict[str, Contract]: contract.secType = "FUT" contract.exchange = "GLOBEX" contract.currency = "USD" - contract.lastTradeDateOrContractMonth = "202206" + contract.lastTradeDateOrContractMonth = "202209" rst["future_1"] = contract contract = Contract() contract.secType = "FUT" contract.exchange = "GLOBEX" contract.currency = "USD" - contract.localSymbol = "MESZ2" + contract.localSymbol = "MESU2" rst["future_2"] = contract contract = Contract() contract.symbol = "DAX" contract.secType = "FUT" - contract.exchange = "DTB" + contract.exchange = "EUREX" contract.currency = "EUR" - contract.lastTradeDateOrContractMonth = "202206" - contract.multiplier = "5" + contract.lastTradeDateOrContractMonth = "202209" + contract.multiplier = "1" rst["future_3"] = contract contract = Contract() @@ -125,7 +125,7 @@ def get_contracts() -> Dict[str, Contract]: contract.exchange = "BOX" contract.currency = "USD" contract.lastTradeDateOrContractMonth = "20230120" - contract.strike = 2800 + contract.strike = 110 contract.right = "C" contract.multiplier = "100" rst["option_1"] = contract @@ -157,7 +157,7 @@ def get_contracts() -> Dict[str, Contract]: contract.secType = "FOP" contract.exchange = "GLOBEX" contract.currency = "USD" - contract.lastTradeDateOrContractMonth = "202206" + contract.lastTradeDateOrContractMonth = "202209" contract.strike = 4700 contract.right = "C" contract.multiplier = "50" @@ -295,12 +295,38 @@ def get_contracts() -> Dict[str, Contract]: bar_type=dhib.BarDataType.OPTION_IMPLIED_VOLATILITY, keep_up_to_date=False) client.request_bars_historical(rc, duration=dhib.Duration.days(10), bar_size=dhib.BarSize.MIN_5, bar_type=dhib.BarDataType.TRADES) +client.request_bars_historical(rc, duration=dhib.Duration.days(10), bar_size=dhib.BarSize.MIN_5, + bar_type=dhib.BarDataType.ADJUSTED_LAST, keep_up_to_date=False) client.request_bars_realtime(rc, bar_type=dhib.BarDataType.MIDPOINT) client.request_bars_realtime(rc, bar_type=dhib.BarDataType.BID) client.request_bars_realtime(rc, bar_type=dhib.BarDataType.ASK) client.request_bars_realtime(rc, bar_type=dhib.BarDataType.TRADES) + +print("==============================================================================================================") +print("==== Request bars (bonds).") +print("==============================================================================================================") + +# enter CUSIP as symbol +contract = Contract() +contract.symbol = "IBCID411964960" +contract.secType = "BOND" +contract.exchange = "SMART" +contract.currency = "USD" + +rc = client.get_registered_contract(contract) +print(contract) + +client.request_bars_historical(rc, duration=dhib.Duration.days(22), bar_size=dhib.BarSize.DAY_1, + bar_type=dhib.BarDataType.YIELD_BID, keep_up_to_date=False) +client.request_bars_historical(rc, duration=dhib.Duration.days(22), bar_size=dhib.BarSize.DAY_1, + bar_type=dhib.BarDataType.YIELD_ASK, keep_up_to_date=False) +client.request_bars_historical(rc, duration=dhib.Duration.days(22), bar_size=dhib.BarSize.DAY_1, + bar_type=dhib.BarDataType.YIELD_BID_ASK, keep_up_to_date=False) +client.request_bars_historical(rc, duration=dhib.Duration.days(22), bar_size=dhib.BarSize.DAY_1, + bar_type=dhib.BarDataType.YIELD_LAST, keep_up_to_date=False) + print("==============================================================================================================") print("==== Request tick data.") print("==============================================================================================================") @@ -389,7 +415,7 @@ def get_contracts() -> Dict[str, Contract]: contract.exchange = "BOX" contract.currency = "USD" contract.lastTradeDateOrContractMonth = "20230120" -contract.strike = 2800 +contract.strike = 110 contract.right = "C" contract.multiplier = "100" diff --git a/setup.py b/setup.py index bcebdfa16..86e89c1ab 100644 --- a/setup.py +++ b/setup.py @@ -39,8 +39,7 @@ packages=setuptools.find_packages(where="src"), python_requires=">=3.6", install_requires=[ - "deephaven-jpy", - "deephaven", + "deephaven-server", "pandas", "ibapi", "lxml", diff --git a/sphinx/Dockerfile b/sphinx/Dockerfile deleted file mode 100644 index 2db21a4da..000000000 --- a/sphinx/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -ARG VERSION - -FROM ghcr.io/deephaven/server:${VERSION} - -ARG DH_IB_VERSION -ARG DH_IB_BRANCH - -# Install requirements -RUN apt update && \ - apt install --yes git python3-venv make && \ - python3 -m pip install --upgrade pip && \ - python3 -m pip install --upgrade setuptools wheel build twine sphinx sphinx-autodoc-typehints furo - -# Build and install deephaven-ib -RUN mkdir /build && \ - cd /build && \ - git clone --branch ${DH_IB_BRANCH} https://github.com/deephaven-examples/deephaven-ib.git && \ - cd deephaven-ib && \ - python3 -m build && \ - pip3 install dist/*.whl - -# Build sphinx -ENTRYPOINT cd /build/deephaven-ib/sphinx && make html && touch build/html/.nojekyll - - diff --git a/sphinx/lib/dh_sphinx.py b/sphinx/lib/dh_sphinx.py index ad475c049..480884aa3 100644 --- a/sphinx/lib/dh_sphinx.py +++ b/sphinx/lib/dh_sphinx.py @@ -1,24 +1,15 @@ import os import pkgutil import shutil -import sys -from pathlib import Path -import jpy -from deephaven.start_jvm import start_jvm +from deephaven_server import Server + +_server = None def setup_sphinx_environment(): - # add the deephaven-ib path - new_python_path = Path(os.path.realpath(__file__)).parents[2].joinpath("src") - sys.path.append(str(new_python_path)) - - # start the jvm so that deephaven can be loaded - if not jpy.has_jvm(): - os.environ['JAVA_VERSION'] = '11' - start_jvm(devroot="/tmp", workspace="/tmp", propfile='dh-defaults.prop', - java_home=os.environ.get('JDK_HOME', None), - jvm_classpath="/opt/deephaven/server/lib/*", skip_default_classpath=True) + global _server + _server = Server() def glob_package_names(packages): diff --git a/sphinx/source/conf.py b/sphinx/source/conf.py index cc32a1aa1..c15fc7f3f 100644 --- a/sphinx/source/conf.py +++ b/sphinx/source/conf.py @@ -75,11 +75,14 @@ import sys -sys.path.append("/build/deephaven-ib/sphinx/lib/") +import pathlib +sys.path.append("%s/lib/"%(pathlib.Path(__file__).parent.parent.resolve())) +# sys.path.append("/build/deephaven-ib/sphinx/lib/") import dh_sphinx dh_sphinx.setup_sphinx_environment() +import deephaven_server import deephaven_ib import deephaven import ibapi.order @@ -87,7 +90,7 @@ import jpy docs_title = "deephaven_ib python modules." -package_roots = [deephaven_ib, deephaven, jpy, ibapi.contract, ibapi.order] +package_roots = [deephaven_server, deephaven_ib, deephaven, jpy, ibapi.contract, ibapi.order] package_excludes = ['._'] dh_sphinx.gen_sphinx_modules(docs_title, package_roots, package_excludes) diff --git a/src/deephaven_ib/_tws/contract_registry.py b/src/deephaven_ib/_tws/contract_registry.py index 9258ad3ea..d60364b8e 100644 --- a/src/deephaven_ib/_tws/contract_registry.py +++ b/src/deephaven_ib/_tws/contract_registry.py @@ -34,13 +34,13 @@ def add_contract_details(self, contract_details: ContractDetails): self.contract_details.append(contract_details) - def add_error_sring(self, error_string: str): + def add_error_string(self, req_id: int, error_string: str): """Adds an error string to the entry.""" if self.contract_details: - raise Exception(f"Adding an error string to an entry that already has contract details: {self.contract}") + raise Exception(f"Adding an error string to an entry that already has contract details: req_id={req_id} {self.contract}") - self.error_strings.append(error_string) + self.error_strings.append(f"req_id={req_id} {error_string}") def get(self) -> List[ContractDetails]: """Gets the details or raises an exception if there are no details.""" @@ -106,7 +106,8 @@ def add_error_data(self, req_id: int, error_string: str) -> None: return contract, event = self._requests_by_id[req_id] - self._update_error(contract, error_string) + self._update_error(contract, req_id, error_string) + event.set() def request_end(self, req_id: int) -> None: """Indicate that the request is over and all data has been received.""" @@ -178,7 +179,7 @@ def request_contract_details_blocking(self, contract: Contract) -> List[Contract event_happened = event.wait(time_out) if not event_happened: - raise Exception(f"ContractRegistry.request_contract_details_blocking() timed out after {time_out} sec.") + raise Exception(f"ContractRegistry.request_contract_details_blocking() timed out after {time_out} sec. contract={contract}") cd = self._get_contract_details(contract) return cd.get() @@ -223,7 +224,7 @@ def _update_contract_details(self, contract: Contract, contract_details: Contrac self._contracts[key].add_contract_details(contract_details) - def _update_error(self, contract: Contract, error_string: str) -> None: + def _update_error(self, contract: Contract, req_id: int, error_string: str) -> None: """Updates the error string for a query contract.""" key = str(contract) @@ -231,4 +232,4 @@ def _update_error(self, contract: Contract, error_string: str) -> None: if key not in self._contracts: self._contracts[key] = ContractEntry(contract) - self._contracts[key].add_error_sring(error_string) + self._contracts[key].add_error_string(req_id, error_string)