> 블로그 > Unsupported filling mode(MT5 오류 10030) 완전 해결

MT5MQL5오류문제 해결EA

Unsupported filling mode(MT5 오류 10030) 완전 해결

공개일: 2026-07-07읽기 시간: 약 4분
본 기사는 게시일 시점의 정보입니다. EA의 실적 수치(PF·DD·연율)는 운용 및 재검증으로 변동하므로 최신 값은 각 EA 페이지에서 확인하세요. 최신 EA 실적 보기

Unsupported filling mode(MT5 오류 10030) 완전 해결

어제까지 다른 브로커에서 정상적으로 작동하던 EA를 새 계좌로 옮기자마자 Expert 탭에 Unsupported filling modeOrderSend error 10030이 줄줄이 뜨며 단 한 건도 주문이 들어가지 않는 상황 — 이는 MT5 EA 운용에서 가장 흔한 브로커 이전 트러블입니다. EA가 고장 난 것도, 계좌에 문제가 있는 것도 아닙니다. 주문의 "체결 방식(filling mode)" 지정이 새 브로커의 해당 심볼에서는 허용되지 않는다, 그것뿐입니다.

이 글은 MT5에서 EA를 사용하는 사람과 MQL5로 EA를 작성하는 사람 모두를 위해, TRADE_RETCODE_INVALID_FILL(10030)의 정체·FOK/IOC/RETURN의 의미·30초 만에 가능한 확인법·코드 차원의 근본 대책까지를 한 번에 정리한 결정판입니다. 오류 코드 전반의 목록은 MQL5 / MT5 오류 코드 대처법 종합 가이드를 참조하세요.

이 글은 2026년 7월 시점의 MT5(build 4xxx 계열)를 기준으로 합니다. 화면 명칭·표기는 브로커나 빌드에 따라 다소 다를 수 있습니다.


10030(TRADE_RETCODE_INVALID_FILL)이란

OrderSend()의 결과는 MqlTradeResult.retcode에 담깁니다. 여기에 반환되는 10030 = TRADE_RETCODE_INVALID_FILL은 "요청에서 지정한 type_filling(체결 방식)이 이 심볼에서는 허용되지 않는다"는 서버 측의 거부 통지입니다.

의미: 지정된 체결 방식(filling type)이 지원되지 않음
상수: TRADE_RETCODE_INVALID_FILL
값  : 10030
표시: Unsupported filling mode / Invalid order filling type
// 로그에서 확인할 수 있는 전형적인 출력 예시
2026.07.07 09:15:32.441 EA_NAME EURUSD,M15: OrderSend error 10030
2026.07.07 09:15:32.441 EA_NAME EURUSD,M15: failed market buy 0.10 EURUSD [Unsupported filling mode]

핵심은 자금·로트·가격과는 전혀 무관하다는 점입니다. 10030은 요청 안의 MqlTradeRequest.type_filling 필드 단 하나의 문제이며, 그것만 고치면 동일한 주문이 그대로 통과합니다.

체결 방식(type_filling)의 4가지 종류

MQL5의 ENUM_ORDER_TYPE_FILLING에는 4가지 값이 있습니다.

상수통칭의미
ORDER_FILLING_FOKFill or Kill전량 체결이 가능한 경우에만 실행. 1로트 주문에 0.7로트분 유동성만 있으면 주문 자체가 취소
ORDER_FILLING_IOCImmediate or Cancel체결 가능한 만큼만 즉시 실행하고 나머지는 취소. 0.7로트만 체결되고 0.3로트는 사라짐
ORDER_FILLING_RETURNReturn체결 가능한 만큼 실행하고, 잔량은 주문으로 호가창에 남음(추가 체결을 나중에 대기). 거래소형 체결에서 사용됨
ORDER_FILLING_BOCBook or Cancel호가창에 걸리는(수동적으로 대기하는) 경우에만 접수하고, 즉시 체결되어버리는 가격이면 거부. 지정가/스톱리밋 전용(비교적 새로운 빌드에서 추가)

일반적인 FX용 EA에서 실제로 쓰는 것은 거의 FOK 아니면 IOC입니다. RETURN은 주식·선물 등 거래소 체결(Exchange execution)에서 의미를 가지며, BOC는 메이커 주문을 강제하고 싶은 특수 용도입니다.

왜 "불량"으로 처리되는가 — SYMBOL_FILLING_MODE

어떤 체결 방식을 받아들일지는 브로커가 심볼별로 설정하는 플래그(SYMBOL_FILLING_MODE)로 결정됩니다. MQL5에서는 다음과 같이 읽을 수 있습니다.

long flags = SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);
// SYMBOL_FILLING_FOK 플래그가 켜져 있으면 FOK 가능
// SYMBOL_FILLING_IOC 플래그가 켜져 있으면 IOC 가능

