แก้ปัญหา Off quotes / Requote บน MT5 — 10021
สารบัญ
- ความแตกต่างระหว่างสองกรณีนี้ (+ error 136/138 ของ MT4)
- ① TRADE_RETCODE_PRICE_OFF = 10021 (ไม่มีราคาให้ประมวลผล)
- ② TRADE_RETCODE_REQUOTE = 10004 (Requote = เสนอราคาใหม่)
- ③ Error 136 / 138 ในยุค MT4
- ขั้นตอนตรวจสอบเบื้องต้นภายใน 30 วินาที
- สาเหตุและวิธีแก้ไข (5 รูปแบบ)
- ① ตลาดผันผวนรุนแรง / spike ตอนประกาศตัวเลขเศรษฐกิจ (ราคาที่ส่งไปล้าสมัยก่อนถึงเซิร์ฟเวอร์)
- ② deviation (slippage ที่ยอมรับได้) ถูกตั้งค่าแคบเกินไป
- ③ ความแตกต่างของวิธีการส่งคำสั่ง (Requote เป็นปรากฏการณ์เฉพาะของ instant execution)
- ④ ช่วงเวลาหรือสัญลักษณ์ที่ราคาบางเบาหรือหยุดนิ่ง
- ⑤ ความหน่วงของเครือข่าย (VPS อยู่ห่างจากเซิร์ฟเวอร์ของโบรกเกอร์)
- โค้ด MQL5 สำหรับลด error นี้ (สำหรับผู้พัฒนา EA)
- ตั้งค่า deviation ให้เหมาะสมในหน่วย points
- retry เฉพาะ retcode กลุ่มราคา (ส่งซ้ำด้วย tick ล่าสุด)
- ใช้ราคาที่เสนอใหม่จาก Requote (10004)
- สร้างช่วงเวลาที่ไม่เปิดออเดอร์เลยตั้งแต่แรก
- เช็คลิสต์ลำดับความสำคัญ
- สรุป
- คำถามที่พบบ่อย
- Q: 10004 กับ 10021 อันไหนร้ายแรงกว่ากัน?
- Q: โบรกเกอร์ที่ไม่เคยเจอ requote เลยถือว่าดีกว่าหรือไม่?
- Q: EA บน MT4 ขึ้น error 136 / 138 แก้ไขด้วยวิธีเดียวกันได้ไหม?
- Q: ตอน backtest ไม่เจอ error นี้ แต่พอใช้งานจริงกลับเจอ ทำไมถึงเป็นแบบนี้?
แก้ปัญหา Off quotes / Requote (MT5/MQL5) แบบเบ็ดเสร็จ
เมื่อรัน EA แล้วเจอ off quotes (10021) หรือ requote (10004) ปรากฏใน Journal หรือแท็บ Expert อาจทำให้รู้สึกกังวลว่า "ถูกโบรกเกอร์ปฏิเสธคำสั่ง" แต่ทั้งสองกรณีนี้ไม่ใช่ปัญหาเรื่องเงินทุนหรือขนาดล็อต แต่เป็นปัญหาเรื่อง "ราคา" เท่านั้น ราคาที่คุณส่งไปกับราคาที่เซิร์ฟเวอร์มีอยู่ ณ ขณะนั้นไม่ตรงกัน แค่นั้นเอง สาเหตุส่วนใหญ่มักมาจากอย่างใดอย่างหนึ่งใน 4 เรื่องนี้ คือ ตลาดผันผวนรุนแรง ค่า slippage ที่ยอมรับได้ วิธีการส่งคำสั่ง (execution mode) หรือความหน่วงของเครือข่าย
บทความนี้เขียนขึ้นสำหรับทั้งผู้ที่ใช้ EA บน MT5 และผู้ที่เขียน EA ด้วย MQL5 โดยรวบรวม10021 (TRADE_RETCODE_PRICE_OFF), 10004 (TRADE_RETCODE_REQUOTE) รวมถึง error 136/138 ในยุค MT4 ทั้งที่มา สาเหตุ วิธีแก้ไขเบื้องต้นที่ทำได้ทันที ไปจนถึงวิธีแก้ไขถาวรในโค้ด ไว้ในบทความเดียว สำหรับรายการ error code ทั้งหมด สามารถดูได้ที่ คู่มือรวมวิธีแก้ error code ของ MQL5 / MT5
บทความนี้อ้างอิงจาก MT5 (build 4xxx) ณ เดือนกรกฎาคม 2026 รายละเอียดพฤติกรรม (จะส่ง requote กลับมาหรือเปิดออเดอร์ให้เลย ฯลฯ) อาจแตกต่างกันไปตามวิธีการส่งคำสั่งของแต่ละโบรกเกอร์
ความแตกต่างระหว่างสองกรณีนี้ (+ error 136/138 ของ MT4)
การปฏิเสธประเภท "ราคาไม่ตรงกัน" นี้ เซิร์ฟเวอร์จะตอบกลับมา 2 รูปแบบ
① TRADE_RETCODE_PRICE_OFF = 10021 (ไม่มีราคาให้ประมวลผล)
เป็นค่าที่อยู่ใน MqlTradeResult.retcode ซึ่งเป็นผลลัพธ์จาก OrderSend() หมายถึงการปฏิเสธที่ว่า "ไม่มีราคาสำหรับประมวลผลคำขอนี้ (There are no quotes to process the request)" หมายความว่าฝั่งเซิร์ฟเวอร์ไม่มีราคาที่ใช้งานได้ หรือราคาที่ส่งไปห่างจากราคาปัจจุบันมากเกินกว่าจะประมวลผลได้
ความหมาย: ไม่มีราคาสำหรับประมวลผลคำขอ
ค่าคงที่ : TRADE_RETCODE_PRICE_OFF
ค่า : 10021
② TRADE_RETCODE_REQUOTE = 10004 (Requote = เสนอราคาใหม่)
เป็นค่า retcode ของ OrderSend() เช่นกัน แต่กรณีนี้ไม่ใช่แค่การปฏิเสธเฉยๆ แต่เป็นการเสนอราคาใหม่ (requote) ในลักษณะ "ราคานั้นใช้ไม่ได้ แต่ราคาใหม่นี้จะรับได้ไหม" โดยค่า bid / ask ใน MqlTradeResult จะเป็นราคาที่เซิร์ฟเวอร์เสนอใหม่ส่งกลับมา
ความหมาย: Requote — การเสนอราคาใหม่
ค่าคงที่: TRADE_RETCODE_REQUOTE
ค่า : 10004
// ตัวอย่าง log ที่พบได้ทั่วไป
2026.07.07 21:30:02.118 EA_NAME EURUSD,M5: OrderSend error 10004 (requote)
2026.07.07 21:30:02.310 EA_NAME EURUSD,M5: OrderSend error 10021
③ Error 136 / 138 ในยุค MT4
ใน MQL4 (MT4) ปรากฏการณ์เดียวกันนี้จะถูกส่งกลับมาเป็น error code ผ่าน GetLastError()
| ค่าคงที่ใน MT4 | ค่า | retcode ที่ตรงกันใน MT5 |
|---|---|---|
ERR_OFF_QUOTES | 136 | 10021 (TRADE_RETCODE_PRICE_OFF) |
ERR_REQUOTE | 138 | 10004 (TRADE_RETCODE_REQUOTE) |
หากเจอ "error 136" หรือ "error 138" ในบทความเก่าหรือ log ของ EA เวอร์ชัน MT4 เนื้อหาในบทความนี้สามารถนำไปใช้ได้ตรงๆ (ใน MT4 วิธีมาตรฐานคือเรียก RefreshRates() เพื่อดึงราคาใหม่ก่อนส่งซ้ำ ส่วนวิธีเขียนใน MT5 จะอธิบายด้านล่าง)
การแยกแยะในทางปฏิบัติ:
| retcode | เหตุผลจากฝั่งเซิร์ฟเวอร์ | สิ่งที่ EA ควรทำ |
|---|---|---|
| 10004 (requote) | "ราคาเปลี่ยนไปแล้ว ขอเสนอราคาใหม่" | ส่งคำสั่งซ้ำด้วยราคาล่าสุด (หรือยกเลิก) |
| 10021 (price off) | "ไม่มีราคาที่ประมวลผลได้" | รอสักครู่แล้วส่งซ้ำด้วย tick ล่าสุด |
ทั้งสองกรณีเป็นerror ชั่วคราว (สามารถ retry ได้) ไม่สามารถแก้ไขโค้ดหรือปรับตั้งค่าให้ "ไม่เกิดขึ้นเลย" ได้ 100% แต่สามารถลดความถี่ลงได้อย่างมาก
ขั้นตอนตรวจสอบเบื้องต้นภายใน 30 วินาที
- ตรวจสอบเวลาที่เกิด จากเวลาใน Journal
- ช่วงประกาศตัวเลขเศรษฐกิจ เช่น Nonfarm Payroll, FOMC → ตลาดผันผวนตามปกติ หาก EA มีตัวกรองข่าวให้เปิดใช้งาน
- ช่วงเที่ยงคืนตามเวลาเซิร์ฟเวอร์ (rollover) หรือช่วง gap วันเปิดตลาดต้นสัปดาห์ → ช่วงที่ราคาบางเบา ถือเป็นเรื่องปกติ
- เกิดขึ้นแบบสุ่มโดยไม่เกี่ยวกับช่วงเวลา → ให้สงสัยเรื่องเครือข่าย, VPS หรือค่า deviation
- ตรวจสอบว่าเกิดกับสัญลักษณ์ใด
- หากกระจุกตัวอยู่ที่คู่เงินรอง, exotic pair, CFD ที่สภาพคล่องต่ำ สาเหตุน่าจะมาจากราคาที่บางเบาของสัญลักษณ์นั้นๆ
- ทดสอบส่งคำสั่งด้วยมือ
- หากส่งคำสั่งด่วนด้วยมือผ่านได้ปกติ แต่ EA ถูกปฏิเสธเท่านั้น → มีแนวโน้มสูงว่าค่า
deviation(slippage ที่ยอมรับได้) ของ EA ถูกตั้งค่าแคบเกินไป
- หากส่งคำสั่งด่วนด้วยมือผ่านได้ปกติ แต่ EA ถูกปฏิเสธเท่านั้น → มีแนวโน้มสูงว่าค่า
จากทั้ง 3 ข้อนี้ ให้ลองประเมินว่าเป็นเพราะ "สภาพตลาด" "สัญลักษณ์" หรือ "การตั้งค่า/สภาพแวดล้อม" ก่อนที่จะไปดูวิธีแก้ไขตามสาเหตุแต่ละแบบต่อไป
สาเหตุและวิธีแก้ไข (5 รูปแบบ)
① ตลาดผันผวนรุนแรง / spike ตอนประกาศตัวเลขเศรษฐกิจ (ราคาที่ส่งไปล้าสมัยก่อนถึงเซิร์ฟเวอร์)
อาการ: เกิด 10004/10021 กระจุกตัวในช่วงเวลาประกาศตัวเลขเศรษฐกิจ ถ้อยแถลงของบุคคลสำคัญ หรือเช้าวันจันทร์
สาเหตุ: EA รับ tick มาคำนวณราคา แล้วในช่วงหลักสิบถึงหลักร้อยมิลลิวินาทีที่คำสั่งเดินทางไปถึงเซิร์ฟเวอร์ ราคาได้ขยับไปแล้วหลาย pips ราคาที่ส่งไปจึงไม่มีอยู่จริงแล้ว เซิร์ฟเวอร์จึงตอบกลับเป็น requote (10004) หรือไม่มีราคา (10021) ปรากฏการณ์นี้ไม่ใช่ความผิดปกติ แต่เป็นเรื่องปกติที่เกิดขึ้นได้ในตลาดที่เคลื่อนไหวเร็ว
วิธีแก้ไข:
- หยุดเปิดออเดอร์ใหม่ในช่วงก่อน-หลังประกาศตัวเลขเศรษฐกิจ (news filter) EA ที่แจกจ่ายในเว็บนี้มี
EconomicFilterเป็นฟีเจอร์มาตรฐาน - ขยายค่า
deviation(slippage ที่ยอมรับได้) ให้เป็นค่าที่เหมาะสมกับความเป็นจริง (ดูข้อ ②) - ใส่ logic การ retry (ดูโค้ดด้านล่าง)
② deviation (slippage ที่ยอมรับได้) ถูกตั้งค่าแคบเกินไป
อาการ: เกิดขึ้นประปรายแม้ในช่วงตลาดสงบ ส่งคำสั่งด้วยมือผ่านได้ปกติ แต่ EA ถูกปฏิเสธ
สาเหตุ: MqlTradeRequest.deviation คือค่าที่ระบุว่า "ยอมรับราคาที่เบี่ยงเบนจากราคาที่ส่งไปได้กี่points" หากตั้งค่านี้ไว้ที่ 0 ถึงไม่กี่ points การขยับของราคาแม้เพียงเล็กน้อยตามการอัปเดต tick ปกติก็จะถูกปฏิเสธ ข้อผิดพลาดที่พบบ่อยคือความเข้าใจผิดเรื่องหน่วย ไม่ใช่ pips แต่เป็น points (โบรกเกอร์ที่แสดงราคา 5 หลัก 1 pip = 10 points)
วิธีแก้ไข:
- ลองตั้งค่า
deviationเริ่มต้นที่ 10-30 points (= 1-3 pips) หากไม่ใช่กลยุทธ์ scalping ค่า 20 points เป็นจุดเริ่มต้นที่เหมาะสม - ตรวจสอบว่ามีความเข้าใจผิดเรื่องหน่วยหรือไม่ เช่น ตั้งใจจะใส่ deviation=5 แต่กลายเป็น 0.5 pips
- หากกลยุทธ์ไม่ต้องการยอมรับ slippage เลย ให้ยอมรับว่าการถูกปฏิเสธเป็นเรื่องปกติ และควบคุมเพียงจำนวนครั้งของการ retry เท่านั้น
③ ความแตกต่างของวิธีการส่งคำสั่ง (Requote เป็นปรากฏการณ์เฉพาะของ instant execution)
อาการ: เกิดถี่ที่โบรกเกอร์ A แต่ไม่เคยเจอเลยที่โบรกเกอร์ B
สาเหตุ: Requote (10004) เป็นปรากฏการณ์เฉพาะของ instant execution เพราะ instant execution เป็นคำสั่งที่บอกว่า "ให้เปิดออเดอร์ที่ราคานี้เท่านั้น" เมื่อราคาขยับ เซิร์ฟเวอร์จึงเสนอราคาใหม่กลับมา (requote) ในขณะที่ market execution เป็นคำสั่งที่บอกว่า "ให้เปิดออเดอร์ที่ราคาตลาด ณ ขณะนั้น" จึงไม่มี requote เกิดขึ้นในทางหลักการ แต่จะเปิดออเดอร์ที่ราคาซึ่งเบี่ยงเบนไปแทน (slippage)
กล่าวคือ "ไม่มี requote = ดี" ไม่ใช่ข้อสรุปที่ถูกต้องเสมอไป แต่เป็นtrade-off ระหว่างการถูกปฏิเสธกับการเปิดออเดอร์ที่ราคาเบี่ยงเบน วิธีการส่งคำสั่งของแต่ละสัญลักษณ์สามารถตรวจสอบได้จากช่อง Execution ใน "ข้อมูลจำเพาะของสัญลักษณ์ (Specification)" ของ MT5 หรือในโค้ดใช้ SYMBOL_TRADE_EXEMODE
วิธีแก้ไข:
- ตรวจสอบวิธีการส่งคำสั่งของบัญชีตนเอง (บัญชีมาตรฐานของโบรกเกอร์ต่างประเทศส่วนใหญ่ใช้ market execution ซึ่งจะไม่มี requote เกิดขึ้นเลย)
- หาก requote ที่เกิดถี่เป็นอุปสรรคต่อกลยุทธ์ ให้พิจารณาประเภทบัญชีหรือโบรกเกอร์ที่ใช้ market execution
- แม้จะเป็น market execution ก็มีทั้งโบรกเกอร์ที่เคารพค่า
deviationและไม่เคารพ หากไม่สามารถยอมรับ slippage ที่รุนแรงได้ ให้ตรวจสอบ slippage จริงจากประวัติการเทรด
④ ช่วงเวลาหรือสัญลักษณ์ที่ราคาบางเบาหรือหยุดนิ่ง
อาการ: เกิด 10021 ในช่วงเที่ยงคืนตามเวลาเซิร์ฟเวอร์ (rollover) ช่วงเปิดตลาดต้นสัปดาห์ ช่วงเทศกาลอย่างคริสต์มาสที่การซื้อขายเบาบาง หรือกับสัญลักษณ์รอง
สาเหตุ: ช่วง rollover จะมีการหยุดส่งราคาชั่วคราวเนื่องจากการประมวลผล swap หรือสเปรดขยายกว้างผิดปกติ ในช่วงเปิดตลาดต้นสัปดาห์หรือสัญลักษณ์ที่สภาพคล่องต่ำ ราคาที่ประมวลผลได้ก็มีน้อยอยู่แล้ว หากส่งคำสั่งในสภาวะนี้จึงเกิด 10021 (ไม่มีราคา)
วิธีแก้ไข:
- หลีกเลี่ยงการเปิดออเดอร์ใหม่ช่วง 23:55-0:05 ตามเวลาเซิร์ฟเวอร์ (time filter)
- หลีกเลี่ยงไม่กี่นาทีแรกหลังเปิดตลาดวันจันทร์ (ตั้งค่าประเภท
AvoidMondayOpen) - ใส่ตัวกรองสเปรด (
MaxSpread) เนื่องจากช่วงที่ราคาบางเบา สเปรดมักจะขยายกว้าง จึงสามารถหลีกเลี่ยงช่วงเวลานี้ได้โดยอัตโนมัติ
⑤ ความหน่วงของเครือข่าย (VPS อยู่ห่างจากเซิร์ฟเวอร์ของโบรกเกอร์)
อาการ: เกิดถี่กว่าสภาพแวดล้อมอื่นอย่างชัดเจน ไม่ว่าจะช่วงเวลาหรือสัญลักษณ์ใด ค่า ping สูง
สาเหตุ: ยิ่งเวลาที่คำสั่งเดินทางไป-กลับ (latency) จนถึงเซิร์ฟเวอร์นานเท่าไร โอกาสที่ราคาจะขยับในระหว่างนั้นก็ยิ่งสูงขึ้น หากรันบน PC ที่บ้านหรือ VPS ที่อยู่ห่างจากที่ตั้งเซิร์ฟเวอร์ของโบรกเกอร์ (ส่วนใหญ่อยู่ที่ลอนดอนหรือนิวยอร์ก) ความถี่ของ 10004/10021 จะสูงขึ้นในเชิงโครงสร้าง ค่า ping ที่แสดงมุมล่างขวาของ MT5 เป็นตัวชี้วัดหนึ่ง (หลักร้อย ms ถือว่าเสียเปรียบชัดเจน หลักสิบ ms หรือต่ำกว่าถือว่าดี)
วิธีแก้ไข:
- ตรวจสอบค่า ping มุมล่างขวาของ MT5 หากสูงตลอดเวลา ควรพิจารณาสภาพแวดล้อมที่รัน EA ใหม่
- ย้ายไปใช้ VPS ในภูมิภาคที่อยู่ใกล้เซิร์ฟเวอร์ของโบรกเกอร์ ตามจริงแล้ว 10004/10021 ที่เกิดจากความหน่วงไม่สามารถลดได้ด้วยโค้ด มีเพียงการเข้าใกล้ทางกายภาพเท่านั้นที่เป็นทางแก้ วิธีเลือก VPS สามารถดูได้ที่ วิธีเลือก VPS สำหรับ EA
- EA ประเภท scalping จะได้รับผลกระทบจาก latency มากกว่า หาก EA เป็นแบบ daily หรือ H4 สาเหตุนี้จะมีความสำคัญน้อยกว่า
โค้ด MQL5 สำหรับลด error นี้ (สำหรับผู้พัฒนา EA)
แนวทางมี 3 ข้อ (1) ตั้งค่า deviation ให้เหมาะสมกับความเป็นจริง (2) เมื่อถูกปฏิเสธให้ดึง tick ล่าสุดมาส่งซ้ำ (3) จำกัดการ retry ไว้เฉพาะ retcode กลุ่มราคาเท่านั้น
ตั้งค่า deviation ให้เหมาะสมในหน่วย points
MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);
req.action = TRADE_ACTION_DEAL;
req.symbol = _Symbol;
req.type = ORDER_TYPE_BUY;
req.volume = lots;
req.deviation = 20; // slippage ที่ยอมรับได้ 20 points (5 หลัก = 2.0 pips)
// ต้องตั้งค่า req.price / req.sl / req.tp / req.magic ด้วยเช่นกัน
หน่วยของ deviation คือ points สำหรับโบรกเกอร์ที่แสดงราคา 5 หลัก (หรือ 3 หลัก) 10 points = 1 pip การตั้งค่า 0 หรือค่าที่น้อยเกินไปจะเพิ่มอัตราการถูกปฏิเสธโดยไม่จำเป็น
retry เฉพาะ retcode กลุ่มราคา (ส่งซ้ำด้วย tick ล่าสุด)
จุดสำคัญคือทุกครั้งที่ retry ต้องดึงราคาใหม่ด้วย SymbolInfoTick() (หากส่งซ้ำด้วยราคาเดิมจะถูกปฏิเสธเหมือนเดิม) และจำกัดเป้าหมายการ retry ไว้เฉพาะ 10004/10021 เท่านั้น การส่งซ้ำแบบอัตโนมัติสำหรับ error เช่น เงินทุนไม่พอ (10019) หรือคำขอไม่ถูกต้อง (10013) นั้นไม่มีประโยชน์ มีแต่จะทำให้ log รก
bool IsRetryableRetcode(uint rc)
{
return (rc == TRADE_RETCODE_REQUOTE // 10004
|| rc == TRADE_RETCODE_PRICE_OFF); // 10021
}
// อัปเดตราคาด้วย tick ล่าสุดและส่งซ้ำสูงสุด 3 ครั้ง
bool SendWithRetry(MqlTradeRequest &req, MqlTradeResult &res, int maxTries = 3)
{
for(int attempt = 0; attempt < maxTries; attempt++)
{
MqlTick tick;
if(!SymbolInfoTick(req.symbol, tick))
{
Print("SymbolInfoTick failed: ", GetLastError());
return false;
}
req.price = (req.type == ORDER_TYPE_BUY) ? tick.ask : tick.bid;
if(OrderSend(req, res) && res.retcode == TRADE_RETCODE_DONE)
return true; // เปิดออเดอร์สำเร็จ
if(!IsRetryableRetcode(res.retcode))
{
PrintFormat("OrderSend failed (no retry): retcode=%d", res.retcode);
return false; // ไม่ retry สำหรับ retcode อื่นที่ไม่ใช่กลุ่มราคา
}
PrintFormat("Retry %d/%d after retcode=%d", attempt + 1, maxTries, res.retcode);
Sleep(200 + 150 * attempt); // รอทีละน้อย 200ms→350ms→500ms
}
Print("Order abandoned after retries (price kept moving).");
return false;
}
เหตุผลที่ค่อยๆ เพิ่มเวลารอใน Sleep() ทีละขั้น เป็นเพราะถ้ายิงซ้ำทันทีที่ 0ms ในช่วงตลาดผันผวนรุนแรงก็จะถูกปฏิเสธซ้ำเช่นเดิม ในทางกลับกัน หากรอนานเกินไป ราคาที่จะเข้าออเดอร์จะห่างจากที่กลยุทธ์คาดการณ์ไว้มากขึ้น การ retry ควรยอมแพ้หลังจาก 2-3 ครั้ง จึงจะเหมาะสม และสำหรับคำสั่ง pending order (TRADE_ACTION_PENDING) โปรดสังเกตว่า retcode เมื่อสำเร็จจะเป็น TRADE_RETCODE_PLACED (10008)
ใช้ราคาที่เสนอใหม่จาก Requote (10004)
เมื่อเกิด 10004 ค่า bid / ask ใน MqlTradeResult จะเป็นราคาที่เซิร์ฟเวอร์เสนอใหม่ หากส่งซ้ำด้วย tick ล่าสุดตามตัวอย่างข้างต้นก็เพียงพอสำหรับการใช้งานทั่วไป แต่หากต้องการเขียน logic สำหรับ instant execution ที่ "รับราคาใหม่หากอยู่ในช่วงที่ยอมรับได้" ก็สามารถเปรียบเทียบส่วนต่างระหว่าง res.ask / res.bid กับราคาที่ตั้งใจไว้เดิมในหน่วย points ก่อนตัดสินใจส่งซ้ำ
สร้างช่วงเวลาที่ไม่เปิดออเดอร์เลยตั้งแต่แรก
การ retry ในโค้ดเป็นเพียงการแก้ปัญหาที่ปลายเหตุ ตัวกรองที่หยุดการเปิดออเดอร์ใหม่ในช่วงก่อน-หลัง rollover, ก่อน-หลังประกาศตัวเลขเศรษฐกิจ และช่วงสเปรดขยายกว้าง จะได้ผลที่รากของปัญหามากกว่า
// ตัวอย่างตัวกรองสเปรด: เลื่อนการเปิดออเดอร์ใหม่ในช่วงที่สเปรดกว้าง
long spreadPts = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
if(spreadPts > MaxSpreadPoints)
{
// เลื่อนการเปิดออเดอร์ใหม่ (หลีกเลี่ยงช่วงที่ราคาบางเบาซึ่งมักเกิด 10021 ได้โดยอัตโนมัติ)
return;
}
EA ที่แจกจ่ายโดย FXEA365 มีการติดตั้งตัวกรองสเปรด, ตัวกรองข่าว และการ retry อัตโนมัติสำหรับ retcode กลุ่มราคาเป็นมาตรฐานอยู่แล้ว
เช็คลิสต์ลำดับความสำคัญ
| ลำดับ | ตรวจสอบ | วิธีแก้ไข |
|---|---|---|
| 🚨 อันดับแรก | เกิดกระจุกตัวช่วงประกาศตัวเลขเศรษฐกิจ/ตลาดผันผวนรุนแรงหรือไม่ | เปิดใช้ news filter และยอมรับว่าเป็นเรื่องปกติในช่วงนั้น |
| 🚨 อันดับแรก | deviation แคบเกินไปหรือไม่ (หน่วยเป็น points) | ปรับเป็น 10-30 points และตรวจสอบความเข้าใจผิดเรื่อง pips/points |
| ⚠️ ถัดไป | กระจุกตัวช่วง rollover, ต้นสัปดาห์, สัญลักษณ์ที่เทรดเบาบางหรือไม่ | ใช้ time filter ร่วมกับ spread filter |
| ⚠️ ถัดไป | วิธีส่งคำสั่งเป็น instant หรือไม่ | พิจารณาบัญชีแบบ market execution (แลกกับ trade-off เรื่อง slippage) |
| ⚠️ ถัดไป | ping สูงหรือไม่ (หลักร้อย ms) | ย้ายไปใช้ VPS ที่ใกล้เซิร์ฟเวอร์มากขึ้น |
| 🛠 สำหรับผู้พัฒนา | การ retry จำกัดเฉพาะ retcode กลุ่มราคาหรือไม่ | ดึงราคาใหม่ด้วย SymbolInfoTick และหยุดหลัง 2-3 ครั้ง |
สรุป
- 10021 (TRADE_RETCODE_PRICE_OFF) คือ "ไม่มีราคาให้ประมวลผล" ส่วน 10004 (TRADE_RETCODE_REQUOTE) คือ "การเสนอราคาใหม่" ทั้งสองอยู่ในกลุ่ม error ปฏิเสธราคาเดียวกับ 136/138 ในยุค MT4 ไม่ใช่ปัญหาเรื่องเงินทุนหรือขนาดล็อต
- สาเหตุสรุปรวมได้ 5 ข้อ คือ ตลาดผันผวนรุนแรง, deviation แคบเกินไป, instant execution, ช่วงเวลา/สัญลักษณ์ที่ราคาบางเบา และความหน่วงของเครือข่าย
- Requote เป็นปรากฏการณ์เฉพาะของ instant execution ส่วน market execution จะปรากฏเป็น slippage แทน "ไม่มี requote = ดี" ไม่ใช่ข้อสรุปเสมอไป แต่เป็น trade-off
- ผู้พัฒนา EA ควรแก้ไขถาวรด้วย การ retry 2-3 ครั้งโดยดึง tick ล่าสุด (จำกัดเฉพาะ 10004/10021) ร่วมกับการปรับ deviation ให้เหมาะสม และตัวกรองเวลา/สเปรด ส่วนที่มาจาก latency ต้องแก้ด้วยวิธีทางกายภาพเท่านั้น (ใช้ VPS ที่ใกล้โบรกเกอร์มากขึ้น)
สำหรับ error code ทั้งหมด ดูได้ที่ คู่มือรวมวิธีแก้ error code ของ MQL5 / MT5 และ EA ฟรีที่ติดตั้งมาตรการเหล่านี้เป็นมาตรฐาน ดูได้ที่ รายการ EA
คำถามที่พบบ่อย
Q: 10004 กับ 10021 อันไหนร้ายแรงกว่ากัน?
ทั้งสองเป็น error ชั่วคราวเกี่ยวกับราคา ระดับความร้ายแรงไม่แตกต่างกันมากนัก 10004 คือ "ถูกเสนอราคาใหม่" ส่วน 10021 คือ "ไม่มีราคาที่ประมวลผลได้" ต่างกันเพียงรูปแบบการตอบกลับ หากเกิดเพียงครั้งคราวก็ไม่มีปัญหาแต่อย่างใด เฉพาะกรณีที่เกิดถี่ในช่วงเวลาหรือสัญลักษณ์ใดสัญลักษณ์หนึ่งเท่านั้นที่ควรแก้ไขสาเหตุ (ข่าว, rollover, deviation, เครือข่าย)
Q: โบรกเกอร์ที่ไม่เคยเจอ requote เลยถือว่าดีกว่าหรือไม่?
มีความเป็นไปได้สูงว่าเป็นเพราะวิธีการส่งคำสั่งที่แตกต่างกัน บัญชีที่ใช้ market execution จะไม่เกิด requote ในทางหลักการ แต่หากราคาขยับจะเปิดออเดอร์ที่ราคาเบี่ยงเบนแทน (slippage) เนื่องจากเป็น trade-off ระหว่างการถูกปฏิเสธกับการเลื่อนราคา ควรตรวจสอบ slippage จริงจากประวัติการเทรดก่อนตัดสินใจ
Q: EA บน MT4 ขึ้น error 136 / 138 แก้ไขด้วยวิธีเดียวกันได้ไหม?
ได้ 136 (ERR_OFF_QUOTES) เทียบเท่ากับ 10021 และ 138 (ERR_REQUOTE) เทียบเท่ากับ 10004 ทั้งสาเหตุและวิธีแก้ไขเหมือนกัน ใน MQL4 วิธีมาตรฐานคือเรียก RefreshRates() เพื่ออัปเดต Bid / Ask ให้เป็นค่าล่าสุดก่อนส่งซ้ำ ซึ่งเป็นแนวคิดเดียวกับการดึงราคาใหม่ด้วย SymbolInfoTick() ใน MQL5
Q: ตอน backtest ไม่เจอ error นี้ แต่พอใช้งานจริงกลับเจอ ทำไมถึงเป็นแบบนี้?
เป็นเรื่องปกติ เพราะ Strategy Tester ไม่มี (หรือทำให้ง่ายขึ้นมาก) เรื่อง "ความล่าช้าในการส่งคำสั่งไปถึงเซิร์ฟเวอร์" และ "การเคลื่อนไหวของราคาในช่วงเวลานั้น" ทำให้ 10004/10021 จะปรากฏเฉพาะในการใช้งานจริง (forward) เท่านั้น แม้ backtest จะออกมาดี แต่การใช้งานจริงยังต้องจัดการเรื่องการตั้งค่า deviation, retry และสภาพแวดล้อมการรัน (VPS) แยกต่างหาก
บทความที่เกี่ยวข้อง
📧 แจ้งเตือนก่อนขึ้นราคา + คอร์สอีเมลฟรี 5 วัน
EA ทั้งหมดจำหน่ายในราคาเปิดตัวและจะปรับขึ้นเป็นขั้นตามยอดขาย รับการแจ้งเตือนก่อนการขึ้นราคาแต่ละครั้ง พร้อมอีเมลรายวันเกี่ยวกับการเทรดอัตโนมัติ การอ่านแบ็กเทสต์ และการเลือกโบรกเกอร์
* ปกป้องความเป็นส่วนตัวอย่างเคร่งครัด คุณสามารถยกเลิกการสมัครได้ตลอดเวลา