English
中文
日本語
ID
Vietnam
한국어
Filipino
 
   대학 내비게이션

Forex MQL4 지능형 거래 시스템 예

MQL4 Expert Advisor Example

거래 EA를 프로그래밍하는 데 도움이 되는 완전한 MQL4 Expert Advisor 예제 기사에서 완전한 기능을 갖춘 MA Expert Advisor를 작성하는 방법을 알아보세요.


Expert Advisors 구성을 논의하는 몇 가지 매뉴얼과 가이드에서는 이동 평균 교차(MACross)를 예로 사용하는 경향이 있습니다. 그 이유는 현재 가장 인기 있는 지표 기반 전략이며, 대부분의 사람들에게 이미 익숙한 거래 개념을 사용하여 새로운 코딩 개념을 가르치는 것이 훨씬 쉽기 때문입니다.


이 익숙한 경로를 따라 간단한 이동 크로스오버(20-200)를 기반으로 한 기본 전문 조언자를 제출했습니다.


// 섹션 1:

// 전처리기 지시어, 외부 및 내부 변수

#property copyright “Copyright © 2008-2010, Excel Markets”
#property link “/article/”

extern string EAName = “MACross”;
extern double MagicNumber = 59483;

extern double Lots =0.1;
extern double LotDigits =2;
extern int Slippage = 5;

extern double StopLoss = 80;
extern double TakeProfit =0;

extern bool OppositeClose = true;
extern bool EnterOpenBar = true;

extern int FastMATime = 0;
extern int FastMAPeriod = 2;
extern int FastMAType = 0; //0:SMA 1:EMA 2:SMMA 3:LWMA
extern int FastMAPrice = 0;
extern int FastMAShift = 0;
extern int SlowMATime = 0;
extern int SlowMAPeriod = 30;
extern int SlowMAType = 1; //0:SMA 1:EMA 2:SMMA 3:LWMA
extern int SlowMAPrice = 0;
extern int SlowMAShift = 0;

// Global Variables

int Counter, vSlippage;
double ticket, number, vPoint;

double
FastMACurrent,
FastMAPrevious,
SlowMACurrent,
SlowMAPrevious;

// Section 2: Initialization

int init(){

if(Digits==3 || Digits==5)
{ vPoint=Point*10; vSlippage=Slippage*10; }
else{ vPoint=Point; vSlippage=Slippage; }

return(0); }

//——————————————————-
// Section 3: Start

int start()
{

if(Bars<100) { Print(“Bars less than 100”);
return(0); }

//——————————————————–
// Section 3A: Define ShortCuts to Common Functions

int Total, OType=-1, Ticket;
double Price, SL, TP, Lot;
bool CloseBuy=false, CloseSell=false, OpenBuy=false, OpenSell=false;

for(int Counter=1; Counter<=OrdersTotal(); Counter++)
{
if (OrderSelect(Counter-1,SELECT_BY_POS)==true)
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)

{
Ticket=OrderTicket();
OType =OrderType();
Price =OrderOpenPrice();
SL =OrderStopLoss();
TP =OrderTakeProfit();
Lot =OrderLots();
}
}
//—————————————————-
// Section 3B: Indicator Calling

int Current = 0;

FastMACurrent = iMA(NULL, FastMATime, FastMAPeriod, FastMAShift, FastMAType, FastMAPrice, Current + 0);

FastMAPrevious = iMA(NULL, FastMATime, FastMAPeriod, FastMAShift, FastMAType, FastMAPrice, Current + 1);

SlowMACurrent = iMA(NULL, SlowMATime, SlowMAPeriod, SlowMAShift, SlowMAType, SlowMAPrice, Current + 0);

SlowMAPrevious = iMA(NULL, SlowMATime, SlowMAPeriod, SlowMAShift, SlowMAType, SlowMAPrice, Current + 1);

//————————————————
// Section 3C: Entry Conditions

bool OpenBar=true;
if(EnterOpenBar) if(iVolume(NULL,0,0)>1) OpenBar=false;

if (FastMACurrent > SlowMACurrent&& FastMAPrevious < SlowMAPrevious
&& OpenBar){
OpenBuy=true;
if (OppositeClose) CloseSell=true;
}

if (FastMACurrent<slowmacurrent&&amp> < SlowMACurrent&& FastMAPrevious > SlowMAPrevious
&& OpenBar){
OpenSell=true;
if (OppositeClose) CloseBuy=true;
}
//————————————————-
// Section 3D: Close Conditions

while(true)
{
if (OType==0 && CloseBuy==true)
{
close (OP_BUY); // Close Buy
return;
}

if (OType==1 && CloseSell==true)
{
close (OP_SELL); // Close Sell
return;
}
break;
}
//————————————————–
// Section 3E: Order Placement

while(true)

