ข้ามไปที่เนื้อหา

S4-LAB · backtest งานแรกตั้งแต่ต้นจนจบ

▶ clip: https://youtu.be/j4GVsxiy404

จบบทนี้แล้วทำได้:

  • ตั้งช่วงทดสอบจาก is_oos โดยไม่พิมพ์วันที่เอง
  • เขียนเกณฑ์ผ่าน/ตกและลงบัญชี Šidák ก่อนกด run
  • ตรวจแผนงานด้วย --dry-run แล้วเข้า queue ผ่าน dashboard
  • หา file รายงาน อ่าน History Quality ก่อนตัวเลขอื่น แล้วใช้ mc กับ verdict อ่านผล
  • บันทึกคำตัดสินลง research\status.yaml และตรวจด้วย ea_status --check

ต้องมีก่อน: ทำ M0-LAB จบแล้ว · มีบัญชี demo อย่างน้อย 1 บัญชี (ใน clip คือ RoboForex demo) · bt\ea-bt.exe tick_depth --terminal mt5\MT5_<ชื่อ> --from 2026-01 ตอบ yes แล้ว

EA ที่ใช้คือ LAB_MACROSS v1.00 ที่มากับ kit (eas\LAB_MACROSS\LAB_MACROSS_v1.00.mq5) · ทุกคำสั่งพิมพ์ใน PowerShell ที่ folder kit (C:\ea-research-starter ใน clip) · ขั้นตอนตรงกับ README.md ของ kit หัวข้อ "lab แรก" ข้อ 1–7 และข้อ 8 ของ "ทดสอบ EA ของตัวเอง"

clip นี้ไม่มีเสียงพูด อ่าน subtitle แทน และไม่มี slide บทอ่านนี้จึงไม่มีภาพ


1 · เอาช่วงทดสอบจาก is_oos

bt\ea-bt.exe is_oos --year 2026 --yaml

ผลคือ date_from / date_to ของ IS 2026 = 2026-01-01 → 2026-04-30

แล้วเปิด bt\config.yaml ดู date_from กับ date_to — kit ตั้งค่านี้ไว้ตรงกันแล้ว

ทำไมห้ามพิมพ์วันที่เอง: ช่วง IS/OOS ของแต่ละปีถูกสุ่มครั้งเดียวแล้ว lock ไว้ ถ้าเลือกวันที่เองหลังเคยเห็นผล ก็คือเลือกช่วงที่ผลออกมาถูกใจ ซึ่งทำให้การแยก IS กับ OOS ไม่มีความหมาย

tester หยุดที่ 00:00 ของ date_to — วันที่ 30 เม.ย. จึงไม่ถูก run

ต่างจาก clip: ตอนอัด config ยังตั้ง deposit: 1000 · kit ปัจจุบันตั้ง deposit: 10000 เหตุผลเขียนไว้ใน bt\config.yaml: risk 1% ÷ (SL $10 × contract 100) ได้ 0.01 lot ซึ่งเท่ากับขั้นต่ำพอดี พอขาดทุน trade แรก lot ปัดลงเหลือ 0 แล้ว EA หยุดยิงทั้งรอบ (เกิดจริงใน sandbox 2026-11-01: 3 trade แล้วเงียบ 4 เดือน) · ห้ามลดกลับเป็น 1,000

2 · เขียนเกณฑ์ก่อน run

เปิด bt\config.yaml คู่กับ research\3-prereg\prereg-template.md

  1. เขียนเกณฑ์ผ่าน/ตก S1–S6 ในหัว bt\config.yaml ทุกบรรทัดขึ้นต้นด้วย # — การเขียนไว้ก่อน run นับเป็น prereg
  2. ใช้เกณฑ์จากตารางข้อ 4 ของ template (ที่มาเต็มอยู่ใน docs\ea-screen-criteria.md):
รหัส criteria ผ่านเมื่อ
S1 ข้อมูลใช้ได้ history_quality ≥ 90%
S2 trade กระจายพอ ≥ 10 วันที่มี trade
S3 edge E[R] > 0 และ CI ล่าง > 0 (bootstrap รายวัน) · t ≥ ค่าจาก ledger
S4 ไม่พึ่ง tail ตัด 3 trade บนสุดแล้วยังบวก
S5 ความเสี่ยง Equity DD Relative ≤ 30%
S6 เกินฐานรูปทรง win% > 1 / (1 + payoff)
  1. เปิด research\3-prereg\sidak-ledger.md เพิ่มแถวที่ 1 · ช่อง "ผล" เว้นไว้ กรอกหลัง verdict
  2. บันทึกทั้งสอง file

