DEV Community

네이쳐스테이
네이쳐스테이

Posted on • Originally published at smartaireviewer.com

When Four Markets Print Zero: Building an Automated Market-to-Article Pipeline with n8n and GPT-4

The day the tape went flat

On June 8th, 2026, four of the most volatile markets on Earth closed at exactly the same number: zero. The S&P 500 at $738, the Nasdaq at $705, Bitcoin at $63,272, gold at $396 — all flat, 0.00%. A perfectly correlated nothing.

As a developer, my first reaction wasn't "is this calm before the storm?" It was: this is a perfect trigger event for an automated content pipeline. A flat tape is rare, newsworthy, and — critically — detectable with a single boolean. That makes it an ideal test case for the kind of event-driven LLM workflow many of us are being asked to ship right now.

This post walks through the architecture I use to turn a market data event into a published draft article, using n8n for orchestration and GPT-4 for generation. The market angle is the example; the pattern is the point.

The architecture

The pipeline is four stages, each a node (or small cluster) in n8n:

Schedule/Webhook → Fetch quotes → Detect event → Generate draft → Publish

The key design decision: detection logic lives in code, not in the prompt. LLMs are unreliable threshold-checkers. You don't want GPT-4 deciding whether the market is "flat enough" — you want deterministic JavaScript doing that, and the LLM only doing what it's good at: prose.

Stage 1 & 2: Fetch and detect

A scheduled trigger hits a quotes API, then a Function node decides whether anything worth writing about happened. Here's the detection logic — the one piece I'd argue you should own, because the threshold encodes editorial judgment:

javascript
// n8n Function node: classify the session
const quotes = $input.all().map(i => i.json);
const FLAT_BPS = 5; // within 5 basis points = "unchanged"

const flat = quotes.filter(q =>
Math.abs(q.changePercent) * 100 <= FLAT_BPS
);

// Only newsworthy if MULTIPLE uncorrelated assets are flat at once
const isStory = flat.length >= 3;

return isStory
? [{ json: { trigger: 'multi_flat', assets: flat } }]
: []; // empty array = pipeline halts, no spurious articles

Returning an empty array short-circuits the rest of the workflow — no event, no API spend, no junk drafts. That guard is what makes the thing safe to run on a cron every market close.

Stage 3: Generation with structured output

The LLM call is where most pipelines go wrong. Don't ask for a blob of markdown and hope. Ask for structured JSON so downstream nodes can validate before anything gets published:

javascript
const res = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': Bearer ${$env.OPENAI_API_KEY},
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4',
response_format: { type: 'json_object' },
messages: [
{ role: 'system', content: 'You are a markets writer. Return JSON with keys: title, body_markdown, tags (max 3).' },
{ role: 'user', content: Write ~800 words on why these assets all closed flat: ${JSON.stringify($json.assets)} }
]
})
});

response_format: { type: 'json_object' } is the unsung hero here — it turns "parse the model's freeform reply and pray" into a contract. Pair it with a schema check in the next node and reject anything malformed instead of publishing it.

Stage 4: Publish (behind a human gate)

The final node POSTs to the Dev.to API — but creates a draft, never a live post:

javascript
await fetch('https://dev.to/api/articles', {
method: 'POST',
headers: { 'api-key': $env.DEVTO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
article: { ...$json, published: false } // human reviews before it ships
})
});

What the flat-market example actually teaches

The market story is a clean lesson in correlation, and it maps directly onto pipeline design:

  • Flat ≠ idle. Equilibrium is buyers and sellers in a standoff ahead of a catalyst (here, a mid-June Fed meeting). Your pipeline should treat "nothing happened" as a real, explicit state — not an error.
  • Correlation is the signal. One flat asset is noise; four flat at once is the story. Good event detection looks at the joint condition, not isolated metrics.
  • Deterministic gates around a probabilistic core. Code decides whether to write; the LLM decides what to write. Never blur those.

Practical takeaways

  1. Keep thresholds in code. LLMs write prose, not boolean logic.
  2. Halt early. An empty return in your detection node saves tokens and prevents spam.
  3. Demand structured output. json_object mode + schema validation beats regex-scraping every time.
  4. Always gate publishing. Auto-generate, human-approve. published: false is one line and saves you from shipping a hallucination.

A flat tape told the markets to hold their breath. For a developer, it's just a well-shaped trigger — and a reminder that the best AI pipelines are mostly boring, deterministic plumbing wrapped around one clever model call.


Want the done-for-you AI automation templates from this post? Get the NSST AI toolkit.

Top comments (0)