SYMBOL_FILLING_MODE는 비트 플래그이며, FOK와 IOC의 허용 여부가 담깁니다(둘 다 허용이면 양쪽 플래그가 켜짐). RETURN은 이 플래그에 포함되지 않으며, 심볼의 실행 모드(후술)에 따라 사용 가능 여부가 결정됩니다.

즉 10030의 구조는 단순합니다.

EA가 보낸 type_filling ∉ 해당 심볼에서 허용된 체결 방식 → 10030

이것뿐입니다.


왜 하필 "브로커를 바꾼 날"에 발생하는가

10030이 "브로커 이전의 고전적 오류"라 불리는 이유는 다음과 같습니다.

  1. 허용되는 체결 방식은 브로커마다·심볼마다 다릅니다. 어떤 브로커는 FX 심볼에 FOK만 허용하고, 다른 브로커는 IOC만, 또 다른 브로커는 둘 다 허용합니다. 같은 브로커 내에서도 FX와 CFD·주식의 설정이 다른 경우가 흔합니다.
  2. 많은 EA가 type_filling을 하드코딩하고 있습니다. 예를 들어 request.type_filling = ORDER_FILLING_FOK;라고 작성된 EA는 FOK를 허용하는 브로커 A에서는 몇 년이고 문제없이 작동합니다. 제작자의 환경에서는 잘 돌아가기 때문에 버그로 인식되지 못한 채 배포됩니다.
  3. 이전할 브로커 B가 FOK를 허용하지 않으면, 첫 주문부터 전멸합니다. 백테스트에서는 나타나지 않는 경우도 많아서(테스터의 동작은 실제 서버보다 관대함), "실계좌로 옮긴 날"에만 드러납니다.

즉 10030은 EA의 버그라기보다 "환경을 전제로 한 확정 값"이 드러난 것입니다. 반대로 말하면, 심볼의 허용 플래그를 읽어 동적으로 선택하도록 고치면 어떤 브로커에서도 작동하는 EA가 됩니다(코드는 후술).

실행 모드(SYMBOL_TRADE_EXEMODE)와의 관계

심볼에는 체결 방식과 별개로 실행 모드가 있으며, 이것이 어떤 체결 방식이 의미를 갖는지에 영향을 줍니다.

실행 모드상수전형적 예체결 방식 경향
InstantSYMBOL_TRADE_EXECUTION_INSTANT일부 FX(DD 계열에 많음)지정 가격에서의 실행. FOK/IOC + 리퀴트의 세계
MarketSYMBOL_TRADE_EXECUTION_MARKET대다수 FX/CFD(NDD 계열)시장가 실행. FOK 또는 IOC(브로커 설정에 따라 다름)
ExchangeSYMBOL_TRADE_EXECUTION_EXCHANGE주식·선물호가창에 흘리는 실행. RETURN이 기본
RequestSYMBOL_TRADE_EXECUTION_REQUEST레거시요청 실행(현재는 드묾)

정확한 허용 조합은 브로커의 서버 설정에 따라 다르지만, 실무적으로는 "FX/CFD의 Market 실행이면 FOK 또는 IOC, 거래소형이면 RETURN"으로 기억해두면 충분합니다. 실행 모드 역시 SymbolInfoInteger(_Symbol, SYMBOL_TRADE_EXEMODE)로 확인할 수 있습니다.


먼저 30초 만에 가능한 원인 분리

① 심볼의 허용 방식을 확인한다(MT5 화면)

**시세 표시 → 심볼 우클릭 → 사양(Specification)**을 열고 "체결"(Filling) 행을 확인합니다. Fill or Kill / Immediate or Cancel / 둘 다, 와 같이 표시됩니다. 여기에 적혀 있지 않은 방식을 EA가 보내고 있다면 10030 확정입니다.

② EA의 입력 파라미터를 확인한다

잘 만들어진 EA는 FillingType / Filling Mode 같은 입력값을 가지고 있습니다. 있다면, ①에서 확인한 허용 방식에 맞춰 변경하기만 하면 해결됩니다(코드 수정 불필요).

③ 코드로 확인한다(개발자용)

long flags = SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);
PrintFormat("%s filling: FOK=%s IOC=%s exemode=%d",
            _Symbol,
            ((flags & SYMBOL_FILLING_FOK) != 0) ? "yes" : "no",
            ((flags & SYMBOL_FILLING_IOC) != 0) ? "yes" : "no",
            (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_EXEMODE));

이를 스크립트로 실행하면, 해당 브로커·해당 심볼의 실제 허용 상황이 한 줄로 출력됩니다.


근본 대책 — 허용 플래그를 읽어 자동 선택하는 MQL5 코드