เขียนแล้วห้ามแก้หลังเห็นผล ถ้าพบทีหลังว่าเกณฑ์ตั้งผิด ให้เขียนเพิ่มว่าผิดตรงไหน ไม่ใช่แก้ทับ

ทำไมต้องลงบัญชี Šidák: ยิ่งทดสอบหลายครั้ง โอกาสที่จะเจอ "ผ่าน" จากโชคล้วนยิ่งสูง (sidak-ledger.md ยกตัวอย่าง k = 10 ที่ α = 5% → โอกาสผ่านเพราะโชค 40%) เกณฑ์ t จึงต้องเข้มขึ้นตามจำนวนการทดสอบ ถ้าไม่จดไว้ก็ไม่รู้ว่าต้องเข้มขึ้นเท่าไร

ต่างจาก clip: ใน clip พิมพ์ S3 เป็น t >= 1.96 · verdict ใช้เส้นขั้นต่ำ 2.0 (G4_MIN_T ใน code) ให้เขียน t ≥ 2.0

template ข้อ 2–3 ยังเขียนคำสั่งเป็น python bt/... · ในเครื่องผู้เรียนไม่มี Python ให้ใช้รูป bt\ea-bt.exe <เครื่องมือ> แทน เช่น bt\ea-bt.exe is_oos --year 2026 --yaml

3 · dry-run ตรวจแผนงาน

bt\ea-bt.exe run --config bt\config.yaml --dry-run

dry-run พิมพ์แผนงานออกมาให้ดูอย่างเดียว ยังไม่ run จริง ตรวจว่า:

  • หนึ่งงานต่อหนึ่งบัญชี (มี 1 บัญชีก็ต้องได้ 1 งาน)
  • EA LAB_MACROSS · preset V1.00/default · period H1 · วันที่ 2026-01-01 → 2026-04-30

ถ้าเห็น ⚠ .ex5 not found แล้วบรรทัดท้ายเป็น (dry-run) would run 1 jobs ไม่ต้องทำอะไร — kit มีแต่ .mq5 และ run จะ compile ให้เองก่อน backtest

4 · เข้า queue แล้วกดเริ่ม

  1. เปิด dashboard (2-เปิดหน้าคุม.bat) → tab ระบบ backtest → card queue งาน
  2. ช่อง file config เลือก config.yaml — dashboard ใช้ file ที่เลือกตรง ๆ ไม่ได้สร้างสำเนา
  3. กด + เพิ่มงานนี้เข้า queue → แถวใหม่ขึ้นสถานะ "รอ"
  4. กด "เริ่ม queue" เอง ระบบไม่เริ่มให้
  5. MT5 เปิดเอง run เสร็จแล้วปิดเอง แถวใน queue เปลี่ยนเป็น "เสร็จ"

queue เก็บ config ทั้งก้อนไว้ตอนกดเพิ่ม แก้ YAML หลังจากนั้นไม่ถึงงานที่รออยู่ ต้องเอางานออกแล้วเพิ่มใหม่ (ดู S4)

เรื่อง tick ครั้งแรก:

  • ถ้าดึง tick ไว้ก่อนด้วย tick_depth --from 2026-01 แล้ว (แบบใน clip) MT5 เริ่ม run ได้เลย · ใน clip การดึง tick ม.ค.–เม.ย. 2026 ใช้ราว 3 นาที และ run backtest เองใช้ 21 วินาที
  • ถ้ายังไม่ได้ดึง MT5 จะโหลด tick จาก broker ก่อน ดูได้ที่ "Download history: xx%" มุมขวาล่างของ Strategy Tester ระหว่างนั้นเส้นทุนไม่ขยับ ไม่ได้ค้าง · เวลาโหลดนับรวมใน run_timeout_sec (7200 วินาที) · ถ้า % ไม่ขยับนานหลายนาที ให้ check network
  • ถ้าไม่มี tick จริงในช่วงนั้นเลย MT5 จะสร้าง tick จาก M1 เองโดยไม่เตือน แล้ว History Quality จะต่ำ (S2)

ระหว่าง run ดูเส้นทุนใน tab Graph ของ tester:

เห็นอะไร ทำอะไร
ลงต่อเนื่องหลายเดือน หยุดได้ · กด Stop แล้วปิด MT5 ตัวนั้นด้วย ไม่งั้น queue รอจนครบ timeout
ขึ้นเรียบสวย ห้ามอ่านว่าผ่าน — grid/martingale เป็นแบบนี้ก่อนพัง
แกว่ง หรือลงแล้วเด้ง ห้ามปิด ปล่อยให้จบ

