Đi tới nội dung chính
Chuyển tới nội dung chính

Tiện ích và giới hạn

combine([x1, x2, …], (giaTri, i) => so) → chuỗi

combine​

combine([x1, x2, …], (giaTri, i) => so) → chuỗi

Ghép nhiều chuỗi bằng một hàm JavaScript chạy ở từng nến: giaTri là mảng giá trị của các chuỗi ở nến đó, i là chỉ số nến. Hàm phải thuần (không nhớ gì giữa các nến). Hai chuỗi thì dùng gọn hơn a.zip(b, (x, y) => …); một chuỗi a.map((x, i) => …).

indicator({
name: "Vị trí giá trong nến (combine)",
plot: (d) => ({
"Vị trí đóng cửa": columns(
combine([d.open, d.high, d.low, d.close], ([o, h, l, c]) => (h > l ? (c - l) / (h - l) : 0.5)),
{ color: "accent" }
),
"Giữa": hline(0.5),
}),
});

Script có combine, map, zip chạy hơi chậm hơn script chỉ dùng phép có sẵn.

stats: thống kê trên mảng​

Tính ngay trên một mảng số (không phải chuỗi) — dùng trong onBar với mảng tự giữ trong trạng thái, hoặc trong Quant AI Studio. NaN bị bỏ qua.

HàmKết quả
stats.mean(a)Trung bình
stats.std(a)Độ lệch chuẩn mẫu
stats.variance(a)Phương sai mẫu
stats.median(a)Trung vị
stats.quantile(a, q)Phân vị q (0–1)
stats.corr(a, b)Hệ số tương quan (cần ≥ 3 cặp)
stats.linreg(x, y){ slope, intercept, r2 }
stats.tstat(a)Thống kê t của trung bình
stats.sharpe(loiNhuan, soKyMoiNam = 250)Sharpe quy năm
stats.maxDrawdown(giaTri)Sụt giảm sâu nhất (số âm)
stats.drawdown(giaTri)Mảng sụt giảm từ đỉnh tại từng điểm
stats.forward(giaTri, h)Lợi nhuận h kỳ sau — chỉ để nghiên cứu, không dùng làm tín hiệu

dates: ngày​

Ngày biểu diễn bằng số ngày kể từ 01/01/1970. Từ mốc thời gian (ms) của nến: Math.floor(ctx.time / 86400000).

HàmKết quả
dates.parse("2025-03-10")Số ngày (nhận cả "2025" = 01/01/2025)
dates.format(ngay)"10/03/2025"
dates.iso(ngay)"2025-03-10"
dates.year(ngay), dates.month(ngay), dates.day(ngay)Năm, tháng (1–12), ngày
dates.weekday(ngay)0 = Chủ nhật … 6 = thứ Bảy
indicator({
name: "Thống kê trượt và ngày",
pane: "price",
state: () => ({ loiNhuan: [] }),
onBar: (ctx, s) => {
const truoc = ctx.bar(1).close;
if (truoc > 0) s.loiNhuan.push(ctx.close / truoc - 1);
if (s.loiNhuan.length > 60) s.loiNhuan.shift();
const ngay = Math.floor(ctx.time / 86400000);
if (dates.month(ngay) === 1 && dates.day(ngay) <= 7 && dates.weekday(ngay) === 1) {
ctx.draw.label({ id: `nam-${dates.year(ngay)}`, at: { barsAgo: 0, price: ctx.high }, text: `${dates.year(ngay)}`, size: "s", color: "textMuted" });
}
if (s.loiNhuan.length < 60) return;
return {
sharpe: stats.sharpe(s.loiNhuan, 250),
trungVi: stats.median(s.loiNhuan) * 100,
p90: stats.quantile(s.loiNhuan, 0.9) * 100,
lech: stats.std(s.loiNhuan) * 100,
};
},
plot: (d, p, o) => ({
"Sharpe 60 phiên": line(o.sharpe, { pane: "Sharpe", color: "accent" }),
"Trung vị LN ngày %": line(o.trungVi, { pane: "Phân phối", color: "ref" }),
"Phân vị 90 % LN ngày %": line(o.p90, { pane: "Phân phối", color: "up" }),
"Độ lệch chuẩn %": line(o.lech, { pane: "Phân phối", color: "down" }),
}),
});

