Run the daily loop on a server with systemd user units

deploy/systemd holds an IB Gateway service (IBC under Xvfb, paper) and
timers for the 09:50 ET rebalance, 16:15 ET fills, and a weekly
constituents refresh; make install-units installs them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 22:03:57 +08:00
parent dc94f63839
commit 787c41ba63
8 changed files with 83 additions and 1 deletions

View File

@@ -6,7 +6,7 @@
# open, so start after 09:47 ET. # open, so start after 09:47 ET.
RUN = uv run ibkr-quant RUN = uv run ibkr-quant
.PHONY: test universe check bars plan submit fills backtest .PHONY: test universe check bars plan submit fills backtest install-units
test: test:
uv run pytest -q uv run pytest -q
@@ -32,3 +32,13 @@ fills:
# e.g. make backtest ARGS="--top-n 5 10 20 --every 1 5 --capital 10000" # e.g. make backtest ARGS="--top-n 5 10 20 --every 1 5 --capital 10000"
backtest: backtest:
$(RUN) backtest $(ARGS) $(RUN) backtest $(ARGS)
# On the server: install the systemd user units from deploy/systemd. The timers
# start now; the Gateway is only enabled for boot, so start it by hand
# (systemctl --user start ibgateway) once ~/ibc/config.ini has the credentials.
install-units:
mkdir -p ~/.config/systemd/user
cp deploy/systemd/* ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable ibgateway.service
systemctl --user enable --now ibkr-quant-trade.timer ibkr-quant-fills.timer ibkr-quant-universe.timer

View File

@@ -0,0 +1,12 @@
[Unit]
Description=IB Gateway (paper) logged in by IBC, headless under Xvfb
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/xvfb-run -a -s "-screen 0 1024x768x24" %h/ibc/gatewaystart.sh -inline
Restart=always
RestartSec=60
[Install]
WantedBy=default.target

View File

@@ -0,0 +1,9 @@
[Unit]
Description=ibkr-quant: record today's executions
After=ibgateway.service
[Service]
Type=oneshot
WorkingDirectory=%h/projects/ibkr-quant
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/bin/make fills

View File

@@ -0,0 +1,8 @@
[Unit]
Description=ibkr-quant executions, 16:15 New York time on weekdays
[Timer]
OnCalendar=Mon..Fri 16:15 America/New_York
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,15 @@
[Unit]
Description=ibkr-quant daily rebalance: today's bars, then MOC orders
After=ibgateway.service
# Retries cover today's bar arriving late (delayed data) and Gateway restarts;
# make submit refuses to double-submit while orders are open.
StartLimitIntervalSec=7200
StartLimitBurst=6
[Service]
Type=oneshot
WorkingDirectory=%h/projects/ibkr-quant
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/bin/make bars submit
Restart=on-failure
RestartSec=300

View File

@@ -0,0 +1,9 @@
[Unit]
Description=ibkr-quant daily rebalance, 09:50 New York time on weekdays
[Timer]
OnCalendar=Mon..Fri 09:50 America/New_York
Persistent=true
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,10 @@
[Unit]
Description=ibkr-quant: refresh S&P 500 constituents from Wikipedia
[Service]
Type=oneshot
WorkingDirectory=%h/projects/ibkr-quant
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
# pc reaches Wikipedia only through its local proxy.
Environment=https_proxy=http://127.0.0.1:7890
ExecStart=/usr/bin/make universe

View File

@@ -0,0 +1,9 @@
[Unit]
Description=ibkr-quant constituents refresh, Sundays
[Timer]
OnCalendar=Sun 12:00 America/New_York
Persistent=true
[Install]
WantedBy=timers.target