{
if (OrdersTotalMagicOpen()==0 && OpenBuy==true)
{

if(StopLoss>0){SL=Bid – StopLoss*vPoint;}else{SL=0;} if(TakeProfit>0){TP=Bid+TakeProfit*vPoint;}else{TP=0;}
ticket=0;number=0;
while(ticket<=0 && number<100){
RefreshRates();
ticket = OrderSend(Symbol(),OP_BUY,NormalizeDouble(Lots,LotDigits), Ask,vSlippage,SL,TP,EAName, MagicNumber, 0, Green);
return (ticket);
}}

if (OrdersTotalMagicOpen()==0 && OpenSell==true)
{
if(StopLoss>0){SL=Ask + StopLoss*vPoint;}else{SL=0;} if(TakeProfit>0){TP=Ask-TakeProfit*vPoint;}else{TP=0;}
ticket=0;number=0;
while(ticket<=0 && number<100){
RefreshRates();
ticket= OrderSend(Symbol(),OP_SELL, NormalizeDouble(Lots,LotDigits), Bid,vSlippage,SL,TP, EAName, MagicNumber, 0, Red);
return (ticket);
}}
break;
}
//———————————————————
return; // End of start()
}

// Section 4A: Close Function

void close(int type){
if(OrdersTotal()>0){
for(Counter=OrdersTotal()-1;Counter>=0;Counter–){
OrderSelect(Counter,SELECT_BY_POS,MODE_TRADES);

if(type==OP_BUY && OrderType()==OP_BUY){
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) {
RefreshRates();
OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits), vSlippage);
} }

if(type==OP_SELL && OrderType()==OP_SELL){
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) {
RefreshRates(); OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),vSlippage);
}}
}}}

// Section 4B: OrdersTotalMagicOpen Function

int OrdersTotalMagicOpen() {
int l_count_0 = 0;
for (int l_pos_4 = OrdersTotal() – 1; l_pos_4 >= 0; l_pos_4–) {
OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
if (OrderType() == OP_SELL || OrderType() == OP_BUY) l_count_0++;
}
return (l_count_0);
}
</slowmacurrent&&amp>

이전에 프로그래밍 경험이 없다면 위의 코드가 다소 신비스럽고 위협적으로 보일 수 있습니다. 위협 요인을 극복하는 한 가지 방법은 작은 세부 사항에 대해 덜 걱정하고 큰 그림에 집중하는 것입니다.


언어의 모든 부분이 어떻게 작동하는지 알아내거나 프로세서 수준에서 뒤에서 무슨 일이 벌어지고 있는지 궁금해하지 마세요. 일하고 있습니다. 언어의 세부사항과 형식에 집착할 필요가 없습니다. EA를 이해하고 구축하기 위해 특정 세부 사항에 주의를 기울일 필요는 없습니다. 이 시점에서는 퍼즐 조각이 어떻게 맞춰지는지, 가장 중요한 조각 중 어떤 조각을 조작하여 새로운 전략을 만들 수 있는지만 알면 됩니다.


저는 당신이 퍼즐 조각을 맞추고 가장 중요한 조각의 방향을 알려줄 수 있도록 도와드리겠습니다. 각 섹션을 안내할 때 상호 참조하기 쉽도록 EA의 각 섹션에 번호를 매기고 레이블을 지정했습니다.

섹션 1: 전처리기 지시문, 외부 및 내부 변수

먼저 몇 가지 설명입니다. // 뒤에 포함된 몇 가지 설명을 볼 수 있습니다.


/로 시작하는 모든 줄은 자유 텍스트이며 프로그램에서 무시됩니다.


컴퓨터가 무시하더라도 프로그래밍 명령문의 의미를 일반 영어로 설명하는 데 도움이 되는 주석을 포함합니다. 네, 프로그래밍 언어는 언뜻 이해하기 어려울 수 있으며, 코드를 작성할 때 주석을 추가하면 생활이 더 편해지는 데 유용할 수 있습니다.


