Bài 11 — Tối ưu tham số và tránh quá khớp
- 🇻🇳 Tiếng Việt
- 🇬🇧 English
- 🇰🇷 한국어
- 🇨🇳 中文
Bạn sẽ học: dùng thẻ Tối ưu và Walk-forward để chọn tham số, đọc bản đồ nhiệt, độ phẳng, Deflated Sharpe, và các nguyên tắc để chiến lược không chỉ "đẹp trên quá khứ".
11.1. Quá khớp là gì
Thử đủ nhiều tổ hợp tham số trên cùng một đoạn lịch sử, kiểu gì cũng có một tổ hợp cho kết quả rất đẹp — vì nó khớp với nhiễu của đúng đoạn đó, không phải vì nó nắm được quy luật. Sang dữ liệu mới, kết quả sụp đổ. Đó là quá khớp (overfitting).
Dấu hiệu:
- Tham số tốt nhất là một "đỉnh nhọn": đổi EMA 23 thành 22 hay 25 là lợi nhuận mất hẳn.
- Kết quả trong mẫu (đoạn dùng để chọn tham số) tốt hơn hẳn ngoài mẫu (đoạn chưa nhìn thấy).
- Chiến lược có nhiều điều kiện, nhiều tham số, mà ít giao dịch.
11.2. Viết chiến lược để tối ưu được
Thẻ Tối ưu quét các tham số số (param.int, param.num, param.pct) trong khoảng min–max của chúng. Chuẩn bị:
- Chỉ để 1–3 tham số quan trọng là tham số; số còn lại để cố định trong mã.
- Đặt
min/maxhợp lý theo ý nghĩa (EMA nhanh 5–40, không phải 1–500). maxcũng quyết định đoạn khởi động: mọi tổ hợp chấm trên cùng khoảng nến, bắt đầu sau đoạn khởi động của tổ hợp có chu kỳ dài nhất (EMA cần khoảng 20 × chu kỳ nến). EMA chậm tới 300 cần khoảng 6.000 nến — nhiều hơn cả lịch sử của phần lớn mã, nên gần như không còn nến để chấm. Giữmaxvừa lịch sử của mã.- Hai tham số số đầu tiên được chọn sẵn làm hai trục — xếp chúng lên đầu
params.
strategy({
name: "EMA nhanh / chậm để tối ưu",
params: {
fast: param.int(20, { min: 5, max: 40, label: "EMA nhanh" }),
slow: param.int(60, { min: 40, max: 160, label: "EMA chậm" }),
sl: param.pct(0.08, { min: 0.04, max: 0.15, label: "Dừng lỗ" }),
},
signals: (d, p) => {
const f = ta.ema(d.close, p.fast);
const s = ta.ema(d.close, p.slow);
return { entry: f.crossAbove(s), exit: f.crossBelow(s) };
},
risk: (p) => ({ stopLoss: p.sl }),
plot: (d, p) => ({
"EMA nhanh": line(ta.ema(d.close, p.fast), { color: "accent" }),
"EMA chậm": line(ta.ema(d.close, p.slow), { color: "ref" }),
}),
});
11.3. Chạy tối ưu và đọc bản đồ nhiệt
- Thêm chiến lược vào biểu đồ và chạy kiểm thử chính trước (thẻ Tổng quan) — tối ưu chạy trên cùng nến của biểu đồ, cùng kỳ, phí, luật khớp với lần kiểm thử này.
- Thẻ Tối ưu › chọn Trục ngang, Trục dọc › Chạy tối ưu (theo Sharpe). Mỗi trục chia khoảng
min–maxthành 7 mức (một trục thì 12 mức), tối đa 49 tổ hợp. - Đọc kết quả:

