MT5 "Not enough money"(134/10019) 원인 7가지와 해결 방법
목차
- ERR_NO_MONEY란(134와 10019의 차이)
- ① ERR_NO_MONEY = 134(`GetLastError()`의 런타임 오류)
- ② TRADE_RETCODE_NO_MONEY = 10019(`OrderSend()`의 리턴 코드)
- 우선 30초 만에 할 수 있는 구분
- 원인과 대처(6가지 패턴)
- ① 순수하게 증거금이 부족한 경우
- ② 로트가 너무 큰 경우(잔고 대비)
- ③ 레버리지가 낮거나, 주말·이벤트로 제한된 경우
- ④ 기존 포지션으로 증거금이 구속된 경우
- ⑤ 보너스·크레딧을 증거금에 포함하고 있는 경우
- ⑥ 계좌 유형의 계약 크기 차이(스탠다드 vs 센트/마이크로)
- 브로커별 주의점
- MQL5에서 이 오류를 방지하는 코드(EA 개발자용)
- 주문 전에 필요 증거금을 체크한다
- 로트를 최소·스텝에 맞춰 정규화한다
- OrderSend의 retcode를 반드시 확인한다
- 증거금 유지율에 의한 긴급 정지
- 우선순위 체크리스트
- 정리
- FAQ
- Q: 잔고는 충분한데 ERR_NO_MONEY가 발생합니다. 왜 그런가요?
- Q: 134와 10019는 어떻게 다른가요?
- Q: 백테스트에서는 발생하지 않는데 실전에서 발생합니다.
- Q: 물타기/그리드 EA에서 단수가 깊어지면 ERR_NO_MONEY가 됩니다.
- Q: EA의 코드로 자동 회피할 수 있나요?
- Q: 최소 얼마부터 무리 없이 시작할 수 있나요?
ERR_NO_MONEY(MT5/MQL5) 완전 해결
EA를 운용하다 Expert 탭이나 저널에 ERR_NO_MONEY나 not enough money가 뜨면 "벌써 자금이 부족한가?" 하고 당황하기 쉽지만, 실제로는 잔고에 여유가 있어도 발생하는 오류입니다. 원인은 "자금이 제로"인 경우뿐만 아니라 로트 계산, 레버리지, 기존 포지션에 의한 증거금 구속 등 여러 가지가 있습니다.
이 글은 MT5에서 EA를 사용하는 분과 MQL5로 EA를 작성하는 분 모두를 위해, ERR_NO_MONEY의 정체·6가지 원인·즉시 가능한 대처·브로커별 주의점·코드 단에서의 영구 방지까지를 한 번에 정리한 결정판입니다. 오류 코드 전반의 목록은 MQL5 / MT5 오류 코드 대처법 종합 가이드를 참고하세요.
이 글은 2026년 6월 기준 MT5(build 4xxx대)를 전제로 합니다. 수치·화면 명칭은 브로커나 빌드에 따라 다소 다를 수 있습니다.
ERR_NO_MONEY란(134와 10019의 차이)
MQL5에서 "자금 부족"을 나타내는 값은 어디서 가져왔는지에 따라 두 가지가 있습니다. 이를 혼동하면 원인 규명이 멀어집니다.
① ERR_NO_MONEY = 134(GetLastError()의 런타임 오류)
GetLastError()가 반환하는 런타임 오류 코드입니다. OrderCalcMargin()이나 OrderCalcProfit() 등 계산 계열 함수, 또는 구 스타일 코드에서 "필요 증거금이 자유 증거금을 초과한다"고 판정되었을 때 134가 발생합니다.
의미: 거래 조작에 필요한 자금이 부족함(not enough money)
상수: ERR_NO_MONEY
값 : 134
② TRADE_RETCODE_NO_MONEY = 10019(OrderSend()의 리턴 코드)
MQL5에서 실제로 주문을 넣는 OrderSend()의 결과는 MqlTradeResult.retcode에 담깁니다. 주문이 서버에 거부되었을 때의 "자금 부족"은 134가 아니라 **10019(TRADE_RETCODE_NO_MONEY)**입니다. 이는 MT5 측 오류가 아니라 브로커 서버로부터의 거부 통지입니다.
의미: 주문 실행에 충분한 자금이 없음(There is not enough money to complete the request)
상수: TRADE_RETCODE_NO_MONEY
값 : 10019
// 로그에서 확인할 수 있는 전형적인 출력 예시
2026.06.12 09:15:32.441 EA_NAME XAUUSD,H1: OrderSend error 10019
실무상 구분법:
| 획득 위치 | 값 | 발생 상황 |
|---|---|---|
GetLastError() | 134 (ERR_NO_MONEY) | OrderCalcMargin 등의 계산, 내부 체크 |
MqlTradeResult.retcode | 10019 (TRADE_RETCODE_NO_MONEY) | OrderSend가 서버에 거부됨 |
CTrade.ResultRetcode() | 10019 | CTrade 경유 주문 거부 |
로그에 "134"가 나오면 계산/내부 체크 단계, "10019"나 Expert 탭의 not enough money라면 서버 거부 단계로 구분할 수 있습니다. 어느 쪽이든 근본 원인은 동일(필요 증거금 > 사용 가능 증거금)하므로 대처법은 공통입니다.
우선 30초 만에 할 수 있는 구분
MT5의 "툴박스 → 거래" 탭에서 다음 세 가지를 확인하세요.
잔고(Balance) : 계좌의 현금
유효 증거금(Equity) : 잔고 ± 미실현 손익
여유 증거금(Free Margin): 지금 신규로 사용 가능한 증거금 ← 이것이 핵심
증거금 유지율(Margin Level %): Equity / Margin × 100
- 여유 증거금(Free Margin)이 앞으로 진입할 1포지션의 필요 증거금보다 작다 → 100% ERR_NO_MONEY가 발생합니다.
- 잔고는 충분한데도 발생한다면 후술할 "②로트 과대", "④기존 포지션에 의한 증거금 구속", "⑥계좌 유형 차이" 중 하나입니다.
1포지션의 필요 증거금은 MT5의 "호가 → 심볼 우클릭 → 사양"에서 확인할 수 있습니다(1로트의 증거금). 대략적인 계산식은 다음과 같습니다.
필요 증거금 ≈ (로트 × 계약 크기 × 가격) / 레버리지
원인과 대처(6가지 패턴)
① 순수하게 증거금이 부족한 경우
증상: 미실현 손실이 커져 Free Margin이 신규 진입분을 밑돌았다. 연패 후나 물타기 단수가 깊을 때 많이 발생.
대처:
- 추가 입금하거나
- 보유 포지션 일부를 수동 청산해 증거금을 회수
- EA 측의
RiskPercent를 낮춰 이후 로트를 작게 설정
이 패턴이 반복해서 발생하는 EA는 애초에 로트가 자금 대비 과대한 상태입니다. ②로 이동.
② 로트가 너무 큰 경우(잔고 대비)
증상: 잔고는 있는데 첫 번째 진입부터 ERR_NO_MONEY. 고정 로트 운용에서 흔함.
원인: FixedLot이 계좌 잔고·레버리지에 맞지 않음. 예를 들어 10만 엔(≈$670) 계좌로 XAUUSD를 0.1로트 진입하려 하면 레버리지에 따라 필요 증거금이 잔고를 초과합니다.
대처:
- 고정 로트를 최소(0.01)로 낮춰 진입 가능한지 확인
- 리스크% 자동 계산(
UseFixedLot=false/RiskPercent)으로 전환 - 그래도 0.01조차 진입할 수 없다면 계좌의 레버리지나 자금이 부족한 것 → ③·⑥으로 이동
기준: 10만 엔(≈$670) 스탠다드 계좌에서 최소 로트 0.01부터 시작할 수 있는 설계가 무리 없는 기준입니다. 이보다 적은 자금이거나 더 안전하게 소액으로 운용하고 싶다면 다음의 "마이크로(센트) 계좌"를 검토하세요.
③ 레버리지가 낮거나, 주말·이벤트로 제한된 경우
증상: 동일한 EA·동일한 로트가 다른 계좌에서는 진입되는데 이 계좌에서만 ERR_NO_MONEY. 또는 오류가 금요일 저녁~월요일 아침에 집중된다.
원인: 계좌의 레버리지가 낮으면(예: 1:30의 EU 규제 계좌 vs 1:1000의 해외 계좌) 필요 증거금이 수십 배 달라집니다. 게다가 브로커가 주말·주요 지표 전후로 레버리지를 낮추는 경우가 있어(XM은 주말에 레버리지를 200:1로 제한하는 방식), 포지션 보유 중 필요 증거금이 갑자기 늘어나 발생합니다. 골드나 암호화폐는 심볼 단위로 레버리지 상한이 별도로 설정된 경우도 있습니다.
대처:
- 계좌의 레버리지를 확인(브로커의 마이페이지/MT5 계좌 정보)
- 심볼 사양의 "증거금율"을 확인(종목별로 낮은 경우 있음)
- 주말을 넘기지 않는 설정(
CloseAllBeforeWeekend=true등)을 사용하거나, 주말 레버리지 제한이 없는 브로커로 변경 - 고레버리지 계좌로 전환하거나 로트를 낮춤
④ 기존 포지션으로 증거금이 구속된 경우
증상: 첫 번째는 진입되었지만 두 번째 이후나 추가 진입(물타기)에서 ERR_NO_MONEY.
원인: 이미 보유 중인 포지션이 증거금을 구속해 Free Margin이 신규 진입분을 밑돈 상태. 여러 통화쌍·여러 EA를 한 계좌에서 운용하면 발생하기 쉽습니다.
대처:
- "거래" 탭에서 사용 중 증거금(Margin)과 Free Margin을 확인
- EA끼리 같은 계좌에서 증거금을 서로 잠식하고 있지 않은지(복수 EA 운용 시)
- 동시 포지션 수 상한을 EA 파라미터로 제한
- 물타기/그리드 EA는 단수가 깊을수록 증거금을 급격히 소모함 → 단수 상한·로트 배율·긴급 청산 설정을 재검토
⑤ 보너스·크레딧을 증거금에 포함하고 있는 경우
증상: "잔고 + 보너스"로는 충분할 텐데 ERR_NO_MONEY가 발생.
원인: 브로커에 따라 크레딧(보너스)이 증거금 계산에 포함되지 않거나 일부만 포함되는 경우가 있습니다. 표시 잔고와 서버가 사용하는 증거금이 어긋납니다.
대처: 브로커의 보너스 규약에서 "크레딧이 증거금에 산입되는지"를 확인. 산입되지 않는다면 실입금분만으로 필요 증거금을 충족하는 로트로 낮춥니다.
⑥ 계좌 유형의 계약 크기 차이(스탠다드 vs 센트/마이크로)
증상: 동일한 "0.01로트"인데 계좌를 바꾸니 갑자기 ERR_NO_MONEY. 혹은 반대로 과대 로트가 됨.
원인: 센트(마이크로) 계좌와 스탠다드 계좌는 계약 크기가 약 100배 다릅니다. 센트 계좌의 0.01은 실제 익스포저가 약 1/100입니다. EA가 계좌 유형을 구분하지 않고 고정 로트를 사용하면 한쪽에서 증거금 부족이 발생합니다.
대처:
- 소액·안전 운용이라면 센트/마이크로 계좌를 사용해 최소 로트로도 과대 리스크가 되지 않도록 함
- EA는 계좌 유형을 하드코딩하지 말고
OrderCalcMargin()으로 실제 필요 증거금을 확인해 로트를 결정하는 설계로 만듦(다음 장)
브로커별 주의점
| 브로커 | 특징 | ERR_NO_MONEY 빈도 |
|---|---|---|
| XM | 주말 레버리지 제한 있음·Stop Out 20% | 중(주말은 높은 편) |
| Exness | 무제한 레버리지 계좌 있음·Stop Out 0% | 낮음 |
| HFM / FXGT 등 | 고레버리지 계좌 있음 | 낮음 |
Exness의 무제한 레버리지 계좌(Pro/Raw Spread 계좌)는 여유 증거금이 사실상 제로여도 신규 주문이 통과되는 경우가 많아 이 오류가 잘 발생하지 않습니다. 물타기 계열 EA와 궁합이 좋은 반면, 스탑아웃이 잘 작동하지 않아 손실이 커지기 쉬운 반대급부의 리스크가 있다는 점에 주의하세요. 브로커 비교는 브로커 비교 페이지도 참고하세요.
MQL5에서 이 오류를 방지하는 코드(EA 개발자용)
"고치는" 것뿐만 아니라, 애초에 ERR_NO_MONEY를 주문 전에 차단하는 것이 EA의 올바른 설계입니다. 핵심은 "주문하기 전에 필요 증거금을 계산하고, 부족하면 진입하지 않거나 로트를 줄이는" 것입니다.
주문 전에 필요 증거금을 체크한다
// 주문 전 게이트: 필요 증거금 <= 여유 증거금을 확인한 후 OrderSend 실행
bool HasEnoughMargin(ENUM_ORDER_TYPE type, double lots)
{
double price = (type == ORDER_TYPE_BUY)
? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
: SymbolInfoDouble(_Symbol, SYMBOL_BID);
double margin = 0.0;
if(!OrderCalcMargin(type, _Symbol, lots, price, margin))
{
Print("OrderCalcMargin failed: ", GetLastError()); // 134 등
return false;
}
double freeMargin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
if(margin > freeMargin)
{
PrintFormat("Skip: need %.2f > free %.2f (ERR_NO_MONEY guard)", margin, freeMargin);
return false; // 진입하지 않음 = ERR_NO_MONEY를 미연에 방지
}
return true;
}
로트를 최소·스텝에 맞춰 정규화한다
리스크%로 계산한 값을 그대로 전송하면 최소 로트·로트 스텝에 맞지 않아 거부됩니다(정규화 누락은 주문 거부의 전형적인 원인). 진입할 수 없는 경우 포기하지 말고 진입 가능한 범위로 줄이면 기회 손실을 줄일 수 있습니다.
double NormalizeLot(double lots)
{
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lots = MathFloor(lots / step) * step; // 스텝에 맞춰 반올림
lots = MathMax(minLot, MathMin(maxLot, lots)); // 최소~최대로 클램프
return NormalizeDouble(lots, 2);
}
OrderSend의 retcode를 반드시 확인한다
OrderSend()의 반환값(bool)뿐만 아니라 result.retcode를 확인해 10019(TRADE_RETCODE_NO_MONEY)를 개별적으로 처리합니다.
MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);
// ... req 구성 ...
if(!OrderSend(req, res) || res.retcode != TRADE_RETCODE_DONE)
{
if(res.retcode == TRADE_RETCODE_NO_MONEY) // 10019
Print("Not enough money. 로트를 줄이거나 입금이 필요합니다.");
else
PrintFormat("OrderSend failed: retcode=%d, lastError=%d", res.retcode, GetLastError());
}
CTrade를 사용하는 경우 trade.ResultRetcode()가 10019인지, trade.ResultRetcodeDescription()으로 확인할 수 있습니다.
증거금 유지율에 의한 긴급 정지
유지율이 일정 %를 밑돌면 신규 진입을 중단하거나 전량 청산하는 안전장치를 넣어두면 ERR_NO_MONEY의 연발과 계좌 파산 양쪽을 모두 방지할 수 있습니다.
double level = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL); // 유지율%
if(level > 0 && level < EmergencyMarginLevel) // 예: 150%
{
// 신규 진입을 중단한다 / 필요하면 보유분을 일부 청산한다
}
FXEA365가 배포하는 EA는 이 "리스크% 자동 로트"·"주문 전 증거금 체크"·"증거금 유지율에 의한 긴급 정지(UseMarginEmergencyClose)"를 표준으로 구현하고 있어, 최소 자금으로도 무리 없이 운용할 수 있습니다.
우선순위 체크리스트
| 우선순위 | 확인 | 대처 |
|---|---|---|
| 🚨 먼저 | 여유 증거금 < 필요 증거금인지 | 입금 또는 일부 청산 또는 로트↓ |
| 🚨 먼저 | 고정 로트가 잔고 대비 과대한지 | 0.01로 변경 / 리스크% 자동으로 전환 |
| ⚠️ 다음 | 계좌 레버리지가 낮거나 주말 제한이 있는지 | 고레버리지 계좌 / 주말 청산 / 로트↓ |
| ⚠️ 다음 | 기존 포지션·다른 EA로 증거금이 구속되었는지 | 동일 계좌의 보유 포지션 정리 |
| ✅ 확인 | 센트/스탠다드의 계약 크기 차이 | 계좌 유형에 맞는 로트로 조정 |
| 🛠 개발 | 주문 전 OrderCalcMargin으로 방어 | 위 코드 구현 |
정리
ERR_NO_MONEY는 **134(GetLastError)**와 **10019(OrderSend의 retcode = TRADE_RETCODE_NO_MONEY)**라는 두 가지 얼굴을 가지지만, 근본은 "필요 증거금 > 사용 가능 증거금"으로 공통됩니다.- 잔고가 있어도 로트 과대·낮은 레버리지(주말 제한 포함)·기존 포지션의 증거금 구속·계좌 유형 차이로 발생합니다.
- EA 운용자는 "리스크% 자동 로트"·"적절한 계좌 유형"으로 예방하고, EA 개발자는 "주문 전
OrderCalcMargin게이트"·"로트 정규화"·"retcode 10019 처리"로 영구 대책을 마련합니다.
오류 코드 전반은 MQL5 / MT5 오류 코드 대처법 종합 가이드를, 무리 없는 자금 설정으로 운용 가능한 무료 EA는 EA 목록을 참고하세요. 저희 사이트의 EA를 사용 중이며 설정 변경으로도 해결되지 않는 경우, 지원 폼에서 계좌의 증거금 상황 스크린샷을 첨부해 문의해 주세요.
FAQ
Q: 잔고는 충분한데 ERR_NO_MONEY가 발생합니다. 왜 그런가요?
잔고(Balance)가 아니라 **여유 증거금(Free Margin)**으로 판정되기 때문입니다. 미실현 손실이나 기존 포지션의 증거금 구속으로 Free Margin이 줄어들면 잔고가 있어도 신규 진입을 할 수 없습니다. "거래" 탭의 Free Margin을 확인하세요.
Q: 134와 10019는 어떻게 다른가요?
134(ERR_NO_MONEY)는 GetLastError()가 반환하는 런타임 오류이고, 10019(TRADE_RETCODE_NO_MONEY)는 OrderSend()의 결과(retcode)입니다. 발생 위치가 다를 뿐 원인(자금 부족)은 동일합니다.
Q: 백테스트에서는 발생하지 않는데 실전에서 발생합니다.
실전 계좌의 레버리지·계좌 유형(센트/스탠다드)·기존 포지션이 테스트 설정과 다르기 때문입니다. 특히 레버리지 차이와 계약 크기 차이가 크게 영향을 미칩니다.
Q: 물타기/그리드 EA에서 단수가 깊어지면 ERR_NO_MONEY가 됩니다.
정상적인 거동의 바로 직전 단계입니다. 단수가 늘어날수록 증거금 소모가 가속됩니다. 단수 상한·로트 배율을 낮추고 UseMarginEmergencyClose 등의 긴급 청산을 반드시 활성화하며, 잃어도 문제없는 자금으로 운용하세요.
Q: EA의 코드로 자동 회피할 수 있나요?
가능합니다. 주문 전에 OrderCalcMargin()으로 필요 증거금을 계산하고, AccountInfoDouble(ACCOUNT_MARGIN_FREE)를 초과하면 진입하지 않거나(또는 로트를 줄이는) 게이트를 넣습니다. 본문의 코드 예시를 참고하세요.
Q: 최소 얼마부터 무리 없이 시작할 수 있나요?
10만 엔(≈$670) 스탠다드 계좌에서 최소 로트 0.01부터가 무리 없는 기준입니다. 그보다 소액이거나 더 안전하게 운용하고 싶다면 센트(마이크로) 계좌를 사용하면 최소 로트로도 실제 익스포저가 작아져 ERR_NO_MONEY를 피하기 쉬워집니다.
관련 기사
📧 가격 인상 사전 알림 + 무료 5일 이메일 강좌
모든 EA는 현재 출시 가격이며 판매 수량에 따라 단계적으로 인상됩니다. 인상 전 사전 알림과 함께 자동매매의 본질, 백테스트 해석법, 브로커 선택 요령을 매일 한 통씩 보내드립니다.
※ 개인정보는 엄격히 보호. 언제든 구독 해지 가능.