Mẫu biến động và khối lượng
- 🇻🇳 Tiếng Việt
- 🇬🇧 English
- 🇰🇷 한국어
- 🇨🇳 中文
Dải Bollinger, Keltner, nén biến động, ATR, biến động lịch sử; khối lượng đột biến, OBV, MFI, dòng tiền Chaikin, VWAP.
Bollinger nén
Mẫu Bollinger nén của thư viện: đánh dấu khi độ rộng dải hẹp nhất lookback nến — vùng nén hay đi trước biến động mạnh.
indicator({
name: "Bollinger nén",
description: "Dải Bollinger; đánh dấu khi độ rộng dải thấp nhất 120 nến.",
pane: "price",
params: {
n: param.int(20, { min: 5, max: 100, label: "Chu kỳ" }),
k: param.num(2, { min: 1, max: 4, step: 0.5, label: "Độ lệch chuẩn" }),
lookback: param.int(120, { min: 20, max: 500, label: "So với n nến" }),
},
plot: (d, p) => {
const b = ta.bb(d.close, p.n, p.k);
const squeeze = b.width.lte(b.width.lowest(p.lookback));
return {
Dải: band(b.upper, b.lower, { color: "accent", opacity: 0.12 }),
Giữa: line(b.mid, { color: "textMuted", dash: "dash" }),
Nén: shape(squeeze, { at: "below", shape: "circle", color: "ref" }),
};
},
alerts: (d, p) => {
const b = ta.bb(d.close, p.n, p.k);
return { "Bollinger nén chặt": b.width.lte(b.width.lowest(p.lookback)) };
},
});
Bóp Bollinger trong Keltner (squeeze)
Khi dải Bollinger nằm trong kênh Keltner là biến động đang bị nén; thoát ra kèm động lượng (độ dốc) cho hướng bứt phá. Ngăn riêng: cột động lượng hai màu, chấm đỏ khi đang nén, xanh khi đã thoát.
indicator({
name: "Squeeze Bollinger / Keltner",
params: {
n: param.int(20, { min: 10, max: 50, label: "Chu kỳ" }),
bbK: param.num(2, { min: 1, max: 3, step: 0.5, label: "Hệ số Bollinger" }),
kcK: param.num(1.5, { min: 1, max: 3, step: 0.25, label: "Hệ số Keltner" }),
},
plot: (d, p) => {
const bb = ta.bb(d.close, p.n, p.bbK);
const kc = ta.keltner(d, p.n, p.kcK, p.n);
const nen = bb.upper.lt(kc.upper).and(bb.lower.gt(kc.lower));
const dongLuong = d.close.sub(d.high.highest(p.n).add(d.low.lowest(p.n)).div(2).add(ta.sma(d.close, p.n)).div(2));
const ml = ta.slope(dongLuong, p.n).mul(p.n);
return {
"Động lượng": hist(ml, { up: "up", down: "down", opacity: 0.7 }),
"Đang nén": shape(nen, { at: "value", value: 0, shape: "circle", size: "s", color: "down" }),
"Thoát nén": shape(nen.fillna(0).not().and(nen.shift(1)), { at: "value", value: 0, shape: "diamond", color: "up" }),
};
},
alerts: (d, p) => {
const bb = ta.bb(d.close, p.n, p.bbK);
const kc = ta.keltner(d, p.n, p.kcK, p.n);
const nen = bb.upper.lt(kc.upper).and(bb.lower.gt(kc.lower));
return { "Thoát nén": nen.fillna(0).not().and(nen.shift(1)) };
},
});
ATR theo % giá và vùng biến động
ATR chia cho giá để so được giữa các mã; tô theo hạng của ATR % trong 250 nến (cao = biến động lớn bất thường).
indicator({
name: "ATR % và hạng biến động",
params: { n: param.int(14, { min: 5, max: 50, label: "Chu kỳ ATR" }) },
plot: (d, p) => {
const atrPct = ta.atr(d, p.n).div(d.close).mul(100);
const hang = atrPct.rolling(250).rank();
return {
"ATR %": area(atrPct, { color: "accent", opacity: 0.2, format: "number" }),
"Biến động cao (top 10 %)": bgcolor(hang.gt(0.9), { color: "down", opacity: 0.1 }),
"Biến động thấp (đáy 10 %)": bgcolor(hang.lt(0.1), { color: "up", opacity: 0.1 }),
};
},
});
Biến động lịch sử (năm hoá)
Độ lệch chuẩn lợi nhuận log 20 phiên, nhân √250 — biến động theo năm (%).
indicator({
name: "Biến động lịch sử 20 phiên",
params: { n: param.int(20, { min: 5, max: 120, label: "Số phiên" }) },
plot: (d, p) => {
const hv = d.close.log().diff(1).rolling(p.n).std(true).mul(Math.sqrt(250)).mul(100);
return {
"HV %/năm": line(hv, { color: "accent" }),
"Trung vị 1 năm": line(hv.rolling(250).median(), { color: "textMuted", dash: "dash" }),
};
},
});
Khối lượng đột biến
Mẫu Khối lượng đột biến của thư viện.
indicator({
name: "Khối lượng đột biến",
pane: "new",
params: {
n: param.int(20, { min: 5, max: 100, label: "Trung bình" }),
mult: param.num(2, { min: 1.2, max: 10, step: 0.1, label: "Gấp mấy lần" }),
},
plot: (d, p) => {
const avg = ta.sma(d.volume, p.n);
const spike = d.volume.gt(avg.mul(p.mult));
return {
"Khối lượng": hist(d.volume, { color: "textMuted", opacity: 0.6, format: "volume" }),
"Trung bình": line(avg, { color: "accent", format: "volume" }),
"Đột biến": shape(spike, { at: "above", shape: "diamond", color: "ref" }),
};
},
alerts: (d, p) => ({ "Khối lượng đột biến": d.volume.gt(ta.sma(d.volume, p.n).mul(p.mult)) }),
});
Khối lượng tô theo chiều giá
indicator({
name: "Khối lượng hai màu",
plot: (d) => ({
"Khối lượng": columns(d.volume, { color: "down", colors: [{ when: d.close.gte(d.open), color: "up" }], opacity: 0.7, format: "volume" }),
"TB 20": line(ta.sma(d.volume, 20), { color: "ref", format: "volume" }),
"TB 50": line(ta.sma(d.volume, 50), { color: "ai", format: "volume", dash: "dash" }),
}),
});
OBV với đường tín hiệu
indicator({
name: "OBV và tín hiệu",
params: { n: param.int(20, { min: 5, max: 100, label: "EMA của OBV" }) },
plot: (d, p) => {
const obv = ta.obv(d);
const tinHieu = ta.ema(obv, p.n);
return {
OBV: line(obv, { color: "accent", format: "compact" }),
"Tín hiệu": line(tinHieu, { color: "ref", format: "compact" }),
"OBV trên tín hiệu": fill("OBV", "Tín hiệu", { color: "up", below: "down", opacity: 0.12 }),
"OBV đỉnh mới, giá chưa": shape(obv.gte(obv.highest(60)).and(d.close.lt(d.close.highest(60))), { at: "top", shape: "circle", color: "up", size: "s" }),
};
},
});
"OBV đỉnh mới, giá chưa" — dòng tiền tích luỹ đi trước giá, một dấu hiệu tích luỹ hay được theo dõi.
MFI — RSI có khối lượng
indicator({
name: "MFI",
scale: { range: [0, 100], levels: [20, 80] },
params: { n: param.int(14, { min: 5, max: 50, label: "Chu kỳ" }) },
plot: (d, p) => {
const m = ta.mfi(d, p.n);
return {
MFI: line(m, { color: "accent" }),
"Quá bán": bgcolor(m.lt(20), { color: "up", opacity: 0.12 }),
"Quá mua": bgcolor(m.gt(80), { color: "down", opacity: 0.12 }),
};
},
});
Dòng tiền Chaikin (CMF)
indicator({
name: "Dòng tiền Chaikin",
params: { n: param.int(20, { min: 5, max: 60, label: "Chu kỳ" }) },
plot: (d, p) => {
const hl = d.high.sub(d.low);
const mfm = d.close.sub(d.low).sub(d.high.sub(d.close)).div(hl);
const cmf = mfm.mul(d.volume).rolling(p.n).sum().div(d.volume.rolling(p.n).sum());
return {
CMF: hist(cmf, { up: "up", down: "down" }),
"Thư viện (kiểm)": line(ta.run("cmf", { n: p.n }).v, { color: "textMuted", hidden: true }),
"0": hline(0),
};
},
});
Tự tính bằng phép chuỗi và đối chiếu với chỉ báo cmf của thư viện (đầu ra ẩn) — cách hay để học công thức.
VWAP phiên và độ lệch trên biểu đồ trong ngày
// khung: 5 (script cho biểu đồ trong ngày)
indicator({
name: "VWAP phiên ± độ lệch",
pane: "price",
series: (d) => ({ dau: d.session.first, tp: d.hlc3 }),
state: () => ({ pv: 0, v: 0, pv2: 0 }),
onBar: (ctx, s) => {
if (ctx.v.dau === 1) {
s.pv = 0;
s.v = 0;
s.pv2 = 0;
}
s.pv += ctx.v.tp * ctx.volume;
s.v += ctx.volume;
s.pv2 += ctx.v.tp * ctx.v.tp * ctx.volume;
if (s.v === 0) return;
const vwap = s.pv / s.v;
const sd = Math.sqrt(Math.max(0, s.pv2 / s.v - vwap * vwap));
return { vwap, tren: vwap + 2 * sd, duoi: vwap - 2 * sd };
},
plot: (d, p, o) => ({
VWAP: line(o.vwap, { color: "ai", width: 2 }),
"Dải ±2σ": band(o.tren, o.duoi, { color: "ai", opacity: 0.06 }),
}),
});
Khối lượng tương đối (RVOL)
Khối lượng nến so với trung bình 20 nến; trên biểu đồ ngày là "phiên hôm nay gấp mấy lần bình thường".
indicator({
name: "Khối lượng tương đối",
scale: { levels: [1, 2] },
plot: (d) => {
const rvol = d.volume.div(ta.sma(d.volume, 20).shift(1));
return {
RVOL: columns(rvol, { color: "textMuted", colors: [{ when: rvol.gte(2), color: "ref" }, { when: rvol.gte(1), color: "accent" }] }),
};
},
alerts: (d) => ({ "KL gấp đôi bình thường": d.volume.div(ta.sma(d.volume, 20).shift(1)).crossAbove(2) }),
});
ta.sma(d.volume, 20).shift(1) — trung bình 20 phiên trước (không tính phiên đang xét), để phiên đột biến không tự kéo trung bình lên.
Bollinger Bands, Keltner, volatility squeeze, ATR, historical volatility; volume spikes, OBV, MFI, Chaikin money flow, VWAP.
Bollinger squeeze
The library template Bollinger nén (Bollinger squeeze): marks when the band width is the narrowest of lookback bars — a squeeze zone often comes before a strong move.
indicator({
name: "Bollinger nén",
description: "Dải Bollinger; đánh dấu khi độ rộng dải thấp nhất 120 nến.",
pane: "price",
params: {
n: param.int(20, { min: 5, max: 100, label: "Chu kỳ" }),
k: param.num(2, { min: 1, max: 4, step: 0.5, label: "Độ lệch chuẩn" }),
lookback: param.int(120, { min: 20, max: 500, label: "So với n nến" }),
},
plot: (d, p) => {
const b = ta.bb(d.close, p.n, p.k);
const squeeze = b.width.lte(b.width.lowest(p.lookback));
return {
Dải: band(b.upper, b.lower, { color: "accent", opacity: 0.12 }),
Giữa: line(b.mid, { color: "textMuted", dash: "dash" }),
Nén: shape(squeeze, { at: "below", shape: "circle", color: "ref" }),
};
},
alerts: (d, p) => {
const b = ta.bb(d.close, p.n, p.k);
return { "Bollinger nén chặt": b.width.lte(b.width.lowest(p.lookback)) };
},
});
Bollinger inside Keltner (squeeze)
When the Bollinger Bands sit inside the Keltner channel, volatility is being compressed; the breakout comes with momentum (slope) that gives its direction. Separate pane: two-color momentum columns, a red dot while squeezed, green once released.
indicator({
name: "Squeeze Bollinger / Keltner",
params: {
n: param.int(20, { min: 10, max: 50, label: "Chu kỳ" }),
bbK: param.num(2, { min: 1, max: 3, step: 0.5, label: "Hệ số Bollinger" }),
kcK: param.num(1.5, { min: 1, max: 3, step: 0.25, label: "Hệ số Keltner" }),
},
plot: (d, p) => {
const bb = ta.bb(d.close, p.n, p.bbK);
const kc = ta.keltner(d, p.n, p.kcK, p.n);
const nen = bb.upper.lt(kc.upper).and(bb.lower.gt(kc.lower));
const dongLuong = d.close.sub(d.high.highest(p.n).add(d.low.lowest(p.n)).div(2).add(ta.sma(d.close, p.n)).div(2));
const ml = ta.slope(dongLuong, p.n).mul(p.n);
return {
"Động lượng": hist(ml, { up: "up", down: "down", opacity: 0.7 }),
"Đang nén": shape(nen, { at: "value", value: 0, shape: "circle", size: "s", color: "down" }),
"Thoát nén": shape(nen.fillna(0).not().and(nen.shift(1)), { at: "value", value: 0, shape: "diamond", color: "up" }),
};
},
alerts: (d, p) => {
const bb = ta.bb(d.close, p.n, p.bbK);
const kc = ta.keltner(d, p.n, p.kcK, p.n);
const nen = bb.upper.lt(kc.upper).and(bb.lower.gt(kc.lower));
return { "Thoát nén": nen.fillna(0).not().and(nen.shift(1)) };
},
});
ATR as % of price and volatility zones
ATR divided by price so it can be compared across tickers; shaded by the rank of ATR % over 250 bars (high = unusually high volatility).
indicator({
name: "ATR % và hạng biến động",
params: { n: param.int(14, { min: 5, max: 50, label: "Chu kỳ ATR" }) },
plot: (d, p) => {
const atrPct = ta.atr(d, p.n).div(d.close).mul(100);
const hang = atrPct.rolling(250).rank();
return {
"ATR %": area(atrPct, { color: "accent", opacity: 0.2, format: "number" }),
"Biến động cao (top 10 %)": bgcolor(hang.gt(0.9), { color: "down", opacity: 0.1 }),
"Biến động thấp (đáy 10 %)": bgcolor(hang.lt(0.1), { color: "up", opacity: 0.1 }),
};
},
});
Historical volatility (annualized)
Standard deviation of 20-session log returns, multiplied by √250 — annual volatility (%).
indicator({
name: "Biến động lịch sử 20 phiên",
params: { n: param.int(20, { min: 5, max: 120, label: "Số phiên" }) },
plot: (d, p) => {
const hv = d.close.log().diff(1).rolling(p.n).std(true).mul(Math.sqrt(250)).mul(100);
return {
"HV %/năm": line(hv, { color: "accent" }),
"Trung vị 1 năm": line(hv.rolling(250).median(), { color: "textMuted", dash: "dash" }),
};
},
});
Volume spike
The library template Khối lượng đột biến (Volume spike).
indicator({
name: "Khối lượng đột biến",
pane: "new",
params: {
n: param.int(20, { min: 5, max: 100, label: "Trung bình" }),
mult: param.num(2, { min: 1.2, max: 10, step: 0.1, label: "Gấp mấy lần" }),
},
plot: (d, p) => {
const avg = ta.sma(d.volume, p.n);
const spike = d.volume.gt(avg.mul(p.mult));
return {
"Khối lượng": hist(d.volume, { color: "textMuted", opacity: 0.6, format: "volume" }),
"Trung bình": line(avg, { color: "accent", format: "volume" }),
"Đột biến": shape(spike, { at: "above", shape: "diamond", color: "ref" }),
};
},
alerts: (d, p) => ({ "Khối lượng đột biến": d.volume.gt(ta.sma(d.volume, p.n).mul(p.mult)) }),
});
Volume colored by price direction
indicator({
name: "Khối lượng hai màu",
plot: (d) => ({
"Khối lượng": columns(d.volume, { color: "down", colors: [{ when: d.close.gte(d.open), color: "up" }], opacity: 0.7, format: "volume" }),
"TB 20": line(ta.sma(d.volume, 20), { color: "ref", format: "volume" }),
"TB 50": line(ta.sma(d.volume, 50), { color: "ai", format: "volume", dash: "dash" }),
}),
});
OBV with a signal line
indicator({
name: "OBV và tín hiệu",
params: { n: param.int(20, { min: 5, max: 100, label: "EMA của OBV" }) },
plot: (d, p) => {
const obv = ta.obv(d);
const tinHieu = ta.ema(obv, p.n);
return {
OBV: line(obv, { color: "accent", format: "compact" }),
"Tín hiệu": line(tinHieu, { color: "ref", format: "compact" }),
"OBV trên tín hiệu": fill("OBV", "Tín hiệu", { color: "up", below: "down", opacity: 0.12 }),
"OBV đỉnh mới, giá chưa": shape(obv.gte(obv.highest(60)).and(d.close.lt(d.close.highest(60))), { at: "top", shape: "circle", color: "up", size: "s" }),
};
},
});
OBV đỉnh mới, giá chưa (OBV at a new high, price not yet) — accumulated money flow leading price, a commonly watched sign of accumulation.
MFI — RSI with volume
indicator({
name: "MFI",
scale: { range: [0, 100], levels: [20, 80] },
params: { n: param.int(14, { min: 5, max: 50, label: "Chu kỳ" }) },
plot: (d, p) => {
const m = ta.mfi(d, p.n);
return {
MFI: line(m, { color: "accent" }),
"Quá bán": bgcolor(m.lt(20), { color: "up", opacity: 0.12 }),
"Quá mua": bgcolor(m.gt(80), { color: "down", opacity: 0.12 }),
};
},
});
Chaikin Money Flow (CMF)
indicator({
name: "Dòng tiền Chaikin",
params: { n: param.int(20, { min: 5, max: 60, label: "Chu kỳ" }) },
plot: (d, p) => {
const hl = d.high.sub(d.low);
const mfm = d.close.sub(d.low).sub(d.high.sub(d.close)).div(hl);
const cmf = mfm.mul(d.volume).rolling(p.n).sum().div(d.volume.rolling(p.n).sum());
return {
CMF: hist(cmf, { up: "up", down: "down" }),
"Thư viện (kiểm)": line(ta.run("cmf", { n: p.n }).v, { color: "textMuted", hidden: true }),
"0": hline(0),
};
},
});
Computed by hand with series operations and cross-checked against the library's cmf indicator (a hidden output) — a good way to learn the formula.
Session VWAP and deviation on an intraday chart
// khung: 5 (script cho biểu đồ trong ngày)
indicator({
name: "VWAP phiên ± độ lệch",
pane: "price",
series: (d) => ({ dau: d.session.first, tp: d.hlc3 }),
state: () => ({ pv: 0, v: 0, pv2: 0 }),
onBar: (ctx, s) => {
if (ctx.v.dau === 1) {
s.pv = 0;
s.v = 0;
s.pv2 = 0;
}
s.pv += ctx.v.tp * ctx.volume;
s.v += ctx.volume;
s.pv2 += ctx.v.tp * ctx.v.tp * ctx.volume;
if (s.v === 0) return;
const vwap = s.pv / s.v;
const sd = Math.sqrt(Math.max(0, s.pv2 / s.v - vwap * vwap));
return { vwap, tren: vwap + 2 * sd, duoi: vwap - 2 * sd };
},
plot: (d, p, o) => ({
VWAP: line(o.vwap, { color: "ai", width: 2 }),
"Dải ±2σ": band(o.tren, o.duoi, { color: "ai", opacity: 0.06 }),
}),
});
Relative volume (RVOL)
A bar's volume compared with the 20-bar average; on a daily chart it reads as "how many times normal is today's session".
indicator({
name: "Khối lượng tương đối",
scale: { levels: [1, 2] },
plot: (d) => {
const rvol = d.volume.div(ta.sma(d.volume, 20).shift(1));
return {
RVOL: columns(rvol, { color: "textMuted", colors: [{ when: rvol.gte(2), color: "ref" }, { when: rvol.gte(1), color: "accent" }] }),
};
},
alerts: (d) => ({ "KL gấp đôi bình thường": d.volume.div(ta.sma(d.volume, 20).shift(1)).crossAbove(2) }),
});
ta.sma(d.volume, 20).shift(1) — the average of the previous 20 sessions (excluding the current one), so a spike session does not pull the average up by itself.
볼린저 밴드, 켈트너 채널, 변동성 수축, ATR, 역사적 변동성; 거래량 급증, OBV, MFI, 차이킨 자금 흐름, VWAP.
볼린저 수축
라이브러리의 Bollinger nén(볼린저 수축) 템플릿: 밴드 폭이 lookback개 봉 중 가장 좁아질 때 표시합니다. 수축 구간은 강한 변동에 앞서 나타나는 경우가 많습니다.
indicator({
name: "Bollinger nén",
description: "Dải Bollinger; đánh dấu khi độ rộng dải thấp nhất 120 nến.",
pane: "price",
params: {
n: param.int(20, { min: 5, max: 100, label: "Chu kỳ" }),
k: param.num(2, { min: 1, max: 4, step: 0.5, label: "Độ lệch chuẩn" }),
lookback: param.int(120, { min: 20, max: 500, label: "So với n nến" }),
},
plot: (d, p) => {
const b = ta.bb(d.close, p.n, p.k);
const squeeze = b.width.lte(b.width.lowest(p.lookback));
return {
Dải: band(b.upper, b.lower, { color: "accent", opacity: 0.12 }),
Giữa: line(b.mid, { color: "textMuted", dash: "dash" }),
Nén: shape(squeeze, { at: "below", shape: "circle", color: "ref" }),
};
},
alerts: (d, p) => {
const b = ta.bb(d.close, p.n, p.k);
return { "Bollinger nén chặt": b.width.lte(b.width.lowest(p.lookback)) };
},
});
켈트너 안의 볼린저 수축(squeeze)
볼린저 밴드가 켈트너 채널 안에 있으면 변동성이 눌려 있는 상태입니다. 모멘텀(기울기)과 함께 빠져나오면 돌파 방향을 알려 줍니다. 별도 패널: 두 색의 모멘텀 막대, 수축 중이면 빨간 점, 빠져나오 면 초록 점.
indicator({
name: "Squeeze Bollinger / Keltner",
params: {
n: param.int(20, { min: 10, max: 50, label: "Chu kỳ" }),
bbK: param.num(2, { min: 1, max: 3, step: 0.5, label: "Hệ số Bollinger" }),
kcK: param.num(1.5, { min: 1, max: 3, step: 0.25, label: "Hệ số Keltner" }),
},
plot: (d, p) => {
const bb = ta.bb(d.close, p.n, p.bbK);
const kc = ta.keltner(d, p.n, p.kcK, p.n);
const nen = bb.upper.lt(kc.upper).and(bb.lower.gt(kc.lower));
const dongLuong = d.close.sub(d.high.highest(p.n).add(d.low.lowest(p.n)).div(2).add(ta.sma(d.close, p.n)).div(2));
const ml = ta.slope(dongLuong, p.n).mul(p.n);
return {
"Động lượng": hist(ml, { up: "up", down: "down", opacity: 0.7 }),
"Đang nén": shape(nen, { at: "value", value: 0, shape: "circle", size: "s", color: "down" }),
"Thoát nén": shape(nen.fillna(0).not().and(nen.shift(1)), { at: "value", value: 0, shape: "diamond", color: "up" }),
};
},
alerts: (d, p) => {
const bb = ta.bb(d.close, p.n, p.bbK);
const kc = ta.keltner(d, p.n, p.kcK, p.n);
const nen = bb.upper.lt(kc.upper).and(bb.lower.gt(kc.lower));
return { "Thoát nén": nen.fillna(0).not().and(nen.shift(1)) };
},
});
가격 대비 ATR %와 변동성 구간
ATR을 가격으로 나누면 종목 간 비교가 가능합니다. 250개 봉 안에서 ATR %의 순위에 따라 배경을 칠합니다(높음 = 비정상적으로 큰 변동성).
indicator({
name: "ATR % và hạng biến động",
params: { n: param.int(14, { min: 5, max: 50, label: "Chu kỳ ATR" }) },
plot: (d, p) => {
const atrPct = ta.atr(d, p.n).div(d.close).mul(100);
const hang = atrPct.rolling(250).rank();
return {
"ATR %": area(atrPct, { color: "accent", opacity: 0.2, format: "number" }),
"Biến động cao (top 10 %)": bgcolor(hang.gt(0.9), { color: "down", opacity: 0.1 }),
"Biến động thấp (đáy 10 %)": bgcolor(hang.lt(0.1), { color: "up", opacity: 0.1 }),
};
},
});
역사적 변동성(연율화)
20세션 로그 수익률의 표준편차에 √250을 곱한 값 — 연간 변동성(%)입니다.
indicator({
name: "Biến động lịch sử 20 phiên",
params: { n: param.int(20, { min: 5, max: 120, label: "Số phiên" }) },
plot: (d, p) => {
const hv = d.close.log().diff(1).rolling(p.n).std(true).mul(Math.sqrt(250)).mul(100);
return {
"HV %/năm": line(hv, { color: "accent" }),
"Trung vị 1 năm": line(hv.rolling(250).median(), { color: "textMuted", dash: "dash" }),
};
},
});
거래량 급증
라이브러리의 Khối lượng đột biến(거래량 급증) 템플릿입니다.
indicator({
name: "Khối lượng đột biến",
pane: "new",
params: {
n: param.int(20, { min: 5, max: 100, label: "Trung bình" }),
mult: param.num(2, { min: 1.2, max: 10, step: 0.1, label: "Gấp mấy lần" }),
},
plot: (d, p) => {
const avg = ta.sma(d.volume, p.n);
const spike = d.volume.gt(avg.mul(p.mult));
return {
"Khối lượng": hist(d.volume, { color: "textMuted", opacity: 0.6, format: "volume" }),
"Trung bình": line(avg, { color: "accent", format: "volume" }),
"Đột biến": shape(spike, { at: "above", shape: "diamond", color: "ref" }),
};
},
alerts: (d, p) => ({ "Khối lượng đột biến": d.volume.gt(ta.sma(d.volume, p.n).mul(p.mult)) }),
});
가격 방향에 따라 색을 입힌 거래량
indicator({
name: "Khối lượng hai màu",
plot: (d) => ({
"Khối lượng": columns(d.volume, { color: "down", colors: [{ when: d.close.gte(d.open), color: "up" }], opacity: 0.7, format: "volume" }),
"TB 20": line(ta.sma(d.volume, 20), { color: "ref", format: "volume" }),
"TB 50": line(ta.sma(d.volume, 50), { color: "ai", format: "volume", dash: "dash" }),
}),
});