log​

log(...) (và console.log) ghi khi script dựng — hiện ở Nhật ký chạy của Quant AI Studio. Trên biểu đồ, thẻ Nhật ký hiện lỗi, những gì ghi bằng ctx.log(...) trong onBar (gắn với nến — onBar › ctx.log) và dòng console.log(...); log(...) không hiện ở đây.

JavaScript chuẩn​

Dùng được: Math (Math.max, Math.min, Math.abs, Math.round, Math.floor, Math.sqrt, Math.log, Math.pow…), Number (Number.isNaN, Number.isFinite), mảng (push, shift, slice, map, filter, reduce, sort…), Object, JSON, chuỗi chữ, template …${x}…, for, while, if, switch, hàm, const / let.

Không có: import, mạng (fetch), lưu trữ trình duyệt, DOM, hẹn giờ (setTimeout), async trong indicator / strategy. Trong onBar và hàm tự viết, Math.random() cho cùng dãy số ở mọi lần chạy và Date.now() / new Date() là mốc của nến đang tính — để script luôn cho cùng kết quả.

Giới hạn​

Giới hạnMức
Khai báo mỗi script1 (indicator hoặc strategy)
Script gắn trên một biểu đồ5
Đầu ra (plot)64
Điều kiện cảnh báo (alerts)32
Mã khác (d.symbol)4
Nút tính của đồ thị5.000
Đối tượng vẽ mỗi loạimặc định 50, tối đa 500 (limits)
Bảng9 vị trí, 100 ô mỗi bảng
Nhật ký1.000 dòng gần nhất
ctx.track500 nến mỗi khoá, tối đa 5.000 (limits.track)
Trạng thái onBar256 KB
Thời gian tính toàn bộ lịch sử2 giây
Thời gian mỗi lần cập nhật giá50 ms (vượt nhiều lần liên tiếp: script tạm dừng, chỉ chạy lại khi có nến mới)
Thời gian biên dịch3 giây

Vượt thời gian: Script chạy quá 2 giây khi tính toàn bộ lịch sử — đã dừng. Có thể do vòng lặp quá nặng hoặc vô hạn. — xem Hỏi đáp › hiệu năng.

Mã lỗi​

Mỗi lỗi có một mã (hiện ở Nhật ký, Copilot đọc được). Lỗi thường gặp kèm cách sửa: Lỗi thường gặp.

MãKhi nào
syntaxMã viết sai cú pháp JavaScript (thiếu ngoặc, dấu phẩy…)
runtimeLỗi khi chạy: gọi tên không có, sai kiểu, lỗi trong onBar…
no-declaration, multiple-declarationsKhông gọi / gọi nhiều lần indicator / strategy
lookaheadĐọc nến sau: shift(-1), ctx.bar(-1), ctx.prev(…, -1), ctx.track(…).at(-1)
universe-onlyPhép chỉ có trong Studio (rank, topN…, d.meta)
eager-in-streamĐọc giá trị ngay lúc dựng (.data, .last()…)
tf-lower, tf-misalignedd.tf khung nhỏ hơn / không là bội số khung đang tính
ta-orderctx.ta.* gọi khác thứ tự giữa các nến
state-not-jsonTrạng thái chứa hàm / đối tượng không thuần
paramĐối số / tham số sai (fillna("0"), hline("70"), d.source("abc"), param.session("9-11")…)
importThư viện use(…): thiếu thư viện / phiên bản, khoá sai dạng, dùng vòng tròn, vượt 16 thư viện / 200.000 ký tự
limitVượt giới hạn (đầu ra, cảnh báo, mã khác, trạng thái)
budget-history, budget-tickVượt thời gian tính