Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: lmax connector service #239

Merged
merged 27 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
28bc941
feat: lmax connector first draft
EvolveArt Jan 7, 2025
9ba191a
fix: config and shutdown
EvolveArt Jan 7, 2025
1358a68
feat: working connection!
EvolveArt Jan 8, 2025
6b28e2b
Update README.md
EvolveArt Jan 8, 2025
def2513
fix: send request
EvolveArt Jan 13, 2025
e72a0fd
fix: kinda works
EvolveArt Jan 13, 2025
45d22b9
fix: receiving snapshots
EvolveArt Jan 13, 2025
3d02aca
fix: field error
EvolveArt Jan 13, 2025
cc6d01a
fix: publishing works!
EvolveArt Jan 13, 2025
be7e5db
fix: linter
EvolveArt Jan 13, 2025
e5a22ef
fix: lint
EvolveArt Jan 13, 2025
5027e7d
:recycle: streamline admin message handling
yezz123 Jan 13, 2025
ec3db73
:wrench: update quickfix dependency to quickfix-py
yezz123 Jan 13, 2025
1d23d7b
:memo: update README with Docker usage instructions
yezz123 Jan 13, 2025
d40c109
:sparkles: add Dockerfile for lmax-connector setup
yezz123 Jan 13, 2025
a6f506b
:rocket: add lmax-connector to Docker build and test workflows
yezz123 Jan 13, 2025
737e346
:bug: reconfigure Stunnel to work as Entry Point
yezz123 Jan 13, 2025
1eac8dd
:rocket: add g++, libssl-dev, and swig to lmax-connector Dockerfile
yezz123 Jan 13, 2025
f0f2927
:rocket: add pkg-config to lmax-connector Dockerfile
yezz123 Jan 13, 2025
9b5e78a
:sparkles: add Infra configuration for lmax-connector
yezz123 Jan 14, 2025
cee2891
:recycle: fix formatting & linting issue
yezz123 Jan 14, 2025
39dfbe3
:bug: fix Stunnel execution in entrypoint and Dockerfile
yezz123 Jan 14, 2025
530ef49
:rocket: install stunnel4 in Dockerfile and update entrypoint script …
yezz123 Jan 14, 2025
ceb0576
:sparkles: update lmax-connector Dockerfile to include stunnel and ad…
yezz123 Jan 15, 2025
66130df
:recycle: remove unused Fix44 configuration file from Dockerfile
yezz123 Jan 15, 2025
3eca2fe
:sparkles: add Fix44 configuration file to lmax-connector Dockerfile
yezz123 Jan 15, 2025
848ff3a
:recycle: correct case of Fix44 configuration file path in Dockerfile
yezz123 Jan 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
package:
[pragma-sdk, price-pusher, vrf-listener, checkpointer, merkle-maker]
[pragma-sdk, price-pusher, vrf-listener, checkpointer, merkle-maker, lmax-connector]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
build_containers:
strategy:
matrix:
package: [pragma-sdk, price-pusher, vrf-listener, checkpointer]
package: [pragma-sdk, price-pusher, vrf-listener, checkpointer, lmax-connector]
runs-on: ubuntu-latest
permissions:
checks: write
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,8 @@ devnet.pkl

# Mac
.DS_STORE

# Lmax connector metadata
lmax-connector/log/
lmax-connector/store/
lmax-connector/config/fix_settings.cfg
43 changes: 43 additions & 0 deletions infra/lmax-connector/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
FROM python:3.12-slim AS base

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100

ENV PATH="/root/.local/bin:${PATH}"

FROM base as builder

RUN apt-get update && \
apt-get install --no-install-recommends -y \
gcc \
g++ \
libssl-dev \
swig \
libgmp3-dev \
pkg-config \
pipx \
stunnel4

RUN apt-get update && apt-get install -y bash curl && curl -1sLf \
'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash \
&& apt-get update && apt-get install -y infisical

RUN pipx install uv
COPY pragma-sdk/ /opt/pragma-sdk/
COPY lmax-connector/ /opt/lmax-connector/
COPY lmax-connector/config/Fix44.xml /opt/lmax-connector/config/Fix44.xml
WORKDIR /opt/lmax-connector
RUN uv sync

FROM base as final

COPY --from=builder /usr/bin/infisical /usr/bin/infisical
COPY --from=builder /usr/bin/stunnel /usr/bin/stunnel
COPY --from=builder /usr/lib /usr/lib
COPY --from=builder /opt /opt
COPY infra/lmax-connector/entrypoint.sh /opt/lmax-connector/
WORKDIR /opt/lmax-connector
ENTRYPOINT ["bash","/opt/lmax-connector/entrypoint.sh"]
29 changes: 29 additions & 0 deletions infra/lmax-connector/buildspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- aws ecr get-login-password --region $ECR_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$ECR_REGION.amazonaws.com
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$ECR_REGION.amazonaws.com/$ECR_REPOSITORY_NAME
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- ls -ltr
- docker build -f infra/lmax-connector/Dockerfile -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Pushing the Docker images...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"%s","imageUri":"%s"}]' $ECS_CONTAINER_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
- infra/lmax-connector/config.yml
discard-paths: yes
9 changes: 9 additions & 0 deletions infra/lmax-connector/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
path: "/"
container_port: 8080
health_check_path: "/"
container_environment:
- region: "eu-west-3"
- prefix: "/conf/{{ SERVICE_NAME }}/{{ RUN_ENV }}"
- keys:
- INFISICAL_ENV
- INFISICAL_APP_PATH
15 changes: 15 additions & 0 deletions infra/lmax-connector/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