다음으로 전처리기 지시문에 대해 이야기해 보겠습니다. 각 명령은 파운드 기호(#)로 시작됩니다. #import 및 #include와 같은 고급 형태의 지시문이 많이 있지만 우리는 그 중 가장 간단한 것, 즉 코드를 우리 코드로 식별하는 #property 저작권 전처리기 지시문만 사용하겠습니다. 그 외에는 그다지 중요하지도 않고 특별할 것도 없습니다.


다음은 외부 변수입니다. 매우 중요합니다. 이전 기사에서 변수가 나중에 사용하기 위해 물건을 저장할 수 있는 작은 상자와 같다는 점을 설명했습니다. 외부 변수(extern이라는 단어 앞에 오는)는 사용자가 쉽게 조작할 수 있도록 전문가 대화 상자의 프로그램 외부에 해당 매개변수를 표시하므로 중요합니다.


위의 기본 EA에서 볼 수 있는 많은 외부 변수는 설명이 필요하지 않습니다. 나중에 OrderSend 함수의 구문을 배울 때 EAName, MagicNumber, Lotssize, TakeProfit 및 Stoploss에 대해 논의하겠습니다. 섹션 3E, OrderPlacement를 참조하세요. 이러한 변수는 주로 해당 기능을 참조합니다.


이 섹션에서 흥미로운 외부 변수는 이동 평균 매개변수 변수(특히 MAPeriod), OppositeClose 및 EnterOpenBar입니다.

移动平均参数变量。

참고로 이동평균 매개변수 값은 모두 외부변수로 두었습니다. 이런 일을 할 필요는 없어요. 섹션 3B "인디케이터 호출"에서 호출할 때 가장 중요한 변수 MAPeriod만 외부 변수로 만들고 나머지 매개변수는 인디케이터 내에서 기본값으로 둘 수 있었습니다. 나중에 매개변수를 최적화하려는 경우를 대비해 거의 모든 매개변수를 외부 변수로 선언했습니다. 지금은 MAPeriod만 최적화할 것입니다. 하지만 다른 것들도 최적화하면 나중에 유용할 수 있습니다. 섹션 3B "지표 호출"을 다룰 때 이러한 매개변수에 대해 자세히 논의할 것입니다.

나의 True/False Bool(Boolean) 변수: OppositeClose 및 EnterOpenBar

변수에 bool이 표시되면 true 값에 사용되는 유형입니다. bool 유형은 논리 미적분학 창시자의 성(姓)인 Boolean에서 유래되었습니다. bool OppositeClose를 확인해 보겠습니다.


외부 부울 OpositeClose=True


이 변수의 외부 부울을 사용하면 다음을 열고 반대 닫기 조건을 닫습니다. 코드에서 reverseclose가 참조될 때마다 기본값은 true로 설정됩니다. 즉, 해당 항목이 열리길 원한다는 뜻입니다. false로 설정하면 꺼집니다. 또는 true 또는 false를 사용하는 대신 false에는 0을, true에는 1을 사용할 수 있습니다.


OppositeClose bool은 반대 신호에 따라 주문을 청산할 수 있다는 아이디어를 의미합니다. 무슨 뜻이에요? true로 설정하고 현재 매수 포지션에 있고 매도 진입 주문이 실행되면 매도 진입 주문은 매도 거래를 하기 전에 현재 매수 포지션을 청산합니다. 매도 진입 신호는 현재 매수 포지션을 청산하는 반대 신호입니다(그 반대도 마찬가지). 나는 확실히 활성화되기를 원하기 때문에 true에 반대쪽에 가깝습니다. 거짓을 선택하면, 즉 반대쪽 청산을 비활성화하면 매도 진입 신호는 이전 매수 거래를 청산하지 않으며 매수 거래는 손절매나 이익실현을 눌러 청산될 때까지 열린 상태로 유지됩니다. 보통은 reverseclose를 true로 설정하고 활성화하는 것이 좋습니다. 섹션 3D "닫기 조건"에서 reverseclose의 인코딩에 대해 논의하고 섹션 4A "닫기 함수"에서 찾을 수 있는 관련 함수를 논의합니다.


EnterOpenBar bool은 인터바나 마감이 아닌 각 새 바의 개시 시에만 거래를 입력한다는 아이디어를 나타냅니다. 지표를 기반으로 새로운 전략을 만들 때 저는 전략이 어떻게 백테스트되고 있는지 빠르게 확인하기 위해 EnterOpenBar를 true로 기본 설정하는 것을 선호합니다. strategytester의 드롭다운 메뉴에는 모든 틱, 제어점, 공개 틱의 세 가지 유형의 백테스팅 모드가 있습니다. 각 틱은 다른 틱보다 더 정확하지만 느립니다. 시가는 다른 가격에 비해 정확도는 떨어지지만 빠릅니다. 제어점은 정확성과 속도 모두에서 둘 사이의 어딘가에 있습니다. 그러나 EnterOpenBar가 true로 설정되면 공개 가격 전용 모드에서 안전하게 백테스트할 수 있으므로 백테스트 속도가 크게 높아지면서 모든 틱 모드와 매우 유사한 정확도와 결과를 얻을 수 있습니다. 백테스트 속도 외에도 enteronopenbar를 true로 설정하면 특히 공통 메트릭을 기반으로 하는 경우 시스템의 전반적인 성능과 안정성이 향상된다는 점도 확인했습니다. 결과의 차이를 확인하려면 enteronopenbar를 true 및 false로 설정해 보시기 바랍니다. EnterOpenBar 뒤에 있는 코딩은 섹션 3C, "입력 논리"에서 찾을 수 있습니다.


마지막으로 이 섹션에서는



과 같은 일부 내부 변수(전역 변수라고도 함)를 선언합니다. p>

복권, 번호, vPoint;


각 식별자에 대해 구체적인 값을 선언하지 않았음을 참고하시기 바랍니다. 값이 선언되지 않으면 각 식별자의 기본값은 0이며 나중에 결정됩니다. 판정이 완료되면 0으로 되돌아갑니다. 또한 세미콜론으로 명령문을 끝낼 때까지 이중 뒤에 식별자를 쉼표로 구분하여 하나씩 나열한다는 점에 유의하세요. 이는 그 중 어느 것도 전역적으로 다른 값을 가지지 않기 때문에 수행될 수 있습니다. 여기 대신 start() 함수에서 이를 선언할 수도 있지만 이 섹션에 선언하면 내 코드의 모든 함수에서 전역적으로 참조할 수 있습니다. 이는 매우 편리하며 불필요한 중복을 방지합니다.

팁!

특정 식별자를 발견하고 그것이 참조하는 코드 부분을 확인하기 어려울 때마다 빠른 방법이 있다는 것을 기억하세요. 일치하는 항목을 찾으세요. 식별자(예: ExpertName)를 복사하여 조회 필드(Cnt+F)에 붙여넣기만 하면 코드의 다른 곳에 있는 일치하는 식별자로 빠르게 이동할 수 있습니다. 단어를 가지고 ISPY를 플레이하는 것을 좋아하지 않는 한, 코드의 다른 부분을 일치시키기 위해 이 작업을 자주 수행하게 될 것입니다.

파트 2: 초기화

보시다시피 이 섹션에는 많은 내용이 없습니다.


이 섹션에 포함된 코드는 브로커의 통화 번호를 기준으로 pip 값을 설정하는 데 사용됩니다(브로커는 4자리 또는 5자리 견적 시스템으로 설정됨):

if(Digits== 3 | | 숫자==5)
{ vPoint=Point*10; vSlippage=Slippage*10; }
else{ vPoint=Point; vSlippage=Slippage; }

< /strong>

간단한 영어 번역: 통화 쌍이 3 또는 5의 숫자로 표시되는 경우 pip 값은 포인트*10과 동일합니다. 그렇지 않은 경우(예: 2 또는 4), pip 값은 배수가 없는 pip 값으로 유지됩니다.


소수점 3자리 또는 5자리의 브로커를 자동으로 감지하고 조정하는 코드를 삽입하는 것은 제가 자체 기사 "자동으로 미끄러짐 감지 및 이는 포인트 가치에서 자세히 설명했습니다.


구문, 언어 및 구조를 알아보세요. if 조건이 어떻게 괄호()로 묶여 있고 명령문이 중괄호 {}로 묶여 있는지 확인하세요. 이는 if 조건 뒤에 해당 문이 오는 일반적인 구조입니다. 이 경우 if 조건은 if(Digits==3 || Digits==5)이며 이중 등호(==)는 같음을 의미하고 이중 수직 막대(||)는 "또는"을 의미한다는 점을 기억하세요. , 당신은 당신의 단어가 기계어로 어떻게 번역되는지 알아야 합니다: 단지 "and" 또는 "or"라고 말하면 편리하겠지만, 이러한 단어를 사용하면 프로그램은 당신을 이해하지 못할 것입니다. 대신에 당신은 다음을 사용해야 합니다. "or"를 나타내는 이중 수직 막대(||)와 "and"를 나타내는 이중 기호(&&)

참고

'and'에 이중 기호(&&)를 입력하는 것은 쉽지만 'or'에 이중 수직 막대(||)를 입력하는 것은 어렵기 때문에 빠른 단축키는 복사하여 붙여넣는 것입니다.

마지막으로 괄호 안의 첫 번째 문{ vPoint=Point*10; vSlippage=Slippage*10; }에는 실제로 세미콜론으로 구분된 두 개의 문이 있습니다. 하나는 vPoint의 의미를 정의하는 문이고 다른 하나는 정의하는 문입니다. vSlippage의 의미. 조건이 충족되지 않으면 대괄호 { vPoint=Point; vSlippage=Slippage; } 안의 대체 복합문을 가리키는 연동 else 함수가 있습니다.
마지막으로 대괄호 { vPoint=Point*10; vSlippage=Slippage*10; } 안의 첫 번째 문은 실제로 세미콜론으로 구분된 두 개의 문입니다. 한 문은 vPoint의 의미를 정의하고 다른 문은 정의합니다. vSlippage의 의미. 조건이 충족되지 않으면 대괄호 { vPoint=Point; vSlippage=slippage; } 안의 대체 복합문을 가리키는 연동 else 함수가 있습니다.

섹션 3: () 함수 시작

이 섹션이 가장 중요하고 가장 길기 때문에 이 섹션을 3A, 3B 등으로 구분된 덩어리로 나누는 것이 좋습니다.


이 start() 함수 시작 부분에 다음 줄을 포함했습니다:


< p>if(Bars<100) { Print(“100보다 작은 막대”);

Return (0); }


번역: 바가 100 미만인 경우 거래하지 말고 화면에 100 미만의 바를 인쇄하세요. 차트에 로드된 막대가 충분하지 않은 경우 거래가 발생하는 것을 방지하려면 이 코드를 포함하는 것이 유용합니다.


구문, 언어 및 구조를 알아보세요. 이것은 "if" 뒤의 괄호 안에 설정된 또 다른 if 조건입니다(Bars < 100). 이제 if 조건 뒤에 오는 표현식이 두 개 이상의 복합 문을 포함하는 경우 중괄호 {} 내에 설정되어야 하며 중괄호 내의 각 문은 세미콜론으로 구분되어야 합니다. 이 예에서는 if 조건 뒤에 두 개의 명령문이 있습니다. 첫 번째 명령문에서 Print는 상주 함수이므로 따옴표로 묶어 설명하고 괄호로 묶어야 합니다. 조건이 충족되면 해당 설명을 화면에 인쇄합니다. 세미콜론이 표현식을 완성합니다. 두 번째 명령문에서 반환(0)은 막대가 100개 미만이면 거래가 발생하지 않음을 의미합니다.

참고

각 여는 중괄호는 다음과 같아야 합니다. 일치하는 닫는 중괄호가 없으면 컴파일되지 않으므로 닫는 중괄호를 사용하여 두 명령문을 모두 닫습니다.

섹션 3A: 일반적인 거래 기능을 위한 짧은 태그 정의

여기에서는 일반적인 거래 기능을 나타내는 몇 가지 짧은 태그를 정의했습니다. 짧은 태그이며 MagicNumbers와 함께 사용할 수 있습니다.


내 거래 기능을 MagicNumbers와 함께 작동시키려는 이유는 무엇입니까?


MagicNumber는 EA의 지문으로, 프로그램이 이 EA를 동일한 통화 및 시간대에서 운영되는 다른 EA(또는 거래)와 구별할 수 있게 해줍니다. 예를 들어 프로그램이 플랫폼 자체의 공개 구매 포지션이 아닌 이 EA에 대한 공개 구매 포지션만 추적하도록 하려는 경우입니다. 따라서 거래 정보 기능을 참조할 때 해당 기능이 MagicNumber와 연결되기를 원합니다.

이러한 거래 정보 기능의 전체 목록과 정의를 보려면 여기를 클릭하십시오: http://docs.mql4.com/trading


< p>저는 매직넘버를 OrderSelect() 함수 아래에 배치하여 거래 함수가 매직넘버와 작동하도록 만들었습니다:

for(int Counter=1; Counter<=OrdersTotal(); Counter++)
{ if ( OrderSelect(Counter-1,SELECT_BY_POS, MODE_TRADES)==true)
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
태그 이름 = 일반적인 거래 기능;
}
}}

