OGT Owl Group Trading by Dr. Ken Long
Home About Learn The Loop Code Courses Essays Store Partners FAQ
JavaScript · Indicator Code

The River, Flood Plain & Red Line in JavaScript

Owl Group Trading's 30-period Bollinger zones around the Mean: River (+/-1 SD), Flood Plain (+/-2 SD), Red Line (+/-3 SD).

Concept: what RIVER-FLOOD-PLAIN means →

Verified. Python and JavaScript implementations agree to 2.84e-14 on a 60-bar reference price series (Python vs JavaScript across the River/Flood Plain/Red Line bands (+/-1, +/-2, +/-3 SD over 30 periods) - float64 round-off only).

JavaScript

// The River, Flood Plain and Red Line - 30-period Bollinger zones around the
// Mean (Z0 = the 30-period SMA). River = +/-1 SD (Z1), Flood Plain = +/-2 SD
// (Z2), Red Line = +/-3 SD (Z3).
function sma(values, n = 30) {
  const len = values.length, out = new Array(len).fill(null);
  let sum = 0, count = 0;
  for (let i = 0; i < len; i++) {
    const v = values[i];
    if (v != null && !Number.isNaN(v)) { sum += v; count++; }
    if (i >= n) { const old = values[i - n]; if (old != null && !Number.isNaN(old)) { sum -= old; count--; } }
    if (i >= n - 1 && count === n) out[i] = sum / n;
  }
  return out;
}
function rollingStd(values, n) {            // population std
  const len = values.length, out = new Array(len).fill(null);
  for (let i = n - 1; i < len; i++) {
    let s = 0, c = 0;
    for (let j = i - n + 1; j <= i; j++) { const v = values[j]; if (v != null && !Number.isNaN(v)) { s += v; c++; } }
    if (!c) continue;
    const m = s / c; let sq = 0;
    for (let j = i - n + 1; j <= i; j++) { const v = values[j]; if (v != null && !Number.isNaN(v)) sq += (v - m) * (v - m); }
    out[i] = Math.sqrt(sq / c);
  }
  return out;
}
export function riverFloodPlain(closes, n = 30) {
  const mean = sma(closes, n), sd = rollingStd(closes, n);
  const band = (k) => ({
    upper: mean.map((m, i) => (m != null && sd[i] != null) ? m + k * sd[i] : null),
    lower: mean.map((m, i) => (m != null && sd[i] != null) ? m - k * sd[i] : null),
  });
  return { mean, river: band(1), floodPlain: band(2), redLine: band(3) };
}