lab นี้ไม่ต้องกด Stop — ต้องให้ run จนจบเพื่อมีรายงานใช้ในหัวข้อถัดไป

5 · file รายงาน · History Quality ก่อน

รายงานไปอยู่ใต้ backtest_root ของ config ตามโครงนี้:

<backtest_root>\<strategy>\<version>\<ชื่อบัญชี>\<preset>.htm
research\4-backtest\_lab\LAB_MACROSS_IS2026\LAB_MACROSS\V1.00\<ชื่อบัญชี>\default.htm

<ชื่อบัญชี> คือชื่อที่ตั้งตอนเพิ่มบัญชี demo (ใน clip คือ RoboMT5DemoECN) · preset default มาจากชื่อ file LAB_MACROSS_v1.00_default.set

ใน folder เดียวกันมีสาม file:

file คืออะไร
default.htm รายงานของ tester
default.ini ค่าที่ tester ใช้จริง
default.log journal ของรอบนั้น

ผลแปลกเมื่อไร เปิด .ini ก่อน ชื่อ file บอกแค่ว่าตั้งใจ run อะไร .ini บอกว่า run อะไรจริง ใน clip เปิดดูได้ Period=H1 · FromDate=2026.01.01 · ToDate=2026.04.30

เปิด default.htm ใน browser แล้วอ่านตามลำดับใน S5:

  1. History Quality ก่อนตัวเลขอื่น · ต่ำกว่า 90% = ทิ้งผลนั้น (รอบใน clip ได้ 99% real ticks)
  2. drawdown อ่านแถว Relative ไม่ใช่ Maximal

แล้วเปิด research\4-backtest\_lab\LAB_MACROSS_IS2026\summary.csv — ทุกงานใน config นี้รวมไว้แถวละงาน ดู column history_quality · total_trades · equity_dd_rel_pct

6 · mc: R · CI · DD จาก shuffle

bt\ea-bt.exe mc research\4-backtest\_lab\LAB_MACROSS_IS2026\LAB_MACROSS\V1.00\<ชื่อบัญชี>\default.htm --daily

mc แปลงแต่ละ trade เป็น R แล้วสลับลำดับ trade (shuffle) เพื่อดูว่า drawdown ลึกได้แค่ไหน · --daily ยุบ trade ในวันเดียวกันเป็นหนึ่งตัวอย่าง

บรรทัดที่ได้ใน clip:

days 24 · win 20.8% · E[R] -0.596 (bootstrap 95% -1.006..-0.138) · sd 1.09 · t -2.67  FAIL G4

อ่านแบบนี้:

  • days 24 — มี 29 trade แต่กระจายอยู่ใน 24 วัน · trade ในวันเดียวกันไม่ใช่ตัวอย่างอิสระ n ที่ใช้จึงเป็นจำนวนวัน (S6)
  • CI ทั้งช่วงอยู่ใต้ 0 (−1.006 ถึง −0.138) = ขาดทุนอย่างเป็นระบบ ไม่ใช่โชคไม่ดี · ถ้า CI คร่อม 0 แปลว่ายังบอกไม่ได้ว่ามี edge
  • ป้าย FAIL G4 ท้ายบรรทัดเป็น gate ชุดเก่า ไม่ใช่เกณฑ์ S3 (S7)
  • แถว risk 1%: DD ลำดับจริง 15% · shuffle p50 14% · p95 16% — ลำดับที่เกิดจริงเป็นแค่เส้นทางเดียว ใช้ค่าหางจาก shuffle ตั้ง risk ไม่ใช่ค่าที่เกิดจริง

7 · verdict: เทียบกับเกณฑ์

bt\ea-bt.exe verdict research\4-backtest\_lab\LAB_MACROSS_IS2026\LAB_MACROSS\V1.00\<ชื่อบัญชี>

ผลใน clip: FAIL G2 — win% 20.69 ต่ำกว่า need% 39.05 · net −1,279.3 · t net −2.24

  • need% คือ 1 / (1 + payoff) — win rate ขั้นต่ำที่ payoff ของ EA เองต้องการเพื่อคุ้มทุน ชนะต่ำกว่านี้ = แพ้โดยโครงสร้าง (เงื่อนไขเดียวกับ S6)
  • ทำไม mc ขึ้น G4 แต่ verdict ขึ้น G2: verdict ตรวจ G2 (รูปทรง win/payoff) ก่อน G4 (net และ t) แล้วรายงานด่านแรกที่ตก
  • verdict ไม่ได้ตรวจครบ S1–S6 — ไม่ดู History Quality และไม่ตัดสินด้วย DD Relative หรือ CI รายวัน ใช้เป็นตัวช่วยอ่าน ไม่ใช่คำตัดสิน (รายละเอียดใน S7)

