/* Serving mart: KC=F Coffee C futures prices, analytics-ready. */ /* Adds moving averages (20-day, 50-day SMA) and 52-week high/low range. */ /* Filtered to trading days only (NULL close rows excluded upstream). */ /* Grain: one row per trade_date. */
MODEL (
  name serving.coffee_prices,
  kind INCREMENTAL_BY_TIME_RANGE (
    time_column trade_date
  ),
  grain (
    trade_date
  ),
  start '1971-08-16',
  cron '@daily'
);

WITH base AS (
  SELECT
    f.trade_date,
    f.open,
    f.high,
    f.low,
    f.close,
    f.adj_close,
    f.volume,
    ROUND(
      (
        f.close - LAG(f.close, 1) OVER (ORDER BY f.trade_date)
      ) / NULLIF(LAG(f.close, 1) OVER (ORDER BY f.trade_date), 0) * 100,
      4
    ) AS daily_return_pct, /* Daily return: (close - prev_close) / prev_close * 100 */
    ROUND(
      AVG(f.close) OVER (ORDER BY f.trade_date ROWS BETWEEN 19 PRECEDING AND CURRENT ROW),
      4
    ) AS sma_20d, /* 20-day simple moving average (1 trading month) */
    ROUND(
      AVG(f.close) OVER (ORDER BY f.trade_date ROWS BETWEEN 49 PRECEDING AND CURRENT ROW),
      4
    ) AS sma_50d, /* 50-day simple moving average (2.5 trading months) */
    MAX(f.high) OVER (ORDER BY f.trade_date ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) AS high_52w, /* 52-week high (approximately 252 trading days) */
    MIN(f.low) OVER (ORDER BY f.trade_date ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) AS low_52w /* 52-week low */
  FROM foundation.fct_coffee_prices AS f
  WHERE
    f.trade_date BETWEEN @start_ds AND @end_ds
)
SELECT
  b.trade_date,
  d.commodity_name,
  d.ticker,
  b.open,
  b.high,
  b.low,
  b.close,
  b.adj_close,
  b.volume,
  b.daily_return_pct,
  b.sma_20d,
  b.sma_50d,
  b.high_52w,
  b.low_52w
FROM base AS b
CROSS JOIN foundation.dim_commodity AS d
WHERE
  d.ticker = 'KC=F'
ORDER BY
  b.trade_date