| Bạn thấy | Nghĩa |
|---|---|
| Vùng xanh rộng, liền | Chiến lược ổn với nhiều tổ hợp — tốt |
| Một ô xanh lẻ giữa vùng đỏ | Đỉnh nhọn, gần như chắc chắn là may |
| Độ phẳng gần 1 | Các ô kề ô tốt nhất cũng tốt gần bằng — "cao nguyên" ổn định |
| Độ phẳng thấp (dưới 0,5) | Ô tốt nhất đứng một mình — đừng chọn nó |
| Deflated Sharpe cao (trên 0,9) | Sharpe dương vẫn đứng vững sau khi trừ hiệu ứng "thử nhiều tổ hợp" |
| Deflated Sharpe thấp | Kết quả tốt nhất có thể chỉ do thử nhiều |
Nên chọn ô ở giữa vùng xanh rộng, không nhất thiết ô có Sharpe cao nhất. Bấm một ô để dùng tổ hợp đó, Áp dụng bộ tốt nhất, hoặc Áp dụng vùng ổn định (…) — ô có Sharpe trung bình các ô lân cận cao nhất, tức tâm của cao nguyên.
Mọi tổ hợp chấm trên cùng khoảng nến, bắt đầu sau đoạn khởi động dài nhất của lưới, nên khoảng chấm có thể ngắn hơn thẻ Tổng quan; tối ưu cũng chưa dùng kính lúp nến 1 phút. So các tổ hợp với nhau trong thẻ Tối ưu; con số cuối cùng hãy đọc ở Tổng quan sau khi áp tham số và chạy lại kiểm thử.
11.4. Walk-forward và ngoài mẫu
Thẻ Walk-forward › Chạy walk-forward: chia các phiên thành 4 đoạn kiểm (40 % đầu chỉ để huấn luyện). Ở mỗi bước, tối ưu trên toàn bộ phần trước (cùng lư ới như thẻ Tối ưu), rồi kiểm trên đoạn ngay sau bằng tham số vừa chọn; nối các đoạn kiểm thành kết quả ngoài mẫu. Đây là mô phỏng gần nhất của việc "định kỳ chọn lại tham số rồi giao dịch tiếp".
| Kết quả | Kết luận |
|---|---|
| Ngoài mẫu ghép lại có lãi, Hiệu quả walk-forward từ 0,6 (nhãn Quá khớp thấp) | Chiến lược đáng theo dõi tiếp |
| Hiệu quả dưới 0,3 (Quá khớp cao): ngoài mẫu kém xa trong mẫu | Tham số quá khớp với đoạn đã tối ưu |
| Ngoài mẫu lỗ dù tối ưu đẹp | Chiến lược không có lợi thế thật |
| Tham số chọn ở các đoạn nhảy lung tung | Không có vùng tham số ổn định |
| Đoạn kiểm có rất ít Lệnh | Mẫu quá nhỏ để kết luận |
Hiệu quả walk-forward = CAGR ngoài mẫu bình quân ÷ CAGR trong mẫu bình quân của bộ đã chọn. Lịch sử quá ngắn so với đoạn khởi động thì thẻ báo Quá ít phiên cho walk-forward 4 đoạn (… phiên) — hạ max của tham số hoặc dùng khung có nhiều nến hơn.

