Hello World in a container. About deploying strategies...
Thomas Schmelzer
Portfolio construction and technology | Commodities and LS Equities | Visiting Scholar at Stanford.
This article has been written without the help of ChatGPT. It's me. Today I describe the way I deploy quantitative trading strategies. The introduction of Docker was a game changer for me. Laurent Bindschaedler introduced me to this technology back in '15. Containers made any nasty technical interference between strategies impossible. Before we spent weeks trying to verify that the updates required for B do not harm A. Everything was running on the same environment and protected by an entire group of system administrators.
Let's start with a simple Python program:
if __name__ == '__main__':
print("Hello Thomas")
Eh, voila. It prints "Hello Thomas". Let's crank it up.
from pathlib import Path
def hello(config_file):
? ? """Simple program that greets NAME"""
? ? config = read_yaml(file=config_file)
? ? print(f"Hello {config['name']}")
if __name__ == '__main__':
? ? hello(Path(__file__).parent / "configurations" / "test.yaml")
It does the same again but this time it injects my name from a yaml file. The yaml file may contain dozens of parameters and we may have multiple such files. We want to inject the name of the file using a cli (command line interface). The standard tool for this is the click package by Armin Ronacher (of Flask fame).
We write
from pathlib import Path
import click
@click.command()
@click.argument("filename", type=click.Path(exists=True))
def hello(filename):
"""Simple program that greets NAME"""
config_file = Path(filename)
config = read_yaml(file=config_file)
print(f"Hello {config['name']}")
if __name__ == '__main__':
hello()
Using our new cli we can now run
领英推荐
python hello.py configurations/test.yaml
The injection of yaml files might lack some robustness but tools such as pydantic are of great help here. Nevertheless, there are some implicit assumptions baked into the last statement. We rely on click and hello.py may require a bunch of libraries (such as PyYAML). Here Docker helps. We can create a container and simple do
docker run -v $(pwd)/configurations:/app/configurations
hello:latest configurations/test.yaml
Injecting the filename of the yaml file is best done by defining an entrypoint in a Dockerfile:
# Use a standard Python container
FROM python:3.10-slim-buster
# Install click and pyyaml
RUN pip install --no-cache-dir click=="8.1.3" pyyaml=="6.0"
# Set a working directory
WORKDIR app
COPY hello.py /app/hello.py
ENTRYPOINT ["python", "/app/hello.py"]
This simple example illustrates a beautiful concept. The host doesn't need to know details about the Python environment in the container. In fact, the host can get away with running no Python itself at all. This is in particular useful if the host has to interact with multiple containers each with their own (contradicting?!) requirements.
I hope you see the link to trading. A trading strategy is a hello function on steroids. All your strategies will be equipped with the same command line interface which will simplify any downstream processing a great deal.
There is a lot more to say about containers, robustness, reproducibility, communication (between containers and with system administrators) and the setup of trading strategies. Please share your thoughts down in the comments.
Quantitative Research & Dev Lead
2 年Thank you Thomas Schmelzer for sharing. This technology is useful anytime you have a time to market constraint. You can deliver the additional derivatives product say a new payoff without having to put the whole system at risk. More than that you can deliver a new model with its embedded data model, it algorithm and its reporting as simply. It brings flexibility. This is so important . However more importantly you can create a resilient system that is robust to partial failure. Indeed let us be honest , systems are complex and they contain a large number of combinatorial calls and our jobs as quant and Its alike is to make sure that the show must go on all the time especially for real time trading. Putting partial objects with no dependences or correlation makes the problem easier to operate. The conductor contains a hard coded slow releasing capability and dictates the rhythm for the myriads of little ba y functional sollist codes. One last point that is sometimes neglected in the IT decision process and which in my sense is critical : the cost of running the system. Whenever results are not as expected or we need to debug and analyse , concentrating on a concise image makes the problem easier to reproduce and to analyse.
Account Executive By Day | Pythonista & Amateur Natural Bodybuilder By Night
2 年Nicely done - nice call keeping the quant work out to focus on just passing in config
Thomas Schmelzer you should consider adding Tini or another sub reaper to deal with the zombie processes. Then I would grant you the full docker nerd status. Bonus points if you also solve the user ID issue ?? so you don't fail the audit for all your containers running on root ??
Partner I Professor I Entrepreneur
2 年Nerd ??
La Sorbonne
2 年Just using PI.