The most boring chart of 2026 taught me something about code
The S&P 500 closed at $725 today. Yesterday? $725. Last week? Basically $725. The Nasdaq is parked at $694 and hasn't twitched. Here's the uncomfortable stat for engineers who invest: in flat markets, the average retail investor underperforms a cron job. Not a fancy model — a literal scheduled task that buys a fixed amount and does nothing else.
So I stopped manually "watching the market" and shipped the discipline as code. Here's the architecture.
Why flat markets are a systems problem, not a trading problem
A flat market is a market in equilibrium — buyers and sellers agree on price while waiting for the next catalyst (inflation print, Fed tone, Q2 earnings). Your brain hates equilibrium, so it invents signals to react to. That's the bug. Emotional, discretionary trading is an unhandled exception in an otherwise simple loop.
The fix is the same one we use for any flaky manual process: remove the human from the hot path. Dollar-cost averaging (DCA) — buying a fixed amount on a fixed schedule — is mathematically built for sideways chop. You can't time a bottom that doesn't exist, so you stop trying and let the schedule average your cost into the middle of the range.
The stack
- n8n — open-source workflow orchestration (the cron + glue)
- Broker API — Alpaca here, but any REST brokerage works
- GPT-4 — not for picking trades. Only for summarizing the macro context into a plain-English log entry so I have an audit trail of why nothing changed.
The key design decision: GPT-4 never touches the buy logic. LLMs hallucinate; your order size must not. The model is a narrator, not a trader.
The DCA executor
The core is ~15 lines. Fixed cash in, fractional shares out, no branching on price:
python
import os, requests
BUY_USD = 500 # fixed contribution, never derived from price
def dca_buy(symbol: str) -> dict:
resp = requests.post(
"https://paper-api.alpaca.markets/v2/orders",
headers={
"APCA-API-KEY-ID": os.environ["ALPACA_KEY"],
"APCA-API-SECRET-KEY": os.environ["ALPACA_SECRET"],
},
json={
"symbol": symbol,
"notional": BUY_USD, # dollar-based -> auto fractional shares
"side": "buy",
"type": "market",
"time_in_force": "day",
},
timeout=10,
)
resp.raise_for_status()
return resp.json()
At $725, a $500 notional order buys ~0.69 shares. If the index dips to $710 next cycle, the same $500 buys more; if it pops to $740, I already bought in cheaper. No guessing.
The n8n workflow
Four nodes, runs every two weeks:
[Schedule Trigger: */14 days]
↓
[HTTP Request: GET /v2/account] ← check buying power
↓
[Function: dca_buy("VOO")] ← the code above
↓
[OpenAI node: GPT-4 summary] ← narrate, don't decide
The GPT-4 node gets a tightly scoped prompt so it can't drift into advice:
javascript
// n8n Function node feeding the OpenAI node
const prompt = You are a logging assistant, NOT a financial advisor.;
In 2 sentences, neutrally summarize today's market context.
Do NOT recommend any action. Data: ${JSON.stringify($json.macro)}
return { prompt, temperature: 0.2 };
Low temperature, explicit role constraint, and the output is written to a log — never read back into a decision. That separation is the whole safety model.
The trap I designed around
The failure mode isn't a bad trade — it's "I'll wait until things get clear." Clarity never arrives in a flat market, and the breakout historically happens fast. Sitting in cash is itself a position, and an undisciplined one. Encoding the schedule means the cash-drag decision can't be made by my mood at 2am.
Practical takeaways
-
Make the boring thing automatic. A
Schedule Triggerbeats willpower. Discipline you have to summon will eventually not show up. - Keep the LLM out of the critical path. Use GPT-4 for summaries, logs, and narration — never for order sizing. Deterministic money, probabilistic prose.
-
Fixed inputs, not derived ones.
BUY_USDis a constant. The moment contribution size depends on price, you've reinvented market timing. - Log the why, not just the what. The GPT-4 narration gives you a reviewable trail so future-you can audit the system instead of second-guessing it.
-
Paper-trade first. Point it at
paper-api, watch a few cycles, then flip the endpoint.
Flat markets are where amateurs quietly lose money and disciplined systems quietly compound. The good news for us: discipline is just a workflow you haven't shipped yet.
Not financial advice — automate responsibly and test against a paper account.
Want the done-for-you AI automation templates from this post? Get the NSST AI toolkit.
Top comments (0)