11.5. Mười nguyên tắc chống quá khớp
- Có lý do trước khi có mã. Viết một câu vì sao chiến lược nên có lãi (xu hướng kéo dài, hồi về trung bình sau bán tháo…).
- Ít tham số. Mỗi tham số thêm vào là thêm một cách để khớp nhiễu.
- Chọn cao nguyên, không chọn đỉnh trên bản đồ nhiệt.
- Giữ lại dữ liệu chưa nhìn: luôn xem ngoài mẫu / walk-forward trước khi tin.
- Kiểm trên nhiều mã — một mã là một mẫu thử; cả rổ trong Quant AI Studio mới là bằng chứng.
- Kiểm trên nhiều giai đoạn: thị trường tăng, giảm, đi ngang.
- Đủ giao dịch (≥ 30, càng nhiều càng tốt).
- Phí và trượt giá thực tế, thậm chí cao hơn thực tế một chút.
- Đừng sửa chiến lược để "né" một khoản lỗ cụ thể trong quá khứ — đó là khớp theo nhiễu.
- Giao dịch thử bằng giấy (theo dõi tín hiệu thật trên biểu đồ, cảnh báo) một thời gian trước khi dùng tiền thật.
11.6. Khai báo tối ưu cho Quant AI Studio
Khi chiến lược được mở sang Quant AI Studio, mục optimize của mã quy định cách tối ưu ở đó (mục tiêu, lưới, các phép kiểm độ vững). Bảng kiểm thử trên biểu đồ không đọc mục này — nó dùng min / max của tham số như trên.
strategy({
name: "Donchian bứt phá — khai báo tối ưu",
params: {
n: param.int(55, { min: 20, max: 120, label: "Đỉnh n phiên" }),
exitN: param.int(20, { min: 10, max: 60, label: "Đáy thoát" }),
},
signals: (d, p) => ({
entry: d.close.gt(d.high.highest(p.n).shift(1)),
exit: d.close.lt(d.low.lowest(p.exitN).shift(1)),
}),
risk: { stopLoss: 0.1 },
optimize: {
objective: "calmar",
grid: { n: [40, 55, 70, 90], exitN: [10, 20, 30] },
tests: ["oos", "walkforward", "costs"],
},
});
Chi tiết các phép kiểm độ vững của Studio: Tối ưu và kiểm định độ vững.
You will learn: how to use the Tối ưu (Optimization) and Walk-forward tabs to choose parameters, how to read the heat map, flatness and Deflated Sharpe, and the principles that keep a strategy from being merely "pretty on the past".
11.1. What overfitting is
Try enough parameter combinations on the same stretch of history and one of them is bound to look great — because it fits the noise of that exact stretch, not because it has captured a real pattern. On new data, the result collapses. That is overfitting.
Signs:
- The best parameter is a "sharp peak": changing EMA 23 to 22 or 25 wipes out the profit.
- In-sample results (the stretch used to pick parameters) are far better than out-of-sample results (the stretch not yet seen).
- The strategy has many conditions and many parameters but few trades.
11.2. Writing a strategy that can be optimized
The Tối ưu (Optimization) tab sweeps numeric parameters (param.int, param.num, param.pct) across their min–max range. To prepare:
- Make only 1–3 important values parameters; keep the rest fixed in code.
- Set
min/maxto ranges that make sense (fast EMA 5–40, not 1–500). maxalso determines the warm-up period: every combination is scored on the same candle range, starting after the warm-up of the combination with the longest period (an EMA needs about 20 × period candles). A slow EMA of up to 300 needs about 6,000 candles — more than the entire history of most tickers, leaving almost no candles to score. Keepmaxwithin the ticker's history.- The first two numeric parameters are preselected as the two axes — put them at the top of
params.
strategy({
name: "EMA nhanh / chậm để tối ưu",
params: {
fast: param.int(20, { min: 5, max: 40, label: "EMA nhanh" }),
slow: param.int(60, { min: 40, max: 160, label: "EMA chậm" }),
sl: param.pct(0.08, { min: 0.04, max: 0.15, label: "Dừng lỗ" }),
},
signals: (d, p) => {
const f = ta.ema(d.close, p.fast);
const s = ta.ema(d.close, p.slow);
return { entry: f.crossAbove(s), exit: f.crossBelow(s) };
},
risk: (p) => ({ stopLoss: p.sl }),
plot: (d, p) => ({
"EMA nhanh": line(ta.ema(d.close, p.fast), { color: "accent" }),
"EMA chậm": line(ta.ema(d.close, p.slow), { color: "ref" }),
}),
});
11.3. Running an optimization and reading the heat map
- Add the strategy to the chart and run the main backtest first (the Tổng quan (Overview) tab) — the optimization runs on the same chart candles, with the same period, fees and fill rules as that backtest.
- Tối ưu (Optimization) tab › choose Trục ngang (Horizontal axis) and Trục dọc (Vertical axis) › Chạy tối ưu (theo Sharpe) (Run optimization (by Sharpe)). Each axis splits its
min–maxrange into 7 levels (12 levels with a single axis), for at most 49 combinations. - Read the results:

| What you see | Meaning |
|---|---|
| A wide, continuous green area | The strategy holds up across many combinations — good |
| A single green cell inside a red area | A sharp peak, almost certainly luck |
| Độ phẳng (Flatness) near 1 | The cells next to the best one are nearly as good — a stable "plateau" |
| Low Độ phẳng (below 0.5) | The best cell stands alone — don't pick it |
| High Deflated Sharpe (above 0.9) | The positive Sharpe still holds after accounting for the "many combinations tried" effect |
| Low Deflated Sharpe | The best result may just come from trying many combinations |
Pick a cell in the middle of a wide green area, not necessarily the one with the highest Sharpe. Click a cell to use that combination, Áp dụng bộ tốt nhất (Apply best set), or Áp dụng vùng ổn định (…) (Apply stable region (…)) — the cell whose neighbors have the highest average Sharpe, i.e. the center of the plateau.
Every combination is scored on the same candle range, starting after the longest warm-up in the grid, so the scored range may be shorter than in the Tổng quan (Overview) tab; the optimization also does not yet use the 1-minute candle magnifier. Compare combinations with each other in the Optimization tab; read the final numbers in Tổng quan after applying the parameters and rerunning the backtest.
11.4. Walk-forward and out-of-sample
Walk-forward tab › Chạy walk-forward (Run walk-forward): splits the sessions into 4 test segments (the first 40% is used only for training). At each step, it optimizes on everything before (using the same grid as the Tối ưu (Optimization) tab), then tests on the segment right after with the parameters just chosen; the test segments are stitched together into an out-of-sample result. This is the closest simulation of "periodically re-picking parameters and continuing to trade".
| Result | Conclusion |
|---|---|
| Ngoài mẫu ghép lại (Combined out-of-sample) is profitable, Hiệu quả walk-forward (Walk-forward efficiency) of 0.6 or more (label Quá khớp thấp (Low overfitting)) | The strategy is worth continuing to watch |
| Efficiency below 0.3 (Quá khớp cao (High overfitting)): out-of-sample far worse than in-sample | The parameters overfit the optimized segment |
| Out-of-sample loses despite a pretty optimization | The strategy has no real edge |
| Tham số chọn (Chosen parameters) jump around between segments | There is no stable parameter region |
| Test segments have very few Lệnh (Trades) | The sample is too small to conclude anything |
Hiệu quả walk-forward (Walk-forward efficiency) = average out-of-sample CAGR ÷ average in-sample CAGR of the chosen set. If the history is too short relative to the warm-up, the tab shows Quá ít phiên cho walk-forward 4 đoạn (… phiên) (Too few sessions for a 4-segment walk-forward (… sessions)) — lower the parameters' max or use a timeframe with more candles.

