Automate MACD analysis using n8n workflows

Creating a Custom Candlestick and MACD Analysis Tool in n8n

I built a compact workflow that turns raw stock charts into candlestick and MACD analysis inside n8n. It pulls OHLCV data, calculates MACD, checks a few candlestick patterns, and writes out tidy results that can feed a dashboard or alert.

Design and data flow

Keep the flow linear: fetch OHLCV, normalise it, calculate indicators, run pattern checks, then emit the result. That keeps the workflow readable and easier to debug.

What data you need

  • Time, open, high, low, close, volume for each bar. That is OHLCV.
  • A consistent timeframe. Do not mix minute bars with daily bars in the same run.
  • A reliable source. Any REST API that returns JSON or CSV will do.

Indicator choices

  • I use standard MACD settings: 12, 26, 9. MACD is the difference between a short EMA and a long EMA. The signal line is an EMA of the MACD. The histogram is MACD minus signal. That is straightforward to compute in a Function node.
  • The candlestick patterns I check are low-cost and deterministic: bullish engulfing, bearish engulfing, hammer, and shooting star. They are quick to compute and give clear signals when combined with MACD crossovers.

Data flow in n8n

  • Trigger node: Cron or Webhook. Cron for scheduled batch runs. Webhook for on-demand checks.
  • HTTP Request node: Pull OHLCV from your chosen API. Keep the API key secret. Request only the fields you need.
  • Function node: Convert timestamps to ISO, sort bars ascending, and calculate EMAs, MACD, signal, histogram, and basic candlestick booleans.
  • IF node: Filter bars with the conditions you care about. For example, bullish engulfing and MACD histogram turning positive on the same bar.
  • Output node: Post to an endpoint, save to Google Sheets, or write a JSON file. I tend to push an annotated CSV to an S3-compatible bucket for later charting.

Why this layout works

  • It separates fetching, calculation, and decision logic. That makes debugging easier.
  • n8n nodes are easy to replace. If the API changes, only the HTTP Request node needs work.
  • The Function node keeps the heavy lifting local. That avoids round trips and reduces cost.

Concrete example of checks

  • Bullish signal: bullish engulfing + MACD histogram crossing from negative to positive on the same bar.
  • Bearish signal: bearish engulfing + MACD histogram crossing from positive to negative.
  • Weak signal: MACD histogram with a small absolute value. Log it, but do not act on it.

Step-by-step n8n implementation and verification

I used the steps below. The MACD and EMA logic can go straight into a Function node.

1) Trigger and fetch

  • Add a Cron node to run at your chosen cadence.
  • Add an HTTP Request node. Point it at a provider that returns OHLCV. Set authentication and query parameters.
  • Map the response to the Function node. Pass only the array of bars.

2) Normalise and sort

  • In the Function node, coerce timestamps to ISO and sort ascending by time. That avoids off-by-one errors in EMA calculations.

3) EMA and MACD calculation

function ema(prices, period) {
  const k = 2 / (period + 1);
  let emaPrev = prices[0];
  const out = [emaPrev];
  for (let i = 1; i < prices.length; i++) {
    const v = prices[i] * k + emaPrev * (1 - k);
    out.push(v);
    emaPrev = v;
  }
  return out;
}

const closes = items.map(i => i.json.close);
const emaShort = ema(closes, 12);
const emaLong = ema(closes, 26);
const macd = emaShort.map((v, idx) => v - emaLong[idx]);
const signal = ema(macd, 9);
const hist = macd.map((v, idx) => v - (signal[idx] || 0));
  • Attach MACD, signal, and histogram back to each bar object.

4) Candlestick pattern checks

  • Use deterministic checks. Example for bullish engulfing:
const isBullishEngulfing = (prev, curr) =>
  prev.close < prev.open &&
  curr.close > curr.open &&
  curr.open < prev.close &&
  curr.close > prev.open;
  • Add booleans for patterns to each bar.

5) Decision logic

  • Use an IF node or continue the logic inside the Function node.
  • Condition example: current.hist > 0 and previous.hist <= 0 and isBullishEngulfing(prev, curr).
  • When true, format an output message with timestamp, symbol, pattern, MACD, signal, and histogram.

6) Output and storage

  • Output options: webhook POST, plain text file, CSV, spreadsheet row, or push to a time-series database.
  • I favour storing raw annotated OHLCV plus flags. It makes later charting and auditing easier.

Verification steps

  • Test with static sample data. Feed known OHLC sequences where the expected MACD values are calculable by hand. Compare results.
  • Export the output to CSV and overlay MACD and pattern flags on a charting tool.
  • Watch for missing bars, NaN from short input arrays, and timezone mismatches. Add guards in the Function node that skip insufficient data and log the issue.

Practical tips and pitfalls

  • Use UTC throughout. Local timezones lead to invisible bugs in intraday data.
  • Keep MACD parameters configurable. Different markets may prefer different settings.
  • If your data has gaps, fill or skip the gaps deliberately. EMA is sensitive to gaps.
  • Rate limits matter: fetch only what you need. Requesting decades of minute data hits limits and costs more.
  • For speed, compute EMA iteratively and carry the last EMA forward between runs if you run the workflow often.

Concrete output examples

  • Single-row alert: { time: “2025-09-01T09:30:00Z”, symbol: “ABC”, signal: “bullish_engulfing + MACD_cross”, macd: 0.12, signalLine: 0.05, hist: 0.07 }
  • Daily CSV: time,open,high,low,close,volume,macd,signal,hist,bullishEngulfing,bearishEngulfing

What the tool delivers

  • Automated candlestick MACD analysis on a schedule.
  • Simple decision flags for filtering.
  • Clean, auditable output for charting or feeding into dashboards.
  • Raw annotated data that supports later analysis.

Takeaways

  • Keep the Function node small and testable. Small functions are easier to validate.
  • Store annotated outputs. It saves hours when you need to show why a signal fired.
  • MACD plus a clear candlestick pattern gives conservative and explainable signals.
  • Use n8n for orchestration, not charting. Push results to the right tool for visualisation.

That is the setup I use. It runs on simple cron schedules, handles more data without much fuss, and makes candlestick MACD analysis repeatable.

Related posts

Agentic AI still needs domain judgement

Agentic AI can write the thing, but it still cannot tell you whether the thing is right. That is where domain expertise matters, because a clean config or neat bit of glue logic can still be wrong in...

Weekly Tech Digest | 06 Jul 2026

Stay updated with the latest in tech! This digest covers AI ethics, auto industry shifts, and the impact of politics on technology, exploring today's pressing issues.

wolfCOSE zero-allocation parsing in embedded C

wolfCOSE looks sensible only if you care about what your firmware actually has to carry. I like that, because on small targets the wrong crypto feature can cost more than the message itself, and there...