번역: 내 MagicNumber에 진행 중이거나 대기 중인 거래가 있는 경우 다음 태그 이름은 다음을 나타냅니다. 일반적인 거래 기능


린 구문, 언어 및 구조. 일반적으로 사용자 정의 함수의 첫 번째 줄에서 다양한 EA에서 OrderSelect 함수의 일부 변형을 자주 볼 수 있습니다(저는 이를 두 가지 함수인 4A와 4B에서 사용했습니다). OrderSelect 함수는 추가 처리를 위한 주문을 선택하고 함수가 성공하면 true를 반환하고 실패하면 false를 반환합니다.


OrderSelect() 함수는 매우 중요하기 때문에 제가 직접 작성한 글은 Retrieving Order Information with OrderSelect

< p >

나의 목적을 위해 OrderSelect 함수를 사용하여 거래, MODE_TRADES(미결 주문 및 대기 주문을 나타냄) 및 MagicNumber별로 선택합니다. 즉, 나는 이 함수에 포함된 거래 기능이 내 매직 넘버에 속하는 미결 주문과 보류 주문을 처리할 수 있기를 원합니다. 세 번째 줄, 특히 OrderMagicNumber() == MagicNumber 부분은 MagicNumber에 거래 기능을 포함시키기 위한 조건을 나타냅니다. 이 함수 아래에 그룹화한 모든 거래 함수 중에서 나중에 코드에서 사용한 함수는 섹션 3D "닫기 함수"에서 사용한 OType=OrderType()이었습니다.