11.5. Ten rules against overfitting
- Have a reason before you have code. Write one sentence on why the strategy should make money (trends persist, mean reversion after a sell-off…).
- Few parameters. Every added parameter is one more way to fit noise.
- Pick a plateau, not a peak on the heat map.
- Keep unseen data in reserve: always check out-of-sample / walk-forward before you trust a result.
- Test on many tickers — one ticker is one sample; a whole basket in Quant AI Studio is real evidence.
- Test across many phases: rising, falling and sideways markets.
- Enough trades (≥ 30, the more the better).
- Realistic fees and slippage, even slightly higher than reality.
- Don't tweak the strategy to "dodge" one specific past loss — that is fitting noise.
- Paper trade (follow real signals on the chart, alerts) for a while before using real money.
11.6. Declaring the optimization for Quant AI Studio
When the strategy is opened in Quant AI Studio, the optimize field in the code defines how it is optimized there (objective, grid, robustness tests). The backtest table on the chart does not read this field — it uses the parameters' min / max as above.
strategy({
name: "Donchian bứt phá — khai báo tối ưu",
params: {
n: param.int(55, { min: 20, max: 120, label: "Đỉnh n phiên" }),
exitN: param.int(20, { min: 10, max: 60, label: "Đáy thoát" }),
},
signals: (d, p) => ({
entry: d.close.gt(d.high.highest(p.n).shift(1)),
exit: d.close.lt(d.low.lowest(p.exitN).shift(1)),
}),
risk: { stopLoss: 0.1 },
optimize: {
objective: "calmar",
grid: { n: [40, 55, 70, 90], exitN: [10, 20, 30] },
tests: ["oos", "walkforward", "costs"],
},
});
Details of the Studio's robustness tests: Optimization and robustness validation.
Next: Lesson 12 — Screening the whole market and Quant AI Studio
배울 내용: Tối ưu(최적화)와 Walk-forward 탭으로 매개변수 고르기, 히트맵, 평탄도, Deflated Sharpe 읽기, 그리고 전략이 "과거에서만 보기 좋은" 것이 되지 않게 하는 원칙들.
11.1. 과최적화란
같은 과거 구간에서 매개변수 조합을 충분히 많이 시험하면, 어떻게든 결과가 아주 좋은 조합이 하나는 나옵니다. 규칙을 잡아서가 아니라 바로 그 구간의 노이즈에 맞춰졌기 때문입니다. 새 데이터로 가면 결과가 무너집니다. 이것이 과최적화(overfitting)입니다.
징후:
- 최적 매개변수가 "뾰족한 봉우리"입니다. EMA 23을 22나 25로 바꾸면 수익이 완전히 사라집니다.
- 표본 내(매개변수를 고르는 데 쓴 구간) 결과가 표본 외(보지 않은 구간)보다 훨씬 좋습니다.
- 조건과 매개변수는 많은데 거래는 적습니다.
11.2. 최적화할 수 있게 전략 작성하기
Tối ưu(최적화) 탭은 숫자 매개변수(param.int, param.num, param.pct)를 각각의 min–max 범위에서 탐색합니다. 준비 사항:
- 중요한 1–3개만 매개변수로 두고, 나머지 숫자는 코드에 고정합니다.
min/max는 의미에 맞게 합리적으로 정합니다(빠른 EMA 5–40, 1–500이 아님).max는 워밍업 구간도 결정합니다. 모든 조합은 같은 캔들 구간에서 채점되며, 가장 긴 기간을 가진 조합의 워밍업 구간 이후부터 시작합니다(EMA는 약 20 × 기간만큼의 캔들이 필요). 느린 EMA가 300까지 가면 약 6,000캔들이 필요한데, 이는 대부분 종목의 과거 데이터보다도 많아 채점할 캔들이 거의 남지 않습니다.max는 종목의 과거 데이터에 맞게 유지하세요.- 처음 두 숫자 매개변수가 기본으로 두 축으로 선택되므로, 이들을
params맨 앞에 두세요.
strategy({
name: "EMA nhanh / chậm để tối ưu",
params: {
fast: param.int(20, { min: 5, max: 40, label: "EMA nhanh" }),
slow: param.int(60, { min: 40, max: 160, label: "EMA chậm" }),
sl: param.pct(0.08, { min: 0.04, max: 0.15, label: "Dừng lỗ" }),
},
signals: (d, p) => {
const f = ta.ema(d.close, p.fast);
const s = ta.ema(d.close, p.slow);
return { entry: f.crossAbove(s), exit: f.crossBelow(s) };
},
risk: (p) => ({ stopLoss: p.sl }),
plot: (d, p) => ({
"EMA nhanh": line(ta.ema(d.close, p.fast), { color: "accent" }),
"EMA chậm": line(ta.ema(d.close, p.slow), { color: "ref" }),
}),
});
11.3. 최적화 실행과 히트맵 읽기
- 전략을 차트에 추가하고 먼저 기본 테스트를 실행합니다(Tổng quan(개요) 탭). 최적화는 이 테스트와 같은 차트 캔들, 같은 기간, 수수료, 체결 규칙으로 실행됩니다.
- Tối ưu(최적화) 탭 › Trục ngang(가로축), Trục dọc(세로축) 선택 › Chạy tối ưu (theo Sharpe)(최적화 실행(Sharpe 기준)). 각 축은
min–max범위를 7단계로 나누며(축이 하나면 12단계), 최대 49개 조합입니다. - 결과 읽기:

