feat: Tradier parallel-stack compose template
Self-contained shakeout stack beside the paper stack: own postgres (host 5434, disposable pgdata-tradier volume), own dashboard (host 8768), loop with BROKER=tradier (sandbox). Data plane stays Alpaca; Telegram/deadman disabled so main-stack alerts stay unambiguous; main data dir mounted read-only (inherits learned_params/overrides.env). Filled local copy is git-excluded; bootstrap_live_db.sh playbook reused for DB parity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1cefb51c63
commit
df85201c45
2 files changed
+131
No files matched your search
@@ -0,0 +1,111 @@
|
||||
# TRADIER PARALLEL STACK — template (fill <FILL-ME-*>, save as
|
||||
# truenas-compose.tradier.local.yaml, never commit the filled copy).
|
||||
#
|
||||
# Runs the SAME image/strategy as the paper stack but executes through the
|
||||
# Tradier mirror (BROKER=tradier, sandbox by default). Fully self-contained:
|
||||
# own postgres (host 5434), own dashboard (host 8768). Market data stays on
|
||||
# Alpaca (keys still required). Telegram + deadman are OFF here so the main
|
||||
# stack's alerts stay unambiguous.
|
||||
#
|
||||
# Shares the main stack's data dir READ-ONLY: the loop inherits the nightly
|
||||
# learned_params.json and overrides.env without being able to clobber them.
|
||||
#
|
||||
# Fresh-DB bootstrap (same playbook as live staging), run on cube:
|
||||
# ./bootstrap_live_db.sh <nightly-backup.sql.gz> <this-stack-postgres-container>
|
||||
# or skip it and let the loop start from an empty DB (research baselines absent,
|
||||
# config knobs at code defaults — fine for a first shakeout).
|
||||
#
|
||||
# Requires an image built from >= 1cefb51 (tradier_broker in image).
|
||||
#
|
||||
# Sandbox caveat: Tradier sandbox fills are simulated and can be slow/absent —
|
||||
# an order parked in 'pending_new' is usually the sandbox, not the code.
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
environment:
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
POSTGRES_DB: momentum
|
||||
POSTGRES_PASSWORD: <FILL-ME-PG-PASSWORD>
|
||||
POSTGRES_USER: momentum
|
||||
TZ: America/New_York
|
||||
healthcheck:
|
||||
interval: 10s
|
||||
retries: 5
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- pg_isready -U momentum -d momentum
|
||||
timeout: 5s
|
||||
ports:
|
||||
- 5434:5432
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/Volume/Storage/Apps/momentum/pgdata-tradier:/var/lib/postgresql/data
|
||||
|
||||
loop:
|
||||
image: docker.io/fez5587/momentum-app:latest
|
||||
command:
|
||||
- python
|
||||
- -u
|
||||
- run_live_paper.py
|
||||
- --no-dashboard
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment: &tradier-env
|
||||
BROKER: tradier
|
||||
TRADIER_ACCESS_TOKEN: <FILL-ME-TRADIER-TOKEN>
|
||||
TRADIER_ACCOUNT_ID: <FILL-ME-TRADIER-ACCOUNT>
|
||||
TRADIER_ENV: sandbox
|
||||
ALPACA_API_KEY: <FILL-ME-ALPACA-KEY>
|
||||
ALPACA_SECRET_KEY: <FILL-ME-ALPACA-SECRET>
|
||||
ALPACA_BACKFILL_FEED: sip
|
||||
ALPACA_BASE_URL: https://paper-api.alpaca.markets
|
||||
ALPACA_PAPER_SYNC_ENABLED: '1'
|
||||
DATABASE_URL: postgresql://momentum:<FILL-ME-PG-PASSWORD>@postgres:5432/momentum
|
||||
# alerts stay with the MAIN stack — no double Telegram / deadman pings
|
||||
TELEGRAM_BOT_TOKEN: ''
|
||||
TELEGRAM_CHAT_ID: ''
|
||||
DEADMAN_DAILY_PING: '0'
|
||||
DEADMAN_STALE_MIN: '5'
|
||||
INGEST_STALE_BLOCK: '0'
|
||||
INGEST_STALE_SECONDS: '180'
|
||||
ORB_BARS: '5'
|
||||
PG_SKIP_SCHEMA: '0'
|
||||
QUOTE_SNAPSHOT_INTERVAL_SECONDS: '8'
|
||||
STRATEGY_SETUPS: opening_range_break
|
||||
DEPTH_RECORD_ENABLED: '0'
|
||||
TZ: America/New_York
|
||||
healthcheck:
|
||||
interval: 60s
|
||||
retries: 5
|
||||
start_period: 180s
|
||||
test:
|
||||
- CMD
|
||||
- python
|
||||
- -c
|
||||
- import os; os.environ['PG_SKIP_SCHEMA']='1'; import datetime,sys; from research.multi_schema import open_research_db; r=open_research_db('market').execute('SELECT max(timestamp) FROM events').fetchall()[0][0]; sys.exit(0 if r and (datetime.datetime.now()-r).total_seconds()<300 else 1)
|
||||
timeout: 20s
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/Volume/Storage/Apps/momentum/data:/app/data:ro
|
||||
|
||||
dashboard:
|
||||
image: docker.io/fez5587/momentum-app:latest
|
||||
command:
|
||||
- python
|
||||
- -u
|
||||
- dashboard_api.py
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
<<: *tradier-env
|
||||
COMMAND_BUS_ENABLED: '1'
|
||||
DASHBOARD_HOST: 0.0.0.0
|
||||
DASHBOARD_PORT: '8765'
|
||||
DASHBOARD_TOKEN: <FILL-ME-DASHBOARD-TOKEN>
|
||||
ports:
|
||||
- 8768:8765
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/Volume/Storage/Apps/momentum/data:/app/data:ro
|
||||
@@ -44,6 +44,26 @@ Smoke refuses order exercises against the live base URL.
|
||||
filters are client-side; the live loop only queries today + held symbols, so
|
||||
behavior matches.
|
||||
|
||||
## Parallel shakeout stack (TrueNAS)
|
||||
|
||||
`deploy/docker/truenas-compose.tradier.yaml` is the committed template; the
|
||||
filled copy lives (git-excluded) at `truenas-compose.tradier.local.yaml`.
|
||||
Runs beside the paper stack, fully isolated:
|
||||
|
||||
- own postgres (host **5434**, fresh `pgdata-tradier` volume), own dashboard
|
||||
(host **8768**), loop with `BROKER=tradier` against the sandbox account
|
||||
- market data still Alpaca; Telegram + deadman OFF (main stack keeps alerts)
|
||||
- main data dir mounted **read-only** — inherits nightly
|
||||
`learned_params.json` / `overrides.env`, cannot clobber them; if a service
|
||||
ever crashes on a read-only-filesystem error, switch that mount to a
|
||||
writable copy
|
||||
- fresh DB starts empty (knobs at code defaults). For research-baseline +
|
||||
knob parity with the paper stack, reuse the live-staging playbook:
|
||||
`./bootstrap_live_db.sh <nightly-backup.sql.gz> <tradier-postgres-container>`
|
||||
- needs an image built from >= 1cefb51 (`tradier_broker/` in image)
|
||||
- sandbox fills are simulated and can be slow or absent — an order parked in
|
||||
`pending_new` is usually the sandbox, not the code
|
||||
|
||||
## Before flipping live money to Tradier
|
||||
|
||||
1. Rotate the sandbox token (it transited chat) and mint a live token.
|
||||
|
||||
Reference in new issue
Block a user