거래 전략 "돌이나 도표"는 주식 시장과 포렉스에서 주로 사용되는 고위험 단기 거래 방법에 속합니다. 이 이름은 동전 던지기와 같이 운으로 결정을 내림을 의미하며("돌"은 자산 매수를, "도표"는 자산 판매를 나타냅니다). 이 전략은 직관적인 결정이나 임의적 신호에만 기반하여 시장의 기본적인 요소들을 무시합니다.
코드 저장소에 원본 코드가 추가되었습니다:
MetaTrader 5: https://www.mql5.com/ko/code/11637
#property copyright "Copyright 2025, Trading-Go." // 저작권 설정 #property link "https://www.mql5.com/en/channels/tradingo-go-en" // 개발자 리소스 링크 설정 #property version "26.010" // 프로그램 버전
이 섹션은 컴파일러 지시문으로서 메타트레이더용 엑스페리트 어드바이저(EA)나 인덱터로 작성된 MQL4/MQL5 언어의 프로그램을 위한 것입니다.
각 줄별로 살펴보겠습니다:
1. #property copyright "Copyright 2025, Trading-Go."
이 문구는 소스 코드에 대한 법적 소유권을 설정하는 것입니다. 저작권 정보는 상품의 소유주를 명확히 하고, 메타트레이더 클라이언트 터미널의 속성 창에서 확인됩니다.
2. #property link " "
개발자의 웹사이트 링크를 설정할 수 있습니다. 트레이더가 해당 EA나 인덱터를 사용할 때 이 링크는 속성창을 통해 접근 가능해져 개발자가 제공하는 지원, 문서화, 커뮤니티 등으로 이동할 수 있게 합니다.
3. #property version "26.010"
여기서 프로그램 버전을 설정하고 있습니다. 일반적으로 개발자들은 버전 번호를 XX.XX 형태로 정의하며, 첫 자리는 메이저 버전, 두번째 자리는 마이너 버전, 세번째 자리는 패치 레벨을 나타내는 경우가 많습니다. 이 값은 사용자가 간단히 업데이트 여부를 파악하고 도구간의 호환성 유지를 돕습니다.
#include // Trade.mqh 라이브러리 포함 CTrade trade; // 거래 관리를 위한 CTrade 클래스 객체 #include // PositionInfo.mqh 라이브러리 포함 CPositionInfo posit; // 포지션 처리를 위한 CPositionInfo 클래스 객체
이 부분은 거래 환경 및 포지션 처리를 위해 메타트레이더 플랫폼에서 거래 운영 및 관리에 필요한 라이브러리를 포함하고 객체를 생성하는 부분입니다.
각 섹션을 자세히 살펴보겠습니다:
1. #include
트레이딩 관련 기능을 제공하는 Trade.mqh 라이브러리를 포함합니다. 이 라이브러리는 거래와 관련된 다양한 기능을 제공하며, 포지션 개설, 변경, 삭제 등의 행동을 간편하게 수행할 수 있습니다.
2. CTrade trade;
CTrade 클래스의 객체인 trade를 선언합니다. 이 객체는 모든 거래 관련 작업을 조율하기 위해 사용됩니다.
3. #include
포지션 관련 정보를 처리하는 PositionInfo.mqh 라이브러리를 포함합니다. 이 라이브러리는 현재 포지션에 대한 상세 정보를 추출하고 처리하는 기능을 제공합니다.
4. CPositionInfo posit;
CPositionInfo 클래스의 객체인 posit를 선언합니다. 이 객체는 현재 오픈 된 포지션에 대한 정보를 추출하고 처리하는 데 사용됩니다.
종합적 목적:
이 두 개의 라이브러리는 거래 자동화를 위한 중심 API를 제공하여 개발자가 복잡한 로직 구현에 집중할 수 있도록 서버와의 낮은 수준의 상호 작용을 최소화합니다.
input double iLots = 0.10; // 거래량 입력 변수 (로트 사이즈) input int iTakeProfit = 450; // 이익 실현 수준 (테이크 프롭) input int iStopLoss = 390; // 손실 한계 수준 (스톱 로스) input int iMagicNumber = 227; // 거래 고유번호 (매직 넘버) input int iSlippage = 30; // 최대 슬라이프값 (가격 편차) string sy = ""; // 금융 상품 기호 저장 변수 double pt = 0; // 포인트 계산 단계 변수 int dt = 0; // 소수점 자리수 카운트 변수
아래 코드 블록은 메타트레이더의 자동화된 엑스페리트 어드바이저(EA)에서 거래 환경을 설정하고 이를 준비하는 과정을 보여줍니다. 각 요소를 개별적으로 살펴볼까 합니다:
입력 변수:
1. iLots = 0.10;
이 변수는 거래량(로트 사이즈)을 입력 받습니다. 기본값은 0.10입니다. 이 값은 거래 당 구매 또는 판매할 자산의 양을 조절합니다.
2. iTakeProfit = 450;
이익 실현 수준(Take Profit)을 정의하는 정수형 변수입니다. 기본값은 450입니다. 이 값은 입금 시장 가격에 비해 특정 이익 수준에 도달했을 때 자동으로 포지션을 청산합니다.
3. iStopLoss = 390;
손실 한계 수준(Stop Loss)을 정의하는 정수형 변수입니다. 기본값은 390입니다. 이 값은 시장이 반대 방향으로 움직여 손실이 이 수준에 도달하면 자동으로 포지션을 청산합니다.
4. iMagicNumber = 227;
특정 거래에 고유한 식별자(Magic Number)를 정의하는 정수형 변수입니다. 기본값은 227입니다. 이 번호는 거래를 필터링하고 특정 전략에 의해 수행된 거래를 식별하는 데 사용됩니다.
5. iSlippage = 30;
가격 편차(Slippage)를 제한하는 정수형 변수입니다. 기본값은 30입니다. 이 값은 거래 가격과 실제 가격 사이의 최대 허용 편차를 제한합니다.
지역 변수:
1. sy = "";
금융 상품 기호를 저장하는 문자열 변수입니다. 초기값은 빈 문자열입니다.
2. pt = 0;
포인트 계산 단계를 저장하는 실수형 변수입니다. 초기값은 0입니다.
3. dt = 0;
소수점 자리수를 카운트하는 정수형 변수입니다. 초기값은 0입니다.
이 코드 블록은 메타트레이더의 자동화된 엑스페리트 어드바이저를 구성하고 준비하는 데 필요한 초기 설정을 제공합니다.
sy = _Symbol; // 현재 거래 상품명 설정 pt = _Point; // 최소 단위 변화 크기 설정 dt = _Digits; // 가격 소수점 자리수 설정 trade.SetExpertMagicNumber(iMagicNumber); // 거래 고유번호 설정 trade.SetDeviationInPoints(iSlippage); // 최대 가격 편차 설정 trade.SetTypeFillingBySymbol(sy); // 거래 체결 방식 설정 trade.SetMarginMode(); // 마진 모드 설정
이 코드 블록은 메타트레이더 플랫폼에서 자동화된 엑스페리트 어드바이저(EA)의 초기화 과정을 보여줍니다. 각 명령어를 자세히 살펴볼까 합니다:
환경 변수 설정:
1. sy = _Symbol;
변수 sy에 현재 거래 상품명(_Symbol)을 할당합니다. 이 상품명은 후속 계산 및 작업을 위해 필요합니다.
2. pt = _Point;
변수 pt에 가격의 최소 변화 단위(_Point)를 할당합니다. 이 값은 시장 신호 해석 및 주문 조정에 필요합니다.
3. dt = _Digits;
변수 dt에 가격의 소수점 자리수(_Digits)를 할당합니다. 각 상품은 다른 소수점 자리수를 가지므로 이 값은 올바른 결과 출력을 위해 필요합니다.
거래 객체 설정:
4. trade.SetExpertMagicNumber(iMagicNumber);
모든 거래에 고유한 매직 넘버를 설정합니다. 이 번호는 특정 EA가 수행한 거래를 식별하는 데 사용됩니다.
5. trade.SetDeviationInPoints(iSlippage);
거래 가격과 실제 가격 사이의 최대 편차를 설정합니다. 이 설정은 시장 변동에 대한 보호 기능을 제공합니다.
6. trade.SetTypeFillingBySymbol(sy);
상품의 규칙에 따라 거래 체결 방식을 설정합니다. 일부 상품은 즉시 체결('Market Execution')을 요구하지만 다른 상품은 연기 체결('Instant Execution')을 허용합니다. 이 명령은 상품 규칙에 따라 적절한 체결 방식을 자동 선택합니다.
7. trade.SetMarginMode();
마진 모드를 설정합니다. 마진 모드는 자금 안전을 위한 중요한 설정으로, 자금이 부족하여 포지션이 강제 청산되는 것을 방지합니다.
double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP); // 선택된 상품의 로트 사이즈 변경 단계 조회 if(stepvol > 0.0) // 로트 사이즈 변경 단계가 양수일 경우 lt = stepvol * (MathFloor(iLots / stepvol) - 1); // 로트 사이즈를 단계값으로 내림처리하고 한 단계 감소 //--- double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN); // 선택된 상품의 최소 로트 사이즈 조회 if(lt < minvol) // 조정된 로트 사이즈가 최소값보다 작으면 lt = 0.0; ::MathSrand(GetTickCount()); // 난수 생성기 초기화
이 코드는 거래 환경을 준비하고 로트 사이즈를 교환 규칙에 맞게 조정하는 과정을 보여줍니다. 그 과정을 자세히 살펴볼까 합니다:
단계 1: 로트 사이즈 변경 단계 설정:
double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP);
선택된 상품의 로트 사이즈 변경 단계를 조회합니다. 이 값은 로트 사이즈를 변경할 때 최소 단위를 제공합니다.
단계 2: 양수 검증:
if(stepvol > 0.0)
조회된 단계값이 양수인지 확인합니다. 만약 아니라면 다음 계산은 불필요합니다.
단계 3: 로트 사이즈 조정:
lt = stepvol * (MathFloor(iLots / stepvol) - 1);
입력된 로트 사이즈(iLots)를 단계값으로 내림처리하고 한 단계 감소합니다.
내부 계산 분석:
iLots / stepvol: 입력된 로트 사이즈를 단계값으로 나누어 완전한 단계 수를 계산합니다.
MathFloor(): 소수점 이하를 버려 정수로 내림처리합니다.
-1: 완전한 단계 수에서 하나를 뺏습니다.
* stepvol: 단계값을 곱해 새롭게 조정된 로트 사이즈를 계산합니다.
단계 4: 최소 로트 사이즈 조회:
double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN);
선택된 상품의 최소 로트 사이즈를 조회합니다. 이 값은 교환 규칙에 따라 설정되며, 이 값 이하로 거래할 수 없습니다.
단계 5: 최소 로트 사이즈 검증:
if(lt < minvol)
lt = 0.0;
조정된 로트 사이즈가 최소값보다 작으면 로트 사이즈를 0으로 설정합니다.
단계 6: 난수 생성기 초기화:
::MathSrand(GetTickCount());
난수 생성기를 초기화합니다. 이 함수는 틱 카운트를 기반으로 난수 생성기의 초기값을 설정합니다.
int total = ::PositionsTotal(), b = 0, s = 0; // 전체 포지션 수 및 매수/매도 카운터 double Bid = ::SymbolInfoDouble(sy, SYMBOL_BID); // 현재 매도 가격(Bid) 조회 double Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK); // 현재 매수 가격(Ask) 조회 double new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0; // 새로운 스톱 로스 및 테이크 프롭 수준 if(Bid <= 0 || Ask <= 0) // 가격이 유효하지 않을 경우 return; // 함수 실행 종료
이 코드 블록은 메타트레이더 플랫폼에서 자동화된 엑스페리트 어드바이저(EA)의 거래를 준비하는 과정을 보여줍니다. 각 요소를 자세히 살펴볼까 합니다:
1. 전체 포지션 수 조회:
int total = ::PositionsTotal();
현재 오픈된 포지션의 총 수를 조회합니다. 이 데이터는 포지션 관리 및 최적화를 위해 사용됩니다.
2. 매수/매도 카운터 초기화:
b = 0, s = 0;
매수(b) 및 매도(s) 카운터를 초기화합니다. 이 카운터는 후속 포지션 처리 과정에서 증가됩니다.
3. 현재 가격 조회:
매도 가격(Bid) 및 매수 가격(Ask) 조회:
double Bid = ::SymbolInfoDouble(sy, SYMBOL_BID);
double Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK);
현재 가격을 조회하여 이후의 계산 및 처리에 사용됩니다.
4. 스톱 로스 및 테이크 프롭 수준 설정:
double new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0;
새로운 스톱 로스(new_sl) 및 테이크 프롭(new_tp) 수준을 설정합니다. 기존 스톱 로스(old_sl) 및 테이크 프롭(old_tp) 수준도 함께 설정됩니다.
5. 유효성 검증:
if(Bid <= 0 || Ask <= 0)
return;
가격이 유효하지 않으면 함수를 즉시 종료합니다. 이는 잘못된 가격 정보로 인한 오류를 방지합니다.
for(int i = 0; i < total; i++) // 오픈된 포지션을 순회 if(posit.SelectByIndex(i)) // 포지션을 인덱스로 선택 if(posit.Symbol() == sy) // 상품명이 일치하는지 확인 if(posit.Magic() == iMagicNumber) // 매직 넘버가 일치하는지 확인 { old_sl = ::NormalizeDouble(posit.StopLoss(), dt); // 기존 스톱 로스를 소수점 자리에 맞게 조정 old_tp = ::NormalizeDouble(posit.TakeProfit(), dt); // 기존 테이크 프롭을 소수점 자리에 맞게 조정 if(posit.PositionType() == POSITION_TYPE_BUY) // 매수 포지션인 경우 { new_sl = ::NormalizeDouble(Ask - iStopLoss * pt, dt); // 새로운 스톱 로스 설정 new_tp = ::NormalizeDouble(Ask + iTakeProfit * pt, dt); // 새로운 테이크 프롭 설정 b++; // 매수 카운터 증가 } if(posit.PositionType() == POSITION_TYPE_SELL) // 매도 포지션인 경우 { new_sl = ::NormalizeDouble(Bid + iStopLoss * pt, dt); // 새로운 스톱 로스 설정 new_tp = ::NormalizeDouble(Bid - iTakeProfit * pt, dt); // 새로운 테이크 프롭 설정 s++; // 매도 카운터 증가 } if(old_sl == 0 || old_tp == 0) // 새로운 수준이 기존 수준과 다르면 trade.PositionModify(posit.Ticket(), new_sl, new_tp);// 포지션 수정 }
이 코드 블록은 메타트레이더 플랫폼에서 자동화된 엑스페리트 어드바이저(EA)의 포지션 관리 과정을 보여줍니다. 각 단계를 자세히 살펴볼까 합니다:
1. 포지션 순회:
for(int i = 0; i < total; i++)
오픈된 포지션을 순회합니다. 총 포지션 수(total)만큼 반복문을 실행합니다.
2. 포지션 선택:
if(posit.SelectByIndex(i))
포지션을 인덱스로 선택합니다. 선택된 포지션은 후속 처리에 사용됩니다.
3. 상품명 및 매직 넘버 일치 검증:
if(posit.Symbol() == sy && posit.Magic() == iMagicNumber)
선택된 포지션의 상품명이 일치하고 매직 넘버가 일치하는지 확인합니다. 이 조건이 만족되면 후속 처리가 진행됩니다.
4. 스톱 로스 및 테이크 프롭 조정:
매수 포지션:
if(posit.PositionType() == POSITION_TYPE_BUY)
매수 포지션인 경우 새로운 스톱 로스(new_sl) 및 테이크 프롭(new_tp)을 설정합니다.
매도 포지션:
if(posit.PositionType() == POSITION_TYPE_SELL)
매도 포지션인 경우 새로운 스톱 로스(new_sl) 및 테이크 프롭(new_tp)을 설정합니다.
5. 포지션 수정:
if(old_sl == 0 || old_tp == 0)
trade.PositionModify(posit.Ticket(), new_sl, new_tp);
새로운 스톱 로스 및 테이크 프롭 수준이 기존 수준과 다를 경우 포지션을 수정합니다.
if((b + s) == 0) // 활성 포지션이 없는 경우 if(::MathRand() % 2 == 0) // 거래 방향을 무작위로 선택 { if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY)) // 거래 가능성 검증 if(trade.Buy(lt)) // 매수 포지션 개설 return; // 함수 실행 종료 } else if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL)) // 거래 가능성 검증 if(trade.Sell(lt)) // 매도 포지션 개설 return; // 함수 실행 종료
이 코드 블록은 메타트레이더 플랫폼에서 자동화된 엑스페리트 어드바이저(EA)의 무작위 거래 방향 선택 과정을 보여줍니다. 각 단계를 자세히 살펴볼까 합니다:
1. 활성 포지션 검증:
if((b + s) == 0)
활성 포지션이 없는 경우 무작위 거래 방향을 선택합니다.
2. 거래 방향 무작위 선택:
if(MathRand() % 2 == 0)
무작위로 거래 방향을 선택합니다. MathRand() 함수를 사용하여 0 또는 1을 생성하고, 0일 경우 매수(BUY), 1일 경우 매도(SELL)를 선택합니다.
3. 거래 가능성 검증:
매수 포지션:
if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY))
매수 거래 가능성을 검증합니다. Ask 가격과 함께 거래량을 확인합니다.
매도 포지션:
if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL))
매도 거래 가능성을 검증합니다. Bid 가격과 함께 거래량을 확인합니다.
4. 포지션 개설:
매수 포지션:
if(trade.Buy(lt))
매수 포지션을 개설합니다. 이 과정이 성공적이면 함수를 종료합니다.
매도 포지션:
if(trade.Sell(lt))
매도 포지션을 개설합니다. 이 과정이 성공적이면 함수를 종료합니다.
void OnDeinit(const int reason) // 종료 함수 { }
종료 함수(OnDeinit)는 특별한 정리 작업이 필요하지 않을 때 비워둔 것입니다. 훗날 정리 작업이 필요하게 되면 이곳에 추가할 수 있습니다.