또한 이 코드 블록의 첫 번째 줄의 관련성을 언급해야 합니다:


for(int Counter=1; Counter<=OrdersTotal(); Counter++) < /p>


이것을 for 연산자라고 하며 미리 정해진 횟수만큼 코드 블록을 반복하는 데 사용됩니다. 첫 번째 표현식 int = Counter =1은 Counter 변수를 값 1로 초기화합니다. 두 번째 표현식인 Counter <=OrdersTotal()은 true인 경우 중괄호 안의 코드를 실행하는 조건입니다(3개의 열린 명령이 있는 경우 루프를 3번 실행합니다). 세 번째 표현인 Counter++는 "Counter의 값을 1만큼 증가시킨다"는 의미입니다. 루프가 완료될 때마다 이 경우 카운터는 모든 미결 주문이 처리될 때까지 1씩 증가합니다.


파트 3B: 지표 호출

여기서 4가지 이동 평균을 선언합니다.


FastMACurrent = iMA(NULL, FastMATime, FastMAPeriod, FastMAShift, FastMAType, FastMAPrice, Current + 0);

FastMAPrevious = iMA(NULL, FastMATime, FastMAPeriod, FastMAShift, FastMAType , FastMAPrice, Current + 1);

SlowMACurrent = iMA(NULL, SlowMATime, SlowMAPeriod, SlowMAShift, SlowMAType, SlowMAPrice, 현재 + 0);

