Viết code (SDK)
- 🇻🇳 Tiếng Việt
- 🇬🇧 English
- 🇰🇷 한국어
- 🇨🇳 中文
Mỗi chiến lược, bộ lọc, phân tích trong Quant AI Studio là một đoạn JavaScript gọi bộ hàm của Studio (SDK). Bạn không cần biết lập trình để dùng Studio — mẫu có sẵn và trợ lý Quant viết code cho bạn — nhưng đọc được code giúp hiểu chính xác chiến lược mua bán thế nào, và sửa code là cách nhanh nhất để đổi một ngưỡng, một điều kiện mà không phải mô tả lại cho trợ lý.
Code chạy ngay trong trình duyệt của bạn, trong một vùng cách ly: không truy cập mạng, cookie hay dữ liệu của trang; dữ liệu chỉ đến qua tham số d hoặc data.bars(…) do Studio nạp.
Code nằm ở tab Mã của mỗi mục (chiến lược, bộ lọc, phân tích): khung soạn có tô màu cú pháp, gợi ý hàm, nút Tài liệu SDK (bảng tra hàm ngay trong Studio), Lưu, Chạy và Nhật ký chạy. Từng nút, phiên bản và So sánh được mô tả ở Xem và sửa mã; trang này và các trang con nói về cách viết code.
Ba loại: chiến lược, bộ lọc, phân tích
- Chiến lược
- Bộ lọc
- Phân tích
strategy({
name: "RSI hồi phục · VN30",
universe: universe("VN30"),
period: { from: "2016-01-01" },
params: {
len: param.int(14, { min: 2, max: 30, label: "Chu kỳ RSI" }),
lower: param.num(30, { min: 10, max: 45, label: "Ngưỡng mua" }),
stop: param.pct(0.07, { min: 0.03, max: 0.2, label: "Cắt lỗ" }),
},
signals: (d, p) => {
const r = ta.rsi(d.close, p.len);
const trend = d.close.gt(ta.sma(d.close, 200));
return { entry: r.crossAbove(p.lower).and(trend), exit: r.gt(70), score: r.neg() };
},
portfolio: { maxPositions: 5 },
risk: (p) => ({ stopLoss: p.stop }),
});
Backtest: mua mã VN30 khi RSI(14) cắt lên 30 trong xu hướng tăng, bán khi RSI > 70 hoặc cắt lỗ 7%, tối đa 5 mã. Xem Chiến lược.
screen({
name: "Nền giá chặt, gần đỉnh 52 tuần",
universe: universe("ALL").liquid(3e9).top(240),
columns: (d) => ({
"Cách đỉnh 52T": d.close.div(d.high.highest(250)).sub(1),
"Biên độ 20P": d.high.highest(20).div(d.low.lowest(20)).sub(1),
"RSI14": ta.rsi(d.close, 14),
}),
filter: (c) => c["Cách đỉnh 52T"].gt(-0.1).and(c["Biên độ 20P"].lt(0.12)),
sort: ["Biên độ 20P", "asc"],
limit: 50,
});
Hôm nay mã nào cách đỉnh 52 tuần dưới 10% và dao động 20 phiên dưới 12%. Xem Bộ lọc và phân tích.
research(async ({ data, chart, table }) => {
const vn = await data.bars("VNINDEX", { from: "2010-01-01" });
const m = vn.close.resample("month").last().pct(1);
chart.heatmap(byYearMonth(m), { title: "Lợi nhuận theo tháng VNINDEX" });
table(
monthOfYearMean(m).map((x) => ({ "Tháng": x.month, "TB": x.mean, "Tỷ lệ tăng": x.positive })),
{ format: { "TB": "percent", "Tỷ lệ tăng": "percent" } },
);
});
Báo cáo tự do: nạp dữ liệu, tính, rồi hiện số liệu, biểu đồ, bảng, văn bản. Xem Bộ lọc và phân tích.
Cấu trúc một đoạn code
- JavaScript thuần (ES2022): không
import, không TypeScript. Dòngexport default(quen tay khi viết module) được bỏ qua. - Gọi đúng một lần
strategy({…}),screen({…})hoặcresearch(…). Phía trên lời gọi được khai báo hằng số, hàm phụ (ví dụconst lnst = (d, ago) => d.fin("ParentCompanyShareholderProfitAfterTax", { ago });). - Các tên có sẵn, không cần khai báo:
| Tên | Dùng để |
|---|---|
strategy, screen, research | Khai báo chiến lược, bộ lọc, phân tích |
universe | Chọn rổ mã: universe("HOSE").liquid(10e9).top(240) |
param | Khai báo tham số thành thanh trượt, công tắc, ô chọn |
ta | Chỉ báo kỹ thuật: ta.rsi, ta.macd, ta.atr… |
stats | Thống kê trên mảng số: trung bình, tương quan, hồi quy, sụt giảm… |
dates | Đổi qua lại ngày dạng chữ và số ngày |
Panel | Tự dựng bảng dữ liệu mã × phiên |
log | In giá trị ra Nhật ký chạy |
byYearMonth, monthOfYearMean | Dựng bảng năm × tháng, trung bình theo tháng trong năm |
- Đơn vị: giá theo nghìn đồng (57,3 = 57.300 đ); giá trị theo đồng (10 tỷ viết
10e9); tỷ lệ là số thập phân (0,07 = 7%). - Tính trên cả bảng, không lặp từng phiên. Mỗi trường dữ liệu là một Panel — bảng mã × phiên. Phép tính áp cho cả bảng cùng lúc (
d.close.gt(ta.sma(d.close, 200))): nhanh hơn vòng lặp nhiều lần và không vô tình đọc dữ liệu tương lai.
Một lần chạy diễn ra thế nào
- Biên dịch phần khai báo (tối đa 5 giây) → tên, tham số, rổ mã. Lỗi cú pháp dừng ở đây.
- Xác định rổ mã (dòng tiến độ Xác định rổ mã): danh sách mã, rổ theo thời điểm khi backtest, cắt theo giới hạn số mã của gói.
- Biết code cần dữ liệu gì. Với chiến lược, bộ lọc: Studio chạy thử các hàm trên dữ liệu giả để biết code đọc những trường nào (khối ngoại, BCTC…) rồi chỉ tải phần đó. Với phân tích: bạn khai báo trong
data.bars(…, { fields }). - Nạp dữ liệu (Tải dữ liệu, Đọc dữ liệu n/N tệp, Đọc BCTC, sự kiện, Đọc dữ liệu vĩ mô…) từ kho dữ liệu, căn theo lịch phiên.
- Tính toán: tín hiệu (Tính tín hiệu), cột của bộ lọc (Tính bộ lọc) hoặc chạy hàm phân tích.
- Chiến lược: Kiểm tra nhìn trước tương lai, Mô phỏng danh mục theo luật khớp lệnh, Tính chỉ số.
- Hiện kết quả, kèm Ghi chú dữ liệu (rổ bị cắt, có nến tạm…) và Nhật ký chạy (dòng
log(…)của code và gợi ý cho người viết code: biểu đồ trống, chuỗi vĩ mô thiếu số…).
Mỗi lần chạy dùng một vùng chạy mới rồi huỷ, nên vòng lặp vô h ạn không làm treo trang. Math.random() có hạt giống cố định và cách sắp xếp giống nhau trên mọi trình duyệt: cùng code, cùng dữ liệu luôn cho cùng kết quả.
Giới hạn
| Giới hạn | Mức |
|---|---|
| Thời gian một lần chạy | 2 phút (tối ưu tham số, kiểm định: 5 phút); quá thì dừng với lỗi Chạy quá thời gian |
| Số mã mỗi lần chạy | 250 (Thiết yếu), 2.000 (Chuyên nghiệp, Cao cấp) — xem Giới hạn số mã |
| Khối đầu ra của phân tích | 60 khối; bảng 500 dòng; biểu đồ 30 chuỗi, mỗi chuỗi tự rút gọn còn 3.000 điểm; văn bản 20.000 ký tự |
| Bộ lọc | Tối đa 500 dòng kết quả (mặc định 100) |
| Nhật ký chạy | 1.000 dòng, mỗi dòng 2.000 ký tự |
| Môi trường | Không mạng, không fetch, không lưu trữ trình duyệt, không import |
Sửa và chạy code
Chuyên nghiệp Gói Thiết yếu xem được code (khung có dải Chỉ xem code), chạy mẫu và đổi tham số; sửa code, tự viết hay nhập mục từ tệp cần gói Chuyên nghiệp.
- Mở một mục (từ tab Của tôi của thanh bên, hoặc chạy một mẫu), chọn tab Mã.
- Sửa trực tiếp. Gõ
ta.,d.,param.,stats.,chart.… để hiện gợi ý kèm cách dùng; lỗi cú pháp được gạch đỏ ngay khi gõ, rê chuột để xem Lỗi cú pháp: …. Ctrl+F (macOS Cmd+F) tìm trong code, Ctrl+Z (macOS Cmd+Z) hoàn tác. - Ctrl+S (macOS Cmd+S) lưu thành phiên bản mới; Ctrl+Enter (macOS Cmd+Enter) lưu và chạy.
- Xem kết quả ở tab Báo cáo / Kết quả; giá trị trung gian in bằng
log(…)hiện ở Nhật ký chạy.
Bản nháp, Bỏ thay đổi, thông báo Bản nháp dựa trên v… khi trợ lý vừa tạo phiên bản mới: xem Xem và sửa mã.
Ngưỡng nào bạn hay thử (chu kỳ RSI, mức cắt lỗ, số mã) hãy khai báo bằng param.*: thanh tham số đổi là chạy lại ngay, không tạo phiên bản mới, và tối ưu tham số dùng đúng khoảng min–max bạn khai báo.
Khi code lỗi
Code lỗi thì kết quả hiện khung lỗi: loại lỗi, dòng, thông báo, vài dòng code quanh chỗ lỗi, nút Nhờ Copilot sửa và Xem dòng N (mở tab Mã đúng dòng lỗi). Các loại lỗi và cách xử lý chung: Lỗi khi chạy. Lỗi Dùng dữ liệu tương lai thường do shift với số âm hoặc thống kê trên cả chuỗi — xem Tránh nhìn trước tương lai.
Thông báo riêng của code hay gặp (thông báo về dữ liệu, máy chủ ở trang trên):
| Thông báo | Nghĩa |
|---|---|
| Code chưa gọi strategy({...}), screen({...}) hay research(...) | Thiếu lời gọi khai báo |
| Mỗi đoạn code chỉ khai báo một strategy / screen / research | Gọi hai lần trong một đoạn code |
| strategy cần một trong: signals(d, p), rank(d, p) hoặc weights(d, p) | Chiến lược thiếu cách chọn mã |
| signals(d, p) phải trả về Panel hoặc { entry, exit?, score? } | Hàm tín hiệu trả sai kiểu (thường quên return) |
| Không có trường dữ liệu "…". Các trường: … | Gõ sai tên trư ờng của d |
| Chưa nạp "…" — trong research thêm fields: ["…"] vào data.bars(…) | Phân tích dùng trường chưa khai báo trong fields |
| Không có chỉ tiêu BCTC "…". Gần giống: … | Sai khoá của d.fin; xem danh sách khoá |
| Không ghép được panel 30×2500 với 25×2500 | Hai Panel khác số mã — thường do lấy từ hai lần data.bars khác nhau |
| shift(n) với n âm dùng dữ liệu tương lai — không được phép | shift(-1) |
| Rổ có … mã — gói hiện tại chạy tối đa 250 mã mỗi lần… | Danh sách mã tự chọn vượt giới hạn |
Tự viết hay nhờ trợ lý?
| Nên tự sửa code khi | Nên nhờ trợ lý Quant khi |
|---|---|
| Đổi một ngưỡng, một điều kiện đã biết rõ vị trí | Biến một ý tưởng mô tả bằng lời thành code mới |
| Thêm tham số để kéo thử, để tối ưu | Đổi cấu trúc (từ tín hiệu sang xoay vòng, thêm dữ liệu BCTC, vĩ mô) |
| Muốn kiểm soát chính xác từng dòng, giữ lịch sử phiên bản gọn | Sửa lỗi khó hiểu, giải thích kết quả, gợi ý cải tiến |
| Không muốn dùng hạn mức AI | Tối ưu tham số, kiểm định độ vững theo câu hỏi |
Hai cách dùng chung một mục: trợ lý sửa thì tạo phiên bản mới, bạn sửa tay cũng vậy — So sánh cho thấy từng thay đổi.
Đọc tiếp
- Dữ liệu và Panel — Mọi trường của
d(giá, khối ngoại, BCTC, vĩ mô…), đơn vị,d.fin,d.macrovà phép tính trên Panel. — Dữ liệu và Panel - Chiến lược —
strategy({…}): tín hiệu, xoay vòng, tỷ trọng; danh mục, cắt lỗ, khớp lệnh, chi phí; ví dụ đầy đủ. — Chiến lược - Bộ lọc và phân tích —
screen({…})vàresearch(…): cột, điều kiện, nạp dữ liệu, số liệu, biểu đồ, bảng, văn bản. — Bộ lọc và phân tích - Tham chiếu hàm — Bảng tra
ta.*, phép tính Panel,universe,param,stats,dates, đầu ra của phân tích. — Tham chiếu hàm
Every strategy, screener and analysis in Quant AI Studio is a piece of JavaScript that calls Studio's function set (the SDK). You do not need to know how to program to use Studio — templates are ready-made and the Quant assistant writes code for you — but being able to read code helps you understand exactly how a strategy buys and sells, and editing code is the fastest way to change a threshold or a condition without describing it again to the assistant.
Code runs right in your browser, in an isolated sandbox: no access to the network, cookies or page data; data only arrives through the d parameter or data.bars(…), loaded by Studio.
Code lives in the Mã (Code) tab of each item (strategy, screener, analysis): an editor with syntax highlighting, function suggestions, and the buttons Tài liệu SDK (SDK docs — a function reference right inside Studio), Lưu (Save), Chạy (Run) and Nhật ký chạy (Run log). Each button, versions and So sánh (Compare) are described in View and edit code; this page and its subpages cover how to write code.
Three types: strategy, screener, analysis
- Strategy
- Screener
- Analysis
strategy({
name: "RSI hồi phục · VN30",
universe: universe("VN30"),
period: { from: "2016-01-01" },
params: {
len: param.int(14, { min: 2, max: 30, label: "Chu kỳ RSI" }),
lower: param.num(30, { min: 10, max: 45, label: "Ngưỡng mua" }),
stop: param.pct(0.07, { min: 0.03, max: 0.2, label: "Cắt lỗ" }),
},
signals: (d, p) => {
const r = ta.rsi(d.close, p.len);
const trend = d.close.gt(ta.sma(d.close, 200));
return { entry: r.crossAbove(p.lower).and(trend), exit: r.gt(70), score: r.neg() };
},
portfolio: { maxPositions: 5 },
risk: (p) => ({ stopLoss: p.stop }),
});
Backtest: buy VN30 tickers when RSI(14) crosses above 30 in an uptrend, sell when RSI > 70 or on a 7% stop loss, at most 5 tickers. See Strategy.
screen({
name: "Nền giá chặt, gần đỉnh 52 tuần",
universe: universe("ALL").liquid(3e9).top(240),
columns: (d) => ({
"Cách đỉnh 52T": d.close.div(d.high.highest(250)).sub(1),
"Biên độ 20P": d.high.highest(20).div(d.low.lowest(20)).sub(1),
"RSI14": ta.rsi(d.close, 14),
}),
filter: (c) => c["Cách đỉnh 52T"].gt(-0.1).and(c["Biên độ 20P"].lt(0.12)),
sort: ["Biên độ 20P", "asc"],
limit: 50,
});
Which tickers today are less than 10% below their 52-week high and have a 20-session range under 12%. See Screeners and analyses.
research(async ({ data, chart, table }) => {
const vn = await data.bars("VNINDEX", { from: "2010-01-01" });
const m = vn.close.resample("month").last().pct(1);
chart.heatmap(byYearMonth(m), { title: "Lợi nhuận theo tháng VNINDEX" });
table(
monthOfYearMean(m).map((x) => ({ "Tháng": x.month, "TB": x.mean, "Tỷ lệ tăng": x.positive })),
{ format: { "TB": "percent", "Tỷ lệ tăng": "percent" } },
);
});
A free-form report: load data, compute, then show figures, charts, tables and text. See Screeners and analyses.
Structure of a piece of code
- Plain JavaScript (ES2022): no
import, no TypeScript. Anexport defaultline (a habit from writing modules) is ignored. - Call
strategy({…}),screen({…})orresearch(…)exactly once. Above the call you can declare constants and helper functions (for exampleconst lnst = (d, ago) => d.fin("ParentCompanyShareholderProfitAfterTax", { ago });). - Built-in names, no declaration needed:
| Name | Used for |
|---|---|
strategy, screen, research | Declaring a strategy, screener, analysis |
universe | Choosing the ticker universe: universe("HOSE").liquid(10e9).top(240) |
param | Declaring parameters as sliders, toggles, dropdowns |
ta | Technical indicators: ta.rsi, ta.macd, ta.atr… |
stats | Statistics on number arrays: mean, correlation, regression, drawdown… |
dates | Converting between text dates and day numbers |
Panel | Building your own ticker × session data table |
log | Printing values to the Nhật ký chạy (Run log) |
byYearMonth, monthOfYearMean | Building a year × month table, the average by month of the year |
- Units: prices in VND thousand (57.3 = VND 57,300); values in VND (VND 10 bn is written
10e9); ratios are decimals (0.07 = 7%). - Compute on the whole table, not session by session. Each data field is a Panel — a ticker × session table. Operations apply to the whole table at once (
d.close.gt(ta.sma(d.close, 200))): many times faster than a loop, and you cannot accidentally read future data.
How a run works
- Compile the declaration (up to 5 seconds) → name, parameters, universe. Syntax errors stop here.
- Resolve the universe (progress line Xác định rổ mã — Resolving universe): the ticker list, point-in-time universes for backtests, trimmed to your plan's ticker limit.
- Work out what data the code needs. For strategies and screeners: Studio dry-runs the functions on fake data to see which fields the code reads (foreign investors, financial statements…) and downloads only those. For analyses: you declare them in
data.bars(…, { fields }). - Load data (Tải dữ liệu, Đọc dữ liệu n/N tệp, Đọc BCTC, sự kiện, Đọc dữ liệu vĩ mô… — downloading data, reading data files n/N, reading financial statements and events, reading macro data) from the data store, aligned to the session calendar.
- Compute: signals (Tính tín hiệu — Computing signals), screener columns (Tính bộ lọc — Computing screener) or running the analysis function.
- Strategies: Kiểm tra nhìn trước tương lai (Look-ahead check), Mô phỏng danh mục (Portfolio simulation) following the fill rules, Tính chỉ số (Computing metrics).
- Show results, with Ghi chú dữ liệu (Data notes — universe trimmed, provisional candle present…) and Nhật ký chạy (Run log —
log(…)lines from the code and hints for the code author: empty chart, macro series missing figures…).
Each run uses a fresh sandbox that is then destroyed, so an infinite loop does not freeze the page. Math.random() has a fixed seed and sorting behaves the same in every browser: the same code on the same data always gives the same result.
Limits
| Limit | Level |
|---|---|
| Time per run | 2 minutes (parameter optimization, validation: 5 minutes); beyond that it stops with the error Chạy quá thời gian (Run timed out) |
| Tickers per run | 250 (Essential), 2,000 (Professional, Premium) — see Ticker limit |
| Analysis output blocks | 60 blocks; tables 500 rows; charts 30 series, each automatically downsampled to 3,000 points; text 20,000 characters |
| Screener | At most 500 result rows (default 100) |
| Run log | 1,000 lines, 2,000 characters per line |
| Environment | No network, no fetch, no browser storage, no import |
Editing and running code
Professional The Essential plan can view code (the pane shows a Chỉ xem code (View code only) strip), run templates and change parameters; editing code, writing your own or importing items from a file requires the Professional plan.
- Open an item (from the Của tôi (Mine) tab of the sidebar, or by running a template), then choose the Mã (Code) tab.
- Edit directly. Type
ta.,d.,param.,stats.,chart.… to show suggestions with usage; syntax errors are underlined in red as you type — hover to see Lỗi cú pháp: … (Syntax error: …). Ctrl+F (macOS Cmd+F) searches the code, Ctrl+Z (macOS Cmd+Z) undoes. - Ctrl+S (macOS Cmd+S) saves as a new version; Ctrl+Enter (macOS Cmd+Enter) saves and runs.
- See the results in the Báo cáo (Report) / Kết quả (Results) tab; intermediate values printed with
log(…)appear in the Nhật ký chạy (Run log).
For drafts, Bỏ thay đổi (Discard changes), and the message Bản nháp dựa trên v… (Draft based on v…) when the assistant has just created a new version: see View and edit code.
For any threshold you often try (RSI period, stop-loss level, number of tickers), declare it with param.*: changing the parameter bar reruns immediately without creating a new version, and parameter optimization uses exactly the min–max range you declared.
When code fails
When code fails, the result shows an error box: the error type, line, message, a few lines of code around the error, and the buttons Nhờ Copilot sửa (Ask Copilot to fix) and Xem dòng N (Go to line N — opens the Mã (Code) tab at the failing line). Error types and general handling: Run errors. The Dùng dữ liệu tương lai (Uses future data) error is usually caused by shift with a negative number or statistics over the whole series — see Avoiding look-ahead.
Common code-specific messages (data and server messages are on the page above):
| Message | Meaning |
|---|---|
| Code chưa gọi strategy({...}), screen({...}) hay research(...) (The code does not call strategy, screen or research) | The declaration call is missing |
| Mỗi đoạn code chỉ khai báo một strategy / screen / research (Each piece of code declares only one strategy / screen / research) | Called twice in one piece of code |
| strategy cần một trong: signals(d, p), rank(d, p) hoặc weights(d, p) (strategy needs one of: signals, rank or weights) | The strategy has no way to choose tickers |
| signals(d, p) phải trả về Panel hoặc { entry, exit?, score? } (signals must return a Panel or an entry/exit/score object) | The signal function returns the wrong type (usually a forgotten return) |
| Không có trường dữ liệu "…". Các trường: … (No data field "…". Fields: …) | A misspelled field name on d |
| Chưa nạp "…" — trong research thêm fields: ["…"] vào data.bars(…) (“…” not loaded — in research, add it to fields of data.bars) | The analysis uses a field not declared in fields |
| Không có chỉ tiêu BCTC "…". Gần giống: … (No financial statement item "…". Similar: …) | Wrong d.fin key; see the key list |
| Không ghép được panel 30×2500 với 25×2500 (Cannot combine panel 30×2500 with 25×2500) | Two Panels with different ticker counts — usually from two different data.bars calls |
| shift(n) với n âm dùng dữ liệu tương lai — không được phép (shift with negative n uses future data — not allowed) | shift(-1) |
| Rổ có … mã — gói hiện tại chạy tối đa 250 mã mỗi lần… (The universe has … tickers — your current plan runs at most 250 tickers at a time…) | A custom ticker list exceeds the limit |
Write it yourself or ask the assistant?
| Edit the code yourself when | Ask the Quant assistant when |
|---|---|
| Changing a threshold or condition whose location you know | Turning an idea described in words into new code |
| Adding parameters to try out or optimize | Changing the structure (from signals to rotation, adding financial statement or macro data) |
| You want precise control over every line and a tidy version history | Fixing confusing errors, explaining results, suggesting improvements |
| You do not want to use your AI quota | Optimizing parameters, validating robustness on request |
Both approaches share one item: when the assistant edits, it creates a new version, and so do your manual edits — So sánh (Compare) shows every change.
Read next
- Data and Panel — Every field of
d(prices, foreign investors, financial statements, macro…), units,d.fin,d.macroand Panel operations. — Data and Panel - Strategy —
strategy({…}): signals, rotation, weights; portfolio, stop loss, fills, costs; full examples. — Strategy - Screeners and analyses —
screen({…})andresearch(…): columns, conditions, data loading, figures, charts, tables, text. — Screeners and analyses - Function reference — Lookup tables for
ta.*, Panel operations,universe,param,stats,dates, analysis outputs. — Function reference
Quant AI Studio의 모든 전략, 스크리너, 분석은 Studio의 함수 모음(SDK)을 호출하는 JavaScript 코드 한 조각입니다. Studio를 쓰는 데 프로그래밍 지식은 필요 없습니다. 템플릿이 준비되어 있고 Quant 어시스턴트가 코드를 대신 작성해 주기 때문입니다. 하지만 코드를 읽을 줄 알면 전략이 정확히 어떻게 사고파는지 이해할 수 있고, 코드를 직접 고치는 것이 어시스턴트에게 다시 설명하지 않고 기준값이나 조건 하나를 바꾸는 가장 빠른 방법입니다.
코드는 사용자의 브라우저 안에서, 격리된 영역에서 실행됩니다. 네트워크, 쿠키, 페이지 데이터에 접근할 수 없으며, 데이터는 Studio가 불러온 매개변수 d 또는 data.bars(…)를 통해서만 들어옵니다.
코드는 각 항목(전략, 스크리너, 분석)의 Mã(코드) 탭에 있습니다. 편집기는 구문 강조, 함수 자동 완성, Tài liệu SDK(SDK 문서, Studio 안에서 바로 보는 함수 참조표), Lưu(저장), Chạy(실행), Nhật ký chạy(실행 로그) 버튼을 제공합니다. 각 버튼, 버전, So sánh(비교)는 코드 보기와 편집에서 설명하며, 이 페이지와 하위 페이지는 코드 작성법을 다룹니다.
세 가지 유형: 전략, 스크리너, 분석
- 전략
- 스크리너
- 분석
strategy({
name: "RSI hồi phục · VN30",
universe: universe("VN30"),
period: { from: "2016-01-01" },
params: {
len: param.int(14, { min: 2, max: 30, label: "Chu kỳ RSI" }),
lower: param.num(30, { min: 10, max: 45, label: "Ngưỡng mua" }),
stop: param.pct(0.07, { min: 0.03, max: 0.2, label: "Cắt lỗ" }),
},
signals: (d, p) => {
const r = ta.rsi(d.close, p.len);
const trend = d.close.gt(ta.sma(d.close, 200));
return { entry: r.crossAbove(p.lower).and(trend), exit: r.gt(70), score: r.neg() };
},
portfolio: { maxPositions: 5 },
risk: (p) => ({ stopLoss: p.stop }),
});
백테스트: 상승 추세에서 RSI(14)가 30을 상향 돌파하면 VN30 종목을 매수하고, RSI > 70이거나 7% 손절에 도달하면 매도하며, 최대 5종목까지 보유합니다. 전략을 참고하세요.
screen({
name: "Nền giá chặt, gần đỉnh 52 tuần",
universe: universe("ALL").liquid(3e9).top(240),
columns: (d) => ({
"Cách đỉnh 52T": d.close.div(d.high.highest(250)).sub(1),
"Biên độ 20P": d.high.highest(20).div(d.low.lowest(20)).sub(1),
"RSI14": ta.rsi(d.close, 14),
}),
filter: (c) => c["Cách đỉnh 52T"].gt(-0.1).and(c["Biên độ 20P"].lt(0.12)),
sort: ["Biên độ 20P", "asc"],
limit: 50,
});
오늘 52주 고점과의 거리가 10% 미만이고 20세션 변동폭이 12% 미만인 종목을 찾습니다. 스크리너와 분석을 참고하세요.
research(async ({ data, chart, table }) => {
const vn = await data.bars("VNINDEX", { from: "2010-01-01" });
const m = vn.close.resample("month").last().pct(1);
chart.heatmap(byYearMonth(m), { title: "Lợi nhuận theo tháng VNINDEX" });
table(
monthOfYearMean(m).map((x) => ({ "Tháng": x.month, "TB": x.mean, "Tỷ lệ tăng": x.positive })),
{ format: { "TB": "percent", "Tỷ lệ tăng": "percent" } },
);
});
자유 형식 보고서: 데이터를 불러와 계산한 뒤 수치, 차트, 표, 텍스트로 보여 줍니다. 스크리너와 분석을 참고하세요.
코드의 구조
- 순수 JavaScript(ES2022):
import없음, TypeScript 없음. 모듈을 작성할 때 습관적으로 쓰는export default줄은 무시됩니다. strategy({…}),screen({…}),research(…)중 하나를 정확히 한 번 호출합니다. 호출 위쪽에는 상수와 보조 함수를 선언할 수 있습니다(예:const lnst = (d, ago) => d.fin("ParentCompanyShareholderProfitAfterTax", { ago });).- 선언 없이 바로 쓸 수 있는 이름:
| 이름 | 용도 |
|---|---|
strategy, screen, research | 전략, 스크리너, 분석 선언 |
universe | 종목 바스켓 선택: universe("HOSE").liquid(10e9).top(240) |
param | 매개변수를 슬라이더, 스위치, 선택 상자로 선언 |
ta | 기술적 지표: ta.rsi, ta.macd, ta.atr… |
stats | 숫자 배열 통계: 평균, 상관관계, 회귀, 낙폭… |
dates | 문자열 날짜와 일수 간 변환 |
Panel | 종목 × 세션 데이터 표 직접 만들기 |
log | 값을 Nhật ký chạy(실행 로그)에 출력 |
byYearMonth, monthOfYearMean | 연 × 월 표 만들기, 연중 월별 평균 |
- 단위: 가격은 천 동 단위(57.3 = 57,300동), 금액은 동 단위(100억 동은
10e9), 비율은 소수(0.07 = 7%)입니다. - 세션마다 반복하지 말고 표 전체에 대해 계산합니다. 각 데이터 필드는 Panel, 즉 종목 × 세션 표입니다. 연산은 표 전체에 한꺼번에 적용되므로(
d.close.gt(ta.sma(d.close, 200))) 반복문보다 훨씬 빠르고, 실수로 미래 데이터 를 읽는 일이 없습니다.
한 번의 실행 과정
- 선언 부분 컴파일(최대 5초) → 이름, 매개변수, 종목 바스켓. 구문 오류는 여기서 멈춥니다.
- 종목 바스켓 확정(진행 줄 Xác định rổ mã(종목 바스켓 확정)): 종목 목록, 백테스트 시 시점별 바스켓, 플랜의 종목 수 한도에 맞춘 절단.
- 코드가 필요로 하는 데이터 파악. 전략과 스크리너의 경우 Studio가 가짜 데이터로 함수를 시험 실행해 코드가 어떤 필드(외국인, BCTC…)를 읽는지 파악한 뒤 그 부분만 내려받습니다. 분석의 경우
data.bars(…, { fields })에서 직접 선언합니다. - 데이터 불러오기(Tải dữ liệu(데이터 다운로드), Đọc dữ liệu n/N tệp(데이터 읽기 n/N 파일), Đọc BCTC, sự kiện(재무제표, 이벤트 읽기), Đọc dữ liệu vĩ mô(거시경제 데이터 읽기)…): 데이터 저장소에서 가져와 거래 세션 일정에 맞춥니다.
- 계산: 신호(Tính tín hiệu(신호 계산)), 스크리너 열(Tính bộ lọc(스크리너 계산)) 또는 분석 함수 실행.
- 전략: Kiểm tra nhìn trước tương lai(미래 참조 검사), 체결 규칙에 따른 Mô phỏng danh mục(포트폴리오 모의 실행), Tính chỉ số(지표 계산).
- 결과 표시: Ghi chú dữ liệu(데이터 참고 사항: 바스켓 절단, 임시 봉 존재…)와 Nhật ký chạy(실행 로그: 코드의
log(…)줄과 코드 작성자를 위한 안내 — 빈 차트, 값이 빠진 거시경제 시계열…)가 함께 표시됩니다.
매 실행마다 새 실행 영역을 쓰고 끝나면 폐기하므로, 무한 루프가 있어도 페이지가 멈추지 않습니다. Math.random()은 고정된 시드를 쓰고 정렬 방식도 모든 브라우저에서 같으므로, 같은 코드와 같은 데이터는 항상 같은 결과를 냅니다.
한도
| 한도 | 수준 |
|---|---|
| 1회 실행 시간 | 2분(매개변수 최적화, 검증: 5분). 초과하면 Chạy quá thời gian(실행 시간 초과) 오류로 중단 |
| 1회 실행 종목 수 | 250(Essential), 2,000(Professional, Premium) — 종목 수 한도 참고 |
| 분석의 출력 블록 | 60블록, 표 500행, 차트 30개 시계열(시계열당 자동으로 3,000포인트까지 축소), 텍스트 20,000자 |
| 스크리너 | 결과 최대 500행(기본 100) |
| 실행 로그 | 1,000줄, 줄당 2,000자 |
| 환경 | 네트워크 없음, fetch 없음, 브라우저 저장소 없음, import 없음 |
코드 편집과 실행
Professional Essential 플랜은 코드 보기(편집기에 Chỉ xem code(코드 보기 전용) 띠 표시), 템플릿 실행, 매개변수 변경이 가능합니다. 코드 편집, 직접 작성, 파일에서 항목 가져오기에는 Professional 플랜이 필요합니다.
- 항목을 엽니다(사이드바의 Của tôi(내 항목) 탭에서, 또는 템플릿 실행). Mã(코드) 탭을 선택합니다.
- 바로 편집합니다.
ta.,d.,param.,stats.,chart.… 를 입력하면 사용법과 함께 자동 완성이 나타납니다. 구문 오류는 입력하는 즉시 빨간 밑줄로 표시되며, 마우스를 올리면 Lỗi cú pháp: …(구문 오류: …)를 볼 수 있습니다. Ctrl+F(macOS Cmd+F)로 코드 내 검색, Ctrl+Z(macOS Cmd+Z)로 실행 취소합니다. - Ctrl+S(macOS Cmd+S)는 새 버전으로 저장하고, Ctrl+Enter(macOS Cmd+Enter)는 저장 후 실행합니다.
- 결과는 Báo cáo(보고서) / Kết quả(결과) 탭에서 봅니다.
log(…)로 출력한 중간 값은 Nhật ký chạy(실행 로그)에 나타납니다.
임시 저장본, Bỏ thay đổi(변경 취소), 어시스턴트가 방금 새 버전을 만들었을 때의 Bản nháp dựa trên v…(v… 기반 임시 저장본) 안내: 코드 보기와 편집을 참고하세요.
자주 시험하는 기준값(RSI 주기, 손절 수준, 종목 수)은 param.*로 선언하세요. 매개변수 막대를 바꾸면 새 버전을 만들지 않고 바로 다시 실행되며, 매개변수 최적화는 선언한 min–max 범위를 그대로 사용합니다.
코드 오류가 났을 때
코드에 오류가 있으면 결과에 오류 상자가 나타납니다. 오류 유형, 줄 번호, 메시지, 오류 위치 주변의 코드 몇 줄, Nhờ Copilot sửa(Copilot에게 수정 요청) 버튼과 Xem dòng N(N번 줄 보기, 오류 줄 위치에서 Mã 탭 열기) 버튼이 표시됩니다. 오류 유형과 일반적인 처리 방법: 실행 오류. Dùng dữ liệu tương lai(미래 데이터 사용) 오류는 보통 음수 shift나 시계열 전체에 대한 통계 때문입니다. 미래 참조 피하기를 참고하세요.
코드에서 자주 보는 고유 메시지(데이터, 서버 관련 메시지는 상위 페이지 참고):
| 메시지 | 의미 |
|---|---|
| Code chưa gọi strategy({...}), screen({...}) hay research(...)(코드가 strategy({...}), screen({...}), research(...)를 호출하지 않음) | 선언 호출이 없음 |
| Mỗi đoạn code chỉ khai báo một strategy / screen / research(코드 하나에는 strategy / screen / research를 하나만 선언) | 한 코드에서 두 번 호출함 |
| strategy cần một trong: signals(d, p), rank(d, p) hoặc weights(d, p)(strategy에는 signals(d, p), rank(d, p), weights(d, p) 중 하나가 필요) | 전략에 종목 선택 방식이 없음 |
| signals(d, p) phải trả về Panel hoặc { entry, exit?, score? }(signals(d, p)는 Panel 또는 { entry, exit?, score? }를 반환해야 함) | 신호 함수의 반환 형식이 잘못됨(보통 return 누락) |
| Không có trường dữ liệu "…". Các trường: …(데이터 필드 "…"가 없음. 필드 목록: …) | d의 필드 이름 오타 |
| Chưa nạp "…" — trong research thêm fields: ["…"] vào data.bars(…)("…"를 불러오지 않음 — research에서 data.bars(…)에 fields: ["…"] 추가) | 분석에서 fields에 선언하지 않은 필드를 사용함 |
| Không có chỉ tiêu BCTC "…". Gần giống: …(재무제표 항목 "…"가 없음. 비슷한 항목: …) | d.fin의 키가 잘못됨. 키 목록 참고 |
| Không ghép được panel 30×2500 với 25×2500(panel 30×2500과 25×2500을 결합할 수 없음) | 두 Panel의 종목 수가 다름 — 보통 서로 다른 두 번의 data.bars에서 가져왔기 때문 |
| shift(n) với n âm dùng dữ liệu tương lai — không được phép(음수 n의 shift(n)은 미래 데이터를 사용 — 허용되지 않음) | shift(-1) |
| Rổ có … mã — gói hiện tại chạy tối đa 250 mã mỗi lần…(바스켓에 … 종목 — 현재 플랜은 1회 최대 250종목…) | 직접 고른 종목 목록이 한도를 초과함 |
직접 작성할까, 어시스턴트에게 맡길까?
| 코드를 직접 고치는 것이 좋을 때 | Quant 어시스턴트에게 맡기는 것이 좋을 때 |
|---|---|
| 위치를 정확히 아는 기준값이나 조건 하나를 바꿀 때 | 말로 설명한 아이디어를 새 코드로 만들 때 |
| 슬라이더로 시험하거나 최적화하기 위해 매개변수를 추가할 때 | 구조를 바꿀 때(신호에서 순환 방식으로, 재무제표·거시경제 데이터 추가) |
| 모든 줄을 정확히 통제하고 버전 기록을 깔끔하게 유지하고 싶을 때 | 이해하기 어려운 오류 수정, 결과 설명, 개선 제안 |
| AI 한도를 쓰고 싶지 않을 때 | 질문에 따른 매개변수 최적화, 견고성 검증 |
두 방법은 같은 항목에서 함께 쓸 수 있습니다. 어시스턴트가 고치든 직접 고치든 새 버전이 만들어지며, So sánh(비교)로 모든 변경 사항을 확인할 수 있습니다.
더 읽기
- 데이터와 Panel —
d의 모든 필드(가격, 외국인, 재무제표, 거시경제…), 단위,d.fin,d.macro, Panel 연산. — 데이터와 Panel - 전략 —
strategy({…}): 신호, 순환, 비중; 포트폴리오, 손절, 체결, 비용; 전체 예시. — 전략 - 스크리너와 분석 —
screen({…})와research(…): 열, 조건, 데이터 불러오기, 수치, 차트, 표, 텍스트. — 스크리너와 분석 - 함수 참조 —
ta.*, Panel 연산,universe,param,stats,dates, 분석 출력의 참조표. — 함수 참조
Quant AI Studio 中的每个策略、选股器和分析都是一段调用 Studio 函数库(SDK)的 JavaScript 代码。使用 Studio 无需会编程 — 有现成模板,Quant 助手也会为您编写代码 — 但能读懂代 码有助于准确理解策略如何买卖,而修改代码是更改某个阈值、某个条件的最快方式,无需再向助手重新描述。
代码直接在您的浏览器中运行,处于一个隔离区域:无法访问网络、cookie 或页面数据;数据只通过 Studio 加载的参数 d 或 data.bars(…) 传入。
代码位于每个条目(策略、选股器、分析)的 Mã(代码)标签页:编辑区带语法高亮、函数提示,以及 Tài liệu SDK(SDK 文档,Studio 内的函数速查表)、Lưu(保存)、Chạy(运行)和 Nhật ký chạy(运行日志)按钮。各按钮、版本和 So sánh(比较)的说明见查看和修改代码;本页及其子页面讲解如何编写代码。
三种类型:策略、选股器、分析
- 策略
- 选股器
- 分析
strategy({
name: "RSI hồi phục · VN30",
universe: universe("VN30"),
period: { from: "2016-01-01" },
params: {
len: param.int(14, { min: 2, max: 30, label: "Chu kỳ RSI" }),
lower: param.num(30, { min: 10, max: 45, label: "Ngưỡng mua" }),
stop: param.pct(0.07, { min: 0.03, max: 0.2, label: "Cắt lỗ" }),
},
signals: (d, p) => {
const r = ta.rsi(d.close, p.len);
const trend = d.close.gt(ta.sma(d.close, 200));
return { entry: r.crossAbove(p.lower).and(trend), exit: r.gt(70), score: r.neg() };
},
portfolio: { maxPositions: 5 },
risk: (p) => ({ stopLoss: p.stop }),
});
回测:在上升趋势中,当 RSI(14) 上穿 30 时买入 VN30 股票,当 RSI > 70 或止损 7% 时卖出,最多持有 5 只股票。见策略。
screen({
name: "Nền giá chặt, gần đỉnh 52 tuần",
universe: universe("ALL").liquid(3e9).top(240),
columns: (d) => ({
"Cách đỉnh 52T": d.close.div(d.high.highest(250)).sub(1),
"Biên độ 20P": d.high.highest(20).div(d.low.lowest(20)).sub(1),
"RSI14": ta.rsi(d.close, 14),
}),
filter: (c) => c["Cách đỉnh 52T"].gt(-0.1).and(c["Biên độ 20P"].lt(0.12)),
sort: ["Biên độ 20P", "asc"],
limit: 50,
});
今天哪些股票距 52 周高点不到 10%,且 20 个交易时段的波动幅度低于 12%。见选股器和分析。
research(async ({ data, chart, table }) => {
const vn = await data.bars("VNINDEX", { from: "2010-01-01" });
const m = vn.close.resample("month").last().pct(1);
chart.heatmap(byYearMonth(m), { title: "Lợi nhuận theo tháng VNINDEX" });
table(
monthOfYearMean(m).map((x) => ({ "Tháng": x.month, "TB": x.mean, "Tỷ lệ tăng": x.positive })),
{ format: { "TB": "percent", "Tỷ lệ tăng": "percent" } },
);
});
自由报告:加载数据、计算,然后显示数据指标、图表、表格和文字。见选股器和分析。
一段代码的结构
- 纯 JavaScript(ES2022):不能
import,不支持 TypeScript。export default这一行(编写模块时的习惯写法)会被忽略。 - 只调用一次
strategy({…})、screen({…})或research(…)。调用之前可以声明常量和辅助函数(例如const lnst = (d, ago) => d.fin("ParentCompanyShareholderProfitAfterTax", { ago });)。 - 以下名称已内置,无需声明:
| 名称 | 用途 |
|---|---|
strategy、screen、research | 声明策略、选股器、分析 |
universe | 选择股票池:universe("HOSE").liquid(10e9).top(240) |
param | 把参数声明为滑块、开关、下拉框 |
ta | 技术指标:ta.rsi、ta.macd、ta.atr… |
stats | 数值数组的统计:平均值、相关性、回归、回撤… |
dates | 在文字日期和日期数字之间转换 |
Panel | 自行构建 股票 × 交易时段 的数据表 |
log | 把数值打印到 Nhật ký chạy(运行日志) |
byYearMonth、monthOfYearMean | 构建 年 × 月 表、计算一年中各月的平均值 |
- 单位:价格以千越南盾计(57.3 = 57,300 越南盾);金额以越南盾计(100 亿写作
10e9);比例为小数(0.07 = 7%)。 - 在整张表上计算,不逐个交易时段循环。 每个数据字段都是一个 Panel — 股票 × 交易时段 的表。运算同时作用于整张表(
d.close.gt(ta.sma(d.close, 200))):比循环快很多倍,也不会无意中读到未来数据。
一次运行的过程
- 编译声明部分(最多 5 秒)→ 名称、参数、股票池。语法错误在此停止。
- 确定股票池(进度行 Xác định rổ mã(确定股票池)):股票列表、回测时按时点确定的股票池,并按套餐的股票数量限制截断。
- 了解代码需要哪些数据。 对于策略、选股器:Studio 先在模拟数据上试运行各函数,了解代码读取哪些字段(外资、BCTC…),然后只下载这部分。对于分析:由您在
data.bars(…, { fields })中声明。 - 从数据仓库加载数据(Tải dữ liệu(下载数据)、Đọc dữ liệu n/N tệp(读取数据 n/N 个文件)、Đọc BCTC, sự kiện(读取财报、事件)、Đọc dữ liệu vĩ mô(读取宏观数据)…),并按交易日历对齐。
- 计算:信号(Tính tín hiệu(计算信号))、选股器的列(Tính bộ lọc(计算选股器))或运行分析函数。
- 策略:Kiểm tra nhìn trước tương lai(检查前视偏差)、按成交规则进行 Mô phỏng danh mục(模拟持仓)、Tính chỉ số(计算指标)。
- 显示结果,附带 Ghi chú dữ liệu(数据说明,如股票池被截断、有临时K线…)和 Nhật ký chạy(运行日志,包含代码中的
log(…)输出以及给编写代码者的提示:空图表、宏观序列缺数…)。
每次运行都使用一个新的运行区域,结束后销毁,因此死循环不会让页面卡死。Math.random() 使用固定种子,排序方式在所有浏览器上相同:相同的代码、相同的数据总会得到相同的结果。
限制
| 限制 | 额度 |
|---|---|
| 单次运行时间 | 2 分钟(参数优化、检验:5 分钟);超时则以 Chạy quá thời gian(运行超时)错误停止 |
| 每次运行的股票数 | 250(Essential)、2,000(Professional、Premium)— 见股票数量限制 |
| 分析的输出块 | 60 个块;表格 500 行;图表 30 条序列,每条序列自动精简到 3,000 个点;文字 20,000 个字符 |
| 选股器 | 最多 500 行结果(默认 100) |
| 运行日志 | 1,000 行,每行 2,000 个字符 |
| 运行环境 | 无网络、无 fetch、无浏览器存储、无 import |
修改和运行代码
Professional — Essential 套餐可以查看代码(编辑区带 Chỉ xem code(仅查看代码)横条)、运行模板和更改参数;修改代码、自行编写或从文件导入条目需要 Professional 套餐。
- 打开一个条目(从侧边栏的 Của tôi(我的)标签页,或运行一个模板),选择 Mã(代码)标签页。
- 直接修改。输入
ta.、d.、param.、stats.、chart.… 即可显示提示及用法;语法错误在输入时立即以红色下划线标出,鼠标悬停可查看 Lỗi cú pháp: …(语法错误:…)。Ctrl+F(macOS Cmd+F)在代码中查找,Ctrl+Z(macOS Cmd+Z)撤销。 - Ctrl+S(macOS Cmd+S)保存为新版本;Ctrl+Enter(macOS Cmd+Enter)保存并运行。
- 在 Báo cáo(报告)/ Kết quả(结果)标签页查看结果;用
log(…)打印的中间值显示在 Nhật ký chạy(运行日志)中。
草稿、Bỏ thay đổi(放弃更改)、助手刚创建新版本时的 Bản nháp dựa trên v…(草稿基于 v…)提示:见查看和修改代码。
您常常试验的阈值(RSI 周期、止损幅度、股票数量)请用 param.* 声明:在参数栏中修改即可立即重新运行,不会创建新版本,而且参数优化会使用您声明的 min–max 范围。
代码出错时
代码出错时,结果区会显示错误框:错误类型、行号、提示信息、出错位置附近的几行代码,以及 Nhờ Copilot sửa(请 Copilot 修复)和 Xem dòng N(查看第 N 行,在 Mã(代码)标签页中打开出错的那一行)按钮。各类错误及通用处理方法:运行时的错误。Dùng dữ liệu tương lai(使用未来数据)错误通常由 shift 使用负数或在整条序列上做统计造成 — 见避免前视偏差。
代码特有的常见提示(关于数据、服务器的提示见上一页):
| 提示 | 含义 |
|---|---|
| Code chưa gọi strategy({...}), screen({...}) hay research(...)(代码尚未调用 strategy({...})、screen({...}) 或 research(...)) | 缺少声明调用 |
| Mỗi đoạn code chỉ khai báo một strategy / screen / research(每段代码只能声明一个 strategy / screen / research) | 在一段代码中调用了两次 |
| strategy cần một trong: signals(d, p), rank(d, p) hoặc weights(d, p)(strategy 需要以下之一:signals(d, p)、rank(d, p) 或 weights(d, p)) | 策略缺少选股方式 |
| signals(d, p) phải trả về Panel hoặc { entry, exit?, score? }(signals(d, p) 必须返回 Panel 或 { entry, exit?, score? }) | 信号函数返回类型错误(通常是忘了 return) |
| Không có trường dữ liệu "…". Các trường: …(没有数据字段“…”。可用字段:…) | d 的字段名拼写错误 |
| Chưa nạp "…" — trong research thêm fields: ["…"] vào data.bars(…)(尚未加载“…”— 在 research 中向 data.bars(…) 添加 fields: ["…"]) | 分析使用了未在 fields 中声明的字段 |
| Không có chỉ tiêu BCTC "…". Gần giống: …(没有财报指标“…”。相近的有:…) | d.fin 的键名错误;见键名列表 |
| Không ghép được panel 30×2500 với 25×2500(无法将 30×2500 的 panel 与 25×2500 的合并) | 两个 Panel 的股票数不同 — 通常是取自两次不同的 data.bars |
| shift(n) với n âm dùng dữ liệu tương lai — không được phép(n 为负数的 shift(n) 使用了未来数据 — 不允许) | shift(-1) |
| Rổ có … mã — gói hiện tại chạy tối đa 250 mã mỗi lần…(股票池有 … 只股票 — 当前套餐每次最多运行 250 只…) | 自选股票列表超出限制 |
自己写还是请助手?
| 适合自己修改代码的情况 | 适合请 Quant 助手的情况 |
|---|---|
| 修改一个已清楚位置的阈值或条件 | 把用文字描述的想法变成新代码 |
| 添加参数以便拖动试验、用于优化 | 改变结构(从信号改为轮动,添加财报、宏观数据) |
| 想精确控制每一行、保持版本历史简洁 | 修复难懂的错误、解释结果、建议改进 |
| 不想消耗 AI 额度 | 按问题进行参数优化、稳健性检验 |
两种方式共用同一个条目:助手修改会创建新版本,您手动修改也一样 — So sánh(比较)会显示每处更改。