10030을 올바르게 고치는 방법은 "이전할 때마다 수동으로 맞추는" 것이 아니라, EA 자신이 심볼의 허용 플래그를 읽어 자동으로 선택하게 하는 것입니다. 아래는 그대로 사용할 수 있는 표준 구현입니다.

자동 판별 함수

// 해당 심볼에서 실제로 허용된 체결 방식을 반환
// 우선순위: FOK → IOC → RETURN(거래소형에 대한 폴백)
ENUM_ORDER_TYPE_FILLING GetFillingMode(const string symbol)
{
   long flags = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);

   if((flags & SYMBOL_FILLING_FOK) != 0)
      return ORDER_FILLING_FOK;    // 전량 체결이 가능할 때만 실행(부분 체결 없음)

   if((flags & SYMBOL_FILLING_IOC) != 0)
      return ORDER_FILLING_IOC;    // 체결 가능한 만큼만 실행, 나머지는 취소

   return ORDER_FILLING_RETURN;    // 플래그 없음 = 거래소형 등. RETURN으로 전송
}

OrderSend에서의 사용법

MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);

req.action       = TRADE_ACTION_DEAL;
req.symbol       = _Symbol;
req.volume       = lots;
req.type         = ORDER_TYPE_BUY;
req.price        = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
req.deviation    = 20;
req.magic        = MagicNumber;
req.type_filling = GetFillingMode(_Symbol);   // ← 하드코딩하지 않는다

if(!OrderSend(req, res) || res.retcode != TRADE_RETCODE_DONE)
{
   if(res.retcode == TRADE_RETCODE_INVALID_FILL)   // 10030
      PrintFormat("Unsupported filling mode: sent=%d, allowed flags=%d",
                  (int)req.type_filling,
                  (int)SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE));
   else
      PrintFormat("OrderSend failed: retcode=%d", res.retcode);
}

이렇게 하면 FOK 전용 브로커에서도 IOC 전용 브로커에서도 동일한 바이너리 그대로 작동합니다. 이전할 때마다 수정할 필요가 없어집니다.

CTrade를 사용하는 경우

표준 라이브러리의 CTrade에는 심볼의 허용 플래그로부터 체결 방식을 자동 설정하는 SetTypeFillingBySymbol()이 마련되어 있습니다.

#include <Trade/Trade.mqh>
CTrade trade;

int OnInit()
{
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetTypeFillingBySymbol(_Symbol);   // 허용 플래그를 읽어 자동 설정
   return INIT_SUCCEEDED;
}

이전 방식인 trade.SetTypeFilling(ORDER_FILLING_FOK);(고정값)가 원인이 되어 10030이 발생하는 EA는 이 한 줄로 교체하는 것만으로 해결됩니다. 수동으로 지정하고 싶은 경우도, 앞서 소개한 GetFillingMode()의 결과를 SetTypeFilling()에 전달하면 같은 효과를 얻습니다.

지정가 주문(BOC)을 사용할 때의 주의점

ORDER_FILLING_BOC(Book or Cancel)는 지정가·스톱리밋 전용이며, 즉시 체결되어버리는 가격을 지정하면 거부됩니다. 시장가 주문에 지정하는 것은 잘못된 사용이므로, 시장가 계열 EA에서 BOC를 선택지에 넣을 필요는 없습니다.


브로커 관련 주의 사항(이전 시 재점검)

  • 체결 방식의 허용 설정은 브로커마다 다를 뿐 아니라, 같은 브로커 안에서도 심볼(종목 그룹)별로 다릅니다. FX는 IOC가 가능해도 주식 CFD는 RETURN만 가능한 구성은 흔합니다.
  • 계좌 유형이나 서버 변경으로도 설정이 바뀔 수 있습니다. 브로커 이전뿐 아니라, 동일 브로커 내에서의 서버 이전·계좌 유형 변경·종목 사양 개정 후에 갑자기 10030이 발생하기 시작하는 경우도 있습니다.
  • 따라서 운용 규칙으로는 **"계좌·서버·심볼 중 무엇이든 바뀌면 사양 화면(또는 스크립트)에서 체결 방식을 재확인한다"**를 습관화하는 것이 확실합니다. 자동 판별 코드를 넣은 EA라면 이 확인 자체가 불필요해집니다.

특정 브로커의 "이 심볼은 FOK만 가능" 같은 정보는 서버 설정 변경으로 금방 오래된 정보가 되므로, 이 글에서는 나열하지 않습니다. 반드시 본인 계좌의 심볼 사양으로 확인하시기 바랍니다.


우선순위 체크리스트

