공부방 ›
[강좌] [EA 만들기 4] 첫 EA 코드: 이동평균 크로스 (복사해서 바로 쓰기)
3편에서 정한 규칙을 그대로 코드로 옮겨볼게요. MetaEditor에서 2편에 만든 `MyFirstEA` 내용을 전부 지우고 아래 코드를 붙여넣은 뒤 F7(컴파일)을 누르세요.
#include <Trade/Trade.mqh> // 주문을 쉽게 내주는 도구 불러오기
input int FastMA = 20; // 빠른 이동평균 기간
input int SlowMA = 50; // 느린 이동평균 기간
input double Lots = 0.01; // 주문 수량
input int StopPts = 3000; // 손절 (포인트, 금 2자리 기준 3000 = 30달러)
input int TakePts = 6000; // 익절 (포인트)
input long Magic = 20261103; // 이 EA 주문에 붙는 이름표
CTrade trade;
int hFast, hSlow; // 이동평균 계산기 번호
datetime lastBar = 0; // 마지막으로 확인한 봉 시간
int OnInit()
{
hFast = iMA(_Symbol, _Period, FastMA, 0, MODE_EMA, PRICE_CLOSE);
hSlow = iMA(_Symbol, _Period, SlowMA, 0, MODE_EMA, PRICE_CLOSE);
if(hFast == INVALID_HANDLE || hSlow == INVALID_HANDLE) return INIT_FAILED;
trade.SetExpertMagicNumber(Magic);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
IndicatorRelease(hFast);
IndicatorRelease(hSlow);
}
// 이 EA가 연 포지션이 지금 있는지
bool HasPosition()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(PositionSelectByTicket(t)
&& PositionGetString(POSITION_SYMBOL) == _Symbol
&& PositionGetInteger(POSITION_MAGIC) == Magic) return true;
}
return false;
}
void OnTick()
{
// 1) 새 봉이 생겼을 때만 판단
datetime bar = iTime(_Symbol, _Period, 0);
if(bar == lastBar) return;
lastBar = bar;
// 2) 방금 끝난 봉(1)과 그 전 봉(2)의 이동평균 값 가져오기
double f[], s[];
ArraySetAsSeries(f, true);
ArraySetAsSeries(s, true);
if(CopyBuffer(hFast, 0, 1, 2, f) < 2 || CopyBuffer(hSlow, 0, 1, 2, s) < 2) return;
bool goldenCross = f[1] <= s[1] && f[0] > s[0]; // 아래 → 위로 교차
bool deadCross = f[1] >= s[1] && f[0] < s[0]; // 위 → 아래로 교차
// 3) 이미 포지션이 있으면 쉬기 (한 번에 1개)
if(HasPosition()) return;
// 4) 주문
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(goldenCross)
trade.Buy(Lots, _Symbol, ask,
NormalizeDouble(ask - StopPts * _Point, _Digits),
NormalizeDouble(ask + TakePts * _Point, _Digits), "MA cross");
else if(deadCross)
trade.Sell(Lots, _Symbol, bid,
NormalizeDouble(bid + StopPts * _Point, _Digits),
NormalizeDouble(bid - TakePts * _Point, _Digits), "MA cross");
}줄별로 무슨 뜻인지
- input: EA를 차트에 붙일 때 바꿀 수 있는 설정값이에요. 코드를 안 고치고 숫자만 바꿔 실험할 수 있어요.
- iMA: 이동평균 계산기를 만들어요. OnInit에서 한 번만 만들고 계속 써요.
- CopyBuffer(…, 1, 2, …): 1번 봉(방금 끝난 봉)부터 2개 값을 가져와요. `f[0]`이 방금 끝난 봉, `f[1]`이 그 전 봉이에요.
- Magic: 이 EA가 낸 주문에 붙는 이름표예요. 다른 EA나 손으로 낸 주문과 섞이지 않게 해줘요.
- _Point: 그 종목의 가장 작은 가격 단위예요. 금(소수 2자리)은 0.01이라 3000포인트 = 30달러예요.
확인해 보기
- F7 → `0 errors` 확인
- MT5에서 XAUUSD 15분 차트에 붙이기 (데모 계좌!)
- 아래 도구상자 → 전문가 탭에 에러가 없는지 보기
- 교차가 생기면 주문이 들어가요. 15분봉이라 몇 시간 걸릴 수 있어요.
바로 결과를 보고 싶으면 다음 글들의 전략 테스터를 쓰면 몇 년치를 몇 초 만에 돌려볼 수 있어요. 그 전에 5편에서 수량을 제대로 정하는 법부터 볼게요.

