diff --git a/docs/WINDOWS_SCHEDULING.md b/docs/WINDOWS_SCHEDULING.md index 3a0fef2..d5a578f 100644 --- a/docs/WINDOWS_SCHEDULING.md +++ b/docs/WINDOWS_SCHEDULING.md @@ -34,11 +34,28 @@ Create **two** wrapper scripts — they run *different* commands from *different ```bat @echo off -set MARKETDATA_STORE=REPLACE_WITH_MARKETDATA_STORE_PATH -"REPLACE_WITH_VENV_PATH\Scripts\marketdata-update.exe" --bars --domain futures --require-final -"REPLACE_WITH_VENV_PATH\Scripts\marketdata-update.exe" --metadata +setlocal +set "MARKETDATA_STORE=REPLACE_WITH_MARKETDATA_STORE_PATH" +set "MDEXE=REPLACE_WITH_VENV_PATH\Scripts\marketdata-update.exe" + +"%MDEXE%" --bars --domain futures --require-final +if errorlevel 1 exit /b %ERRORLEVEL% + +"%MDEXE%" --metadata +exit /b %ERRORLEVEL% ``` +> **Those two `exit /b` lines are load-bearing.** A `.cmd` exits with the code of its LAST +> command, so running `--metadata` after `--bars` with no guard lets its exit 0 overwrite a +> deferral's exit 1. Task Scheduler then records **success**, restart-on-failure never fires, +> and the task waits until tomorrow having fetched nothing — the gate answering correctly and +> the wrapper discarding the answer. Skipping `--metadata` on a defer also keeps each retry a +> cheap gate check instead of a full contract-spec fetch against NDU. +> +> `if errorlevel 1` tests `>= 1` and needs no variable expansion, so it is safe. `|| exit /b +> %ERRORLEVEL%` would **not** be: cmd expands `%ERRORLEVEL%` when it parses the line, before +> the command on that line has run, so it returns the *previous* command's code. + `run-cot.cmd` — COT (note the **different** command, `--cot-all`): ```bat diff --git a/docs/examples/windows/run-prices.cmd b/docs/examples/windows/run-prices.cmd index 14cac4a..4d02c79 100644 --- a/docs/examples/windows/run-prices.cmd +++ b/docs/examples/windows/run-prices.cmd @@ -15,6 +15,29 @@ REM REM --require-final defers (exits non-zero, having fetched nothing) until Norgate REM holds a newer settled bar than the store does; pair it with Task Scheduler REM "restart on failure". See docs/WINDOWS_SCHEDULING.md. -set MARKETDATA_STORE=REPLACE_WITH_MARKETDATA_STORE_PATH -"REPLACE_WITH_VENV_PATH\Scripts\marketdata-update.exe" --bars --domain futures --require-final -"REPLACE_WITH_VENV_PATH\Scripts\marketdata-update.exe" --metadata +REM +REM THE EXIT CODE IS THE WHOLE POINT, so read the two lines that carry it before +REM editing this file. A .cmd exits with the code of its LAST command. An earlier +REM version of this wrapper ran --metadata after --bars with no guard, so a +REM deferral (exit 1) was overwritten by --metadata's exit 0: Task Scheduler +REM recorded SUCCESS, restart-on-failure never fired, and the task sat until the +REM next day having fetched nothing. The gate worked and the wrapper discarded its +REM answer -- exactly the stale-bar failure --require-final exists to prevent. +REM +REM `if errorlevel 1` tests >= 1 and needs no expansion, so it is safe here. +REM `|| exit /b %ERRORLEVEL%` would NOT be: cmd expands %ERRORLEVEL% when it parses +REM the line, which is BEFORE the command on that line has run, so it would return +REM the previous command's code. On its own line, after the command, it is correct. +setlocal +set "MARKETDATA_STORE=REPLACE_WITH_MARKETDATA_STORE_PATH" +set "MDEXE=REPLACE_WITH_VENV_PATH\Scripts\marketdata-update.exe" + +"%MDEXE%" --bars --domain futures --require-final +REM Stop here on a defer OR a failure, and keep the code. Skipping --metadata on a +REM defer is deliberate as well as convenient: restart-on-failure turns this task +REM into a poll loop, and each retry should be the cheap gate check rather than a +REM full contract-spec fetch of every symbol against NDU. +if errorlevel 1 exit /b %ERRORLEVEL% + +"%MDEXE%" --metadata +exit /b %ERRORLEVEL%