우선순위확인 사항대처
🚨 먼저심볼 사양의 "체결" 항목과 EA의 지정이 일치하는가허용된 방식에 맞춘다
🚨 먼저EA에 FillingType 입력이 있는가입력값 변경만으로 해결(코드 불필요)
⚠️ 다음EA 코드에서 type_filling이 하드코딩되어 있지 않은가GetFillingMode() / SetTypeFillingBySymbol()로 교체
⚠️ 다음브로커 이전·서버 변경·계좌 유형 변경을 했는가변경 후에는 반드시 사양 재확인
✅ 확인실행 모드(Instant/Market/Exchange)의 차이거래소형 종목은 RETURN 전제
🛠 개발10030을 retcode로 개별 처리하고 있는가보낸 방식과 허용 플래그를 로그로 출력

정리

  • Unsupported filling mode(10030 / TRADE_RETCODE_INVALID_FILL)는 주문의 type_filling(FOK / IOC / RETURN / BOC)이 해당 심볼에서 허용되지 않을 때의 서버 거부입니다. 자금이나 로트와는 무관합니다.
  • 허용 방식은 브로커마다·심볼마다 다르기 때문에, type_filling을 하드코딩한 EA는 브로커 이전일에 일제히 10030을 뱉습니다. 이것이 이 오류의 전형적인 패턴입니다.
  • 사용자는 "심볼 사양의 체결 항목 → EA의 입력 변경"으로 즉시 해결할 수 있습니다. 개발자는 SymbolInfoInteger(SYMBOL_FILLING_MODE)의 플래그를 읽어 자동 선택하도록(또는 CTrade::SetTypeFillingBySymbol()) 구현하여 근본적으로 해결할 수 있습니다.

오류 코드 전반은 MQL5 / MT5 오류 코드 대처법 종합 가이드를 참조하세요. FXEA365가 배포하는 EA는 체결 방식 자동 판별을 구현하고 있어, 브로커에 관계없이 작동합니다(EA 목록).


FAQ

Q: 어제까지 작동하던 EA가 브로커를 바꾸자 10030으로 전혀 주문이 들어가지 않습니다. EA 고장인가요?

고장이 아닙니다. EA가 지정하는 체결 방식(예: FOK)을 새 브로커의 해당 심볼이 허용하지 않을 뿐입니다. 심볼 사양의 "체결" 항목을 확인하고, EA의 입력값(FillingType 등)을 맞추거나 코드 쪽을 자동 판별로 고치면 이전처럼 작동합니다.

Q: FOK와 IOC 중 어느 쪽을 사용해야 하나요?

심볼이 둘 다 허용한다면, 동작 차이는 "유동성이 부족할 때" 나타납니다. FOK는 전량 체결이 불가능하면 주문 자체가 취소되고(포지션이 어중간해지지 않음), IOC는 체결된 만큼만 보유합니다(부분 체결이 발생할 수 있음). 개인 FX 거래의 로트 규모에서는 유동성 부족 자체가 드물기 때문에, 실용적으로는 어느 쪽이든 큰 차이는 없습니다. 자동 판별 코드처럼 FOK를 우선하면 문제없습니다.

Q: 백테스트에서는 발생하지 않는데 실계좌에서 10030이 발생합니다.

전략 테스터의 체결 처리는 실제 서버의 설정을 완전히 재현하지 않기 때문에, type_filling의 불일치가 테스트에서는 드러나지 않는 경우가 있습니다. 실계좌·데모 계좌에서 첫 가동 시, 먼저 심볼 사양의 체결 항목과 대조해보세요.

Q: 같은 브로커인데 심볼에 따라 10030이 발생하기도 하고 안 하기도 합니다.

정상적인(있을 수 있는) 동작입니다. 체결 방식의 허용은 심볼 단위 설정이므로, FX 페어는 IOC가 가능하고 주식 CFD는 RETURN만 가능한 것처럼 종목 그룹마다 다릅니다. 멀티 심볼 EA는 반드시 심볼별로 SYMBOL_FILLING_MODE를 읽어야 합니다.

Q: EA의 코드를 고칠 수 없습니다(.ex5만 보유). 어떻게 해야 하나요?

먼저 EA의 입력 파라미터에 FillingType 관련 항목이 없는지 확인하세요. 없다면, 그 EA는 현재 브로커의 해당 심볼에서는 사용할 수 없습니다. 제작자에게 대응을 요청하거나, EA가 전제로 하는 체결 방식을 허용하는 브로커/계좌 유형에서 운용해야 합니다.

📧 가격 인상 사전 알림 + 무료 5일 이메일 강좌

모든 EA는 현재 출시 가격이며 판매 수량에 따라 단계적으로 인상됩니다. 인상 전 사전 알림과 함께 자동매매의 본질, 백테스트 해석법, 브로커 선택 요령을 매일 한 통씩 보내드립니다.

※ 개인정보는 엄격히 보호. 언제든 구독 해지 가능.

댓글 및 질문