| 보이는 것 | 의미 |
|---|---|
| 넓고 이어진 초록 영역 | 여러 조합에서 전략이 안정적 — 좋음 |
| 빨강 영역 가운데 홀로 있는 초록 칸 | 뾰족한 봉우리, 거의 확실히 운 |
| Độ phẳng(평탄도)이 1에 가까움 | 최적 칸의 이웃 칸도 거의 비슷하게 좋음 — 안정적인 "고원" |
| Độ phẳng이 낮음(0.5 미만) | 최적 칸이 혼자 서 있음 — 고르지 마세요 |
| Deflated Sharpe가 높음(0.9 초과) | "많은 조합 시험" 효과를 빼도 양의 Sharpe가 유지됨 |
| Deflated Sharpe가 낮음 | 최고 결과가 많이 시험한 덕일 수 있음 |
Sharpe가 가장 높은 칸이 아니라 넓은 초록 영역의 가운데 칸을 고르세요. 칸을 클릭해 그 조합을 쓰거나, Áp dụng bộ tốt nhất(최적 조합 적용) 또는 Áp dụng vùng ổn định (…)(안정 영역 적용(…))을 누르세요. 후자는 이웃 칸들의 평균 Sharpe가 가장 높은 칸, 즉 고원의 중심입니다.
모든 조합은 그리드의 가장 긴 워밍업 구간 이후부터 같은 캔들 구간에서 채점되므로, 채점 구간이 Tổng quan(개요) 탭보다 짧을 수 있습니다. 최적화는 아직 1분봉 돋보기도 쓰지 않습니다. 조합끼리는 최적화 탭에서 비교하고, 최종 숫자는 매개변수를 적용해 테스트를 다시 실행한 뒤 Tổng quan에서 읽으세요.
11.4. Walk-forward와 표본 외
Walk-forward 탭 › Chạy walk-forward(walk-forward 실행): 세션을 4개의 검증 구간으로 나눕니다(처음 40 %는 학습 전용). 각 단계에서 앞부분 전체로 최적화하고(Tối ưu 탭과 같은 그리드), 방금 고른 매개변수로 바로 다음 구간에서 검증합니다. 검증 구간들을 이어 붙여 표본 외 결과를 만듭니다. "주기적으로 매개변수를 다시 고르고 계속 거래하는 것"에 가장 가까운 시뮬레이션입니다.
| 결과 | 결론 |
|---|---|
| Ngoài mẫu ghép lại(이어 붙인 표본 외)가 수익이고 Hiệu quả walk-forward(walk-forward 효율)가 0.6 이상(라벨 Quá khớp thấp(과최적화 낮음)) | 계속 지켜볼 만한 전략 |
| 효율이 0.3 미만(Quá khớp cao(과최적화 높음)): 표본 외가 표본 내보다 훨씬 나쁨 | 매개변수가 최적화 구간에 과최적화됨 |
| 최적화는 좋았는데 표본 외가 손실 | 전략에 실제 우위가 없음 |
| 구간마다 Tham số chọn(선택된 매개변수)이 제멋대로 바뀜 | 안정적인 매개변수 영역이 없음 |
| 검증 구간의 Lệnh(주문)이 매우 적음 | 결론을 내리기엔 표본이 너무 작음 |
Hiệu quả walk-forward = 선택된 조합의 평균 표본 외 CAGR ÷ 평균 표본 내 CAGR. 워밍업 구간에 비해 과거 데이터가 너무 짧으면 탭에 Quá ít phiên cho walk-forward 4 đoạn (… phiên)(4구간 walk-forward에 세션이 너무 적음(… 세션))이 표시됩니다. 매개변수의 max를 낮추거나 캔들이 더 많은 시간 프레임을 쓰세요.