SlowMAPrevious = iMA(NULL, SlowMATime, SlowMAPeriod, SlowMAShift, SlowMAType, SlowMAPrice, Current + 1);


각각은 고유한 구문을 갖는 MT4의 기본 이동 평균 표시기를 참조합니다.

< p>

double iMA(String Symbo), int Timeframe, int MAPeriod, int MAShift, int MAMethod, int MAPrice, int Shift)


< /p>

iMA 식별자 뒤의 괄호 안에 있는 구조를 여러 좌석이 할당된 버스로 생각하고 싶습니다. 버스의 각 좌석은 쉼표로 구분되며 이를 매개변수라고 합니다. iMA 표시기에는 7개의 매개변수가 있습니다. 각 매개변수에는 사용자 정의(또는 버스 비유를 유지하기 위해 개인화)할 수 있는 기본값이 있습니다. 각 매개변수의 기능, 각 매개변수의 기본값, 맞춤 설정 방법, 실제로 버스를 구동하는 매개변수를 이해하는 것이 유용합니다.


다음 표에서는 이동 평균의 각 매개변수를 설명합니다.

< colgroup>
MA
매개변수
설명
기호기호 거래 , EURUSD와 같은. Symbol()은 통화 차트 쌍을 나타냅니다
TimeFrame 이동평균이 적용되는 차트 기간으로, 일반적으로 다음과 같이 설정됩니다. 0은 EA가 차트에 기호를 첨부했음을 나타냅니다.
MAPeriod이동평균의 룩백 기간입니다. 가장 중요한 변수입니다.
MAShift이동평균의 전진 이동(바 단위)은 일반적으로 0으로 설정됩니다.
MAMethod이동 평균 계산 방법은 단순, 지수, 평활 또는 선형 가중치를 선택할 수 있습니다. 두 번째로 중요한 변수입니다.
MAPrice이동평균을 계산할 때 사용되는 가격 배열로, 종가, 시가, 최고가, 최저가 또는 일부 유형이 될 수 있습니다. 평균. 일반적으로 기본값인 0 또는 끄기를 사용합니다.
Shift계산된 막대의 뒤로 이동을 반환합니다. 값 0은 현재 바의 표시 값을 반환하고, 값 3은 3바 전의 표시 값을 반환합니다. 앞으로 살펴보겠지만 이는 세 번째로 중요한 변수입니다.

가능 MA 매개변수(및 모든 20개 기본 지표의 매개변수)에 대한 편리한 빠른 참조는 http://docs.mql4.com/indicators/iMA < /span> 우리의 경우 direct 우리의 목적을 위해 우리는 기본 매개변수 값을 사용할 것입니다. 우리의 목적에 가장 중요한 매개변수는 이동 평균의 길이인 MAPeriod입니다. FastMAPeriod I의 기본값은 2이고 SlowMAPeriod I의 기본값은 30입니다. 버스를 구동하는 것은 MAPeriod입니다. MAPeriod는 빠른 이동 평균과 느린 이동 평균을 구별하기 때문입니다. MAMethod도 중요하며 특히 Simple(Integer=0) 및 Exponential(Integer=1)이 중요합니다. 빠른 이동 평균의 경우 기본값은 0 또는 단순이고, 느린 이동 평균의 경우 기본값은 1 또는 지수입니다. 따라서 30주기 지수이동평균이 2주기 단순이동평균을 교차하여 매수 신호를 보낼 것으로 예상합니다. MAShift 및 MAPrice는 일반적으로 0으로 유지되며 이러한 매개변수를 변경해도 거의 영향을 미치지 않습니다. 마지막 매개변수 Shift는 네 번째 매개변수 MAShift와 아무 관련이 없으므로 둘을 혼동하지 마세요. 사실 마지막 매개변수는 이동평균의 시간적 위치를 결정하는 중요한 매개변수입니다. 이전 막대를 현재 막대와 구별하는 것이 특히 중요합니다. 이는 진입 및 퇴출 논리의 필수 부분입니다. 이 모든 매개변수는 나중에 쉽게 수정하거나 최적화할 수 있도록 외부 변수로 배치되었음을 기억하세요. 빠른 질문: 이중 MA 크로스오버에 빠르고 느린 이동 평균만 사용한다면 왜 4개의 이동 평균을 선언해야 합니까? 더블 MA 크로스오버를 하고 싶을 때, 크로스오버 전후에 무슨 일이 일어나는지 지적할 필요가 있습니다. 앞으로 살펴보겠지만 매수 크로스오버의 예는 현재 빠른 MA가 현재 느린 MA보다 높고 이전 빠른 MA가 이전 느린 MA보다 낮은 경우입니다. 이렇게 하려면 FastMACurrent, FastMAPrevious, SlowMACurrent, SlowMAPrevious의 네 가지 이동 평균을 정의해야 합니다. 현재 이동평균과 이전 이동평균의 차이는 무엇인가요? 현재 이동평균과 이전 이동평균의 유일한 차이점은 마지막 매개변수인 Shift 매개변수입니다. 현재 이동평균은 0이고 이전 이동평균은 1입니다.