กลับไปกรอกคำตัดสินลงช่อง "ผล" ใน sidak-ledger.md

ถ้าผ่าน แปลว่า "น่าลงแรงต่อ" เท่านั้น ยังต้องผ่าน OOS และด่าน robustness R1–R6 (research\5-verdict\robustness.md) · R3 (slippage) วัดจากบัญชี demo ที่ forward เองได้ — ขั้นตอนอยู่ใน README.md ของ kit หัวข้อ "วัด slippage จากบัญชี demo ของตัวเอง"

8 · บันทึกสถานะ

เปิด research\status.yaml แก้แถว LAB_MACROSS:

field ค่า
stage '5'
state ตามคำตัดสิน (รอบใน clip = ตก)
since วันที่ตัดสิน
evidence research/4-backtest/_lab/LAB_MACROSS_IS2026/LAB_MACROSS/V1.00/<ชื่อบัญชี>/default.htm
summary ประโยคเดียวที่คนไม่รู้ศัพท์อ่านเข้าใจ
next งานถัดไป

แล้ว run

bt\ea-bt.exe ea_status --check

ต้องไม่มี [error] · tab "สถานะกลยุทธ์" ใน dashboard อ่านจาก file นี้ ถ้าไม่แก้ dashboard จะยังขึ้นว่า EA อยู่ขั้น 3

ทำไมต้องแก้ทันที: ผ่านหรือตกด่านเมื่อไร แก้ในรอบเดียวกัน ถ้าเลื่อนไว้ก่อน สถานะใน file จะไม่ตรงกับความจริง และอีกไม่กี่สัปดาห์จะจำไม่ได้ว่า EA ตัวไหนตกเพราะอะไร

ค่าที่ได้ใน clip — run ของคุณเองควรได้ใกล้เคียง (bootstrap ขยับเล็กน้อยทุกครั้ง)
ขั้น ค่า
is_oos 2026-01-01 → 2026-04-30
เวลา ดึง tick ม.ค.–เม.ย. 2026 ราว 3 นาที · run backtest 21 วินาที
History Quality 99% real ticks
mc --daily 29 trade · days 24 · win 20.8% · E[R] −0.596 [−1.006, −0.138] · t −2.67
DD risk 1% ลำดับจริง 15% · shuffle p50 14% · p95 16%
verdict FAIL G2 · win% 20.69 < need% 39.05 · net −1,279.3 · t net −2.24
คำตัดสิน ตก — E[R] ≤ 0 และ win% ต่ำกว่าฐาน

ถ้าคุณใช้ broker อื่นหรือ deposit ต่างจาก 10,000 ตัวเลขจะไม่ตรงกับตารางนี้ · ใน clip ใช้ deposit 1,000 (ดูหัวข้อ 1)


จุดที่มักพลาด

พลาด ผลที่ตามมา ทางกัน
พิมพ์ date_from / date_to เอง เลือกช่วงที่ถูกใจโดยไม่รู้ตัว เอาจาก is_oos --year 2026 --yaml
ลด deposit เป็น 1,000 lot เหลือ 0 หลังขาดทุน trade แรก EA หยุดยิงทั้งรอบ ใช้ 10,000 ตาม config ของ kit
เขียนเกณฑ์หลังเห็นผล เกณฑ์ถูกปรับให้ผ่าน เขียนในหัว config และลง ledger ก่อนกด run
แก้ YAML หลังเข้า queue งานยังใช้ config เดิม เอางานออกแล้วเพิ่มใหม่
กด Stop แต่ไม่ปิด MT5 queue ค้างจนครบ run_timeout_sec ปิด MT5 ตัวนั้นด้วย
ไม่ได้ดึง tick ก่อน MT5 สร้าง tick จาก M1 · History Quality ต่ำ tick_depth --from 2026-01 ต้องตอบ yes
อ่าน FAIL G4 / PASS ของ mc หรือ verdict เป็นคำตัดสิน S1–S6 ตัดสินด้วย gate ชุดเก่า ไล่ S1–S6 ตาม S7
ลืมแก้ status.yaml dashboard แสดงสถานะผิด แก้ทันทีแล้ว ea_status --check