11.5. 과최적화를 막는 10가지 원칙
- 코드보다 이유가 먼저. 전략이 왜 수익을 내야 하는지 한 문장으로 쓰세요(추세 지속, 투매 후 평균 회귀…).
- 매개변수는 적게. 매개변수가 하나 늘 때마다 노이즈에 맞출 방법도 하나 늘어납니다.
- 히트맵에서 봉우리가 아니라 고원을 고르세요.
- 보지 않은 데이터를 남겨 두세요: 믿기 전에 항상 표본 외 / walk-forward를 보세요.
- 여러 종목에서 검증 — 한 종목은 시료 하나일 뿐, Quant AI Studio의 바스켓 전체가 증거입니다.
- 여러 국면에서 검증: 상승장, 하락장, 횡보장.
- 거래가 충분해야 합니다(30건 이상, 많을수록 좋음).
- 현실적인 수수료와 슬리피지, 오히려 현실보다 약간 높게.
- 과거의 특정 손실을 "피하려고" 전략을 고치지 마세요 — 그것은 노이즈에 맞추는 것입니다.
- 실제 돈을 쓰기 전에 일정 기간 모의 거래(차트의 실제 신호, 알림 추적)를 하세요.
11.6. Quant AI Studio용 최적화 선언
전략을 Quant AI Studio에서 열면, 코드의 optimize 항목이 그곳에서의 최적화 방식(목표, 그리드, 견고성 검사)을 정합니다. 차트의 테스트 표는 이 항목을 읽지 않으며, 위처럼 매개변수의 min / max를 씁니다.
strategy({
name: "Donchian bứt phá — khai báo tối ưu",
params: {
n: param.int(55, { min: 20, max: 120, label: "Đỉnh n phiên" }),
exitN: param.int(20, { min: 10, max: 60, label: "Đáy thoát" }),
},
signals: (d, p) => ({
entry: d.close.gt(d.high.highest(p.n).shift(1)),
exit: d.close.lt(d.low.lowest(p.exitN).shift(1)),
}),
risk: { stopLoss: 0.1 },
optimize: {
objective: "calmar",
grid: { n: [40, 55, 70, 90], exitN: [10, 20, 30] },
tests: ["oos", "walkforward", "costs"],
},
});
Studio의 견고성 검사 세부 사항: 최적화와 견고성 검증.
您将学到: 使用 Tối ưu(优化)和 Walk-forward 标签页选择参数,解读热力图、平坦度、Deflated Sharpe,以及让策略不只是“在过去看起来漂亮”的原则。
11.1. 什么是过拟合
在同一段历史上尝试足够多的参数组合,总会有某个组合给出非常漂亮的结果——因为它拟合了那一段特有的噪音,而不是掌握了规律。换到新数据上,结果就会崩塌。这就是过拟合(overfitting)。
迹象:
- 最佳参数是一个“尖峰”:把 EMA 23 改成 22 或 25,收益就完全消失。
- 样本内(用来选参数的那一段)结果远好于样本外(尚未见过的那一段)。
- 策略条件多、参数多,交易却很少。
11.2. 编写可优化的策略
Tối ưu(优化)标签页会在 min–max 范围内扫描数值参数(param.int、param.num、param.pct)。准备工作:
- 只把 1–3 个重要参数设为参数;其余数字在代码中固定。
- 按含义合理设置
min/max(快速 EMA 5–40,而不是 1–500)。 max还决定预热段:所有组合都在同一段 K 线上评分,从周期最长的组合的预热段之后开始(EMA 大约需要 20 × 周期根 K 线)。慢速 EMA 高达 300 时需要约 6,000 根 K 线——比大多数代码的全部历史还多,几乎没有 K 线可供评分。请让max与代码的历史长度相称。- 前两个数值参数会被预选为两条坐标轴——把它们放在
params的最前面。
strategy({
name: "EMA nhanh / chậm để tối ưu",
params: {
fast: param.int(20, { min: 5, max: 40, label: "EMA nhanh" }),
slow: param.int(60, { min: 40, max: 160, label: "EMA chậm" }),
sl: param.pct(0.08, { min: 0.04, max: 0.15, label: "Dừng lỗ" }),
},
signals: (d, p) => {
const f = ta.ema(d.close, p.fast);
const s = ta.ema(d.close, p.slow);
return { entry: f.crossAbove(s), exit: f.crossBelow(s) };
},
risk: (p) => ({ stopLoss: p.sl }),
plot: (d, p) => ({
"EMA nhanh": line(ta.ema(d.close, p.fast), { color: "accent" }),
"EMA chậm": line(ta.ema(d.close, p.slow), { color: "ref" }),
}),
});
11.3. 运行优化并解读热力图
- 把策略添加到图表,先运行主测试(Tổng quan(概览)标签页)——优化在图表的同一组 K 线上运行,区间、费用、成交规则都与这次测试相同。
- Tối ưu(优化)标签页 › 选择 Trục ngang(横轴)、Trục dọc(纵轴)› Chạy tối ưu (theo Sharpe)(运行优化,按 Sharpe)。每条轴把
min–max范围分为 7 档(只有一条轴时为 12 档),最多 49 个组合。 - 解读结果:

| 您看到 | 含义 |
|---|---|
| 大片连续的绿色区域 | 策略在很多组合下都稳定——好 |
| 红色区域中孤立的一个绿格 | 尖峰,几乎可以肯定是运气 |
| Độ phẳng(平坦度)接近 1 | 与最佳格相邻的格子也几乎一样好——稳定的“高原” |
| Độ phẳng 低(低于 0.5) | 最佳格孤立存在——不要选它 |
| Deflated Sharpe 高(高于 0.9) | 扣除“尝试多个组合”的影响后,正的 Sharpe 依然站得住 |
| Deflated Sharpe 低 | 最佳结果可能只是因为尝试次数多 |
应选择大片绿色区域中间的格子,不一定是 Sharpe 最高的格子。点击某个格子即可使用该组合,或点击 Áp dụng bộ tốt nhất(应用最佳组合),或 Áp dụng vùng ổn định (…)(应用稳定区域)——即相邻格平均 Sharpe 最高的格子,也就是高原的中心。
所有组合都在同一段 K 线上评分,从网格中最长的预热段之后开始,因此评分区间可能比 Tổng quan(概览)标签页短;优化也尚未使用 1 分钟 K 线放大镜。请在优化标签页内比较各组合;最终数字请在应用参数并重新运行测试后,在 Tổng quan 中查看。
11.4. Walk-forward 与样本外
Walk-forward 标签页 › Chạy walk-forward(运行 walk-forward):把交易时段分为 4 个检验段(前 40% 只用于训练)。每一步都在之前的全部数据上优化(网格与 Tối ưu 标签页相同),然后用刚选出的参数在紧随其后的一段上检验;把各检验段拼接起来就是样本外结果。这是对“定期重新选择参数再继续交易”最接近的模拟。
| 结果 | 结论 |
|---|---|
| Ngoài mẫu ghép lại(拼接后的样本外)盈利,Hiệu quả walk-forward(walk-forward 效率)达到 0.6 及以上(标签 Quá khớp thấp,即过拟合低) | 策略值得继续跟踪 |
| 效率低于 0.3(Quá khớp cao,即过拟合高):样本外远差于样本内 | 参数对已优化的区段过拟合 |
| 优化结果漂亮但样本外亏损 | 策略没有真正的优势 |
| 各段的 Tham số chọn(所选参数)跳来跳去 | 没有稳定的参数区域 |
| 检验段的 Lệnh(委托)非常少 | 样本太小,无法下结论 |
Hiệu quả walk-forward(walk-forward 效率)= 所选组合的平均样本外 CAGR ÷ 平均样本内 CAGR。历史相对预热段太短时,标签页会提示 Quá ít phiên cho walk-forward 4 đoạn (… phiên)(交易时段太少,无法进行 4 段 walk-forward(… 个交易时段))——请降低参数的 max,或使用 K 线更多的周期。

11.5. 防止过拟合的十条原则
- 先有理由,再写代码。 用一句话写出策略为什么应该赚钱(趋势延续、抛售后的均值回归…)。
- 参数要少。 每多一个参数,就多一种拟合噪音的途径。
- 在热力图上选高原,不选尖峰。
- 保留未见过的数据:在相信之前,一定要看样本外 / walk-forward。
- 在多个代码上检验——一个代码只是一个样本;在 Quant AI Studio 中整个篮子的结果才是证据。
- 在多个阶段检验:上涨、下跌、横盘的市场。
- 交易次数足够(≥ 30,越多越好)。
- 费用和滑点符合实际,甚至略高于实际。
- 不要为了“躲过”过去某一笔具体亏损而修改策略——那 就是拟合噪音。
- 在投入真金白银之前,先用模拟单试交易一段时间(在图表上跟踪真实信号、提醒)。
11.6. 为 Quant AI Studio 声明优化
当策略在 Quant AI Studio 中打开时,代码中的 optimize 项规定在那里如何优化(目标、网格、各项稳健性检验)。图表上的测试面板不读取这一项——它使用上文所述参数的 min / max。
strategy({
name: "Donchian bứt phá — khai báo tối ưu",
params: {
n: param.int(55, { min: 20, max: 120, label: "Đỉnh n phiên" }),
exitN: param.int(20, { min: 10, max: 60, label: "Đáy thoát" }),
},
signals: (d, p) => ({
entry: d.close.gt(d.high.highest(p.n).shift(1)),
exit: d.close.lt(d.low.lowest(p.exitN).shift(1)),
}),
risk: { stopLoss: 0.1 },
optimize: {
objective: "calmar",
grid: { n: [40, 55, 70, 90], exitN: [10, 20, 30] },
tests: ["oos", "walkforward", "costs"],
},
});
Studio 各项稳健性检验的详情:优化与稳健性检验。