섹션 3C: 입력 논리:

입력 논리의 첫 번째 부분에서는 앞서 언급한 EnterOpenBar 논리를 작성합니다. 흥미롭게도 이는 많은 전문 컨설턴트가 종종 간과하는 짧지만 중요한 코드 부분입니다. 코드는 다음과 같습니다:


Boolean open bar = true;

if(EnterOpenBar) if(iVolume(NULL,0,0) ) >1) openbar=false;


프로그램은 새 바의 시가를 어떻게 찾나요? 새 막대에 나타나는 첫 번째 틱을 찾아야 합니다. 따라서 위 코드에서는 거래량을 확인하고 발견된 새 막대의 첫 번째 틱을 감지할 때까지 거래 입력을 지연합니다. 두 개의 if 조건문이 연속해서 있는 것을 볼 수 있습니다.


첫 번째 "if(enteronopenbar)"는 이전에 기본값이 true로 설정된 bool 변수를 나타냅니다. true이면 다음 if 조건문인 "if (iVolume(NULL,0,0)>1)"로 전달됩니다. 두 번째 if 조건은 볼륨이 1인지 확인합니다. 이 경우 openbar는 새 막대의 첫 번째 주문 번호를 찾기 때문에 참이 됩니다(1보다 큰 것은 거짓임). 오픈바 확인은 간단하지만 모든 새 시스템의 중요한 구성 요소이므로 해당 기사인 Enter on Open Bar에서 이에 대해 자세히 설명합니다.


다음으로 EA의 두뇌, 진입과 퇴출을 위한 전략적 조건에 대해 계속 논의합니다.


코딩하려는 구매 및 판매 조건은 다음과 같습니다.


구매 조건 1:

3일 이동평균이 30일 이동평균을 초과하는 경우 시장에서 매수(공개 매도 포지션 청산)


< /p> p>

매도 조건 1:

3일 이동평균이 30일 이동평균보다 낮으면 시장에서 매도합니다(공개 매수 포지션도 청산).


이 두 조건은 어떻게 MQL4 코드로 변환됩니까?


교차 조건을 작성하는 방법에는 여러 가지가 있지만 교육 목적으로 가장 간단한 방법을 사용하겠습니다. MT4에는 교차 기능이 내장되어 있지 않으므로 일반적인 2단계 솔루션을 구축하겠습니다. 이전 봉의 빠른 이동평균이 이전에 느린 이동평균보다 낮았는지, 현재 봉의 이동평균이 느린 이동평균보다 높았는지 여부를 살펴봄으로써 매수 교차 조건을 표시합니다. 그러므로 선을 넘었습니다. 이제 다음 코드를 더 잘 이해할 수 있을 것입니다.


If (

FastMACurrent > SlowMACurrent &&

FastMAPrevious < SlowMAPrevious

&& 오픈 바)


{

구매 시 열기=True;

if (OppositeClose) CloseSell=true;

}

If (

FastMACurrent FastMAPrevious > SlowMAPrevious && openbar)

{

OpenBuy=true;

if (OppositeClose) CloseBuy=true;

}


있음 구문 측면에서 if 조건을 선언할 때 특히 두 개 이상의 문이 포함된 경우 논리를 중괄호 {}로 묶어야 합니다. FastMACurrent가 SlowMACurrent보다 커야 함을 나타내기 위해 연산자라고 하는 > 기호를 사용했습니다. 기본적으로 이전 봉의 20일 이동평균이 200일 이동평균보다 낮고 현재 봉의 20일 이동평균이 현재 봉의 200일 이동평균보다 높은 경우를 말합니다. , 시장에서 구매하세요. 연산자는 거래 조건에 매우 중요하기 때문에 이에 대한 간단한 기사를 썼습니다. 단순 논리 연산자


if 조건 뒤에 중괄호가 있습니다. {} 및 세미콜론으로 구분: 이동 평균 조건이 충족되면 하나의 문으로 OpenBuy를 true로 설정합니다. 이는 간단하고 이해하기 쉽습니다. 두 번째 진술은 좀 더 미묘합니다. 이전 이동 평균 조건이 충족되면 CloseSell을 true로 설정하고 extern bool OppositeClose도 true로 설정합니다. CloseSell 또는 CloseBuy bool을 활성화하기 전에 자체 내부 if 조건(이 경우 OppositeClose bool = true 또는 false)을 요청하는 방법에 유의하세요. 나는 이러한 내부 if bool 조건을 키 및 잠금 메커니즘으로 생각하여 최종 사용자가 전문 속성 탭에서 메커니즘(이 경우 OppositeClose)을 쉽게 열고 닫을 수 있도록 하는 것을 좋아합니다.


