JavaScript · Indicator Code
The Dragon (spine, belly & northern skin) in JavaScript
A fast +/-0.5 SD band on the 10-period mean of RL10. The spine is the centerline, the belly is the lower (southern) skin, and the northern skin is the upper band.
Verified. Python and JavaScript implementations agree to
7.11e-14 on a 60-bar reference price series (Python vs JavaScript across the Dragon spine (centerline), belly (lower skin), and northern skin (upper) - float64 round-off only).JavaScript
// The Dragon - a fast +/-0.5 SD band on the 10-period mean of RL10.
// spine = the centerline itself, SMA(10) of RL10
// belly = spine - 0.5 SD (lower / southern skin)
// northern skin = spine + 0.5 SD (upper skin)
// Flips ~6x faster than the River at trend inflections.
function rl(closes, n = 10) { // RL10 endpoint (see the RL10 page)
const len = closes.length, out = new Array(len).fill(null);
if (n <= 0 || len < n) return out;
const sx = (n * (n - 1)) / 2, sx2 = (n * (n - 1) * (2 * n - 1)) / 6, d = n * sx2 - sx * sx;
if (d === 0) return out;
for (let e = n; e <= len; e++) {
let sy = 0, sxy = 0, bad = false;
for (let j = 0; j < n; j++) { const v = closes[e - n + j]; if (v == null || Number.isNaN(v)) { bad = true; break; } sy += v; sxy += j * v; }
if (bad) continue;
const m = (n * sxy - sx * sy) / d, b = (sy - m * sx) / n;
out[e - 1] = m * (n - 1) + b;
}
return out;
}
function sma(values, n) {
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 o = values[i - n]; if (o != null && !Number.isNaN(o)) { sum -= o; count--; } }
if (i >= n - 1 && count === n) out[i] = sum / n;
}
return out;
}
function rollingStd(values, n) {
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 mn = 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 - mn) * (v - mn); }
out[i] = Math.sqrt(sq / c);
}
return out;
}
export function dragon(closes) {
const spine = sma(rl(closes, 10), 10); // centerline
const sd = rollingStd(spine, 10);
return {
spine, // centerline
belly: spine.map((c, i) => (c != null && sd[i] != null) ? c - 0.5 * sd[i] : null), // lower / southern skin
northernSkin: spine.map((c, i) => (c != null && sd[i] != null) ? c + 0.5 * sd[i] : null), // upper skin
};
}
Other platforms: Python
← The Dragon (spine, belly & northern skin) (all platforms) · All indicators · Glossary concept
← The Dragon (spine, belly & northern skin) (all platforms) · All indicators · Glossary concept
Improve Your Craft Every Morning
Daily commentary from Dr. Ken Long — what he's seeing in markets, how he's framing trades, and what's worth practicing today. Free.
Your email:
Tue–Fri mornings. Unsubscribe anytime. No spam, no hype.