set -euo pipefail

export INFISICAL_TOKEN=$(infisical login --method=universal-auth --client-id=${INFISICAL_CLIENT_ID} --client-secret=${INFISICAL_CLIENT_SECRET} --silent --plain)
infisical export --projectId=${INFISICAL_PROJECT_ID} --env=${INFISICAL_ENV} --path=${INFISICAL_APP_PATH} > .env
source .env

# Execute Stunnel
/usr/bin/stunnel stunnel.conf &

sleep 5

# Execute LMAX Connector
exec /opt/lmax-connector/.venv/bin/python3.12 -m lmax_connector
13 changes: 13 additions & 0 deletions lmax-connector/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# LMAX FIX Connection Settings
LMAX_SENDER_COMP_ID=your_sender_id
LMAX_TARGET_COMP_ID=LMXBLM
LMAX_HOST=fix-md.lmaxtrader.com
LMAX_PORT=443
LMAX_PASSWORD=your_fix_password

# Pragma API Settings
PRAGMA_API_KEY=your_api_key
PRAGMA_PUBLISHER_ID=your_publisher_id
PRAGMA_API_BASE_URL=https://api.dev.pragma.build
PRAGMA_ACCOUNT_PRIVATE_KEY=your_account_private_key
PRAGMA_ACCOUNT_CONTRACT_ADDRESS=your_account_contract_address
47 changes: 47 additions & 0 deletions lmax-connector/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM python:3.12-slim AS base

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100

ENV PATH="/root/.local/bin:${PATH}"

FROM base AS builder

RUN apt-get update && \
apt-get install --no-install-recommends -y \
gcc \
g++ \
libssl-dev \
swig \
libgmp3-dev \
pkg-config \
pipx \
stunnel4

RUN pipx install uv
COPY pragma-sdk/ /opt/pragma-sdk/
COPY lmax-connector/ /opt/lmax-connector/
WORKDIR /opt/lmax-connector
RUN uv sync

FROM base AS final
RUN apt-get update && \
apt-get install --no-install-recommends -y stunnel4 && \
rm -rf /var/lib/apt/lists/*

COPY --from=builder /opt /opt
VOLUME /opt/lmax-connector/config/

WORKDIR /opt/lmax-connector

# Create startup script
RUN echo '#!/bin/bash\n\
exec /usr/bin/stunnel stunnel.conf &\n\
sleep 2\n\
exec /opt/lmax-connector/.venv/bin/python3.12 -m lmax_connector' > /start.sh && \
chmod +x /start.sh

ENTRYPOINT ["/start.sh"]
105 changes: 105 additions & 0 deletions lmax-connector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# LMAX Connector

A service that connects to LMAX Exchange via FIX 4.4 protocol and pushes EUR/USD market data to Pragma.

## Prerequisites

- Python 3.11+
- stunnel (for SSL/TLS connection to LMAX)
- LMAX Exchange account credentials
- uv for dependency management

## Installation

1. Install stunnel:

```bash
# macOS
brew install stunnel

# Ubuntu/Debian
apt-get install stunnel4
```

2. Install the package:

```bash
uv sync
```

## Configuration

1. Copy `.env.example` to `.env` and fill in your credentials:

```bash
cp .env.example .env
```

2. Configure stunnel by modifying `stunnel.conf`:

```ini
; Stunnel configuration for LMAX FIX connection
debug = 7
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
fips = no

[Production-MarketData]
client = yes
accept = 127.0.0.1:40003
connect = fix-md.lmaxtrader.com:443
sslVersion = TLSv1.2
verify = 0
delay = no
TIMEOUTclose = 0
```

## Running the Service

1. Start stunnel:

```bash
cd lmax-connector
stunnel stunnel.conf
```

2. Then, start the connector:

```bash
python -m lmax_connector
```

The service will:

1. Connect to LMAX via FIX 4.4 protocol
2. Subscribe to EUR/USD market data
3. Push prices to Pragma API

## Environment Variables

- `LMAX_SENDER_COMP_ID`: Your LMAX username
- `LMAX_TARGET_COMP_ID`: LMXBLM (for production)
- `LMAX_PASSWORD`: Your LMAX password
- `PRAGMA_API_KEY`: Your Pragma API key
- `PRAGMA_ACCOUNT_PRIVATE_KEY`: Your Pragma account private key
- `PRAGMA_ACCOUNT_CONTRACT_ADDRESS`: Your Pragma account contract address

## Using Docker

1. Build the Docker image:

```bash
ddocker build -t lmax-connector:latest -f lmax-connector/Dockerfile .
```

2. Run the Docker container:

```bash
docker run -v ./config:/opt/lmax-connector/config --env-file .env lmax-connector
```

## Troubleshooting

1. If you see SSL/TLS connection errors, make sure stunnel is running and the configuration is correct.
2. If you see authentication errors, verify your LMAX credentials in the `.env` file.
3. Check the logs in `log/` directory for detailed error messages.
Loading
Loading