섹션 3D: 닫기 조건

<스팬 jsaction="click:E6Tfl,Gff3ac,tMZCfe; contextmenu:Nqw7Te,QP7LD; mouseout:Nqw7Te; mouseover:E6Tfl,c2aHje" jsname="W297wb">이 섹션은 while 연산자로 시작합니다. MQL4의 간단한 루프 방식으로 위에서 설명한 for 루프와 비슷하지만 반복 횟수를 잘 모르는 경우에 더 적합합니다. While 루프는 기본적으로 다음과 같습니다:

while (true) {
/ / 루프 코드
}

다음으로 매수 및 매도 주문을 종료하는 조건을 설정합니다.

if (OType==0 && CloseBuy==true)
{
close (OP_BUY); // Close Buy
return;
}

OType은 거래정보 함수 OderType()을 나타내는 변수로, 각각 각 거래 주문 유형에는 해당하는 정수가 있습니다. OrderType == 0은 매수 포지션인 OP_BUY를 나타내고, OrderType = 1은 매도 포지션인 OP_SELL을 나타냅니다.


다음은 다양한 주문 유형과 해당 정수 값입니다:

< td class="rowhead">OP_SELL< td>3
OrderType정수 설명
OP_BUY0매수 포지션
1포지션 매도
OP_BUYLIMIT구매 한도 보류 중
OP_BUYSTOP4구매 중지 보류 중
OP_SELLLIMIT5판매 한도 보류 중
OP_SELLSTOP6판매 중지 보류

현재 있는 경우 구매 포지션(OType==1)을 입력하고 bool CloseBuy가 (==) true인 경우 맞춤 마감 기능인 close(OP_BUY)를 실행할 수 있습니다. 맞춤형 마감 기능에 대해 알아보려면 여기를 클릭하세요.


이 섹션은 break 연산자로 끝납니다. 'break' 연산자는 'while', 'for' 또는 'switch' 유형의 가장 가까운 외부 연산자의 실행을 중지합니다. 'break' 연산자의 실행은 'while', 'for' 또는 'switch' 유형의 복합 연산자를 넘어 제어권을 가장 가까운 후속 연산자로 전달하는 것으로 구성됩니다.


섹션 3E: 주문하기

이전 섹션의 break 연산자 다음에 또 다른 while 연산자로 이 섹션을 시작합니다. 이전 섹션의 인터럽트로 인해 제어 또는 흐름이 두 번째 while 루프로 넘겨졌습니다.


이 섹션에서는 프로그램이 매수 및 매도 주문을 합니다.


다음 조건으로 시작합니다:


if (OrdersTotalMagicOpen()== 0 && OpenBuy==true)


OrdersTotalMagicOpen()은 곧 액세스할 사용자 정의 프로그램으로, EA에 포함된 마법을 계산합니다. 해당 숫자의 미결 주문 수입니다. 총 주문 수가 0(==0)이면 계속할 수 있습니다. (&&) bool OpenBuy가 true이면 계속할 수 있습니다.


다음은 손절매 및 이익 목표 값을 결정하는 코드입니다.


if (StopLoss>0){SL=Bid – StopLoss*vPoint;}else{SL=0;} if(TakeProfit>0){TP=Bid+TakeProfit*vPoint;}else{TP=0;}

< p>

여기서는 두 개의 if-else 순차 문을 연속적으로 사용합니다. 조금 백업해 보겠습니다. else 조건은 앞의 if 문이 false인 경우 대체 조건을 평가한다는 점을 기억하세요. else와 if를 결합하여 true인 경우에만 실행되는 대체 조건을 만듭니다. 이 경우 StopLoss > 0이면 StopLoss 값(Bid-StopLoss *vPoint)을 결정할 수 있다고 말합니다. 그것이 0이 아닌 정지 손실이라면 정지 손실의 가치를 확신할 수 없으며 이 대안은 정지 손실을 0으로 유지하는 것입니다. 이익실현에 대해서도 동일한 논리가 반복됩니다. 이러한 if-else 조건을 기반으로 결정된 값은 OrderSend() 함수의 StopLoss 및 TakeProfit 매개변수에 나타납니다.


다음으로, 갱신율을 계속 유지하고 주문이 실행될 때까지 푸시하려고 합니다.


티켓=0; 번호=0;

while(ticket<=0 && 번호<100){

새로고침 빈도();< /p>< p>

티켓이 0(주문이 아직 채워지지 않음)이고 채우기 시도 횟수가 100회 미만이면 계속해서 새로 고침한다는 뜻입니다. 비율을 확인하고 채우려고 노력하세요. 빠르게 움직이는 시장에서 재견적이 있고 어쨌든 채워지고 싶을 때 유용한 코드입니다. 이번에도 티켓과 주문 시도 횟수를 반복하면서 while 연산자가 실행되는 것을 볼 수 있습니다.


다음은 OrderSend() 함수입니다. 이는 그 자체로 다각적인 기능이며 여기에 짧은 기사를 썼습니다. Market Orders with OrderSend